def getp_fromapbp(fileAP): try: aps=pp(file=fileAP,var="aps",x=0,y=0).getf() bps=pp(file=fileAP,var="bps",x=0,y=0).getf() nz = len(aps) except: print("info: read apbp.txt") ap,bp = np.loadtxt("apbp.txt",unpack=True) nz = len(ap) aps = 0.5*(ap[0:nz-1]+ap[1:nz]) bps = 0.5*(bp[0:nz-1]+bp[1:nz]) nz = len(aps) #print("... ps") ps=pp(file=fileAP,var="ps").getf() nt,ny,nx = ps.shape p = np.zeros((nt,nz,ny,nx)) if method == 1: ps=ppcompute.mean(ps,axis=2) p = np.zeros((nt,nz,ny)) #print("... compute p") for tt in range(nt): for kk in range(nz): if method == 1: p[tt,kk,:] = aps[kk]+bps[kk]*ps[tt,:] elif method == 2: p[tt,kk,:,:] = aps[kk]+bps[kk]*ps[tt,:,:] return p
def calculate_bounds(field,vmin=None,vmax=None,sigma=None): # prescribed cases first zevmin = vmin zevmax = vmax # particular case: only nan in field if False not in np.isnan(field): zevmin = np.nan zevmax = np.nan # GENERAL cases to be computed else: if zevmin is None or zevmax is None: # calculate min and max ind = np.where(np.abs(field) < 9e+35) # select values fieldcalc = field[ ind ] # field must be a numpy array amin = ppcompute.min(field) amax = ppcompute.max(field) # default case: sigma is None, take min and max if sigma is None: zevmin = amin zevmax = amax # if sigma not None: calculate stdev and mean else: dev = np.std(fieldcalc)*sigma damean = ppcompute.mean(fieldcalc) # fill min/max if needed if vmin is None: zevmin = damean - dev if vmax is None: zevmax = damean + dev # special case: negative values with stddev while field is positive if zevmin < 0. and ppcompute.min(fieldcalc) >= 0.: zevmin = 0. # check that bounds are not too tight given the field if np.abs(amin) < 1.e-15: cmin = 0. else: cmin = 100.*np.abs((amin - zevmin)/amin) cmax = 100.*np.abs((amax - zevmax)/amax) if cmin > 150. or cmax > 150.: print "!! WARNING !! Bounds are a bit too tight. Might need to reconsider those." print "!! WARNING !! --> actual",amin,amax,"adopted",zevmin,zevmax return zevmin, zevmax
########################################## print "compute transport" # ---- e.g. Lebonnois et al. 2010 equation 19 # [(vq)bar] : total meridional transport # [qbar][vbar]: by mean meridional circulation # [(qstar)bar][(vstar)bar] : by stationary waves # [(q'v')bar] : by transients (eddies) = [(vq)bar] - [qbar vbar] # ----- # 0. the easy bit (MMC) mmc_trans = meanu2D * meanv2D # 1. compute bar (temporal mean) tot_trans = v4D * u4D eddy_trans = primv4D * primu4D if timeaxis: tot_trans = ppcompute.mean(tot_trans, axis=0) eddy_trans = ppcompute.mean(eddy_trans, axis=0) statu = ppcompute.mean(staru4D, axis=0) statv = ppcompute.mean(starv4D, axis=0) # 2. compute [] (zonal mean) if vertaxis: zeaxis = 2 else: zeaxis = 1 tot_trans = ppcompute.mean(tot_trans, axis=zeaxis) eddy_trans = ppcompute.mean(eddy_trans, axis=zeaxis) if timeaxis: stat_trans = ppcompute.mean(statu, axis=zeaxis) * ppcompute.mean( statv, axis=zeaxis) else: stat_trans = None # 3. multiply by mass/metric term (computed above) tot_trans = tot_trans * massmetric
## BINNING ! ## -- method 1 #meanwind = ppcompute.meanbin(y,x,lats) ## -- method 2 (each dataset has same weight) choi = ppcompute.meanbin(choiwind,choilat,lats) sanch = ppcompute.meanbin(sanchwind,sanchlat,lats) vasa = ppcompute.meanbin(vasawind,vasalat,lats) gmcb = ppcompute.meanbin(gmcbwind,gmcblat,lats) gmmt = ppcompute.meanbin(gmmtwind,gmmtlat,lats) meanwind = [] for iii in range(len(choi)): #tab = [choi[iii],sanch[iii]] #tab = [choi[iii],sanch[iii],vasa[iii]] #tab = [choi[iii],sanch[iii],vasa[iii],gmcb[iii]] tab = [choi[iii],sanch[iii],vasa[iii],gmcb[iii],gmmt[iii]] comp = ppcompute.mean(tab) if np.abs(lats[iii]) >= 85.: comp = 0. if np.abs(lats[iii]) >= 80.: comp = comp/5. if np.abs(lats[iii]) >= 78.: comp = comp/2. if math.isnan(comp): meanwind.append(0.) else: meanwind.append(comp) ## smooth a little bit meanwind = ( np.roll(meanwind,-1) + meanwind + np.roll(meanwind,1) ) / 3. ## ADD LONGITUDE DIMENSION and ALTITUDE DIMENSION unat = np.tile(meanwind,(nlon,1)).transpose() nz = press.shape[0] unat = np.tile(unat,(nz,1,1)).transpose() if writefile:
t=tt, x=0, y=0, changetime="correctls_noadd").getf() except: press = pp(var="presnivs", file=fi, x=0, y=0, changetime="correctls_noadd").getf() lat = np.linspace(-90., 90., up.shape[1]) print press # compute <u'v'> (zonal mean) vptpm = mean(vp * tp, axis=2) upvpm = mean(up * vp, axis=2) # plot p = plot2d() p.f = upvpm p.c = vptpm p.x = lat p.y = press / 100. p.title = r'$\overline{u^\prime v^\prime}$ (shaded) $\overline{v^\prime t^\prime}$ (contours)' p.xlabel = "Latitude" p.ylabel = "Pressure (mb)" p.units = r'$m^{2}s^{-2}$' p.invert = True p.logy = True p.colorbar = "RdBu_r"
def make(self): # get what is done in the parent class... plot.make(self) if self.fmt is None: self.fmt = "%.1e" # ... then add specific stuff ############################################################################################ ### PRE-SETTINGS ############################################################################################ # if projection is set, set mapmode to True if self.proj is not None: self.mapmode = True # set dummy xy axis if not defined if self.x is None: self.x = np.array(range(self.f.shape[0])) self.mapmode = False print "!! WARNING !! dummy coordinates on x axis" if self.y is None: self.y = np.array(range(self.f.shape[1])) self.mapmode = False print "!! WARNING !! dummy coordinates on y axis" # check sizes if self.c is not None: if self.c.ndim != 2: print "!! WARNING !! Contour is not a 2D field. No contour.",self.c.ndim self.c = None if self.f.ndim != 2: print "!! ERROR !! Field is not two-dimensional" ; exit() # transposing if necessary shape = self.f.shape if shape[0] != shape[1]: if len(self.x) == shape[0] and len(self.y) == shape[1]: #print "!! WARNING !! Transposing axes" self.f = np.transpose(self.f) if self.c is not None: self.c = np.transpose(self.c) # bound field zevmin, zevmax = calculate_bounds(self.f,vmin=self.vmin,vmax=self.vmax,sigma=self.sigma) what_I_plot = bounds(self.f,zevmin,zevmax) # define contour field levels. define color palette ticks = self.div + 1 zelevels = np.linspace(zevmin,zevmax,ticks) palette = get_cmap(name=self.colorbar) # do the same thing for possible contourline entries if self.c is not None: # if masked array, set masked values to filled values (e.g. np.nan) for plotting purposes if type(self.c).__name__ in 'MaskedArray': self.c[self.c.mask] = self.c.fill_value # set levels for contour lines if self.clev is None: zevminc, zevmaxc = calculate_bounds(self.c) what_I_contour = bounds(self.c,zevminc,zevmaxc) ticks = self.div + 1 self.clev = np.linspace(zevminc,zevmaxc,ticks) else: what_I_contour = self.c # formatting ft = int(mpl.rcParams['font.size']*0.55) if self.cfmt is None: self.cfmt = "%.2g" ############################################################################################ ### MAIN PLOT ### NB: contour lines are done before contour shades otherwise colorar error ############################################################################################ if not self.mapmode: ## A SIMPLE 2D PLOT ################### # swapping if requested if self.swap: x = self.y ; y = self.x else: x = self.x ; y = self.y # coefficients on axis if self.xcoeff is not None: x=x*self.xcoeff if self.ycoeff is not None: y=y*self.ycoeff # make shaded and line contours if self.c is not None: objC = mpl.contour(x, y, what_I_contour, \ self.clev, colors = self.ccol, linewidths = cline) ft = int(mpl.rcParams['font.size']*0.55) mpl.clabel(objC, inline=1, fontsize=ft,\ inline_spacing=1,fmt=self.cfmt) mpl.contourf(x, y, \ self.f, \ zelevels, cmap=palette) #mpl.pcolor(x,y,\ # self.f, \ # cmap=palette) # make log axes and/or invert ordinate ax = mpl.gca() if self.xdate: import matplotlib.dates as mdates ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%y %Hh')) #ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%b-%d %H:%M:%S')) ax.xaxis.set_major_locator(mdates.DayLocator()) mpl.setp(mpl.xticks()[1], rotation=30, ha='right') # rotate the x labels if self.logx: mpl.semilogx() if self.logy: mpl.semilogy() if self.invert: ax.set_ylim(ax.get_ylim()[::-1]) if self.xmin is not None and self.xmax is not None: if self.xmin > self.xmax: ax.set_xlim(ax.get_xlim()[::-1]) self.xmin,self.xmax = self.xmax,self.xmin if self.xmin is not None: ax.set_xbound(lower=self.xmin) if self.xmax is not None: ax.set_xbound(upper=self.xmax) if self.ymin is not None: ax.set_ybound(lower=self.ymin) if self.ymax is not None: ax.set_ybound(upper=self.ymax) # use back attributes to set a background if self.back is not None: ax.set_axis_bgcolor(self.back) # set the number of ticks if not self.logx: ax.xaxis.set_major_locator(MaxNLocator(self.nxticks)) else: pass #print "!! WARNING. in logx mode, ticks are set automatically." if not self.logy: ax.yaxis.set_major_locator(MaxNLocator(self.nyticks)) else: pass #print "!! WARNING. in logy mode, ticks are set automatically." ## specific modulo labels if self.modx is not None: ax = labelmodulo(ax,self.modx) else: ## A 2D MAP USING PROJECTIONS (basemap) ####################################### mpl.xlabel("") ; mpl.ylabel("") # additional security in case self.proj is None here # ... we set cylindrical projection (the simplest one) if self.proj is None: self.proj = "cyl" # get lon and lat in 2D version. # (but first ensure we do have 2D coordinates) if self.x.ndim == 1: [self.x,self.y] = np.meshgrid(self.x,self.y) elif self.x.ndim > 2: print "!! ERROR !! lon and lat arrays must be 1D or 2D" # get lat lon intervals and associated settings wlon = [np.min(self.x),np.max(self.x)] wlat = [np.min(self.y),np.max(self.y)] # -- area presets are in set_area.txt if self.area is not None: if self.area in area.keys(): wlon, wlat = area[self.area] # -- user-defined limits if self.xmin is not None: wlon[0] = self.xmin if self.xmax is not None: wlon[1] = self.xmax if self.ymin is not None: wlat[0] = self.ymin if self.ymax is not None: wlat[1] = self.ymax # -- settings for meridians and parallels steplon = int(abs(wlon[1]-wlon[0])/3.) steplat = int(abs(wlat[1]-wlat[0])/3.) #mertab = np.r_[wlon[0]:wlon[1]:steplon] ; merlab = [0,0,0,1] #partab = np.r_[wlat[0]:wlat[1]:steplat] ; parlab = [1,0,0,0] if steplon < 1: steplon = 1 if steplat < 1: steplat = 1 if np.abs(wlon[0]) < 180.1 and np.abs(wlon[1]) < 180.1: mertab = np.r_[-180.:180.:steplon] else: mertab = np.r_[0.:360.:steplon] merlab = [0,0,0,1] partab = np.r_[-90.:90.+steplat:steplat] ; parlab = [1,0,0,0] format = '%.1f' # -- center of domain and bounding lats lon_0 = 0.5*(wlon[0]+wlon[1]) lat_0 = 0.5*(wlat[0]+wlat[1]) # some tests, bug fixes, and good-looking settings # ... cyl is good for global and regional if self.proj == "cyl": format = '%.0f' partab = np.r_[-90.:90.+15.:15.] # ... global projections elif self.proj in ["ortho","moll","robin"]: wlat[0] = None ; wlat[1] = None ; wlon[0] = None ; wlon[1] = None lon_0 = np.ceil(lon_0) # reverse map if lon_0 is slightly below 180 with [0,360] steplon = 30. ; steplat = 30. if self.proj in ["moll"]: steplon = 60. if self.proj in ["robin"]: steplon = 90. mertab = np.r_[-360.:360.:steplon] #partab = np.r_[-90.:90.+steplat:steplat] partab = np.r_[-60.,-30.,0.,30.,60.] if self.proj == "ortho": merlab = [0,0,0,0] ; parlab = [0,0,0,0] # in ortho projection, blon and blat can be used to set map center if self.blon is not None: lon_0 = self.blon if self.blat is not None: lat_0 = self.blat elif self.proj == "moll": merlab = [0,0,0,0] format = '%.0f' # ... regional projections elif self.proj in ["lcc","laea","merc"]: if self.proj in ["lcc","laea"] and wlat[0] == -wlat[1]: print "!! ERROR !! with Lambert lat1 must be different than lat2" ; exit() if wlat[0] < -80. and wlat[1] > 80.: print "!! ERROR !! set an area (not global)" ; exit() format = '%.0f' elif self.proj in ["npstere","spstere"]: # in polar projections, blat gives the bounding lat # if not set, set something reasonable if self.blat is None: self.blat = 60. # help the user who forgets self.blat would better be negative in spstere # (this actually serves for the default setting just above) if self.proj == "spstere" and self.blat > 0: self.blat = -self.blat # labels mertab = np.r_[-360.:360.:15.] partab = np.r_[-90.:90.:5.] # ... unsupported projections else: print "!! ERROR !! unsupported projection. supported: "+\ "cyl, npstere, spstere, ortho, moll, robin, lcc, laea, merc" # finally define projection try: from mpl_toolkits.basemap import Basemap except: print "!! ERROR !! basemap is not available." print "... either install it or use another plot type." exit() m = Basemap(projection=self.proj,\ lat_0=lat_0,lon_0=lon_0,\ boundinglat=self.blat,\ llcrnrlat=wlat[0],urcrnrlat=wlat[1],\ llcrnrlon=wlon[0],urcrnrlon=wlon[1]) # in some case need to translated to the left for colorbar + labels # TBD: break stuff. a better solution should be found. if self.leftcorrect: ax = mpl.gca() pos = ax.get_position().bounds newpos = [0.,pos[1],pos[2],pos[3]] ax.set_position(newpos) # draw meridians and parallels ft = int(mpl.rcParams['font.size']*3./4.) zelatmax = 85. m.drawmeridians(mertab,labels=merlab,color='grey',linewidth=0.75,fontsize=ft,fmt=format,latmax=zelatmax) m.drawparallels(partab,labels=parlab,color='grey',linewidth=0.75,fontsize=ft,fmt=format,latmax=zelatmax) # define background (see set_back.txt) if self.back is not None: if self.back in back.keys(): print "**** info: loading a background, please wait.",self.back if self.back not in ["coast","sea"]: try: m.warpimage(back[self.back],scale=0.75) except: print "!! ERROR !! no background image could be loaded. probably not connected to the internet?" elif self.back == "coast": m.drawcoastlines() elif self.back == "sea": m.drawlsmask(land_color='white',ocean_color='aqua') else: print "!! ERROR !! requested background not defined. change name or fill in set_back.txt" ; exit() # define x and y given the projection x, y = m(self.x, self.y) # contour field. first line contour then shaded contour. if self.c is not None: #zelevelsc = np.arange(900.,1100.,5.) objC2 = m.contour(x, y, what_I_contour, \ self.clev, colors = self.ccol, linewidths = cline) #mpl.clabel(objC2, inline=1, fontsize=10,manual=True,fmt='-%2.0f$^{\circ}$C',colors='r') #mpl.clabel(objC2, inline=0, fontsize=8, fmt='%.0f',colors='r', inline_spacing=0) m.contourf(x, y, what_I_plot, zelevels, cmap = palette, alpha = self.trans, antialiased=True) ############################################################################################ ### COLORBAR ############################################################################################ if self.trans > 0. and self.showcb: ## draw colorbar. settings are different with projections. or if not mapmode. #if not self.mapmode: orientation=zeorientation ; frac = 0.075 ; pad = 0.03 ; lu = 0.5 if not self.mapmode: orientation=zeorientation ; frac = 0.15 ; pad = 0.04 ; lu = 0.5 elif self.proj in ['moll']: orientation="horizontal" ; frac = 0.08 ; pad = 0.03 ; lu = 1.0 elif self.proj in ['robin']: orientation="horizontal" ; frac = 0.07 ; pad = 0.1 ; lu = 1.0 elif self.proj in ['cyl']: orientation="vertical" ; frac = 0.023 ; pad = 0.03 ; lu = 0.5 else: orientation = zeorientation ; frac = zefrac ; pad = 0.03 ; lu = 0.5 if self.cbticks is None: self.cbticks = min([ticks/2+1,21]) zelevpal = np.linspace(zevmin,zevmax,num=self.cbticks) zecb = mpl.colorbar(fraction=frac,pad=pad,\ format=self.fmt,orientation=orientation,\ ticks=zelevpal,\ extend='neither',spacing='proportional') if zeorientation == "horizontal": zecb.ax.set_xlabel(self.title) ; self.title = "" # colorbar title --> units if self.units not in ["dimless",""]: zecb.ax.set_title("["+self.units+"]",fontsize=3.*mpl.rcParams['font.size']/4.,x=lu,y=1.025) ############################################################################################ ### VECTORS. must be after the colorbar. we could also leave possibility for streamlines. ############################################################################################ ### not expecting NaN in self.vx and self.vy. masked arrays is just enough. if self.vx is not None and self.vy is not None: # vectors on map projection or simple 2D mapping if self.mapmode: try: #[vecx,vecy] = m.rotate_vector(self.vx,self.vy,self.x,self.y) # for metwinds only ? vecx,vecy = self.vx,self.vy except: print "!! ERROR !! Problem with field shapes for vector?" print self.vx.shape,self.vy.shape,self.x.shape,self.y.shape exit() else: vecx,vecy = self.vx,self.vy if x.ndim < 2 and y.ndim < 2: x,y = np.meshgrid(x,y) # reference vector is scaled if self.wscale is None: self.wscale = ppcompute.mean(np.sqrt(self.vx*self.vx+self.vy*self.vy)) # make vector field if self.mapmode: q = m.quiver( x[::self.svy,::self.svx],y[::self.svy,::self.svx],\ vecx[::self.svy,::self.svx],vecy[::self.svy,::self.svx],\ angles='xy',color=self.colorvec,pivot='middle',\ scale=self.wscale*reducevec,width=widthvec ) else: q = mpl.quiver( x[::self.svy,::self.svx],y[::self.svy,::self.svx],\ vecx[::self.svy,::self.svx],vecy[::self.svy,::self.svx],\ angles='xy',color=self.colorvec,pivot='middle',\ scale=self.wscale*reducevec,width=widthvec ) # make vector key. #keyh = 1.025 ; keyv = 1.05 # upper right corner over colorbar keyh = 0.97 ; keyv = 1.06 keyh = 0.97 ; keyv = 1.11 #keyh = -0.03 ; keyv = 1.08 # upper left corner p = mpl.quiverkey(q,keyh,keyv,\ self.wscale,str(int(self.wscale)),\ fontproperties={'size': 'small'},\ color='black',labelpos='S',labelsep = 0.07) ############################################################################################ ### TEXT. ANYWHERE. add_text.txt should be present with lines x ; y ; text ; color ############################################################################################ try: f = open("add_text.txt", 'r') for line in f: if "#" in line: pass else: userx, usery, usert, userc = line.strip().split(';') userc = userc.strip() usert = usert.strip() userx = float(userx.strip()) usery = float(usery.strip()) if self.mapmode: userx,usery = m(userx,usery) mpl.text(userx,usery,usert,\ color = userc,\ horizontalalignment='center',\ verticalalignment='center') f.close() except IOError: pass
var[:] = fie4[iii] var = None f.close() #################################################### ustart = pp(file=fileAP,var="u" ,t=0 ,x=charx).getf() uend = pp(file=fileAP,var="u" ,t=1e10,x=charx).getf() dudt = (uend - ustart) / (1000.*38052.) ## up = pp(file=fileAP,var="u" ,compute="pert_t").getf() ; etape("up",time0) print up.shape vp = pp(file=fileAP,var="v" ,compute="pert_t").getf() ; etape("vp",time0) upvpb = ppcompute.mean(up*vp ,axis=0) ; etape("upvpb" ,time0) ; del up ; del vp print upvpb.shape upvpbc = ppcompute.mean(upvpb ,axis=2) ; etape("upvpbc",time0) ; del upvpb ### stationary: negligible #us = pp(file=fileAP,var="u" ,compute="pert_x").getf() ; etape("us",time0) #vs = pp(file=fileAP,var="v" ,compute="pert_x").getf() ; etape("vs",time0) #us_b = ppcompute.mean(us ,axis=0) ; etape("usb" ,time0) ; del us #vs_b = ppcompute.mean(vs ,axis=0) ; etape("vsb" ,time0) ; del vs #usvsbc = ppcompute.mean(us_b,axis=2)*ppcompute.mean(vs_b,axis=2) ; etape("usvsbc",time0) #usvsbc = interpolate(targetp1d,press,usvsbc) ; etape("usvsbc",time0) #################################################### print "... interpolating !" ubc = interpolate(targetp1d,press,ubc) ; etape("ubc" ,time0) ; addvar(outfile,nam4,'ubc',ubc)
if is_omega: o=pp(file=fileAP,var="omega",x=charx).getf() ; etape("omega",time0) if is_gwdparam: east_gwstress=pp(file=fileAP,var="east_gwstress",x=charx).getf() ; etape("east_gwstress",time0) west_gwstress=pp(file=fileAP,var="west_gwstress",x=charx).getf() ; etape("west_gwstress",time0) print("... coupled terms") if charx == "999": vpup=pp(file=fileAP,var="vpup",x=charx).getf() ; etape("vpup",time0) vptp=pp(file=fileAP,var="vptp",x=charx).getf() ; etape("vptp",time0) upup=pp(file=fileAP,var="upup",x=charx).getf() ; etape("upup",time0) vpvp=pp(file=fileAP,var="vpvp",x=charx).getf() ; etape("vpvp",time0) else: staru4D=pp(file=fileAP,var="u",compute="pert_x",x=charx).getf() ; etape("staru4D",time0) starv4D=pp(file=fileAP,var="v",compute="pert_x",x=charx).getf() ; etape("starv4D",time0) start4D=pp(file=fileAP,var=vartemp,compute="pert_x",x=charx).getf() ; etape("start4D",time0) vpup=ppcompute.mean(starv4D*staru4D,axis=3) ; etape("vpup",time0) vptp=ppcompute.mean(starv4D*start4D,axis=3) ; etape("vptp",time0) upup=ppcompute.mean(staru4D*staru4D,axis=3) ; etape("upup",time0) vpvp=ppcompute.mean(starv4D*starv4D,axis=3) ; etape("vpvp",time0) if is_omega: staro4D=pp(file=fileAP,var="omega",compute="pert_x",x=charx).getf() ; etape("staro4D",time0) opup=ppcompute.mean(staro4D*staru4D,axis=3) ; etape("opup",time0) optp=ppcompute.mean(staro4D*start4D,axis=3) ; etape("optp",time0) del staro4D del staru4D ; del starv4D ; del start4D #################################################### print("... interpolating !") if method == 1: u = interpolate(targetp1d,press,u,spline=use_spline) ; etape("u",time0) #temp = interpolate(targetp1d,press,temp,spline=use_spline) ; etape(vartemp,time0)
vp = vp[itemindex,:,:,:] tp = tp[itemindex,:,:,:] ############################################################### # coordinates try: press = pp(var="p",file=fi,t=tt,x=0,y=0,changetime="correctls_noadd").getf() except: press = pp(var="presnivs",file=fi,x=0,y=0,changetime="correctls_noadd").getf() lat = np.linspace(-90.,90.,up.shape[1]) print press # compute <u'v'> (zonal mean) vptpm = mean(vp*tp,axis=2) upvpm = mean(up*vp,axis=2) # plot p = plot2d() p.f = upvpm p.c = vptpm p.x = lat p.y = press/100. p.title = r'$\overline{u^\prime v^\prime}$ (shaded) $\overline{v^\prime t^\prime}$ (contours)' p.xlabel = "Latitude" p.ylabel = "Pressure (mb)" p.units = r'$m^{2}s^{-2}$' p.invert = True p.logy = True p.colorbar = "RdBu_r"
temp4D,longit,latit,pniv,time=pp(file=fileAP,var="temp",verbose=verb).getfd() v4D=pp(file=fileAP,var="vitv",verbose=verb).getf() print "get 4D fields (zonal anomaly" anotemp4D=pp(file=fileAP,var="temp",verbose=verb,compute="pert_x").getf() anov4D=pp(file=fileAP,var="vitv",verbose=verb,compute="pert_x").getf() print "get 4D fields (temporal mean)" meantemp4D=pp(file=fileAP,var="temp",verbose=verb,t="0,1e15",x="-180,180").getf() meanv4D=pp(file=fileAP,var="vitv",verbose=verb,t="0,1e15",x="-180,180").getf() print "compute transport" # [(vq)bar] : transport total # [qbar][vbar]: transport mmc # [(q'v')bar] : transport trs = [(vq)bar] - [qbar vbar] tot_trans = ppcompute.mean(ppcompute.mean(v4D*temp4D,axis=3),axis=0) mmc_trans = meantemp4D*meanv4D eddy_trans = ppcompute.mean(ppcompute.mean(anov4D*anotemp4D,axis=3),axis=0) print "make plot" fig = ppplot.figuref(x=20,y=6) subv,subh = ppplot.definesubplot(3, fig) pl = ppplot.plot2d() pl.invert = True pl.logy = True pl.fmt = "%.1f" pl.vmin = -2 pl.vmax = +2 pl.colorbar = "RdBu_r" lat=latit[:,0]
########################################## print "compute transport" # ---- e.g. Lebonnois et al. 2010 equation 19 # [(vq)bar] : total meridional transport # [qbar][vbar]: by mean meridional circulation # [(qstar)bar][(vstar)bar] : by stationary waves # [(q'v')bar] : by transients (eddies) = [(vq)bar] - [qbar vbar] # ----- # 0. the easy bit (MMC) mmc_trans = meanu2D*meanv2D # 1. compute bar (temporal mean) tot_trans = v4D*u4D eddy_trans = primv4D*primu4D if timeaxis: tot_trans = ppcompute.mean(tot_trans,axis=0) eddy_trans = ppcompute.mean(eddy_trans,axis=0) statu = ppcompute.mean(staru4D,axis=0) statv = ppcompute.mean(starv4D,axis=0) # 2. compute [] (zonal mean) if vertaxis: zeaxis=2 else: zeaxis=1 tot_trans = ppcompute.mean(tot_trans,axis=zeaxis) eddy_trans = ppcompute.mean(eddy_trans,axis=zeaxis) if timeaxis: stat_trans = ppcompute.mean(statu,axis=zeaxis)*ppcompute.mean(statv,axis=zeaxis) else: stat_trans = None # 3. multiply by mass/metric term (computed above) tot_trans = tot_trans*massmetric mmc_trans = mmc_trans*massmetric