def Dewpoint(T, rh, method=None): """Computes dewpoint profile from T and rh Usage: Td = Dewpoint(T,rh,method=None) Where: T is in K rh is in % (relative humidity) method used to compute Es: 1: Hyland-Wexler formulation, polynomial coeff (absolute norm) (default) 2: Wexler formulation 3: Hyland-Wexler formulation, polynomial coeff (relative error norm) 4: classic Goff Gratch equation 5: 6.112*numpy.ma.exp(17.67*tempc/(tempc+243.5)) Assumes constant latent temperature (except over ice or water) """ To = 273.15 # K Rv = 461.53 # J/(K*kg) eo = 611 # Pa L = MV2.ones(T.shape) * 2.502e6 # J/kg L = MV2.where(MV2.less(T, To), 2.83e6, L) # J/kg es = Es(T, method=method) # in Pa e = rh * es / 100.0 Td = 1.0 / (1.0 / To - Rv / L * (e / eo)) Td.setAxisList(T.getAxisList()) return Td
def surface_maskvariable(var, surf_mask, surf_type=None): """ Quick script that takes as inputs, a masked variable and a surface mask to create a masked variable, where the area not of interest is masked out. Assumes that the surface mask has values with range 0 to 1. REMEMBER that the surf_mask denotes area that you want to have masked out, NOT the area that you want plotted. Also note: make sure that the mask and the variable have the same shape """ #If no surface mask is given, create mask if surf_mask is None: surf_mask = cdutil.generateLandSeaMask(data) if surf_type is 'land': surf_mask=surf_mask/100. if surf_type is 'ocean': surf_mask=(100.-surf_mask)/100. #Mask the variable according to the surf_mask - assumes that surf_mask is taken from 'LANDFRAC' # check to see if the surface mask and variable have the same shape, otherwise regrid surf_mask if surf_mask.shape!=var.shape: var_grid=var.getGrid() surf_mask=surf_mask.regrid(var_grid) condition=MV2.greater(surf_mask,0.5) var_masked=MV2.masked_where(condition,var) return var_masked
def scrap(data, axis=0): originalOrder = data.getOrder(ids=True) if axis not in ['x', 'y', 'z', 't'] and not isinstance(axis, int): order = "({})...".format(axis) else: order = "{}...".format(axis) new = data(order=order) axes = new.getAxisList() # Save for later new = MV2.array(new.asma()) # lose dims for i in range(new.shape[0] - 1, -1, -1): tmp = new[i] if not isinstance(tmp, (float, numpy.float)) and tmp.mask.all(): a = new[:i] b = new[i + 1:] if b.shape[0] == 0: new = a else: new = MV2.concatenate((a, b)) newAxis = [] for v in new.getAxis(0): newAxis.append(axes[0][int(v)]) ax = cdms2.createAxis(newAxis, id=axes[0].id) axes[0] = ax new.setAxisList(axes) return new(order=originalOrder)
def bias_extrema(self): """ Carte des biais moyens extremes (min,max) entre les champs modelises et observes """ import numpy as np import MV2 # modif J.Gatti biais=self.obs-self.model # index des min et max imin=np.ma.argmin(abs(biais), axis=0) imax=np.ma.argmax(abs(biais), axis=0) #signe des min et max biasminsign=np.zeros((biais.shape[1], biais.shape[2])) biasmaxsign=np.zeros((biais.shape[1], biais.shape[2])) ind1=range(biais.shape[1]) ind2=range(biais.shape[2]) for i in ind1: for j in ind2: biasminsign[i, j]=np.sign(biais.data[imin[i, j], i, j]) biasmaxsign[i, j]=np.sign(biais.data[imax[i, j], i, j]) # min et max self.biasmin=MV2.min(abs(biais), axis=0) *biasminsign self.biasmax=MV2.max(abs(biais), axis=0)*biasmaxsign del biais
def average_engine(x, wts): """ The work horse that does the averaging! This is specific to averageing. We will always be dealing with the first dimension.....and x is already in the order we will average. 1-d wts are always numpy arrays or 'equal' Multi-dimensional arrays are always MV2's """ # __DEBUG__ = 0 # if x is None: return None if wts is None: return None # shx = numpy.ma.shape(x) if __DEBUG__: print '\tInside average_engine.' if __DEBUG__: print '\tIncoming data of shape ', shx # if MV2.isMaskedVariable(wts) or isinstance(wts, numpy.ndarray): y, return_wts = MV2.average(x, weights=wts, returned=1, axis=0) return y, return_wts elif wts in ['equal','unweighted']: y, return_wts = MV2.average(x, returned=1, axis=0) return y, return_wts else: raise AveragerError, 'wts is an unknown type in average_engine' return None
def make_var(lap, id=None, shape=None): lap = MV2.array(lap) if shape is not None: lap = MV2.reshape(lap, shape) if id is not None: lap.id = id return lap
def get(self, var, varInFile=None, *args, **kargs): self.variable = var if varInFile is None: varInFile = var # First extract data f = cdms2.open(os.path.abspath(self())) out = f(varInFile, *args, **kargs) f.close() # Now are we looking at a region in particular? if self.mask is not None: if self.mask.shape != out.shape: dum, msk = genutil.grower(out, self.mask) else: msk = self.mask out = MV2.masked_where(msk, out) if self.targetGrid is not None: out = out.regrid( self.targetGrid, regridTool=self.regridTool, regridMethod=self.regridMethod, coordSys='deg', diag={}, periodicity=1) if self.targetMask is not None: if self.targetMask.shape != out.shape: dum, msk = genutil.grower(out, self.targetMask) else: msk = self.targetMask out = MV2.masked_where(msk, out) return out
def post(self,fetched,slab,axes,specifications,confined_by,aux,axismap): ''' Post processing retouches the bounds and later will deal with the mask''' import cdms2 as cdms fetched=cdms.createVariable(fetched,copy=1) faxes=fetched.getAxisList() a=None for i in range(len(faxes)): if confined_by[i] is self: newaxvals=[] bounds=[] a=None sh=list(fetched.shape) sh[i]=1 for l in self.aux[i]: try: tmp=fetched(**{faxes[i].id:(l,l)}) ax=tmp.getAxis(i) #print ax newaxvals.append(ax[0]) if ax.getBounds()!=None: bounds.append(ax.getBounds()[0]) else: bounds=None except Exception,err: #print 'err:',err,'match:',self.match if self.match==1: raise Exception,'Error axis value :'+str(l)+' was requested but is not present in slab\n(more missing might exists)' elif self.match==0: tmp=MV2.ones(sh,typecode=MV2.float) tmp=MV2.masked_equal(tmp,1) if type(l)==type(cdtime.comptime(1999)) or type(l)==type(cdtime.reltime(0,'days since 1999')) or type(l)==type(''): if type(l)!=type(''): newaxvals.append(l.torel(faxes[i].units).value) else: newaxvals.append(cdtime.s2r(l,faxes[i].units).value) else: newaxvals.append(l) if bounds is not None: bounds.append([ax[-1]-1.,ax[-1]+1]) else: tmp=None if not tmp is None: if a is None: a=tmp elif not tmp is None: a=MV2.concatenate((a,tmp),i) if bounds is not None: newax=cdms.createAxis(numpy.array(newaxvals),bounds=numpy.array(bounds),id=ax.id) else: newax=cdms.createAxis(numpy.array(newaxvals),id=ax.id) for att in faxes[i].attributes.keys(): setattr(newax,att,faxes[i].attributes.get(att)) for j in range(len(fetched.shape)): if j==i: a.setAxis(i,newax) else: a.setAxis(j,faxes[j]) fetched=a.astype(fetched.dtype.char) faxes=fetched.getAxisList()
def sumregions(potential_reg,potential): out = potential_reg[0]*1. wts = potential[0]*1. for i in range(1,potential.shape[0]): c = MV2.greater(potential[i]-wts,0) out = MV2.where(c,potential_reg[i],out) wts = MV2.where(c,potential[i],wts) return out
def vectoravg(hr1, hr2, clocktype): 'Function to test vector-averaging of two time values:' import MV2 sin_avg = (MV2.sin(hrs_to_rad(hr1, clocktype)) + MV2.sin(hrs_to_rad(hr2, clocktype))) / 2 cos_avg = (MV2.cos(hrs_to_rad(hr1, clocktype)) + MV2.cos(hrs_to_rad(hr2, clocktype))) / 2 return rad_to_hrs(MV2.arctan2(sin_avg, cos_avg), clocktype)
def ensrank(obs, ens, gethist=False, getnrz=False, centered=False): """Compute the rank of a reference (observations) in an ensemble If ``nens`` is the size of the ensemble, the rank may go from ``0`` to ``nens``. - **obs**, (...): Observation array - **ens**, (nens,...): Ensemble array - **getrank**, optional: If True, return also the rank histogram - **getnrz**, optional: If True, return also non recovery zones - **centered**, optional: Center the ensemble data on the observations before computing the rank """ # Check ens = MV2.asarray(ens) obs = MV2.asarray(obs) nens = ens.shape[0] assert nens>3, 'Your ensemble is too small (nens=%i)'%nens # Inits rank = obs.clone() rank.id = 'rank' rank.long_name = 'Rank' if hasattr(rank, 'units'): del rank.units nrz = obs.clone() nrz.id = 'nrz' nrz.long_name = 'Non recovery zones' nrz[:] = MV2.masked # Sort ensemble at each pixel and compute the min biais bias = MV2.sort(ens, axis=0)-obs if centered: bias -= bias.mean(axis=0) nrz[:] = MV2.where((bias[-1]<0.).astype('b'), bias[-1], nrz) nrz[:] = MV2.where((bias[0]>0.).astype('b'), bias[0], nrz) # Index of member = rank rank[:] = (bias<0).astype('i').sum(axis=0) del bias ## Apply observation mask #nrz[:] = MV2.masked_where(MV2.getmask(obs), nrz, copy=0) #rank[:] = MV2.masked_where(MV2.getmask(obs), rank, copy=0) # Rank histogram if gethist: if N.ma.isMA(rank): rank = rank.compressed() hist = N.histogram(rank, N.arange(0,nens+1)) # Out ret = rank, if gethist: ret += hist, if getnrz: ret += nrz, return ret[0] if len(ret)==1 else ret
def compute(dm, do): """ Computes bias""" if dm is None and do is None: # just want the doc return { "Name": "Bias", "Abstract": "Compute Full Average of Model - Observation", "Contact": "Peter Gleckler <*****@*****.**>", } return MV2.float(MV2.average(MV2.subtract(dm, do)))
def flatAxes(self): """Return (flatlat, flatlon) where flatlat is a 1D NumPy array having the same length as the number of cells in the grid, similarly for flatlon.""" if self._flataxes_ is None: import MV2 as MV alat = MV.filled(self.getLatitude()) alon = MV.filled(self.getLongitude()) self._flataxes_ = (alat, alon) return self._flataxes_
def mask_var(self, var): if self.mask is None: self.set_file_mask_template() self.mask = self.get_mask_from_var(var) if self.mask.shape != var.shape: dummy, mask = genutil.grower(var, self.mask) else: mask = self.target_mask mask = MV2.not_equal(mask, self.value) return MV2.masked_where(mask, var)
def compute(dm, do): """ Computes bias""" if dm is None and do is None: # just want the doc return { "Name": "Bias", "Abstract": "Compute Full Average of Model - Observation", "Contact": "*****@*****.**", } dif = MV2.subtract(dm, do) return MV2.float(cdutil.averager(dif, axis='xyt', weights='weighted'))
def compute(dm, do): """ Computes Mean Absolute Error""" if dm is None and do is None: # just want the doc return { "Name": "Mean Absolute Error", "Abstract": "Compute Full Average of " + "Absolute Difference Between Model And Observation", "Contact": "Peter Gleckler <*****@*****.**>", } mae = MV.average(MV.absolute(MV.subtract(dm, do))) return float(mae)
def temporal_mean(self): """ Moyennes temporelles pour les champs modelises et observes """ import MV2, cdutil import numpy as np # --------- !!!!!!! -------- Refelchir a Mettre plutot des return pour les fonctions ------- !!!!!!! --------- if np.ndim(self.model) < 3 : self.model.temp_mean = self.model self.obs.temp_mean = self.obs else : # Calcul de la moyenne temporelle ... Resultat => Map self.model.temp_mean = MV2.average(self.model, axis=0) self.obs.temp_mean = MV2.average(self.obs, axis=0)
def ws2w(us, vs, rhoa=1.25, cd=0.016, format_axes=False, alongxy=None): """Convert from wind stress to 10m wind components This function is the reverse one of :func:`wind_stress`. Output variables are formatted using :func:`~vacumm.data.cf.format_var`. :Formula: .. math:: U_{10m} = (\\rho_a C_d)^{-\\frac{1}{2}} (\\tau_x^2+\\tau_y^2)^{-\\frac{1}{4}} \\tau_x V_{10m} = (\\rho_a C_d)^{-\\frac{1}{2}} (\\tau_x^2+\\tau_y^2)^{-\\frac{1}{4}} \\tau_y :Params: - **us/vs**: Wind stress components. - **rhoa**, optional: Air density (in kg.m-3). - **cd**, optional: Drag coefficient. - **format_axes**, optional: Also format axes using :func:`~vacumm.data.cf.format_axis`. - **alongxy**, optional: Format variables considering components are along X/Y direction and not along zonal/meridional direction. :Return: ``u, v`` """ # Init and format variables u = MV2.asarray(us).clone() v = MV2.asarray(vs).clone() if alongxy is None: alongxy = hasattr(u, 'long_name') and 'x' in us.long_name.lower() if alongxy: uname, vname = 'ux10m', 'vy10m' else: uname, vname = 'u10m', 'v10m' format_var(u, uname, format_axes=format_axes) format_var(v, vname, format_axes=format_axes) # Compute zero = us.filled(1)==0. zero &= vs.filled(1)==0. uvsmod = (us**2+vs**2)**-0.25 uvsmod /= N.sqrt(rhoa*cd) u.assignValue(uvsmod*us) v.assignValue(uvsmod*vs) u.assignValue(MV2.where(zero, 0., u)) v.assignValue(MV2.where(zero, 0., v)) del uvsmod return u, v
def compute(dm, do): """ Computes Mean Absolute Error""" if dm is None and do is None: # just want the doc return { "Name": "Mean Absolute Error", "Abstract": "Compute Full Average of " + "Absolute Difference Between Model And Observation", "Contact": "*****@*****.**", } absdif = MV2.absolute(MV2.subtract(dm, do)) mae = cdutil.averager(absdif, axis='xyt', weights='weighted') # mae = MV.average(MV.absolute(MV.subtract(dm, do))) - depricated ... did # not include area weights return float(mae)
def sum_engine(x, wts): """ The work horse that does the summing ! This is specific to summing. We will always be dealing with the first dimension.....and x is already in the order we will sum. 1-d wts are always numpy arrays or 'equal' Multi-dimensional arrays are always MV2's Inputs: x : the input array (can be MV2 or MA) wts : the input weight array (numpy array or MV2 or 'equal') Returned: y : The weighted sum (summed over the first dimension) return_wts : The sum of weights (summed over the first dimension) """ # __DEBUG__ = 0 # if x is None: return None if wts is None: return None # shx = numpy.ma.shape(x) # if __DEBUG__: print '\tInside sum_engine.' if __DEBUG__: print '\tIncoming data of shape ', shx # if MV2.isMaskedVariable(wts) or isinstance(wts, numpy.ndarray): # # wts is an MV2 or numpy array # if __DEBUG__: print '\t********** Weight is an MV2 or numpy array! **********' # xavg, return_wts = MV2.average(x, weights=wts, returned=1, axis=0) y = xavg * return_wts return y, return_wts elif wts in ['equal','unweighted']: # # Equal weights # if __DEBUG__: print '\t********** Weight is Equal! **********' xavg, return_wts = MV2.average(x, returned=1, axis=0) y = xavg * return_wts return y, return_wts # end of if action == 'sum': else: raise AveragerError, 'wts is an unknown type in sum_engine' return None
def fitPolynomial(var,time,polyOrder): """ Documentation for fitPolynomial(var): ------- The fitPolynomial(var,time,polyOrder) function returns a new variable which is the polyOrder estimate of the variable argument Author: Paul J. Durack : [email protected] Usage: ------ >>> from durolib import fitPolynomial >>> var_cubic = fitPolynomial(var,time,polyOrder=3) Notes: ----- - PJD 5 Aug 2013 - Implemented following examples from Pete G. - TODO: only works on 2D arrays, improve to work on 3D http://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html """ if polyOrder > 3: print "".join(['** fitPolynomial Error: >cubic fits not supported **',]) return varFitted = mv.multiply(var,0.) ; # Preallocate output array coefs,residuals,rank,singularValues,rcond = np.polyfit(time,var,polyOrder,full=True) for timeIndex in range(len(time)): timeVal = time[timeIndex] if polyOrder == 1: varFitted[timeIndex] = (coefs[0]*timeVal + coefs[1]) elif polyOrder == 2: varFitted[timeIndex] = (coefs[0]*(timeVal**2) + coefs[1]*timeVal + coefs[2]) elif polyOrder == 3: varFitted[timeIndex] = (coefs[0]*(timeVal**3) + coefs[1]*(timeVal**2) + coefs[2]*timeVal + coefs[3]) return varFitted
def mask_power(power,wvnb,fqcy): w=power.getAxis(1) f=power.getAxis(0) ## print w ## print f iw=-1 for i in range(len(w)): #print w[i],wvnb if w[i]==wvnb: iw=i break if iw==-1: raise 'Could not find wave number:'+str(wvnb) ifq=-1 for i in range(len(f)): #print f[i],fqcy,numpy.ma.subtract(f[i],fqcy) if numpy.ma.allclose(f[i],fqcy): ifq=i break if ifq==-1: print 'Could not find frequency:'+str(fqcy) else: power[ifq,iw]=-999 power=MV2.masked_equal(power,-999) return power
def _extremum_(func,ctime,i0,i,var,spline): """Extremum possibly using splines""" nt = len(var) if spline and nt >= 4: # and i != 0 and i != (nt-1) if i == 0: ifirst, ilast = 0, 4 elif i == nt-1: ifirst, ilast = nt-4, nt else: icenter = i - int(var[i-1] > var[i+1]) ifirst = max(icenter-1, 0) ilast = ifirst + 4 if ilast > nt: ilast -= 1 ifirst -= 1 mn_units = 'minutes since %s'%ctime[i0+ifirst] old_rts = cdms2.createAxis(N.asarray([ct.torel(mn_units).value for ct in ctime[i0+ifirst:i0+ilast]],dtype='d')) old_var = MV2.array(var[ifirst:ilast], axes=[old_rts], copyaxes=0) mn_rts = cdms2.createAxis(N.arange(int(old_rts[-1]+1),dtype='d')) mn_var = interp1d(old_var, mn_rts, method='cubic') del old_var, old_rts # mn_var = spline_interpolate(old_rts,var[i-1:i+2],mn_rts) # mn_var = splev(mn_rts, splrep(old_rts,var[ifirst:ilast])) mn_i = func(mn_var) val = mn_var[mn_i] del mn_var this_ctime = cdtime.reltime(mn_i,mn_units).tocomp() else: this_ctime = ctime[i0+i] val = var[i] return val,this_ctime
def map2four(data,target,regridTool='regrid2'): lons=target.getLongitude() lats=target.getLatitude() lonso=cdms2.createAxis(lons[::2]) lonse=cdms2.createAxis(lons[1::2]) latso=cdms2.createAxis(lats[::2]) latse=cdms2.createAxis(lats[1::2]) oo=cdms2.createRectGrid(latso,lonso) oe=cdms2.createRectGrid(latso,lonse) eo=cdms2.createRectGrid(latse,lonso) ee=cdms2.createRectGrid(latse,lonse) doo = data.regrid(oo,regridTool=regridTool) doe = data.regrid(oe,regridTool=regridTool) deo = data.regrid(eo,regridTool=regridTool) dee = data.regrid(ee,regridTool=regridTool) out=MV2.zeros(data.shape,dtype='f') out[::2,::2]=doo out[::2,1::2]=doe out[1::2,::2]=deo out[1::2,1::2]=dee out.id=data.id out.setAxisList((lats,lons)) return out
def getMesh(self, transpose=None): """Generate a mesh array for the meshfill graphics method. 'transpose' is for compatibility with other grid types, is ignored.""" import MV2 as MV if self._mesh_ is None: LAT=0 LON=1 latbounds, lonbounds = self.getBounds() if latbounds is None or lonbounds is None: raise CDMSError, 'No boundary data is available for grid %s'%self.id nvert = latbounds.shape[-1] mesh = numpy.zeros((self.size(),2,nvert),latbounds.dtype.char) mesh[:,LAT,:] = MV.filled(latbounds) mesh[:,LON,:] = MV.filled(lonbounds) self._mesh_ = mesh return self._mesh_
def regrid(self, input): axes = input.getAxisList() input_id = input.id M = input.getMissing() if input.mask is numpy.ma.nomask: isMasked = False input = input.data else: isMasked = True input = input.filled(float(M)) sh = input.shape if isMasked: dest_field = \ metrics.packages.acme_regridder._regrid.apply_weights_masked( input, self.S, self.row, self.col, self.nb, float(M)) else: dest_field = metrics.packages.acme_regridder._regrid.apply_weights( input, self.S, self.row, self.col, self.nb) if self.mask_b is not False: dest_field = numpy.ma.masked_where(self.mask_b, dest_field) if self.regular: sh2 = list(sh[:-1]) sh2.append(len(self.lats)) sh2.append(len(self.lons)) dest_field.shape = sh2 dest_field = MV2.array(dest_field, id=input_id) dest_field.setAxis(-1, self.lons) dest_field.setAxis(-2, self.lats) for i in range(len(sh2)-2): dest_field.setAxis(i, axes[i]) if isMasked: dest_field.setMissing(M) return dest_field
def coloc_strat_mod_on_pro(self, model, profiles, select, **kwargs): '''Get colocalized stratification data of a model on profiles See: :func:`coloc_mod_on_pro` :Return: - **lons_mod, lats_mod, deps_mod**: - **temp_mod, sal_mod**: temperature and salinity - **pres_mod, dens_mod**: pressure and density ''' # Coloc donnees modele sur profiles varnames = (('temp','temperature'), ('sal', 'psal','salinity')) lons_mod, lats_mod, deps_mod, temp_mod, sal_mod = \ self.coloc_mod_on_pro(model, profiles, varnames, select, **kwargs) # Calcul pression & densite pres_mod = MV2.zeros(temp_mod.shape)+MV2.masked pres_mod.setAxisList(temp_mod.getAxisList()) dens_mod = pres_mod.clone() for ip in xrange(len(lons_mod)): pres_mod[:, ip] = seawater.csiro.pres(deps_mod[:, ip], numpy.resize([lats_mod[ip]], deps_mod[:, ip].shape)) dens_mod[:, ip] = seawater.csiro.dens(sal_mod[:, ip], temp_mod[:, ip], pres_mod[:, ip]) pres_mod.id = 'pressure' dens_mod.id = 'density' return lons_mod, lats_mod, deps_mod, temp_mod, sal_mod, pres_mod, dens_mod
def maskVal(field,valmask): ''' The maskVal() function applies a mask to an array provided Author: Eric Guilyardi : [email protected] Co-author: Paul J. Durack : [email protected] : @durack1. Created on Sun Sep 14 21:13:30 2014 Inputs: ------ - field - 1D/2D/3D array - valmask - 1D scalar of mask value Output: - field - 1D/2D/3D masked array Usage: ------ >> from libDensity import maskVal >> maskedVariable = maskVal(unMaskedVariable,valmask) Notes: ----- - PJD 15 Sep 2014 - ''' field [npy.isnan(field.data)] = valmask field._FillValue = valmask field = mv.masked_where(field > valmask/10, field) return field
def get(self): """ retrieves the variable data """ cmd = '%s -y -d %s %s' % (self.h5dump, self._header, self.file.file) att = os.popen(cmd).read() i0=att.find('DATA {') att=att[i0:] att = inbetween(att,'{','}') # remove garbage HDF5 file and add trailing comma size=1 for l in self.shape: size*=l data = numpy.ones(size,'f') ielement=0 for v in att.split(','): data[ielement]=float(v) ielement+=1 if ielement!=size: raise RuntimeError, 'got wrong number of data %s, expected %s' % (ielement,size) data = numpy.ma.masked_equal(data,self.missing_value) # Now also mask very low and very high values data = numpy.ma.masked_less(data,-1.E100) data = numpy.ma.masked_greater(data,1.E100) # Finally gives it the right shape data = MV2.reshape(data,self.shape) # And sets the attributes back on for a in self._attributes: setattr(data,a,getattr(self,a)) data.id = self.variable return data
def regrid(self, input): axes=input.getAxisList() input_id=input.id input=input.filled() sh=input.shape #dest_field=numpy.zeros((n,self.n_b,)) dest_field = acme_regridder._regrid.apply_weights(input,self.S,self.row,self.col,self.frac_b) print "DEST FIELD",dest_field.shape dest_field = dest_field.astype(input.dtype) dest_field=numpy.ma.masked_where(self.mask_b,dest_field) if self.regular: sh2=list(sh[:-1])#+[len(self.lats),len(self.lons)] sh2.append(len(self.lats)) sh2.append(len(self.lons)) dest_field.shape=sh2 # 'attributes' is a property of the CdmsObj class. It holds 'external', i.e. # 'persistent' attributes, those included when the object is written to a file. # An example is 'units'. # Note that MV2.array is normally TransientVariable. So the following line # is equivalent to a call of createVariable(): dest_field=MV2.array(dest_field,id=input_id,attributes=input.attributes) dest_field.setAxis(-1,self.lons) dest_field.setAxis(-2,self.lats) for i in range(len(sh2)-2): dest_field.setAxis(i,axes[i]) else: print "The regridder has failed to create a cdms2 object. It will return", print "the regridded data in a raw form." return dest_field
def run_diag(parameter): reference_data_path = parameter.reference_data_path test_data_path = parameter.test_data_path variables = parameter.variables seasons = parameter.seasons ref_name = parameter.ref_name regions = parameter.regions for season in seasons: try: filename1 = utils.get_test_filename(parameter, season) filename2 = utils.get_ref_filename(parameter, season) except IOError as e: print(e) # the file for the current parameters wasn't found, move to next parameters continue print('test file: {}'.format(filename1)) print('reference file: {}'.format(filename2)) f_mod = cdms2.open(filename1) f_obs = cdms2.open(filename2) #save land/ocean fraction for masking try: land_frac = f_mod('LANDFRAC') ocean_frac = f_mod('OCNFRAC') except: mask_path = os.path.join(sys.prefix, 'share', 'acme_diags', 'acme_ne30_ocean_land_mask.nc') f0 = cdms2.open(mask_path) land_frac = f0('LANDFRAC') ocean_frac = f0('OCNFRAC') f0.close() for var in variables: print('Variable: {}'.format(var)) parameter.var_id = var mv1 = acme.process_derived_var(var, acme.derived_variables, f_mod, parameter) mv2 = acme.process_derived_var(var, acme.derived_variables, f_obs, parameter) parameter.viewer_descr[var] = mv1.long_name if hasattr( mv1, 'long_name') else 'No long_name attr in test data.' # special case, cdms didn't properly convert mask with fill value # -999.0, filed issue with denise if ref_name == 'WARREN': # this is cdms2 for bad mask, denise's fix should fix mv2 = MV2.masked_where(mv2 == -0.9, mv2) # following should move to derived variable if ref_name == 'AIRS': # mv2=MV2.masked_where(mv2==mv2.fill_value,mv2) # this is cdms2 for bad mask, denise's fix should fix mv2 = MV2.masked_where(mv2 > 1e+20, mv2) if ref_name == 'WILLMOTT' or ref_name == 'CLOUDSAT': print(mv2.fill_value) # mv2=MV2.masked_where(mv2==mv2.fill_value,mv2) # this is cdms2 for bad mask, denise's fix should fix mv2 = MV2.masked_where(mv2 == -999., mv2) print(mv2.fill_value) # following should move to derived variable if var == 'PRECT_LAND': days_season = { 'ANN': 365, 'DJF': 90, 'MAM': 92, 'JJA': 92, 'SON': 91 } # mv1 = mv1 * days_season[season] * 0.1 #following AMWG # approximate way to convert to seasonal cumulative # precipitation, need to have solution in derived variable, # unit convert from mm/day to cm mv2 = mv2 / days_season[season] / \ 0.1 # convert cm to mm/day instead mv2.units = 'mm/day' if mv1.getLevel() and mv2.getLevel(): # for variables with z axis: plev = parameter.plevs print('Selected pressure level: {}'.format(plev)) f_ins = [f_mod, f_obs] for f_ind, mv in enumerate([mv1, mv2]): mv_plv = mv.getLevel() # var(time,lev,lon,lat) convert from hybrid level to pressure if mv_plv.long_name.lower().find('hybrid') != -1: f_in = f_ins[f_ind] hyam = f_in('hyam') hybm = f_in('hybm') ps = f_in('PS') #Pa mv_p = utils.hybrid_to_plevs(mv, hyam, hybm, ps, plev) elif mv_plv.long_name.lower().find( 'pressure') != -1 or mv_plv.long_name.lower().find( 'isobaric') != -1: # levels are presure levels mv_p = utils.pressure_to_plevs(mv, plev) else: raise RuntimeError( "Vertical level is neither hybrid nor pressure. Abort" ) if f_ind == 0: mv1_p = mv_p if f_ind == 1: mv2_p = mv_p #select plev for ilev in range(len(plev)): mv1 = mv1_p[ilev, ] mv2 = mv2_p[ilev, ] #select region if len(regions) == 0: regions = ['global'] for region in regions: print("Selected region: {}".format(region)) mv1_domain, mv2_domain = utils.select_region( region, mv1, mv2, land_frac, ocean_frac, parameter) parameter.output_file = '-'.join([ ref_name, var, str(int(plev[ilev])), season, region ]) parameter.main_title = str(' '.join( [var, str(int(plev[ilev])), 'mb', season, region])) # Regrid towards lower resolution of two variables for # calculating difference mv1_reg, mv2_reg = utils.regrid_to_lower_res( mv1_domain, mv2_domain, parameter.regrid_tool, parameter.regrid_method) # Plotting diff = mv1_reg - mv2_reg metrics_dict = create_metrics(mv2_domain, mv1_domain, mv2_reg, mv1_reg, diff) parameter.var_region = region plot(parameter.current_set, mv2_domain, mv1_domain, diff, metrics_dict, parameter) utils.save_ncfiles(parameter.current_set, mv1_domain, mv2_domain, diff, parameter) f_in.close() # for variables without z axis: elif mv1.getLevel() == None and mv2.getLevel() == None: #select region if len(regions) == 0: regions = ['global'] for region in regions: print("Selected region: {}".format(region)) mv1_domain, mv2_domain = utils.select_region( region, mv1, mv2, land_frac, ocean_frac, parameter) parameter.output_file = '-'.join( [ref_name, var, season, region]) parameter.main_title = str(' '.join([var, season, region])) # regrid towards lower resolution of two variables for # calculating difference mv1_reg, mv2_reg = utils.regrid_to_lower_res( mv1_domain, mv2_domain, parameter.regrid_tool, parameter.regrid_method) # if var is 'SST' or var is 'TREFHT_LAND': #special case if var == 'TREFHT_LAND' or var == 'SST': # use "==" instead of "is" if ref_name == 'WILLMOTT': mv2_reg = MV2.masked_where( mv2_reg == mv2_reg.fill_value, mv2_reg) print(ref_name) # if mv.mask is False: # mv = MV2.masked_less_equal(mv, mv._FillValue) # print("*************",mv.count()) land_mask = MV2.logical_or(mv1_reg.mask, mv2_reg.mask) mv1_reg = MV2.masked_where(land_mask, mv1_reg) mv2_reg = MV2.masked_where(land_mask, mv2_reg) diff = mv1_reg - mv2_reg metrics_dict = create_metrics(mv2_domain, mv1_domain, mv2_reg, mv1_reg, diff) parameter.var_region = region plot(parameter.current_set, mv2_domain, mv1_domain, diff, metrics_dict, parameter) utils.save_ncfiles(parameter.current_set, mv1_domain, mv2_domain, diff, parameter) else: raise RuntimeError( "Dimensions of two variables are difference. Abort") f_obs.close() f_mod.close() return parameter
def get(self, returnTuple=1): # Ok now the tough part try to figure out everything for the user... # overwrite the defintion for the variableConditioners cdmsArguments if self.cdmsArguments != []: setattr(self.V1, 'cdmsArguments', self.cdmsArguments) setattr(self.V2, 'cdmsArguments', self.cdmsArguments) if not self.EV is None: setattr(self.EV, 'cdmsArguments', self.cdmsArguments) # overwrite the defintion for the variableConditioners cdmsKeyowrds for k in self.cdmsKeywords.keys(): self.V1.cdmsKeywords[k] = self.cdmsKeywords[k] self.V2.cdmsKeywords[k] = self.cdmsKeywords[k] if not self.EV is None: self.EV.cdmsKeywords[k] = self.cdmsKeywords[k] # Checks the time: # 2003-9-15: Added options if both var don't have time then still works d1 = None d2 = None frc1 = None frc2 = None autotime = None if not self.V1.cdmsKeywords.has_key('time'): if self.V2.cdmsKeywords.has_key('time'): d2 = self.V2(returnTuple=returnTuple) if returnTuple: t = d2[0].getTime().asComponentTime() else: t = d2.getTime().asComponentTime() self.V1.cdmsKeywords['time'] = (t[0], t[-1]) d1 = self.V1(returnTuple=returnTuple) del (self.V1.cdmsKeywords['time']) else: # Automatically gets the maximum common time d2 = self.V2(returnTuple=returnTuple) if returnTuple: t = d2[0].getTime() if not t is None: t = t.asComponentTime() else: t = d2.getTime() if not t is None: t = t.asComponentTime() if not t is None: self.V1.cdmsKeywords['time'] = (t[0], t[-1]) d1 = self.V1(returnTuple=returnTuple) if returnTuple: t1 = d1[0].getTime() if not t1 is None: t1 = t1.asComponentTime() else: t1 = d1.getTime() if not t1 is None: t1 = t1.asComponentTime() if not t1 is None: autotime = [t1[0], t1[-1], 'ccb'] if cdtime.compare(t1[0], t[0]) == -1: autotime[0] = t[0] if cdtime.compare(t1[-1], t[-1]) == 1: autotime[1] = t[-1] self.V1.cdmsKeywords['time'] = autotime d1 = self.V1(returnTuple=returnTuple) if not t1 is None: del (self.V1.cdmsKeywords['time']) self.V2.cdmsKeywords['time'] = autotime d2 = self.V2(returnTuple=returnTuple) del (self.V2.cdmsKeywords['time']) elif not self.V2.cdmsKeywords.has_key('time'): d1 = self.V1(returnTuple=returnTuple) if returnTuple: t = d1[0].getTime().asComponentTime() else: t = d1.getTime().asComponentTime() if not t is None: self.V2.cdmsKeywords['time'] = (t[0], t[-1]) d2 = self.V2(returnTuple=returnTuple) if not t is None: del (self.V2.cdmsKeywords['time']) # Now get the variableConditioners 1 and 2 if necessary if d1 is None: d1 = self.V1(returnTuple=returnTuple) if d2 is None: d2 = self.V2(returnTuple=returnTuple) if returnTuple: # break the output if necessary frc2 = d2[1] d2 = d2[0] frc1 = d1[1] d1 = d1[0] frc1 = MV2.array(frc1) frc2 = MV2.array(frc2) else: frc1 = MV2.ones(d1.shape, typecode=MV2.float32) frc2 = MV2.ones(d2.shape, typecode=MV2.float32) frc1.setAxisList(d1.getAxisList()) frc2.setAxisList(d2.getAxisList()) ## # Gets the common time period, only if time keyword isn't defined ## if not(d1.getTime() is None) and not (d2.getTime() is None): ## if len(d1.getTime())!=len(d2.getTime()) and not self.V1.cdmsKeywords.has_key('time') and not self.V2.cdmsKeywords.has_key('time'): ## t1=d1.getTime().asComponentTime() ## t2=d2.getTime().asComponentTime() ## t=[t1[0],t1[-1]] ## if cdtime.compare(t1[0],t2[0])<0: ## t[0]=t2[0] ## if cdtime.compare(t1[-1],t2[-1])>0: ## t[1]=t2[-1] ## d1 = d1 (time=(t[0],t[1])) ## frc1 = frc1(time=(t[0],t[1])) ## d2 = d2 (time=(t[0],t[1])) ## frc2 = frc2(time=(t[0],t[1])) ## # remember the number of element in d1 to see if we add non dummy dimensions ## nd1=MV2.count(d1) ## nd2=MV2.count(d2) ## # Now tries to grow extra dims (like dummy levels, etc...) ## o1=d1.getOrder(ids=1) ## o2=d2.getOrder(ids=1) if d1.shape != d2.shape: if d1.rank() > d2.rank(): d1, d2 = genutil.grower(d1, d2, singleton=1) frc1, frc2 = genutil.grower(frc1, frc2, singleton=1) else: d2, d1 = genutil.grower(d2, d1, singleton=1) frc2, frc1 = genutil.grower(frc2, frc1, singleton=1) # External variableConditioner ? if not self.EV is None: ed = None if not self.EV.cdmsKeywords.has_key('time'): t = d1.getTime().asComponentTime() if not t is None: self.EV.cdmsKeywords['time'] = (t[0], t[-1]) ed = self.EV(returnTuple=1) frced = ed[1] ed = ed[0] frced = MV2.array(frced) frced.setAxisList(ed.getAxisList()) ## # Gets the common time between d1 and ed ## if not t is None: del(self.EV.cdmsKeywords['time']) ## if (not ed.getTime() is None) and (not d1.getTime() is None): ## if (len(ed.getTime())!=len(d1.getTime())): ## t1=d1.getTime().asComponentTime() ## t2=ed.getTime().asComponentTime() ## t=[t1[0],t1[-1]] ## if cdtime.compare(t1[0],t2[0])<0: ## t[0]=t2[0] ## if cdtime.compare(t1[-1],t2[-1])>0: ## t[1]=t2[-1] ## d1 = d1 (time=(t[0],t[1])) ## d2 = d2 (time=(t[0],t[1])) ## ed = ed (time=(t[0],t[1])) ## frc1 = frc1(time=(t[0],t[1])) ## frc2 = frc2(time=(t[0],t[1])) ## frced = wed(time=(t[0],t[1])) if ed is None: ed = self.EV(returnTuple=1) frced = ed[1] ed = ed[0] frced = MV2.array(frced) frced.setAxisList(ed.getAxisList()) g = ed.getGrid() g1 = d1.getGrid() rf = regrid2.Regridder(g1, g) d1, frc1 = rf(d1, mask=1. - frc1.filled(0.), returnTuple=1) g2 = d2.getGrid() rf = regrid2.Regridder(g2, g) d2, frc2 = rf(d2, mask=1. - frc2.filled(0.), returnTuple=1) frc1 = MV2.array(frc1) frc1.setAxisList(d1.getAxisList()) frc2 = MV2.array(frc2) frc2.setAxisList(d2.getAxisList()) d1, ed = genutil.grower(d1, ed, singleton=1) d2, ed = genutil.grower(d2, ed, singleton=1) ed, frced = genutil.grower(ed, frced, singleton=1) frc1 = numpy.ma.where(numpy.ma.equal(frc1.filled(0.), 0.), 0., frced.filled(0.)) frc2 = numpy.ma.where(numpy.ma.equal(frc2.filled(0.), 0.), 0., frced.filled(0.)) d1 = MV2.masked_where(MV2.equal(frc1.filled(0.), 0.), d1) d2 = MV2.masked_where(MV2.equal(frc2.filled(0.), 0.), d2) # Final grid ? g = self.weightedGridMaker() if not g is None: g1 = d1.getGrid() g2 = d2.getGrid() rf1 = regrid2.Regridder(g1, g) rf2 = regrid2.Regridder(g2, g) d1, frc1 = rf1(d1, mask=1. - frc1.filled(0.), returnTuple=1) ## m=1.-frc2.filled(0.) d2, frc2 = rf2(d2, mask=1. - frc2.filled(0.), returnTuple=1) frc1 = MV2.array(frc1) frc1.setAxisList(d1.getAxisList()) frc2 = MV2.array(frc2) frc2.setAxisList(d2.getAxisList()) m = self.weightedGridMaker.weightsMaker(d1) if not m is None: d1, m = genutil.grower(d1, m) frc1, m = genutil.grower(frc1, m) frc1 = m.filled(0.) d1 = MV2.masked_where(MV2.equal(frc1, 0.), d1) m = d1.mask if not m is None: frc1 = numpy.where(m, 0., frc1) m = self.weightedGridMaker.weightsMaker(d2) if not m is None: d2, m = genutil.grower(d2, m) frc2, m = genutil.grower(frc2, m) frc2 = m.filled(0.) d2 = MV2.masked_where(MV2.equal(frc2, 0.), d2) m = d2.mask if not m is numpy.ma.nomask: frc2 = numpy.where(m, 0., frc2) elif d1.getGrid() != d2.getGrid(): g1 = d1.getGrid() g2 = d2.getGrid() rf = regrid2.Regridder(g2, g1) d2, frc2 = rf(d2, mask=1. - frc2.filled(0.), returnTuple=1) frc1 = MV2.array(frc1) frc1.setAxisList(d1.getAxisList()) frc2 = MV2.array(frc2) frc2.setAxisList(d2.getAxisList()) # CdmsArguments or CdmsKeywords if not self.cdmsArguments is None: d1 = d1(*self.cdmsArguments) d2 = d2(*self.cdmsArguments) frc1 = frc1(*self.cdmsArguments) frc2 = frc2(*self.cdmsArguments) if not self.cdmsKeywords is None: d1 = d1(**self.cdmsKeywords) d2 = d2(**self.cdmsKeywords) frc1 = frc1(**self.cdmsKeywords) frc2 = frc2(**self.cdmsKeywords) d1 = MV2.masked_where(MV2.equal(frc1, 0.), d1) d2 = MV2.masked_where(MV2.equal(frc2, 0.), d2) if not ((d1.mask is None) or (d1.mask is MV2.nomask)): if numpy.ma.allclose(d1.mask, 0.): d1._mask = numpy.ma.nomask if not ((d2.mask is None) or (d2.mask is MV2.nomask)): if numpy.ma.allclose(d2.mask, 0.): d2._mask = numpy.ma.nomask if returnTuple: if not ((frc1.mask is None) or (frc1.mask is MV2.nomask)): if numpy.ma.allclose(frc1.mask, 0.): frc1._mask = numpy.ma.nomask if not ((frc2.mask is None) or (frc2.mask is MV2.nomask)): if numpy.ma.allclose(frc2.mask, 0.): frc2._mask = numpy.ma.nomask return (d1, frc1), (d2, frc2) else: return d1, d2
def post(self, fetched, slab, axes, specifications, confined_by, aux, axismap): ''' Post processing retouches the bounds and later will deal with the mask''' import cdms2 as cdms fetched = cdms.createVariable(fetched, copy=1) faxes = fetched.getAxisList() a = None for i in range(len(faxes)): if confined_by[i] is self: newaxvals = [] bounds = [] a = None sh = list(fetched.shape) sh[i] = 1 for l in self.aux[i]: try: tmp = fetched(**{faxes[i].id: (l, l)}) ax = tmp.getAxis(i) #print ax newaxvals.append(ax[0]) if ax.getBounds() != None: bounds.append(ax.getBounds()[0]) else: bounds = None except Exception, err: #print 'err:',err,'match:',self.match if self.match == 1: raise Exception, 'Error axis value :' + str( l ) + ' was requested but is not present in slab\n(more missing might exists)' elif self.match == 0: tmp = MV2.ones(sh, typecode=MV2.float) tmp = MV2.masked_equal(tmp, 1) if type(l) == type( cdtime.comptime(1999)) or type(l) == type( cdtime.reltime(0, 'days since 1999') ) or type(l) == type(''): if type(l) != type(''): newaxvals.append( l.torel(faxes[i].units).value) else: newaxvals.append( cdtime.s2r(l, faxes[i].units).value) else: newaxvals.append(l) if bounds is not None: bounds.append([ax[-1] - 1., ax[-1] + 1]) else: tmp = None if not tmp is None: if a is None: a = tmp elif not tmp is None: a = MV2.concatenate((a, tmp), i) if bounds is not None: newax = cdms.createAxis(numpy.array(newaxvals), bounds=numpy.array(bounds), id=ax.id) else: newax = cdms.createAxis(numpy.array(newaxvals), id=ax.id) for att in faxes[i].attributes.keys(): setattr(newax, att, faxes[i].attributes.get(att)) for j in range(len(fetched.shape)): if j == i: a.setAxis(i, newax) else: a.setAxis(j, faxes[j]) fetched = a.astype(fetched.dtype.char) faxes = fetched.getAxisList()
class Portrait: def __init__(self, files_structure=None, exclude=[], **kw): ''' initialize the portrait object, from file structure''' self.verbose = True # output files looked for to the screen self.files_structure = files_structure self.exclude = exclude # First determine the list of parameters on which we can have a portrait self.parameters_list = [] self.dummies = [] self.auto_dummies = [] self.grouped = [] self.slaves = {} self.altered = {} self.aliased = {} self.portrait_types = {} self.PLOT_SETTINGS = Plot_defaults() if files_structure is not None: sp = files_structure.split('%(') for s in sp: i = s.find(')') if i > -1: # to avoid the leading path val = s[:i] if not (val in self.parameters_list or val in ['files_structure', 'exclude']): self.parameters_list.append(s[:i]) self.parameters_list.append('component') self.parameters_list.append('statistic') self.parameters_list.append('time_domain') for p in self.parameters_list: setattr(self, p, None) for k in kw.keys(): setattr(self, k, kw[k]) def alter_parameter(self, parameter=None, x=None, y=None, size=None, color=None): if not parameter is None: self.altered[parameter] = { 'x': x, 'y': y, 'size': size, 'color': color } else: if not color is None: self.PLOT_SETTINGS.parametertable.color = color if not size is None: self.PLOT_SETTINGS.parameterorientation.size = size def string_construct(self, nms): n = nms[0] if not n in self.slaves.keys(): t1 = [n + ' ' for nn in getattr(self, n)] t2 = [str(nn) + ' ' for nn in getattr(self, n)] else: slavs = self.slaves[n] nm = '' for i in slavs: nm = nm + ' ' + i t1 = [n + nm + ' ' for nn in getattr(self, n)] v1 = [res for res in getattr(self, n)] vals = [] for i in range(len(v1)): tmp = '' for a in v1[i]: if not a == '': tmp += ' ' + str(a) + ' ' else: tmp += ' NONE' + ' ' vals.append(tmp) t2 = [nn for nn in vals] for n in nms[1:]: if not n in self.slaves.keys(): t1 = [' ' + t + ' ' + n for t in t1 for nn in getattr(self, n)] t2 = [ ' ' + t + ' ' + str(nn) for t in t2 for nn in getattr(self, n) ] else: slavs = self.slaves[n] nm = ' ' for i in slavs: nm = ' ' + nm + ' ' + i t1b = [n + nm for nn in getattr(self, n)] v1 = [res for res in getattr(self, n)] vals = [] for i in range(len(v1)): tmp = '' for a in v1[i]: if not a == '': tmp += ' ' + str(a) else: tmp += ' NONE' vals.append(tmp) t2b = [nn for nn in vals] t1 = [t + tb for t in t1 for tb in t1b] t2 = [t + tb for t in t2 for tb in t2b] t3 = [] t1 = t1[0] sp = t1.split() n = len(sp) for tmp in t2: if isinstance(tmp, int): tmp = str(tmp) t = [] tt = tmp.split() for i in range(n): t.append(self.makestring(sp[i], tt[i])) t3.append("%%%".join(t)) return t1, t2, t3 def set(self, portrait_type, parameter=None, values=None): if portrait_type.lower() == 'absolute': if 'relative' in self.portrait_types.keys(): del (self.portrait_types['relative']) elif portrait_type.lower() == 'relative': if not isinstance(parameter, str): raise 'Parameter must be a string' if not isinstance(values, (list, tuple)): raise 'values must be a list or tuple' self.portrait_types['relative'] = [parameter, values] elif portrait_type.lower() == 'difference': if not isinstance(parameter, str): raise 'Parameter must be a string' if not isinstance(values, (list, tuple)): raise 'values must be a list or tuple' self.portrait_types['difference'] = [parameter, values] elif portrait_type.lower() in ['mean', 'average']: if not isinstance(parameter, str): raise 'Parameter must be a string' if not isinstance(values, (list, tuple)): raise 'values must be a list or tuple' self.portrait_types['mean'] = [parameter, values] else: raise RuntimeError('Error type:"%s" not supported at this time' % (portrait_type)) def dummy(self, parameter, which_dummy=''): ''' Sets a parameter as dummy, i.e. all possible values will be used''' val = getattr(self, which_dummy + 'dummies') if not parameter in val: val.append(parameter) setattr(self, which_dummy + 'dummies', val) setattr(self, parameter, None) def group(self, param1, param2): ''' sets 2 multiple values of parameters on the same axis''' added = 0 for i in range(len(self.grouped)): g = self.grouped[i] if param1 in g: if not param2 in g: added = 1 self.grouped[i].append(param2) elif param2 in g: added = 1 self.grouped[i].append(param1) if not added: self.grouped.append([param1, param2]) def slave(self, master, slave): ''' defines a parameter as a slave of a master parameter''' if master in self.slaves.keys(): v = self.slaves[master] if not slave in v: v.append(slave) self.dummy(slave, which_dummy='auto_') self.slaves[master] = v else: self.slaves[master] = [slave] self.dummy(slave, which_dummy='auto_') def alias(self, parameter, values): if isinstance(values, dict): self.aliased[parameter] = values else: oldvalue = getattr(self, parameter) if parameter in self.slaves.keys(): ov = [] for n in oldvalue: ov.append(n[0]) oldvalue = nv n = len(oldvalue) if len(values) != n: raise 'Error aliasing ' + parameter + ' you submitted ' + str( len(values)) + ' aliases but it should be:' + str(n) dic = {} for i in range(n): dic[oldvalue[i]] = values[i] self.aliased[parameter] = dic def makestring(self, parameter, value): if parameter in self.aliased.keys(): dic = self.aliased[parameter] if value in dic.keys(): return dic[value] else: return value else: return value def makeaxis(self, names, axis_length): """ Create the axis with the names, etc.. .for portrait plot Usage: makeaxis(self,names,axis_length) Returns: a cdms axis """ # Now creates the axis names t1, t2, t3 = self.string_construct(names) sp1 = t1.split() axis_names = [] for i in range(len(t2)): nm = '' sp2 = t3[i].split('%%%') for j in range(len(sp2)): if not sp1[j] in self.dummies and not sp2[j] == 'NONE': #print sp2,j if not sp2[j][0] == '_': nm += ' ' + sp2[j] else: nm += ' ' + sp2[j][1:] axis_names.append(nm) dic = {} for i in range(len(axis_names)): dic[i] = axis_names[i] y = cdms2.createAxis(range(axis_length)) y.names = repr(dic) nm = [] for t in sp1: if not t in self.dummies: nm.append(t) nm = "___".join(nm) y.id = nm return y def rank(self, data, axis=0): if not axis in [0, 1]: if not isinstance(axis, str): raise 'Ranking error, axis can only be 1 or 2 or name' else: nms = data.getAxisIds() for i in range(len(nms)): nm = nms[i] if axis in nm.split('___'): axis = i if not axis in [0, 1]: raise 'Ranking error, axis can only be 1 or 2 or name' if data.ndim > 2: raise "Ranking error, array can only be 2D" if axis == 1: data = MV2.transpose(data) a0 = MV2.argsort(data.filled(1.E20), axis=0) n = a0.shape[0] b = MV2.zeros(a0.shape, MV2.float) sh = a0[1].shape for i in range(n): I = MV2.ones(sh) * i c = MV2.array(a0[i].filled(n - 1)) b = genutil.arrayindexing.set(b, c, I) m = data.mask if not m is None: b = MV2.masked_where(m, b) else: b = MV2.array(b) n = MV2.count(b, 0) n.setAxis(0, b.getAxis(1)) b, n = genutil.grower(b, n) b = 100. * b / (n - 1) b.setAxisList(data.getAxisList()) if axis == 1: b = MV2.transpose(b) data = MV2.transpose(data) return b def rank_nD(self, data, axis=0): if not axis in [0, 1]: if not isinstance(axis, str): raise 'Ranking error, axis can only be 1 or 2 or name' else: nms = data.getAxisIds() for i in range(len(nms)): nm = nms[i] if axis in nm.split('___'): axis = i if not axis in [0, 1]: raise 'Ranking error, axis can only be 1 or 2 or name' if axis != 0: data = data(order=(str(axis) + '...')) a0 = MV2.argsort(data.filled(1.E20), axis=0) n = a0.shape[0] b = MV2.zeros(a0.shape, MV2.float) sh = a0[1].shape for i in range(n): I = MV2.ones(sh) * i c = MV2.array(a0[i].filled(n - 1)) b = genutil.arrayindexing.set(b, c, I) m = data.mask if not m is None: b = MV2.masked_where(m, b) else: b = MV2.array(b) n = MV2.count(b, 0) n.setAxisList(b.getAxisList()[1:]) b, n = genutil.grower(b, n) b = 100. * b / (n - 1) b.setAxisList(data.getAxisList()) if axis != 0: st = '' for i in range(axis): st += str(i + 1) st += '0...' data = data(order=st) b = b(order=st) return b def get(self): if 'difference' in self.portrait_types.keys(): d = self.portrait_types['difference'] setattr(self, d[0], d[1][0]) a1 = self._get() setattr(self, d[0], d[1][1]) a2 = self._get() return a1 - a2 elif 'mean' in self.portrait_types.keys(): d = self.portrait_types['mean'] setattr(self, d[0], d[1][0]) tmp += self._get() for v in d[1][1:]: setattr(self, d[0], v) tmp += self._get() return tmp / len(d[1]) else: return self._get() def _get(self): if 'relative' in self.portrait_types.keys(): d = self.portrait_types['relative'] vals = d[1] real_value = getattr(self, d[0]) real = self.__get() setattr(self, d[0], vals[0]) a0 = self.__get() sh = list(a0.shape) sh.insert(0, 1) a0 = MV2.reshape(a0, sh) for v in vals[1:]: setattr(self, d[0], v) tmp = self.__get() tmp = MV2.reshape(tmp, sh) a0 = MV2.concatenate((a0, tmp)) a0 = MV2.sort(a0, 0).filled() real2 = real.filled() a0 = MV2.reshape(a0, (a0.shape[0], sh[1] * sh[2])) real2 = MV2.reshape(real2, (sh[1] * sh[2], )) a0 = MV2.transpose(a0) indices = [] for i in range(len(real2)): indices.append(MV2.searchsorted(a0[i], real2[i])) indices = MV2.array(indices) indices = MV2.reshape(indices, (sh[1], sh[2])) if not ((real.mask is None) or (real.mask is MV2.nomask)): indices = MV2.masked_where(real.mask, indices) a = MV2.masked_equal(a0, 1.e20) a = MV2.count(a, 1) a = MV2.reshape(a, indices.shape) indices = indices / a * 100 setattr(self, d[0], real_value) indices.setAxisList(real.getAxisList()) ## print indices.shape return indices else: return self.__get() def __get(self): nfree = 0 names = [] for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if v is None \ or \ (isinstance(v,(list,tuple)) and len(v)>1): already = 0 for pn in names: if p == pn: already = 1 elif isinstance(pn, list): if p in pn: already = 1 if already == 0: nfree += 1 added = 0 for g in self.grouped: if p in g: names.append(g) added = 1 if added == 0: names.append(p) if nfree != 2: raise 'Error MUST end up with 2 multiple values ! (we have ' + str( nfree) + ':' + str(names) + ')' # Now determines length of each axis axes_length = [1, 1] # First make sure with have 2 list of parameters for i in range(2): if not isinstance(names[i], list): names[i] = [names[i]] for n in names[i]: v = getattr(self, n) if v is None: if n == 'component': axes_length[i] *= 28 elif n == 'time_domain': axes_length[i] *= 19 else: raise 'Error, ' + n + ' is not defined correctly, please specify which values you wish to extract' else: axes_length[i] *= len(v) # Creates the dummy array output = MV2.ones((axes_length[0], axes_length[1])) # Now mask everywhere output = MV2.masked_equal(output, 1) # Indices for filling i = 0 j = 0 # First creates the filler object and sets all the fixed values ! F = StringConstructor(self.files_structure) # Ok let's fill it for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if isinstance(v, (list, tuple)): if len(v) == 1: v = v[0] if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') else: if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') #fnms=F() nms = names[0] + names[1] t1, t2, t3 = self.string_construct(nms) output = output.ravel() sp1 = t1.split() n = len(sp1) for i in range(len(t2)): sp2 = t2[i].split() for j in range(n): v = sp2[j] if sp1[j] == 'time_domain': try: v = int(v) except: pass if v == 'NONE': v = '' setattr(F, sp1[j], v) #print 'Search string is:',fnms #f=os.popen('ls '+F()).readlines() #ip,op,ep=os.popen3('ls '+F()) if self.verbose: print 'command line:', F() #f=op.readlines() f = glob.glob(F()) #print 'F is:',f files = [] for file in f: files.append(file) for e in self.exclude: if file.find(e) > -1: files.pop(-1) break if self.verbose: print 'files:', files try: # now we get the one value needed in this file f = cdms2.open(files[0]) V = f[F.statistic] component = F.component time_domain = F.time_domain if isinstance(component, str): dic = eval(f.components) for k in dic.keys(): if dic[k] == F.component: component = k if isinstance(F.time_domain, str): dic = eval(f.time_domain) for k in dic.keys(): if dic[k] == F.time_domain: time_domain = k value = V(time_domain=time_domain, component=component, squeeze=1) output[i] = value # In case sometihng goes wrong (like modle not processed or inexsitant for this var, etc...) f.close() except Exception, err: #print 'Error:',err pass output = MV2.reshape(output, (axes_length[0], axes_length[1])) output.id = 'portrait plot' yaxis = self.makeaxis(names[0], axes_length[0]) xaxis = self.makeaxis(names[1], axes_length[1]) output.setAxis(0, yaxis) output.setAxis(1, xaxis) # Makes the dim with the most element on the X axis if axes_length[0] > axes_length[1]: output = MV2.transpose(output) return output
def __get(self): nfree = 0 names = [] for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if v is None \ or \ (isinstance(v,(list,tuple)) and len(v)>1): already = 0 for pn in names: if p == pn: already = 1 elif isinstance(pn, list): if p in pn: already = 1 if already == 0: nfree += 1 added = 0 for g in self.grouped: if p in g: names.append(g) added = 1 if added == 0: names.append(p) if nfree != 2: raise 'Error MUST end up with 2 multiple values ! (we have ' + str( nfree) + ':' + str(names) + ')' # Now determines length of each axis axes_length = [1, 1] # First make sure with have 2 list of parameters for i in range(2): if not isinstance(names[i], list): names[i] = [names[i]] for n in names[i]: v = getattr(self, n) if v is None: if n == 'component': axes_length[i] *= 28 elif n == 'time_domain': axes_length[i] *= 19 else: raise 'Error, ' + n + ' is not defined correctly, please specify which values you wish to extract' else: axes_length[i] *= len(v) # Creates the dummy array output = MV2.ones((axes_length[0], axes_length[1])) # Now mask everywhere output = MV2.masked_equal(output, 1) # Indices for filling i = 0 j = 0 # First creates the filler object and sets all the fixed values ! F = StringConstructor(self.files_structure) # Ok let's fill it for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if isinstance(v, (list, tuple)): if len(v) == 1: v = v[0] if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') else: if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') #fnms=F() nms = names[0] + names[1] t1, t2, t3 = self.string_construct(nms) output = output.ravel() sp1 = t1.split() n = len(sp1) for i in range(len(t2)): sp2 = t2[i].split() for j in range(n): v = sp2[j] if sp1[j] == 'time_domain': try: v = int(v) except: pass if v == 'NONE': v = '' setattr(F, sp1[j], v) #print 'Search string is:',fnms #f=os.popen('ls '+F()).readlines() #ip,op,ep=os.popen3('ls '+F()) if self.verbose: print 'command line:', F() #f=op.readlines() f = glob.glob(F()) #print 'F is:',f files = [] for file in f: files.append(file) for e in self.exclude: if file.find(e) > -1: files.pop(-1) break if self.verbose: print 'files:', files try: # now we get the one value needed in this file f = cdms2.open(files[0]) V = f[F.statistic] component = F.component time_domain = F.time_domain if isinstance(component, str): dic = eval(f.components) for k in dic.keys(): if dic[k] == F.component: component = k if isinstance(F.time_domain, str): dic = eval(f.time_domain) for k in dic.keys(): if dic[k] == F.time_domain: time_domain = k value = V(time_domain=time_domain, component=component, squeeze=1) output[i] = value # In case sometihng goes wrong (like modle not processed or inexsitant for this var, etc...) f.close() except Exception, err: #print 'Error:',err pass
def set_colormap(self, x): cols = ( 100, 100, 100, 0, 0, 0, 83.9216, 83.9216, 83.9216, 30.9804, 30.9804, 30.9804, 100, 100, 100, 100, 100, 0, 0, 2.7451, 100, 0, 5.4902, 100, 0, 7.84314, 100, 0, 10.9804, 100, 0, 13.7255, 100, 0, 16.4706, 100, 0, 20.3922, 100, 0, 23.1373, 100, 0, 25.4902, 100, 0, 30.1961, 100, 0, 0, 47.451, 10.5882, 13.3333, 54.5098, 21.5686, 27.0588, 61.5686, 32.549, 40.7843, 68.6274, 43.5294, 54.5098, 76.0784, 48.6275, 60.7843, 79.2157, 53.7255, 67.451, 82.7451, 58.8235, 73.7255, 86.2745, 64.3137, 80.3922, 89.4118, 69.4118, 86.6667, 92.9412, 74.5098, 93.3333, 96.4706, 80, 100, 100, 100, 87.0588, 85.098, 100, 69.4118, 67.8431, 100, 52.1569, 50.9804, 100, 34.5098, 33.7255, 100, 17.2549, 16.8627, 100, 0, 0, 87.451, 0, 0, 74.902, 0, 0, 62.7451, 0, 0, 50.1961, 0, 0, 37.6471, 0, 0, 25.4902, 0, 0, 100, 100, 100, 0, 0, 47.451, 0.392157, 0.392157, 47.451, 0.784314, 0.784314, 47.8431, 1.17647, 1.17647, 48.2353, 1.56863, 1.56863, 48.2353, 1.96078, 1.96078, 48.6275, 2.35294, 2.7451, 49.0196, 2.7451, 3.13725, 49.0196, 3.13725, 3.52941, 49.4118, 3.52941, 3.92157, 49.8039, 3.92157, 4.31373, 49.8039, 4.31373, 5.09804, 50.1961, 4.70588, 5.4902, 50.5882, 5.09804, 5.88235, 50.5882, 5.4902, 6.27451, 50.9804, 5.88235, 6.66667, 51.3725, 6.27451, 7.45098, 51.3725, 6.66667, 7.84314, 51.7647, 7.05882, 8.23529, 52.1569, 7.45098, 8.62745, 52.1569, 7.84314, 9.01961, 52.549, 8.23529, 9.80392, 52.9412, 8.62745, 10.1961, 52.9412, 9.01961, 10.5882, 53.3333, 9.41177, 10.9804, 53.7255, 9.80392, 11.3725, 53.7255, 10.1961, 12.1569, 54.1176, 10.5882, 12.549, 54.5098, 10.9804, 12.9412, 54.5098, 11.3725, 13.3333, 54.902, 11.7647, 13.7255, 55.2941, 12.1569, 14.5098, 55.2941, 12.549, 14.902, 55.6863, 13.3333, 15.2941, 56.0784, 13.7255, 15.6863, 56.4706, 14.1176, 16.0784, 56.4706, 14.5098, 16.8627, 56.8627, 14.902, 17.2549, 57.2549, 15.2941, 17.6471, 57.2549, 15.6863, 18.0392, 57.6471, 16.0784, 18.4314, 58.0392, 16.4706, 19.2157, 58.0392, 16.8627, 19.6078, 58.4314, 17.2549, 20, 58.8235, 17.6471, 20.3922, 58.8235, 18.0392, 20.7843, 59.2157, 18.4314, 21.5686, 59.6078, 18.8235, 21.9608, 59.6078, 19.2157, 22.3529, 60, 19.6078, 22.7451, 60.3922, 20, 23.1373, 60.3922, 20.3922, 23.9216, 60.7843, 20.7843, 24.3137, 61.1765, 21.1765, 24.7059, 61.1765, 21.5686, 25.098, 61.5686, 21.9608, 25.4902, 61.9608, 22.3529, 26.2745, 61.9608, 22.7451, 26.6667, 62.3529, 23.1373, 27.0588, 62.7451, 23.5294, 27.451, 62.7451, 23.9216, 27.8431, 63.1373, 24.3137, 28.6275, 63.5294, 24.7059, 29.0196, 63.5294, 25.098, 29.4118, 63.9216, 25.4902, 29.8039, 64.3137, 25.8824, 30.1961, 64.3137, 26.6667, 30.9804, 64.7059, 27.0588, 31.3725, 65.098, 27.451, 31.7647, 65.4902, 27.8431, 32.1569, 65.4902, 28.2353, 32.549, 65.8824, 28.6275, 32.9412, 66.2745, 29.0196, 33.7255, 66.2745, 29.4118, 34.1176, 66.6667, 29.8039, 34.5098, 67.0588, 30.1961, 34.902, 67.0588, 30.5882, 35.2941, 67.451, 30.9804, 36.0784, 67.8431, 31.3725, 36.4706, 67.8431, 31.7647, 36.8627, 68.2353, 32.1569, 37.2549, 68.6274, 32.549, 37.6471, 68.6274, 32.9412, 38.4314, 69.0196, 33.3333, 38.8235, 69.4118, 33.7255, 39.2157, 69.4118, 34.1176, 39.6078, 69.8039, 34.5098, 40, 70.1961, 34.902, 40.7843, 70.1961, 35.2941, 41.1765, 70.5882, 35.6863, 41.5686, 70.9804, 36.0784, 41.9608, 70.9804, 36.4706, 42.3529, 71.3726, 36.8627, 43.1373, 71.7647, 37.2549, 43.5294, 71.7647, 37.6471, 43.9216, 72.1569, 38.0392, 44.3137, 72.549, 38.4314, 44.7059, 72.549, 38.8235, 45.4902, 72.9412, 39.2157, 45.8824, 73.3333, 40, 46.2745, 73.7255, 40.3922, 46.6667, 73.7255, 40.7843, 47.0588, 74.1176, 41.1765, 47.8431, 74.5098, 41.5686, 48.2353, 74.5098, 41.9608, 48.6275, 74.902, 42.3529, 49.0196, 75.2941, 42.7451, 49.4118, 75.2941, 43.1373, 50.1961, 75.6863, 43.5294, 50.5882, 76.0784, 43.9216, 50.9804, 76.0784, 44.3137, 51.3725, 76.4706, 44.7059, 51.7647, 76.8627, 45.098, 52.549, 76.8627, 45.4902, 52.9412, 77.2549, 45.8824, 53.3333, 77.6471, 46.2745, 53.7255, 77.6471, 46.6667, 54.1176, 78.0392, 47.0588, 54.902, 78.4314, 47.451, 55.2941, 78.4314, 47.8431, 55.6863, 78.8235, 48.2353, 56.0784, 79.2157, 48.6275, 56.4706, 79.2157, 49.0196, 57.2549, 79.6078, 49.4118, 57.6471, 80, 49.8039, 58.0392, 80, 50.1961, 58.4314, 80.3922, 50.5882, 58.8235, 80.7843, 50.9804, 59.6078, 80.7843, 51.3725, 60, 81.1765, 51.7647, 60.3922, 81.5686, 52.1569, 60.7843, 81.5686, 52.549, 61.1765, 81.9608, 53.3333, 61.9608, 82.3529, 53.7255, 62.3529, 82.7451, 54.1176, 62.7451, 82.7451, 54.5098, 63.1373, 83.1373, 54.902, 63.5294, 83.5294, 55.2941, 63.9216, 83.5294, 55.6863, 64.7059, 83.9216, 56.0784, 65.098, 84.3137, 56.4706, 65.4902, 84.3137, 56.8627, 65.8824, 84.7059, 57.2549, 66.2745, 85.098, 57.6471, 67.0588, 85.098, 58.0392, 67.451, 85.4902, 58.4314, 67.8431, 85.8824, 58.8235, 68.2353, 85.8824, 59.2157, 68.6274, 86.2745, 59.6078, 69.4118, 86.6667, 60, 69.8039, 86.6667, 60.3922, 70.1961, 87.0588, 60.7843, 70.5882, 87.451, 61.1765, 70.9804, 87.451, 61.5686, 71.7647, 87.8431, 61.9608, 72.1569, 88.2353, 62.3529, 72.549, 88.2353, 62.7451, 72.9412, 88.6274, 63.1373, 73.3333, 89.0196, 63.5294, 74.1176, 89.0196, 63.9216, 74.5098, 89.4118, 64.3137, 74.902, 89.8039, 64.7059, 75.2941, 89.8039, 65.098, 75.6863, 90.1961, 65.4902, 76.4706, 90.5882, 65.8824, 76.8627, 90.5882, 66.6667, 77.2549, 90.9804, 67.0588, 77.6471, 91.3726, 67.451, 78.0392, 91.7647, 67.8431, 78.8235, 91.7647, 68.2353, 79.2157, 92.1569, 68.6274, 79.6078, 92.549, 69.0196, 80, 92.549, 69.4118, 80.3922, 92.9412, 69.8039, 81.1765, 93.3333, 70.1961, 81.5686, 93.3333, 70.5882, 81.9608, 93.7255, 70.9804, 82.3529, 94.1176, 71.3726, 82.7451, 94.1176, 71.7647, 83.5294, 94.5098, 72.1569, 83.9216, 94.902, 72.549, 84.3137, 94.902, 72.9412, 84.7059, 95.2941, 73.3333, 85.098, 95.6863, 73.7255, 85.8824, 95.6863, 74.1176, 86.2745, 96.0784, 74.5098, 86.6667, 96.4706, 74.902, 87.0588, 96.4706, 75.2941, 87.451, 96.8627, 75.6863, 88.2353, 97.2549, 76.0784, 88.6274, 97.2549, 76.4706, 89.0196, 97.6471, 76.8627, 89.4118, 98.0392, 77.2549, 89.8039, 98.0392, 77.6471, 90.5882, 98.4314, 78.0392, 90.9804, 98.8235, 78.4314, 91.3726, 98.8235, 78.8235, 91.7647, 99.2157, 79.2157, 92.1569, 99.6078, 80, 92.9412, 100) cols = MV2.reshape(cols, (len(cols) / 3, 3)) for i in range(cols.shape[0]): co = x.getcolorcell(i) if (co[0] != int(cols[i][0]) or co[1] != int(cols[i][1]) or co[2] != int(cols[i][2])): x.setcolorcell(i, int(cols[i][0]), int(cols[i][1]), int(cols[i][2])) pass
def compute_metrics(Var, dm, do): # Var is sometimes sent with level associated var = Var.split("_")[0] # Did we send data? Or do we just want the info? if dm is None and do is None: metrics_defs = collections.OrderedDict() metrics_defs["rms_xyt"] = pcmdi_metrics.pcmdi.rms_xyt.compute( None, None) metrics_defs["rms_xy"] = pcmdi_metrics.pcmdi.rms_xy.compute(None, None) metrics_defs["bias_xy"] = pcmdi_metrics.pcmdi.bias.compute(None, None) metrics_defs["mae_xy"] = pcmdi_metrics.pcmdi.meanabs_xy.compute( None, None) # metrics_defs["cor_xyt"] = pcmdi_metrics.pcmdi.cor_xyt.compute( # None, # None) metrics_defs["cor_xy"] = pcmdi_metrics.pcmdi.cor_xy.compute(None, None) metrics_defs["std_xy"] = pcmdi_metrics.pcmdi.std_xy.compute(None) metrics_defs["std_xyt"] = pcmdi_metrics.pcmdi.std_xyt.compute(None) metrics_defs["seasonal_mean"] = \ pcmdi_metrics.pcmdi.seasonal_mean.compute( None, None) metrics_defs["annual_mean"] = pcmdi_metrics.pcmdi.annual_mean.compute( None, None) metrics_defs["zonal_mean"] = pcmdi_metrics.pcmdi.zonal_mean.compute( None, None) return metrics_defs cdms.setAutoBounds('on') metrics_dictionary = {} # SET CONDITIONAL ON INPUT VARIABLE if var == 'pr': conv = 1.e5 else: conv = 1. if var in ['hus']: sig_digits = '.5f' else: sig_digits = '.3f' # CALCULATE ANNUAL CYCLE SPACE-TIME RMS, CORRELATIONS and STD rms_xyt = pcmdi_metrics.pcmdi.rms_xyt.compute(dm, do) # cor_xyt = pcmdi_metrics.pcmdi.cor_xyt.compute(dm, do) stdObs_xyt = pcmdi_metrics.pcmdi.std_xyt.compute(do) std_xyt = pcmdi_metrics.pcmdi.std_xyt.compute(dm) # CALCULATE ANNUAL MEANS dm_am, do_am = pcmdi_metrics.pcmdi.annual_mean.compute(dm, do) # CALCULATE ANNUAL MEAN BIAS bias_xy = pcmdi_metrics.pcmdi.bias.compute(dm_am, do_am) # CALCULATE MEAN ABSOLUTE ERROR mae_xy = pcmdi_metrics.pcmdi.meanabs_xy.compute(dm_am, do_am) # CALCULATE ANNUAL MEAN RMS rms_xy = pcmdi_metrics.pcmdi.rms_xy.compute(dm_am, do_am) # CALCULATE ANNUAL OBS and MOD STD stdObs_xy = pcmdi_metrics.pcmdi.std_xy.compute(do_am) std_xy = pcmdi_metrics.pcmdi.std_xy.compute(dm_am) # ZONAL MEANS ###### # CALCULATE ANNUAL MEANS dm_amzm, do_amzm = pcmdi_metrics.pcmdi.zonal_mean.compute(dm_am, do_am) # CALCULATE ANNUAL AND ZONAL MEAN RMS rms_y = pcmdi_metrics.pcmdi.rms_0.compute(dm_amzm, do_amzm) # CALCULATE ANNUAL MEAN DEVIATION FROM ZONAL MEAN RMS dm_amzm_grown, dummy = grower(dm_amzm, dm_am) dm_am_devzm = MV.subtract(dm_am, dm_amzm_grown) do_amzm_grown, dummy = grower(do_amzm, do_am) do_am_devzm = MV.subtract(do_am, do_amzm_grown) rms_xy_devzm = pcmdi_metrics.pcmdi.rms_xy.compute(dm_am_devzm, do_am_devzm) # CALCULATE ANNUAL AND ZONAL MEAN STD # CALCULATE ANNUAL MEAN DEVIATION FROM ZONAL MEAN STD stdObs_xy_devzm = pcmdi_metrics.pcmdi.std_xy.compute(do_am_devzm) std_xy_devzm = pcmdi_metrics.pcmdi.std_xy.compute(dm_am_devzm) metrics_dictionary['std-obs_xy_ann'] = format(stdObs_xy * conv, sig_digits) metrics_dictionary['std_xy_ann'] = format(std_xy * conv, sig_digits) metrics_dictionary['std-obs_xyt_ann'] = format(stdObs_xyt * conv, sig_digits) metrics_dictionary['std_xyt_ann'] = format(std_xyt * conv, sig_digits) metrics_dictionary['std-obs_xy_devzm_ann'] = format( stdObs_xy_devzm * conv, sig_digits) metrics_dictionary['std_xy_devzm_ann'] = format(std_xy_devzm * conv, sig_digits) metrics_dictionary['rms_xyt_ann'] = format(rms_xyt * conv, sig_digits) metrics_dictionary['rms_xy_ann'] = format(rms_xy * conv, sig_digits) metrics_dictionary['bias_xy_ann'] = format(bias_xy * conv, sig_digits) metrics_dictionary['mae_xy_ann'] = format(mae_xy * conv, sig_digits) # ZONAL MEAN CONTRIBUTIONS metrics_dictionary['rms_y_ann'] = format(rms_y * conv, sig_digits) metrics_dictionary['rms_devzm_ann'] = format(rms_xy_devzm * conv, sig_digits) # CALCULATE SEASONAL MEANS for sea in ['djf', 'mam', 'jja', 'son']: dm_sea = pcmdi_metrics.pcmdi.seasonal_mean.compute(dm, sea) do_sea = pcmdi_metrics.pcmdi.seasonal_mean.compute(do, sea) # CALCULATE SEASONAL RMS AND CORRELATION rms_sea = pcmdi_metrics.pcmdi.rms_xy.compute(dm_sea, do_sea) cor_sea = pcmdi_metrics.pcmdi.cor_xy.compute(dm_sea, do_sea) mae_sea = pcmdi_metrics.pcmdi.meanabs_xy.compute(dm_sea, do_sea) bias_sea = pcmdi_metrics.pcmdi.bias.compute(dm_sea, do_sea) # CALCULATE ANNUAL OBS and MOD STD stdObs_xy_sea = pcmdi_metrics.pcmdi.std_xy.compute(do_sea) std_xy_sea = pcmdi_metrics.pcmdi.std_xy.compute(dm_sea) # ZONAL MEANS ###### # CALCULATE SEASONAL MEANS # dm_smzm, do_smzm = pcmdi_metrics.pcmdi.zonal_mean.compute(dm_sea, # do_sea) # CALCULATE SEASONAL AND ZONAL MEAN RMS # rms_y = pcmdi_metrics.pcmdi.rms_y.compute(dm_smzm, do_smzm) # CALCULATE SEASONAL MEAN DEVIATION FROM ZONAL MEAN RMS # dm_smzm_grown,dummy = grower(dm_smzm,dm_sea) # dm_sea_devzm = MV.subtract(dm_sea,dm_smzm_grown) # do_smzm_grown,dummy = grower(do_smzm,do_sea) # do_sm_devzm = MV.subtract(do_sea,do_smzm_grown) # rms_xy_devzm = pcmdi_metrics.pcmdi.rms_xy.compute(dm_sm_devzm, # do_sm_devzm) # print 'SEASONAL ZM HERE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' metrics_dictionary['bias_xy_' + sea] = format(bias_sea * conv, sig_digits) metrics_dictionary['rms_xy_' + sea] = format(rms_sea * conv, sig_digits) metrics_dictionary['cor_xy_' + sea] = format(cor_sea, '.2f') metrics_dictionary['mae_xy_' + sea] = format(mae_sea * conv, sig_digits) metrics_dictionary['std-obs_xy_' + sea] = format( stdObs_xy_sea * conv, sig_digits) metrics_dictionary['std_xy_' + sea] = format(std_xy_sea * conv, sig_digits) # ZONAL AND SEASONAL MEAN CONTRIBUTIONS # metrics_dictionary[ # 'rms_y_' + sea] = format( # rms_y * # conv, # sig_digits) # metrics_dictionary[ # 'rms_devzm_' + sea] = format( # rms_xy_devzm * # conv, # sig_digits) return metrics_dictionary
# -*- coding: utf-8 -*- # Creation d'un jeu de precipitations horaires import MV2, cdms2, numpy as N from vacumm.misc.axes import create_time hours = create_time((12*60, 25.*60, 60), 'minutes since 2000') precip = MV2.sin(N.arange(len(hours))*.2)*10 precip.setAxis(0, hours) precip.units = 'mm' precip.long_name = 'Original' # Nouvel echantillonnage / 2h hours2 = create_time((10, 30., 2), 'hours since 2000') # Regrillage 1D conservatif from vacumm.misc.grid.regridding import regrid1d precip2 = regrid1d(precip, hours2, 'conservative') precip2.long_name = 'Regridded' # Verifications print 'Total precip.:' print '- original =', precip.sum() print '- remapped =', precip2.sum() # > Total precip.: # > - original = 89.957242832779755 # > - remapped = 89.957237 # Plots from vacumm.misc.plot import savefigs from vacumm.misc.plot import bar2 kwplot = dict(color='#00ffff',edgecolor='#55aaaa',
def opendap_data(model, variable, experiment, rip): # Baseline directory base_dir = 'http://mary.ldeo.columbia.edu:81/CMIP6/.' # Write directory df_proclist = pd.DataFrame( columns=['model', 'sim', 'ensemble', 'variable']) #ingrid_cmip6 = pd.read_csv("~/mary_cmip6.csv") #rips=np.unique(np.array(df1.member_id)) df1 = mary[(mary.source_id == model) & (mary.variable_id == variable) & (mary.experiment_id == experiment) & (mary.member_id == rip)] #Construct openDAP link nfiles, nidentifiers = df1.shape times = np.sort(np.array(df1.time_range)) time_range = times[0] i_ens = np.where(df1.time_range == time_range)[0][0] nc_link = base_dir + df1.activity_id.iloc[ i_ens] + '/.' + df1.institution_id.iloc[ i_ens] + '/.' + model + '/.' + experiment + '/.' + df1.member_id.iloc[ i_ens] + '/.' + df1.table_id.iloc[ i_ens] + '/.' + variable + '/.' + df1.grid_label.iloc[ i_ens] + '/.' + df1.version.iloc[ i_ens] + '/.' + df1.file_basename.iloc[ i_ens] + '/.' + variable + '/dods' request = requests.get(nc_link) if request.status_code != 200: raise TypeError("Can't open file: bad request for time range", time_range) f = cdms.open(nc_link) data = f(variable) f.close() if len(times) > 1: for time_range in times[1:]: i_ens = np.where(df1.time_range == time_range)[0][0] nc_link = base_dir + df1.activity_id.iloc[ i_ens] + '/.' + df1.institution_id.iloc[ i_ens] + '/.' + model + '/.' + experiment + '/.' + df1.member_id.iloc[ i_ens] + '/.' + df1.table_id.iloc[ i_ens] + '/.' + variable + '/.' + df1.grid_label.iloc[ i_ens] + '/.' + df1.version.iloc[ i_ens] + '/.' + df1.file_basename.iloc[ i_ens] + '/.' + variable + '/dods' request = requests.get(nc_link) if request.status_code != 200: raise TypeError("Can't open file: bad request for time range", time_range) #return 0 f = cdms.open(nc_link) datat = f(variable) f.close() data = MV.concatenate((data, datat)) atts = datat.attributes.keys() for att in atts: setattr(data, att, datat.attributes[att]) data.id = datat.id return data
def cosp_bin_sum( cld: "FileVariable", prs_low0: Optional[float], prs_high0: Optional[float], tau_low0: Optional[float], tau_high0: Optional[float], ): """sum of cosp bins to calculate cloud fraction in specified cloud top pressure / height and cloud thickness bins, input variable has dimension (cosp_prs,cosp_tau,lat,lon)/(cosp_ht,cosp_tau,lat,lon)""" prs: FileAxis = cld.getAxis(0) tau: FileAxis = cld.getAxis(1) prs_low: float = adjust_prs_val_units(prs, prs[0], prs_low0) prs_high: float = adjust_prs_val_units(prs, prs[-1], prs_high0) if prs_low0 is None and prs_high0 is None: prs_lim = "total cloud fraction" tau_high, tau_low, tau_lim = determine_tau(tau, tau_low0, tau_high0) if cld.id == "FISCCP1_COSP": # ISCCP model cld_bin = cld(cosp_prs=(prs_low, prs_high), cosp_tau=(tau_low, tau_high)) simulator = "ISCCP" if cld.id == "CLISCCP": # ISCCP obs cld_bin = cld(isccp_prs=(prs_low, prs_high), isccp_tau=(tau_low, tau_high)) if cld.id == "CLMODIS": # MODIS prs_lim = determine_cloud_level(prs_low, prs_high, (440, 44000), (680, 68000)) simulator = "MODIS" if prs.id == "cosp_prs": # Model cld_bin = cld(cosp_prs=(prs_low, prs_high), cosp_tau_modis=(tau_low, tau_high)) elif prs.id == "modis_prs": # Obs cld_bin = cld(modis_prs=(prs_low, prs_high), modis_tau=(tau_low, tau_high)) if cld.id == "CLD_MISR": # MISR model if max( prs ) > 1000: # COSP v2 cosp_htmisr in units m instead of km as in v1 cld = cld[ 1:, :, :, :] # COSP v2 cosp_htmisr[0] equals to 0 instead of -99 as in v1, therefore cld needs to be masked manually cld_bin = cld(cosp_htmisr=(prs_low, prs_high), cosp_tau=(tau_low, tau_high)) prs_lim = determine_cloud_level(prs_low, prs_high, (7, 7000), (3, 3000)) simulator = "MISR" if cld.id == "CLMISR": # MISR obs cld_bin = cld(misr_cth=(prs_low, prs_high), misr_tau=(tau_low, tau_high)) cld_bin_sum = MV2.sum(MV2.sum(cld_bin, axis=1), axis=0) try: cld_bin_sum.long_name = simulator + ": " + prs_lim + " with " + tau_lim # cld_bin_sum.long_name = "{}: {} with {}".format(simulator, prs_lim, tau_lim) except BaseException: pass return cld_bin_sum
import vcs, numpy, cdms2, MV2 L = cdms2.createAxis(range(0, 360, 36)) L.designateLongitude() lat = cdms2.createAxis(range(-90, 90, 18)) a = numpy.arange(400) a.shape = (2, 2, 10, 10) b = MV2.cos(a) / 2. a = MV2.sin(a) t = cdms2.createAxis(range(2)) t.designateTime() t.units = "months since 2014" t.id = "time" l = cdms2.createAxis(numpy.arange(1, 3) * 1000.) l.designateLevel() l.units = "hPa" l.id = "plev" a.setAxis(0, t) a.setAxis(1, l) a.setAxis(2, lat) a.setAxis(3, L) b.setAxisList(a.getAxisList()) x = vcs.init() gm = x.createboxfill() gm.level_1 = -.8 gm.level_2 = .8 d = x.plot(a, gm) raw_input("Press enter") x.backend.update_input(d.backend, b(slice(1, 2), slice(1, 2))) raw_input("ok done")
def plot_scattered_locs(lons, lats, depths, slice_type=None, interval=None, plotter=None, lon=None, lat=None, level=None, label='', lon_bounds_margin=.1, lat_bounds_margin=.1, data=None, warn=True, bathy=None, xybathy=None, secbathy=None, size=20, color='#2ca02c', linewidth=0.4, edgecolor='k', add_profile_line=None, add_bathy=True, add_minimap=True, add_section_bathy=True, fig=None, title="{long_name}", register_sm=True, depthshade=False, legend=False, colorbar=True, **kwargs): """Plot scattered localisations Parameters ---------- lons: n-D array lats: n-D array depths: n-D array slice_type: one of "3d"/None, "2d", "zonal", "meridional", "horizontal" The way to slice the observations. "3d"/"2d" are 3D/2D view of all observations. Other slices make a selection with a range (``interval``). interval: None, tuple of float Interval for selecting valid data Required if slice_type is not "3d"/None/"2d". map_<param>: <param> is passed to :func:`create_map` section_<param>: <param> is passed to :func:`vacumm.misc.plot.section2` minimap_<param>: <param> is passed to :func:`vacumm.misc.plot.add_map_box` Todo ---- Add time support. """ # Inits if cdms2.isVariable(data): data = data.asma() kwmap = kwfilter(kwargs, 'map_') kwminimap = kwfilter(kwargs, 'minimap_') kwsecbat = kwfilter(kwargs, 'section_bathy_') kwsection = kwfilter(kwargs, 'section_') kwplt = kwfilter(kwargs, 'plotter_') dict_check_defaults(kwmap, **kwplt) dict_check_defaults(kwsection, **kwplt) kwpf = kwfilter(kwargs, 'add_profile_line') kwleg = kwfilter(kwargs, 'legend') kwcb = kwfilter(kwargs, 'colorbar') long_name = get_long_name(data) units = getattr(data, 'units', '') if long_name is None: long_name = "Locations" if not title: title = None elif title is True: title = long_name else: title = title.format(**locals()) # Slice type if slice_type is None: slice_type = "3d" else: slice_type = str(slice_type).lower() valid_slice_types = [ '3d', "2d", 'zonal', 'merid', 'horiz', 'bottom', 'surf' ] assert slice_type in valid_slice_types, ('Invalid slice type. ' 'It must be one of: ' + ', '.join(valid_slice_types)) # Numeric horizontal coordinates xx = lons[:].copy() yy = lats[:].copy() # Profiles? profiles = (not isinstance(depths, str) and (isaxis(depths) or N.shape(depths) != N.shape(xx) or (data is not None and data.ndim == 2))) # Force some options if not profiles or slice_type not in ('3d', 'merid', 'zonal'): add_profile_line = False elif add_profile_line is None: add_profile_line = True # Bathymetry need_xybathy = int(add_profile_line) if depths == 'bottom' and slice_type not in ('bottom', '2d'): need_xybathy = 2 if need_xybathy and xybathy is not None: if bathy is not None: xybathy = grid2xy(bathy, lons, lats) if xybathy.mask.all(): if warn: sonat_warn( 'Bathymetry is fully masked at bottom locs. Skipping...' ) if need_xybathy == 2: return xybathy = None elif need_xybathy == 2 and warn: # we really need it sonat_warn('Bathymetry is needed at obs locations. Skipping...') return if xybathy is None: add_profile_line = False # Special depths: surf and bottom indepths = depths if (depths == 'surf' and slice_type != 'surf'): # surface depths = N.zeros(len(lons)) elif (depths == 'bottom' and slice_type not in ('bottom', '2d')): # bottom depths = -xybathy if interval is not None and N.isscalar(interval[0]): interval = (depths + interval[0], depths + interval[1]) # Numeric vertical coordinates strdepths = isinstance(depths, str) if not strdepths: zz = N.array(depths[:], copy=True) # Shape if data is not None: dshape = data.shape elif not profiles or strdepths: dshape = xx.shape elif zz.ndim == 2: dshape = zz.shape else: dshape = zz.shape + xx.shape # Masking outside interval if (slice_type != '3d' and slice_type != '2d' and (slice_type != 'surf' or depths != 'surf') and (slice_type != 'bottom' or depths != 'bottom')): assert interval is not None, ( 'You must provide a valid ' '"interval" for slicing scattered locations') stype = 'horiz' if slice_type in ('surf', 'bottom') else slice_type data = mask_scattered_locs(xx, yy, depths, stype, interval, data=data) if data is None: return # Get the full mask: (np), or (nz, np) for profiles # - mask with data if data is not None: if data.dtype.char == '?': mask = data data = None else: mask = N.ma.getmaskarray(data) else: mask = N.zeros(dshape) # - mask with coordinates if N.ma.isMA(xx) or N.ma.isMA(yy): # lons/lats xymask = N.ma.getmaskarray(xx) | N.ma.getmaskarray(yy) mask |= N.resize(mask, dshape) if not strdepths and N.ma.isMA(zz): # depths if profiles: zmask = N.ma.getmaskarray(zz) if zz.ndim == 1: zmask = N.repeat(N.ma.resize(N.ma.getmaskarray(zmask), (-1, 1)), xx.size, axis=1) mask |= zmask else: mask |= N.ma.getmaskarray(zz) # - check if mask.all(): if warn: sonat_warn('All your data are masked') return # - mask back xymask = mask if mask.ndim == 1 else mask.all(axis=0) xx = N.ma.masked_where(xymask, xx, copy=False) yy = N.ma.masked_where(xymask, yy, copy=False) if not strdepths: if mask.shape == zz.shape: zz = N.ma.masked_where(mask, zz, copy=False) elif zz.ndim == 1: zz = N.ma.masked_where(mask.all(axis=1), zz, copy=False) if data is not None: data = N.ma.masked_where(mask, data, copy=0) # Plotter as Axes if isinstance(plotter, P.Axes): ax = plotter fig = ax.get_figure() plotter = None elif plotter is None: ax = None elif isinstance(plotter, Plot): ax = plotter.axes else: raise SONATError('Plotter must be matplotlib Axes instance or ' 'a vacumm Plot instance') if slice_type == '3d': if ax is None: ax = '3d' elif not isinstance(ax, Axes3D): sonat_warn("Requesting 3D plot but provided axes are not 3D." " Skipping...") axes = None # Coordinate bounds if level is None and slice_type in ['3d', 'zonal', 'merid']: if strdepths or zz.min() == 0: level_min = -200 # Fall back to this min depth else: level_min = 1.1 * zz.min() level = (level_min, 0) if (lon is None and slice_type in ['3d', "2d", "horiz", 'surf', 'bottom', 'zonal']): lon = rescale_itv((xx.min(), xx.max()), 1.1) if (lat is None and slice_type in ['3d', "2d", "horiz", 'surf', 'bottom', 'merid']): lat = rescale_itv((yy.min(), yy.max()), 1.1) # Get the plotter if slice_type in ['3d', "2d", "horiz", 'surf', 'bottom']: # map # Map if plotter is None: plotter = create_map(lon, lat, level=level, bathy=bathy, add_bathy=add_bathy, fig=fig, axes=ax, **kwmap) ax = plotter.axes # Projection xx, yy = plotter(xx, yy) else: # sections if plotter is None: # Base plot kwsection.update(fig=fig, axes=ax, show=False, close=False) if add_minimap: dict_check_defaults(kwsection, top=.9, right=.9) if slice_type == 'merid': plotter = section(data=None, xaxis=MV2.array(lat, id='lat'), yaxis=MV2.array(level, id='dep'), **kwsection) else: plotter = section(data=None, xaxis=MV2.array(lon, id='lon'), yaxis=MV2.array(level, id='dep'), **kwsection) ax = plotter.axes # Add minimap if add_minimap: if slice_type == 'merid': xlim = interval ylim = plotter.axes.get_xlim() else: xlim = plotter.axes.get_xlim() ylim = interval extents = dict(x=xlim, y=ylim) dict_check_defaults(kwminimap, map_square=True, map_zoom=.5, map_res=None, map_arcgisimage="ocean", map_epsg=3395, linewidth=.6) kwminimap['map_fig'] = ax.figure add_map_box((xx, yy), extents, **kwminimap) # Bathy profile if add_section_bathy and bathy is not None or secbathy is not None: if secbathy is None: # interpolate if slice_type == 'merid': secbathy = transect( bathy, [0.5 * (interval[0] + interval[1])] * 2, ylim, outaxis='lat') else: secbathy = transect( bathy, xlim, [0.5 * (interval[0] + interval[1])] * 2, outaxis='lon') tx = secbathy.getAxis(0)[:] tb = secbathy.asma() axis_bounds = ax.axis() dict_check_defaults(kwsecbat, facecolor="0.7") ax.fill_between(tx, ax.get_ylim()[0], tb, **kwsecbat) ax.axis(axis_bounds) axis_bounds = ax.axis() # Plot params for scatter kwargs.update(linewidth=linewidth, s=size, edgecolor=edgecolor) # Data kwargs if data is not None: dict_check_defaults(kwargs, vmin=data.min(), vmax=data.max()) # 3D pp = [] if slice_type == "3d": kwargs['depthshade'] = depthshade # Depth labels zfmtfunc = lambda x, pos: deplab(x, nosign=True) ax.zaxis.set_major_formatter(FuncFormatter(zfmtfunc)) # Scatter plots if not profiles: # fully scattered # Points if data is not None: kwargs['c'] = data else: kwargs['c'] = color pp.append(ax.scatter(xx, yy, depths, label=label, **kwargs)) # Profile lines if add_profile_line: for ip, (x, y) in enumerate(zip(xx, yy)): plot_profile_line_3d(ax, x, y, xybathy[ip], zorder=pp[-1].get_zorder() - 0.01, **kwpf) else: # profiles for ip, (x, y) in enumerate(zip(xx, yy)): # Skip fully masked if mask[:, ip].all(): # if warn: # sonat_warn('Profile fully masked') continue # Points if zz.ndim == 2: z = depths[:, ip] else: z = zz z = N.ma.masked_where(mask[:, ip], z, copy=False) if data is not None: kwargs['c'] = data[..., ip] else: kwargs['c'] = color pp.append( ax.scatter([x] * len(z), [y] * len(z), z, label=label, **kwargs)) label = '_' + str(label) # Profile line if add_profile_line: plot_profile_line_3d(ax, x, y, -xybathy[ip], zorder=pp[-1].get_zorder() - 0.01, **kwpf) # Horizontal elif slice_type in ['2d', 'surf', 'bottom', 'horiz']: # Barotropic case if data is not None and data.ndim != 1: data = data.mean(axis=0) # Scatter plot if data is not None: kwargs['c'] = data else: kwargs['c'] = color pp.append(ax.scatter(xx, yy, label=label, **kwargs)) if pp[-1].norm.vmin is None: pass # Sections else: # X axis data if slice_type == 'zonal': xdata = xx else: xdata = yy # Scatter plots if not profiles: # scattered if data is not None: kwargs['c'] = data else: kwargs['c'] = color pp.append(ax.scatter(xdata, depths, label=label, **kwargs)) else: # profiles for ip, x in enumerate(xdata): # Skip fully masked if mask[:, ip].all(): # if warn: # sonat_warn('Profile fully masked') continue # Points if depths[:].ndim == 2: z = zz[:, ip] else: z = zz z = N.ma.masked_where(mask[:, ip], z, copy=False) if data is not None: kwargs['c'] = data[:, ip] else: kwargs['c'] = color pp.append(ax.scatter([x] * len(z), z, label=label, **kwargs)) label = '_' + str(label) # Profile line if add_profile_line: plot_profile_line_3d(ax, x, -xybathy[ip], zorder=pp[-1].get_zorder() - 0.01, **kwpf) # Finalise ax.axis(axis_bounds) if title: ax.set_title(title) if legend: plotter.legend(**kwleg) if colorbar and data is not None: add_colorbar(plotter, pp, units=units, **kwcb) if data is not None and register_sm: register_scalar_mappable(ax, pp, units=units) register_scatter(ax, pp, label) return plotter
def spacevavg(tvarb1, tvarb2, sftlf, model): ''' Given a "root filename" and month/year specifications, vector-average lat/lon arrays in an (amplitude, phase) pair of input data files. Each input data file contains diurnal (24h), semidiurnal (12h) and terdiurnal (8h) Fourier harmonic components of the composite mean day/night cycle. Vector-averaging means we consider the input data to be readings on an 8-, 12- or 24-hour clock and separately average the Cartesian components (called "cosine" and "sine" below). Then the averaged components are combined back into amplitude and phase values and returned. Space-averaging is done globally, as well as separately for land and ocean areas. ''' glolf = cdutil.averager(sftlf, axis='xy') print(' Global mean land fraction = %5.3f' % glolf) outD = {} # Output dictionary to be returned by this function harmonics = [1, 2, 3] for harmonic in harmonics: ampl = tvarb1[harmonic - 1] tmax = tvarb2[harmonic - 1] # print ampl[:, :] # print tmax[:, :] clocktype = 24 / harmonic cosine = MV2.cos(hrs_to_rad(tmax, clocktype)) * ampl # X-component sine = MV2.sin(hrs_to_rad(tmax, clocktype)) * ampl # Y-component print( 'Area-averaging globally, over land only, and over ocean only ...' ) # Average Cartesian components ... cos_avg_glo = cdutil.averager(cosine, axis='xy') sin_avg_glo = cdutil.averager(sine, axis='xy') cos_avg_lnd = cdutil.averager(cosine * sftlf, axis='xy') sin_avg_lnd = cdutil.averager(sine * sftlf, axis='xy') cos_avg_ocn = cos_avg_glo - cos_avg_lnd sin_avg_ocn = sin_avg_glo - sin_avg_lnd # ... normalized by land-sea fraction: cos_avg_lnd /= glolf sin_avg_lnd /= glolf cos_avg_ocn /= (1 - glolf) sin_avg_ocn /= (1 - glolf) # Amplitude and phase: # * 86400 Convert kg/m2/s -> mm/d? amp_avg_glo = MV2.sqrt(sin_avg_glo**2 + cos_avg_glo**2) # * 86400 Convert kg/m2/s -> mm/d? amp_avg_lnd = MV2.sqrt(sin_avg_lnd**2 + cos_avg_lnd**2) # * 86400 Convert kg/m2/s -> mm/d? amp_avg_ocn = MV2.sqrt(sin_avg_ocn**2 + cos_avg_ocn**2) pha_avg_glo = MV2.remainder( rad_to_hrs(MV2.arctan2(sin_avg_glo, cos_avg_glo), clocktype), clocktype) pha_avg_lnd = MV2.remainder( rad_to_hrs(MV2.arctan2(sin_avg_lnd, cos_avg_lnd), clocktype), clocktype) pha_avg_ocn = MV2.remainder( rad_to_hrs(MV2.arctan2(sin_avg_ocn, cos_avg_ocn), clocktype), clocktype) if 'CMCC-CM' in model: # print '** Correcting erroneous time recording in ', rootfname pha_avg_lnd -= 3.0 pha_avg_lnd = MV2.remainder(pha_avg_lnd, clocktype) elif 'BNU-ESM' in model or 'CCSM4' in model or 'CNRM-CM5' in model: # print '** Correcting erroneous time recording in ', rootfname pha_avg_lnd -= 1.5 pha_avg_lnd = MV2.remainder(pha_avg_lnd, clocktype) print( 'Converting singleton transient variables to plain floating-point numbers ...' ) amp_avg_glo = float(amp_avg_glo) pha_avg_glo = float(pha_avg_glo) amp_avg_lnd = float(amp_avg_lnd) pha_avg_lnd = float(pha_avg_lnd) amp_avg_ocn = float(amp_avg_ocn) pha_avg_ocn = float(pha_avg_ocn) print( '%s %s-harmonic amplitude, phase = %7.3f mm/d, %7.3f hrsLST averaged globally' % (monthname, harmonic, amp_avg_glo, pha_avg_glo)) print( '%s %s-harmonic amplitude, phase = %7.3f mm/d, %7.3f hrsLST averaged over land' % (monthname, harmonic, amp_avg_lnd, pha_avg_lnd)) print( '%s %s-harmonic amplitude, phase = %7.3f mm/d, %7.3f hrsLST averaged over ocean' % (monthname, harmonic, amp_avg_ocn, pha_avg_ocn)) # Sub-dictionaries, one for each harmonic component: outD['harmonic' + str(harmonic)] = {} outD['harmonic' + str(harmonic)]['amp_avg_lnd'] = amp_avg_lnd outD['harmonic' + str(harmonic)]['pha_avg_lnd'] = pha_avg_lnd outD['harmonic' + str(harmonic)]['amp_avg_ocn'] = amp_avg_ocn outD['harmonic' + str(harmonic)]['pha_avg_ocn'] = pha_avg_ocn return outD
pass med_rms1 = np.ma.median(out1_rel[vn, :]) med_rms2 = np.ma.median(out2_rel[vn, :]) med_rms3 = np.ma.median(out3_rel[vn, :]) out1_rel[vn, :] = (out1_rel[vn, :] - med_rms1) / med_rms1 out2_rel[vn, :] = (out2_rel[vn, :] - med_rms2) / med_rms2 out3_rel[vn, :] = (out3_rel[vn, :] - med_rms3) / med_rms3 # ADD SPACES FOR LABELS TO ALIGN AXIS LABELS WITH PLOT yax = [m.encode("utf-8") + " " for m in mods] xax = [v + " " for v in vars] # Convert to MV so we can decorate out1_rel = MV2.array(out1_rel) out2_rel = MV2.array(out2_rel) out3_rel = MV2.array(out3_rel) # GENERATE PLOT P.decorate(out1_rel, xax, yax) P.decorate(out2_rel, xax, yax) P.decorate(out3_rel, xax, yax) # PLOT P.plot(out1_rel, x=x, multiple=1.3, bg=1) P.plot(out2_rel, x=x, multiple=2.3, bg=1) P.plot(out3_rel, x=x, multiple=3.3, bg=1) # END OF PLOTTING # SAVE PLOT
cdms2.setAutoBounds('on') f = cdms2.open(os.path.join(cdat_info.get_sampledata_path(),'tas_mo.nc')) fsc = cdms2.open(os.path.join(cdat_info.get_sampledata_path(),'tas_mo_clim.nc')) print "Step #0 : Reading data" s=f(var,longitude=(0,360,'co')) acok=fsc('climseas',longitude=(0,360,'co')) print 'Test #1 : Test result' ac=times.JAN.climatology(s) assert(MV2.allclose(ac[0],acok[0])) f.close() fsc.close() a=cdtime.comptime(1980) b=cdtime.comptime(1980,5) f = cdms2.open(os.path.join(cdat_info.get_sampledata_path(),'tas_6h.nc')) s=f(var,time=(a,b,'co'),squeeze=1) print "Test #2 : 6hourly AND get" jans=times.JAN(s) print "Test #3 : climatology 6h" JFMA=times.Seasons('JFMA')
def testMissingSeason(self): f = cdms2.open(os.path.join(cdat_info.get_sampledata_path(), 'clt.nc')) s = f("clt") cdutil.setTimeBoundsMonthly(s) print('Getting JJA, which should be inexistant in data') with self.assertRaises(Exception): cdutil.JJA(s[:5]) ## Create a year worth of data w/o JJA s1 = s[:5] s2 = s[8:12] s3 = MV2.concatenate((s1, s2)) t = MV2.concatenate((s1.getTime()[:], s2.getTime()[:])) t = cdms2.createAxis(t, id='time') t.units = s.getTime().units t.designateTime() s3.setAxis(0, t) cdutil.setTimeBoundsMonthly(s3) with self.assertRaises(Exception): cdutil.JJA(s3) with self.assertRaises(Exception): cdutil.JJA.departures(s3) ## Original Test (badly impleemnted was checking for this ## But now returns None #with self.assertRaises(Exception): self.assertIsNone(cdutil.JJA.climatology(s3)) # Now gets seasonal cycle, should have JJA all missing print('Testing seasonal cycle on 1 year data w/o JJA should work') a = cdutil.SEASONALCYCLE(s3) self.assertEqual(a.shape, (4, 46, 72)) self.assertTrue(numpy.allclose(a.getTime(), [0., 3., 9., 12.])) self.assertTrue( numpy.allclose( a.getTime().getBounds(), numpy.array([[-1., 2.], [2., 5.], [8., 11.], [11., 14.]]))) self.assertEqual(a.shape, (4, 46, 72), "Error returned data with wrong shape") self.assertTrue( numpy.equal(a.getTime()[:], [0., 3., 9., 12.]).all(), "Error time are not valid") self.assertTrue( numpy.equal(a.getTime().getBounds()[:], [[-1., 2.], [2., 5.], [8., 11.], [11., 14.]]).all(), "Error bound time are not valid") d = cdutil.SEASONALCYCLE.departures(s3) c = cdutil.SEASONALCYCLE.climatology(s3) ## Create 2 year worth of data w/o JJA s1 = s[:5] s2 = s[8:17] s3 = s[20:24] s4 = MV2.concatenate((s1, s2)) s5 = MV2.concatenate((s4, s3)) t = MV2.concatenate((s1.getTime()[:], s2.getTime()[:])) t2 = MV2.concatenate((t, s3.getTime()[:])) t = cdms2.createAxis(t2, id='time') t.units = s.getTime().units t.designateTime() s5.setAxis(0, t) cdutil.setTimeBoundsMonthly(s5) d = cdutil.SEASONALCYCLE.departures(s5) c = cdutil.SEASONALCYCLE.climatology(s5) with self.assertRaises(Exception): cdutil.JJA(s5) # Now gets seasonal cycle, should have JJA all missing print('Testing seasonal cycle on 2 years data w/o JJA should work') a = cdutil.SEASONALCYCLE(s5) self.assertEqual(a.shape, (7, 46, 72), "Error returned data with wrong shape") ## Create 2 years worth of data w/o 1st JJA s1 = s[:5] s2 = s[8:24] s3 = MV2.concatenate((s1, s2)) t = MV2.concatenate((s1.getTime()[:], s2.getTime()[:])) t = cdms2.createAxis(t, id='time') t.units = s.getTime().units t.designateTime() s3.setAxis(0, t) cdutil.setTimeBoundsMonthly(s3) a = cdutil.JJA(s3) self.assertIsNotNone(a, "data w/o 1st season did not return None") # Now gets seasonal cycle, should have JJA all missing print('Testing seasonal cycle on 2 years data w/o 1st JJA should work') a = cdutil.SEASONALCYCLE(s3) d = cdutil.SEASONALCYCLE.departures(s3) c = cdutil.SEASONALCYCLE.climatology(s3) self.assertEqual(a.shape, (8, 46, 72), "Error returned data with wrong shape") self.assertTrue( numpy.equal(a.getTime()[:], [0., 3., 9., 12., 15., 18., 21, 24]).all(), "Error time are not valid") self.assertTrue( numpy.equal( a.getTime().getBounds()[:], [[-1., 2.], [2., 5.], [8., 11.], [11., 14.], [14., 17.], [17., 20.], [20., 23.], [23., 26.]]).all(), "Error bound time are not valid") print(" Ok we test the filling part") print(" this should add month '6' as all missing") b = cdutil.times.insert_monthly_seasons(a, [ 'JJA', ]) self.assertEqual(b.shape, (9, 46, 72), "Error returned data with wrong shape") self.assertTrue( numpy.equal(b.getTime()[:], [0., 3., 6, 9., 12., 15., 18., 21, 24]).all(), "Error time are not valid") self.assertTrue( numpy.equal( b.getTime().getBounds()[:], [[-1., 2.], [2., 5.], [5, 8], [8., 11.], [11., 14.], [14., 17.], [17., 20.], [20., 23.], [23., 26.]]).all(), "Error bound time are not valid") self.assertEqual(b[2].count(), 0, "Error not all times missing in added spot") # Now gets seasonal cycle, should have JJA all missing print('Testing seasonal cycle on 2 years data w/o JJA should work') a = cdutil.SEASONALCYCLE(s5) self.assertEqual(a.shape, (7, 46, 72), "Error returned data with wrong shape") ## Creates data with big gap in years s1 = s[:15] s2 = s[68:] s3 = MV2.concatenate((s1, s2)) t = MV2.concatenate((s1.getTime()[:], s2.getTime()[:])) t = cdms2.createAxis(t, id='time') t.units = s.getTime().units t.designateTime() s3.setAxis(0, t) cdutil.setTimeBoundsMonthly(s3) a = cdutil.JJA(s3) self.assertIsNotNone(a, "data with gap returned None") # Now gets seasonal cycle, should have JJA all missing print('Testing seasonal cycle on data with years of gap should work') a = cdutil.SEASONALCYCLE(s3) d = cdutil.SEASONALCYCLE.departures(s3) c = cdutil.SEASONALCYCLE.climatology(s3) self.assertEqual(s3.shape, (67, 46, 72)) self.assertEqual(a.shape, (24, 46, 72)) self.assertTrue( numpy.equal(a.getTime(), [ 0., 3., 6., 9., 12., 15., 69., 72., 75., 78., 81., 84., 87., 90., 93., 96., 99., 102., 105., 108., 111., 114., 117., 120. ]).all()) print(" Ok we test the filling part") print(" this should add month '6' as all missing") b = cdutil.times.insert_monthly_seasons( a, cdutil.times.SEASONALCYCLE.seasons) self.assertEqual(b.shape, (41, 46, 72)) self.assertTrue( numpy.equal(b.getTime()[:], [ 0., 3., 6., 9., 12., 15., 18., 21., 24., 27., 30., 33., 36., 39., 42., 45., 48., 51., 54., 57., 60., 63., 66., 69., 72., 75., 78., 81., 84., 87., 90., 93., 96., 99., 102., 105., 108., 111., 114., 117., 120. ]).all()) self.assertEqual( cdutil.SEASONALCYCLE.departures(s3).shape, (24, 46, 72)) self.assertEqual(a.shape, (24, 46, 72)) self.assertEqual( cdutil.SEASONALCYCLE.climatology(s3).shape, (4, 46, 72))
def _get(self): if 'relative' in self.portrait_types.keys(): d = self.portrait_types['relative'] vals = d[1] real_value = getattr(self, d[0]) real = self.__get() setattr(self, d[0], vals[0]) a0 = self.__get() sh = list(a0.shape) sh.insert(0, 1) a0 = MV2.reshape(a0, sh) for v in vals[1:]: setattr(self, d[0], v) tmp = self.__get() tmp = MV2.reshape(tmp, sh) a0 = MV2.concatenate((a0, tmp)) a0 = MV2.sort(a0, 0).filled() real2 = real.filled() a0 = MV2.reshape(a0, (a0.shape[0], sh[1] * sh[2])) real2 = MV2.reshape(real2, (sh[1] * sh[2], )) a0 = MV2.transpose(a0) indices = [] for i in range(len(real2)): indices.append(MV2.searchsorted(a0[i], real2[i])) indices = MV2.array(indices) indices = MV2.reshape(indices, (sh[1], sh[2])) if not ((real.mask is None) or (real.mask is MV2.nomask)): indices = MV2.masked_where(real.mask, indices) a = MV2.masked_equal(a0, 1.e20) a = MV2.count(a, 1) a = MV2.reshape(a, indices.shape) indices = indices / a * 100 setattr(self, d[0], real_value) indices.setAxisList(real.getAxisList()) ## print indices.shape return indices else: return self.__get()
def europe_plot(data, projection, **kwargs): laterr = 2 lonerr = 20 v = max([np.abs(np.ma.min(data)), np.abs(np.ma.max(data))]) if "vmin" not in kwargs.keys(): kwargs["vmin"] = -v if "vmax" not in kwargs.keys(): kwargs["vmax"] = v data = MV.masked_where(np.isnan(data), data) #fig = plt.figure() #ax = fig.add_axes([0.1,0.1,0.8,0.8]) llcrnrlat = data.getLatitude()[:][0] - laterr urcrnrlat = data.getLatitude()[:][-1] + laterr llcrnrlon = data.getLongitude()[:][0] - 2 urcrnrlon = data.getLongitude()[:][-1] + 20 lat_0 = np.median(data.getLatitude()) lon_0 = np.median(data.getLongitude()) # m = Basemap(llcrnrlon=llcrnrlon,llcrnrlat=llcrnrlat,urcrnrlon=urcrnrlon,urcrnrlat=urcrnrlat,rsphere=(6378137.00,6356752.3142),resolution='l',area_thresh=1000.,projection='lcc',lat_0=lat_0,lon_0=lon_0,ax=ax) m=Basemap(llcrnrlon=llcrnrlon, \ llcrnrlat=llcrnrlat, \ urcrnrlon=urcrnrlon, \ urcrnrlat= urcrnrlat, \ llcrnrx=None, \ llcrnry=None, \ urcrnrx=None, \ urcrnry=None, \ width=None, \ height=None, \ projection=projection, \ resolution='c', \ area_thresh=1000, \ rsphere=6370997.0, \ ellps=None, \ lat_ts=None, \ lat_1=None, \ lat_2=None, \ lat_0=51.0, \ lon_0=13.0, \ lon_1=None, \ lon_2=None, \ o_lon_p=None, \ o_lat_p=None, \ k_0=None, \ no_rot=True, \ suppress_ticks=True, \ satellite_height=35786000, \ boundinglat=None, \ fix_aspect=True, \ anchor='C', \ celestial=False, \ round=False, \ epsg=None, \ ax=None) lon = data.getLongitude().getBounds()[:, 0] lat = data.getLatitude().getBounds()[:, 0] x, y = m(*np.meshgrid(lon, lat)) stuff = m.pcolormesh(x, y, data, **kwargs) plt.colorbar(stuff) return m
def plot(self, data=None, mesh=None, template=None, meshfill=None, x=None, bg=0, multiple=1.1): # Create the vcs canvas if x is None: x = vcs.init() ## Continents bug x.setcontinentstype(0) # gets the thing to plot ! if data is None: data = self.get() # Do we use a predefined template ? if template is None: template = x.createtemplate() # Now sets all the things for the template... # Sets a bunch of template attributes to off for att in [ 'line1', 'line2', 'line3', 'line4', 'box2', 'box3', 'box4', 'min', 'max', 'mean', 'xtic1', 'xtic2', 'ytic1', 'ytic2', 'xvalue', 'yvalue', 'zvalue', 'tvalue', 'xunits', 'yunits', 'zunits', 'tunits', 'source', 'title', 'dataname', ]: a = getattr(template, att) setattr(a, 'priority', 0) for att in [ 'xname', 'yname', ]: a = getattr(template, att) setattr(a, 'priority', 0) template.data.x1 = self.PLOT_SETTINGS.x1 template.data.x2 = self.PLOT_SETTINGS.x2 template.data.y1 = self.PLOT_SETTINGS.y1 template.data.y2 = self.PLOT_SETTINGS.y2 template.box1.x1 = self.PLOT_SETTINGS.x1 template.box1.x2 = self.PLOT_SETTINGS.x2 template.box1.y1 = self.PLOT_SETTINGS.y1 template.box1.y2 = self.PLOT_SETTINGS.y2 template.xname.y = self.PLOT_SETTINGS.y2 + .02 template.yname.x = self.PLOT_SETTINGS.x2 + .01 template.xlabel1.y = self.PLOT_SETTINGS.y1 template.xlabel2.y = self.PLOT_SETTINGS.y2 template.xlabel1.texttable = self.PLOT_SETTINGS.tictable template.xlabel2.texttable = self.PLOT_SETTINGS.tictable template.xlabel1.textorientation = self.PLOT_SETTINGS.xticorientation template.xlabel2.textorientation = self.PLOT_SETTINGS.xticorientation template.ylabel1.x = self.PLOT_SETTINGS.x1 template.ylabel2.x = self.PLOT_SETTINGS.x2 template.ylabel1.texttable = self.PLOT_SETTINGS.tictable template.ylabel2.texttable = self.PLOT_SETTINGS.tictable template.ylabel1.textorientation = self.PLOT_SETTINGS.yticorientation template.ylabel2.textorientation = self.PLOT_SETTINGS.yticorientation if self.PLOT_SETTINGS.xtic1y1 is not None: template.xtic1.y1 = self.PLOT_SETTINGS.xtic1y1 template.xtic1.priority = 1 if self.PLOT_SETTINGS.xtic1y2 is not None: template.xtic1.y2 = self.PLOT_SETTINGS.xtic1y2 template.xtic1.priority = 1 if self.PLOT_SETTINGS.xtic2y1 is not None: template.xtic2.y1 = self.PLOT_SETTINGS.xtic2y1 template.xtic2.priority = 1 if self.PLOT_SETTINGS.xtic2y2 is not None: template.xtic2.y2 = self.PLOT_SETTINGS.xtic2y2 template.xtic2.priority = 1 if self.PLOT_SETTINGS.ytic1x1 is not None: template.ytic1.x1 = self.PLOT_SETTINGS.ytic1x1 template.ytic1.priority = 1 if self.PLOT_SETTINGS.ytic1x2 is not None: template.ytic1.x2 = self.PLOT_SETTINGS.ytic1x2 template.ytic1.priority = 1 if self.PLOT_SETTINGS.ytic2x1 is not None: template.ytic2.priority = 1 template.ytic2.x1 = self.PLOT_SETTINGS.ytic2x1 if self.PLOT_SETTINGS.ytic2x2 is not None: template.ytic2.priority = 1 template.ytic2.x2 = self.PLOT_SETTINGS.ytic2x2 template.legend.x1 = self.PLOT_SETTINGS.legend_x1 template.legend.x2 = self.PLOT_SETTINGS.legend_x2 template.legend.y1 = self.PLOT_SETTINGS.legend_y1 template.legend.y2 = self.PLOT_SETTINGS.legend_y2 try: tmp = x.createtextorientation('crap22') except: tmp = x.gettextorientation('crap22') tmp.height = 12 #tmp.halign = 'center' # template.legend.texttable = tmp template.legend.textorientation = tmp else: if isinstance(template, vcs.template.P): tid = template.name elif isinstance(template, str): tid = template else: raise 'Error cannot understand what you mean by template=' + str( template) template = x.createtemplate() # Do we use a predefined meshfill ? if meshfill is None: mtics = {} for i in range(100): mtics[i - .5] = '' icont = 1 meshfill = x.createmeshfill() meshfill.xticlabels1 = eval(data.getAxis(1).names) meshfill.yticlabels1 = eval(data.getAxis(0).names) meshfill.datawc_x1 = -.5 meshfill.datawc_x2 = data.shape[1] - .5 meshfill.datawc_y1 = -.5 meshfill.datawc_y2 = data.shape[0] - .5 meshfill.mesh = self.PLOT_SETTINGS.draw_mesh meshfill.missing = self.PLOT_SETTINGS.missing_color meshfill.xticlabels2 = mtics meshfill.yticlabels2 = mtics if self.PLOT_SETTINGS.colormap is None: self.set_colormap(x) elif x.getcolormapname() != self.PLOT_SETTINGS.colormap: x.setcolormap(self.PLOT_SETTINGS.colormap) if self.PLOT_SETTINGS.levels is None: min, max = vcs.minmax(data) if max != 0: max = max + .000001 levs = vcs.mkscale(min, max) else: levs = self.PLOT_SETTINGS.levels if len(levs) > 1: meshfill.levels = levs if self.PLOT_SETTINGS.fillareacolors is None: cols = vcs.getcolors(levs, range(16, 40), split=1) meshfill.fillareacolors = cols else: meshfill.fillareacolors = self.PLOT_SETTINGS.fillareacolors ## self.setmeshfill(x,meshfill,levs) ## if self.PLOT_SETTINGS.legend is None: ## meshfill.legend=vcs.mklabels(levs) ## else: ## meshfill.legend=self.PLOT_SETTINGS.legend # Now creates the mesh associated n = int(multiple) ntot = int((multiple - n) * 10 + .1) ## data=data sh = list(data.shape) sh.append(2) I = MV2.indices((sh[0], sh[1])) Y = I[0] X = I[1] ## if ntot>1: ## meshfill.mesh='y' if ntot == 1: sh.append(4) M = MV2.zeros(sh) M[:, :, 0, 0] = Y - .5 M[:, :, 1, 0] = X - .5 M[:, :, 0, 1] = Y - .5 M[:, :, 1, 1] = X + .5 M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X + .5 M[:, :, 0, 3] = Y + .5 M[:, :, 1, 3] = X - .5 M = MV2.reshape(M, (sh[0] * sh[1], 2, 4)) elif ntot == 2: sh.append(3) M = MV2.zeros(sh) M[:, :, 0, 0] = Y - .5 M[:, :, 1, 0] = X - .5 M[:, :, 0, 1] = Y + .5 - (n - 1) M[:, :, 1, 1] = X - 0.5 + (n - 1) M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X + .5 M = MV2.reshape(M, (sh[0] * sh[1], 2, 3)) elif ntot == 3: design = int((multiple - n) * 100 + .1) if design == 33: sh.append(3) M = MV2.zeros(sh) if n == 1: M[:, :, 0, 0] = Y - .5 M[:, :, 1, 0] = X - .5 M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X - .5 elif n == 2: M[:, :, 0, 0] = Y - .5 M[:, :, 1, 0] = X - .5 M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X + .5 elif n == 3: M[:, :, 0, 0] = Y + .5 M[:, :, 1, 0] = X + .5 M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X + .5 M = MV2.reshape(M, (sh[0] * sh[1], 2, 3)) elif design == 32: sh.append(5) M = MV2.zeros(sh) M[:, :, 0, 0] = Y M[:, :, 1, 0] = X d = .5 / MV2.sqrt(3.) if n == 1: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X - .5 M[:, :, 0, 3] = Y - d M[:, :, 1, 3] = X - .5 # dummy point for n==1 or 3 M[:, :, 0, 4] = Y M[:, :, 1, 4] = X if n == 2: M[:, :, 0, 1] = Y - d M[:, :, 1, 1] = X - .5 M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X - .5 M[:, :, 0, 3] = Y - .5 M[:, :, 1, 3] = X + .5 M[:, :, 0, 4] = Y - d M[:, :, 1, 4] = X + .5 elif n == 3: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X + .5 M[:, :, 0, 3] = Y - d M[:, :, 1, 3] = X + .5 # dummy point for n==1 or 3 M[:, :, 0, 4] = Y M[:, :, 1, 4] = X M = MV2.reshape(M, (sh[0] * sh[1], 2, 5)) else: sh.append(5) M = MV2.zeros(sh) M[:, :, 0, 0] = Y M[:, :, 1, 0] = X d = 1. / 3. if n == 1: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X - .5 M[:, :, 0, 3] = Y - d M[:, :, 1, 3] = X - .5 # dummy point for n==1 or 3 M[:, :, 0, 4] = Y M[:, :, 1, 4] = X if n == 2: M[:, :, 0, 1] = Y - d M[:, :, 1, 1] = X - .5 M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X - .5 M[:, :, 0, 3] = Y - .5 M[:, :, 1, 3] = X + .5 M[:, :, 0, 4] = Y - d M[:, :, 1, 4] = X + .5 elif n == 3: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X + .5 M[:, :, 0, 3] = Y - d M[:, :, 1, 3] = X + .5 # dummy point for n==1 or 3 M[:, :, 0, 4] = Y M[:, :, 1, 4] = X M = MV2.reshape(M, (sh[0] * sh[1], 2, 5)) elif ntot == 4: sh.append(3) M = MV2.zeros(sh) M[:, :, 0, 0] = Y M[:, :, 1, 0] = X if n == 1: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X + .5 M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X - .5 elif n == 2: M[:, :, 0, 1] = Y + .5 M[:, :, 1, 1] = X - .5 M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X - .5 elif n == 3: M[:, :, 0, 1] = Y - .5 M[:, :, 1, 1] = X - .5 M[:, :, 0, 2] = Y - .5 M[:, :, 1, 2] = X + .5 elif n == 4: M[:, :, 0, 1] = Y - .5 M[:, :, 1, 1] = X + .5 M[:, :, 0, 2] = Y + .5 M[:, :, 1, 2] = X + .5 M = MV2.reshape(M, (sh[0] * sh[1], 2, 3)) else: if isinstance(meshfill, vcs.meshfill.P): tid = mesh.id elif isinstance(meshfill, str): tid = mesh else: raise 'Error cannot understand what you mean by meshfill=' + str( meshfill) meshfill = x.createmeshfill() if mesh is None: x.plot(MV2.ravel(data), M, template, meshfill, bg=bg) else: x.plot(MV2.ravel(data), mesh, template, meshfill, bg=bg) # Now prints the rest of the title, etc... # but only if n==1 if n == 1: axes_param = [] for a in data.getAxis(0).id.split('___'): axes_param.append(a) for a in data.getAxis(1).id.split('___'): axes_param.append(a) nparam = 0 for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies and not p in axes_param: nparam += 1 if self.verbose: print 'NPARAM:', nparam if nparam > 0: for i in range(nparam): j = MV2.ceil(float(nparam) / (i + 1.)) if j <= i: break npc = i # number of lines npl = int(j) # number of coulmns if npc * npl < nparam: npl += 1 # computes space between each line dl = (.95 - template.data.y2) / npl dc = .9 / npc npci = 0 # counter for columns npli = 0 # counter for lines for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies and not p in axes_param: txt = x.createtext( None, self.PLOT_SETTINGS.parametertable.name, None, self.PLOT_SETTINGS.parameterorientation.name) value = getattr(self, p) if (isinstance(value, (list, tuple)) and len(value) == 1): txt.string = p + ':' + str( self.makestring(p, value[0])) display = 1 elif isinstance(value, (str, int, float, long)): txt.string = p + ':' + str( self.makestring(p, value)) display = 1 else: display = 0 if display: # Now figures out where to put these... txt.x = [(npci) * dc + dc / 2. + .05] txt.y = [1. - (npli) * dl - dl / 2.] npci += 1 if npci >= npc: npci = 0 npli += 1 if p in self.altered.keys(): dic = self.altered[p] if dic['size'] is not None: txt.size = dic['size'] if dic['color'] is not None: txt.color = dic['color'] if dic['x'] is not none: txt.x = dic['x'] if dic['y'] is not none: txt.y = dic['y'] x.plot(txt, bg=bg, continents=0) if not self.PLOT_SETTINGS.logo is None: x.plot(self.PLOT_SETTINGS.logo, bg=bg, continents=0) if not self.PLOT_SETTINGS.time_stamp is None: import time sp = time.ctime().split() sp = sp[:3] + [sp[-1]] self.PLOT_SETTINGS.time_stamp.string = ''.join(sp) x.plot(self.PLOT_SETTINGS.time_stamp, bg=bg, continents=0)
def __init__(self, name, cutoff='0001-1-1'): if name.find("2.5") >= 0: self.name = name.split("2.5")[0] else: self.name = name #if name.find("+")<0: f = cdms.open("../DROUGHT_ATLAS/PROCESSED/" + name + ".nc") obs = f("pdsi") self.obs = MV.masked_where(np.isnan(obs), obs) self.obs = MV.masked_where(np.abs(self.obs) > 90, self.obs) self.obs = self.obs(time=(cutoff, '2020-12-31')) self.obs = mask_data( self.obs, self.obs.mask[0] ) #Make all the obs have the same mask as the first datapoint f.close() fm = cdms.open("../DROUGHT_ATLAS/CMIP5/pdsi." + name + ".hist.rcp85.nc") self.model = get_rid_of_bad(fm("pdsi")) self.model = MV.masked_where(np.isnan(self.model), self.model) fm.close() # else: #DEPRECATED: MERGE observations onto common grid using old code # name1,name2=name.split("+") # f1 = cdms.open("../DROUGHT_ATLAS/PROCESSED/"+name1+".nc") # obs1 = f1("pdsi") # obs1 = MV.masked_where(np.isnan(obs1),obs1) # obs1 = MV.masked_where(np.abs(obs1)>90,obs1) # obs1 = obs1(time=(cutoff,'2017-12-31')) # obs1=mask_data(obs1,obs1.mask[0]) # f1.close() # fm1 = cdms.open("../DROUGHT_ATLAS/CMIP5/pdsi."+name1+".hist.rcp85.nc") # model1=get_rid_of_bad(fm1("pdsi")) # model1=MV.masked_where(np.isnan(model1),model1) # fm1.close() # f2 = cdms.open("../DROUGHT_ATLAS/PROCESSED/"+name2+".nc") # obs2 = f2("pdsi") # obs2 = MV.masked_where(np.isnan(obs2),obs2) # obs2 = MV.masked_where(np.abs(obs2)>90,obs2) # obs2 = obs2(time=(cutoff,'2017-12-12')) # obs2=mask_data(obs2,obs2.mask[0]) # f2.close() # fm2 = cdms.open("../DROUGHT_ATLAS/CMIP5/pdsi."+name2+".hist.rcp85.nc") # model2=get_rid_of_bad(fm2("pdsi")) # model2=MV.masked_where(np.isnan(model2),model2) # fm2.close() # self.obs=merge.merge(obs1,obs2) # self.model=merge.merge(model1,model2) mma = MV.average(self.model, axis=0) self.mma = mask_data( mma, self.obs[0].mask) #make all the models have the same mask self.solver = Eof(self.mma, weights='area') self.eofmask = self.solver.eofs()[0].mask self.fac = da.get_orientation(self.solver) self.projection = self.solver.projectField( mask_data(self.obs, self.eofmask))[:, 0] * self.fac self.noise = self.projection(time=('1-1-1', '1850-1-1')) self.P = self.model_projections()
cdms2.setAutoBounds('on') f = cdms2.open(os.path.join(cdms2.__path__[0],'..','..','..','..','sample_data','tas_mo.nc')) fsc = cdms2.open(os.path.join(cdms2.__path__[0],'..','..','..','..','sample_data','tas_mo_clim.nc')) print "Step #0 : Reading data" s=f(var,longitude=(0,360,'co')) acok=fsc('climseas',longitude=(0,360,'co')) print 'Test #1 : Test result' ac=times.JAN.climatology(s) if not(MV2.allclose(ac[0],acok[0])) : raise 'Err answer seems to be wrong we Missing Value free dataset' f.close() fsc.close() a=cdtime.comptime(1980) b=cdtime.comptime(1980,5) f = cdms2.open(os.path.join(cdms2.__path__[0],'..','..','..','..','sample_data','tas_6h.nc')) s=f(var,time=(a,b,'co'),squeeze=1) print "Test #2 : 6hourly AND get" jans=times.JAN(s) try: jans=times.JAN(s) except:
import sys, os src = sys.argv[1] import vcs.testing.regression as regression import vcs import vcsaddons, numpy, MV2 import cdms2, cdutil, cdtime x = regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "clt.nc")) # Trim first few months and last month so we have even number of seasons cloudiness = f('clt', time=(11, 119)) cdutil.setAxisTimeBoundsMonthly(cloudiness.getTime()) cloudiness_time_axis = cloudiness.getTime() averaged_seasons = MV2.zeros((36, 46, 72)) # Average the seasons in cloudiness for i in range(36): averaged_seasons[i] = cdutil.averager( cloudiness(time=(cloudiness_time_axis[i * 3], cloudiness_time_axis[(i + 1) * 3])), axis="t") averaged_seasons.setAxis(1, cloudiness.getLatitude()) averaged_seasons.setAxis(2, cloudiness.getLongitude()) regions = { "north_polar": (66, 90), "north_temperate": (22, 66), "tropics": (-22, 22), "south_temperate": (-66, -22), "south_polar": (-90, -66)
def get(self, returnTuple=1): value = self.data frc = None if type(value) in [types.TupleType, types.ListType]: value, frc = value if isinstance(value, numpy.ndarray) or numpy.ma.isMA( value): # Variable defined from array if frc is None: frc = numpy.ma.ones(value.shape, dtype=numpy.float32) kw = {} args = [] # Add user defined cdmsArguments for a in self.cdmsArguments: args.append(a) # Add user defined cdmsKeywords for k in self.cdmsKeywords.keys(): kw[k] = self.cdmsKeywords[k] # try to apply, if not forget about it try: v = value(*args, **kw) frc = frc(*args, **kw) # Now removes the slice types # because they can't be used twice for k in kw.keys(): if type(kw[k]) == types.SliceType: del (kw[k]) for i in range(len(args)): if type(args[i]) == types.SliceType: pop(args, i) i = i - 1 except: v = value else: # Variable comes from a file, need to be retrieved f = cdms2.open(self.file) kw = {} args = [] # Add user defined cdmsArguments for a in self.cdmsArguments: args.append(a) # Add user defined cdmsKeywords for k in self.cdmsKeywords.keys(): kw[k] = self.cdmsKeywords[k] v = f(self.var, *args, **kw) f.close() # Now removes the slice types # because they can't be used twice for k in kw.keys(): if type(kw[k]) == types.SliceType: del (kw[k]) for i in range(len(args)): if type(args[i]) == types.SliceType: pop(args, i) i = i - 1 ## At that stage applied the preprocess function if self.preprocess is not None: v = apply(self.preprocess, (v, ), self.preprocessKeywords) # Create the fractions if frc is None: frc = v.mask if frc is numpy.ma.nomask: #no mask # Create a bunch of ones (100%) frc = numpy.ones(v.shape, numpy.float32) else: # Fraction are actually just the opposite of the mask at that stage ! frc = frc.astype( MV2.float32) # Sometimes if it is bytes it doesn't work frc = 1. - frc frc = frc.astype( MV2.float32) # no need for double precision here ! else: m = v.mask if not m is numpy.ma.nomask: frc = MV2.where(m, 0., frc).filled(0.) # Now get the associted weights object # Note that we pass v in case some of the values are defined as "input" # in which case it would use v instead of the weights for weightsing m = self.weightsMaker(v) if not m is None: # grows the variable and the weights for possible Xtra dimensions m = m(*args, **kw) v, m = genutil.grower(v, m) # make sure variable and weights are compatible if m.shape != v.shape: raise VariableConditionerError, 'weights and variable have different shapes: weights is ' + str( m.shape) + ' and grid is ' + str(v.shape) # make sure they're on the same grid (in case one starts at 0 and one at -180 for example if not m.getGrid() is v.getGrid(): m = m.regrid(v.getGrid()) # Mask the dataset where the fraction are 0. v = MV2.masked_where(MV2.equal(m.filled(0), 0.), v) # Update the fractions frc = m.filled(0.) m = v.mask if not m is numpy.ma.nomask: frc = numpy.where(m, 0., frc) ## # Filll the mask with ones, i.e. set fraction to 0 when the mask is masked hahah ## frc = numpy.where(m.filled(1),0.,frc) # Now get the target grid g = self.weightedGridMaker() if not g is None: # we do have a target grid to go to ! # Create the regridder object rf = regrid2.Regridder(v.getGrid(), g) # and regrid passing the weights to use to each grid cell # at this point it should be only 0/1 v, frc = rf(v, mask=1. - frc, returnTuple=1) frc = MV2.array(frc) frc.setAxisList(v.getAxisList()) v = v(*args, **kw) frc = frc(*args, **kw).filled(0.) # Note that now frc is not necessarily 0. and 1. but actuall fraction # of the grid cell that has real data in it. # do we weights after this regridding ? # once again pass v in case the weightsing wants # to work on the variable m = self.weightedGridMaker.weightsMaker(v) if not m is None: # we have a weights m = m(*args, **kw) # apply the extra cdmsKeywords to it v, m = genutil.grower(v, m) # make sure variable and weights are compatible if m.shape != v.shape: raise VariableConditionerError, 'weights and variable have different shapes: weights is ' + str( m.shape) + ' and grid is ' + str(v.shape) # make sure they're on the same grid (in case one starts at 0 and one at -180 for example if not m.getGrid() is v.getGrid(): m = m.regrid(v.getGrid()) v = MV2.masked_where(MV2.equal(m.filled(0.), 0.), v) # weights the fraction where needed frc = m.filled(0.) m = v.mask if not m is numpy.ma.nomask: frc = numpy.where(m, 0., frc) ## frc=numpy.where(m.filled(1),0.,frc) # Now make the fraction an MV2 and puts the dim from v on it frc = MV2.array(frc) frc.setAxisList(v.getAxisList()) # just in case applies the cdmsKeywords again # usefull in case your final grid is global # and you specified Nino3 region for example. v = v(*args, **kw) frc = frc(*args, **kw).filled(0.) if v.missing_value is None: v.missing_value = 1.e20 v = MV2.masked_where(MV2.equal(frc, 0.), v) # Now applies the slope and offset if necessary if self.slope != 1.: v = v * self.slope if self.offset != 0.: v = v + self.offset if not ((v.mask is None) or (v.mask is MV2.nomask)): if numpy.ma.allclose(v.mask, 0.): v._mask = numpy.ma.nomask # Returns the variable and the fractions or just the variable if returnTuple: ## if not ((frc.mask is None) or (frc.mask is MV2.nomask)): ## if numpy.ma.allclose(frc.mask,0.): ## frc._mask=None return v, frc else: return v
import cdms2, MV2 test_nm = 'CDMS_Test_del_attributes.nc' f = cdms2.open(test_nm,"w") s = MV2.ones((20,20)) s.id="test" s.test_attribute = "some variable attribute" f.test_attribute = "some file attribute" f.write(s) f.close() f = cdms2.open(test_nm,"r+") delattr(f,'test_attribute') s=f["test"] del(s.test_attribute) f.close() f = cdms2.open(test_nm) assert(hasattr(f,'test_attribute') is False) s=f["test"] assert(hasattr(s,'test_attribute') is False)
# Adapted for numpy/ma/cdms2 by convertcdms.py # Let's import the necessary modules import cdms2 as cdms, MV2 as MV # Let's create the variable first rain = MV.array([2., 15., 3.5, 4.]) rain.id = 'pr' rain.units = 'cm' # Now we need to create the associated "time" axis, let's use days' since 2005 as units # First the axis itslef with its values # values can be passed as a list, an array or a variable time = cdms.createAxis([2, 4, 16, 22]) # Remember Jan 1st, is 0 days since Jan 1st! # Now let's name it time.id = 'time' # Let's give it some units time.units = 'days since 2005-1-1' # Another very important attribute are the bounds, indeed we need to know the "extend" of each value # Here we will assume that the data span a full day everytime, but they could as well spend a few hours # of these days only bounds = MV.array([[2., 3.], [4., 5.], [16., 17.], [22., 23.]]) time.setBounds(bounds) # Now we have to link the variable dimension to this axes object rain.setAxis(0, time)
ch_units(taxis, 'days since 2000-1-15 06', copy=0) # - after print taxis.units, taxis[0:2] print taxis.asComponentTime()[0:2] # -> days since 2000-1-15 06 [ 0. 2.] # -> [2000-1-15 6:0:0.0, 2000-1-17 6:0:0.0] # Matplotlib times taxis_mpl = mpl(taxis) print taxis_mpl[0], taxis_mpl.units # -> 730134.25 days since 0001 # Change the time units of a variable import MV2 var = MV2.array(MV2.arange(len(taxis)), dtype='f', axes=[taxis]) ch_units(var, 'hours since 2000-01-15 06') print var.getTime()[0:2] # -> [ 0. 48.] # Change time zone # - UTC time now t_utc = now(True) print strftime('%H:%M', t_utc), t_utc.hour # -> 15:54 15 # - Paris time t_paris = utc_to_paris(t_utc) print strftime('%H:%M', t_paris), t_paris.hour # -> 17:54 17 # - back to UTC print tz_to_tz(t_paris, 'Europe/Paris', 'UTC').hour
def myMakeMask(array, range): """Returns the input array masked where the values are not between range[0] and range[1]""" m1 = MV.less(array, range[0]) # mask where it is less than the 1st value m2 = MV.greater(array, range[1]) # mask where it is more than the 2nd value return MV.logical_or(m1, m2)
def main(): P.add_argument( "-t", "--filename_template", default="pr_%(model)_%(month)_%(firstyear)-%(lastyear)_diurnal_avg.nc", help="template for file names containing diurnal average", ) P.add_argument("--model", default="*") P.add_argument( "--filename_template_LST", default="pr_%(model)_LocalSolarTimes.nc", help="template for file names point to Local Solar Time Files", ) P.add_argument( "--filename_template_std", default="pr_%(model)_%(month)_%(firstyear)-%(lastyear)_diurnal_std.nc", help="template for file names containing diurnal std", ) P.add_argument( "-l", "--lats", nargs="*", default=[31.125, 31.125, 36.4, 5.125, 45.125, 45.125], help="latitudes", ) P.add_argument( "-L", "--lons", nargs="*", default=[-83.125, 111.145, -97.5, 147.145, -169.145, -35.145], help="longitudes", ) P.add_argument( "-A", "--outnameasc", type=str, dest="outnameasc", default= "pr_%(month)_%(firstyear)-%(lastyear)_fourierDiurnalGridPoints.asc", help="Output name for ascs", ) args = P.get_parameter() month = args.month monthname = monthname_d[month] startyear = args.firstyear finalyear = args.lastyear yearrange = "%s-%s" % (startyear, finalyear) # noqa: F841 template = populateStringConstructor(args.filename_template, args) template.month = monthname template_std = populateStringConstructor(args.filename_template_std, args) template_std.month = monthname template_LST = populateStringConstructor(args.filename_template_LST, args) template_LST.month = monthname LSTfiles = glob.glob(os.path.join(args.modpath, template_LST())) print("LSTFILES:", LSTfiles) print("TMPL", template_LST()) ascFile = populateStringConstructor(args.outnameasc, args) ascFile.month = monthname ascname = os.path.join(os.path.abspath(args.results_dir), ascFile()) if not os.path.exists(os.path.dirname(ascname)): os.makedirs(os.path.dirname(ascname)) fasc = open(ascname, "w") gridptlats = [float(x) for x in args.lats] gridptlons = [float(x) for x in args.lons] nGridPoints = len(gridptlats) assert len(gridptlons) == nGridPoints # gridptlats = [-29.125, -5.125, 45.125, 45.125] # gridptlons = [-57.125, 75.125, -169.145, -35.145] # Gridpoints for JULY samples in Figure 4 of Covey et al., JClimate 29: 4461 (2016): # nGridPoints = 6 # gridptlats = [ 31.125, 31.125, 36.4, 5.125, 45.125, 45.125] # gridptlons = [-83.125, 111.145, -97.5, 147.145, -169.145, -35.145] N = 8 # Number of timepoints in a 24-hour cycle for LSTfile in LSTfiles: print("Reading %s ..." % LSTfile, os.path.basename(LSTfile), file=fasc) print("Reading %s ..." % LSTfile, os.path.basename(LSTfile), file=fasc) reverted = template_LST.reverse(os.path.basename(LSTfile)) model = reverted["model"] print("====================", file=fasc) print(model, file=fasc) print("====================", file=fasc) template.model = model avgfile = template() template_std.model = model stdfile = template_std() print("Reading time series of mean diurnal cycle ...", file=fasc) f = cdms2.open(LSTfile) g = cdms2.open(os.path.join(args.modpath, avgfile)) h = cdms2.open(os.path.join(args.modpath, stdfile)) LSTs = f("LST") print("Input shapes: ", LSTs.shape, file=fasc) modellats = LSTs.getLatitude() modellons = LSTs.getLongitude() latbounds = modellats.getBounds() # noqa: F841 lonbounds = modellons.getBounds() # noqa: F841 # Gridpoints selected above may be offset slightly from points in full # grid ... closestlats = MV2.zeros(nGridPoints) closestlons = MV2.zeros(nGridPoints) pointLSTs = MV2.zeros((nGridPoints, N)) avgvalues = MV2.zeros((nGridPoints, N)) stdvalues = MV2.zeros((nGridPoints, N)) # ... in which case, just pick the closest full-grid point: for i in range(nGridPoints): print( " (lat, lon) = (%8.3f, %8.3f)" % (gridptlats[i], gridptlons[i]), file=fasc, ) closestlats[i] = gridptlats[i] closestlons[i] = gridptlons[i] % 360 print( " Closest (lat, lon) for gridpoint = (%8.3f, %8.3f)" % (closestlats[i], closestlons[i]), file=fasc, ) # Time series for selected grid point: avgvalues[i] = g( "diurnalmean", lat=(closestlats[i], closestlats[i], "cob"), lon=(closestlons[i], closestlons[i], "cob"), squeeze=1, ) stdvalues[i] = h( "diurnalstd", lat=(closestlats[i], closestlats[i], "cob"), lon=(closestlons[i], closestlons[i], "cob"), squeeze=1, ) pointLSTs[i] = f( "LST", lat=(closestlats[i], closestlats[i], "cob"), lon=(closestlons[i], closestlons[i], "cob"), squeeze=1, ) print(" ", file=fasc) f.close() g.close() h.close() # Print results for input to Mathematica. if monthname == "Jan": # In printed output, numbers for January data follow 0-5 for July data, # hence begin with 6. deltaI = 6 else: deltaI = 0 prefix = args.modpath for i in range(nGridPoints): print( "For gridpoint %d at %5.1f deg latitude, %6.1f deg longitude ..." % (i, gridptlats[i], gridptlons[i]), file=fasc, ) print(" Local Solar Times are:", file=fasc) print((prefix + "LST%d = {") % (i + deltaI), file=fasc) print(N * "%5.3f, " % tuple(pointLSTs[i]), end="", file=fasc) print("};", file=fasc) print(" Mean values for each time-of-day are:", file=fasc) print((prefix + "mean%d = {") % (i + deltaI), file=fasc) print(N * "%5.3f, " % tuple(avgvalues[i]), end="", file=fasc) print("};", file=fasc) print(" Standard deviations for each time-of-day are:", file=fasc) print((prefix + "std%d = {") % (i + deltaI), file=fasc) print(N * "%6.4f, " % tuple(stdvalues[i]), end="", file=fasc) print("};", file=fasc) print(" ", file=fasc) # Take fast Fourier transform of the overall multi-year mean diurnal cycle. print("************** ", avgvalues[0][0], file=fasc) cycmean, maxvalue, tmax = fastFT(avgvalues, pointLSTs) print("************** ", avgvalues[0][0], file=fasc) # Print Fourier harmonics: for i in range(nGridPoints): print( "For gridpoint %d at %5.1f deg latitude, %6.1f deg longitude ..." % (i, gridptlats[i], gridptlons[i]), file=fasc, ) print(" Mean value over cycle = %6.2f" % cycmean[i], file=fasc) print( " Diurnal maximum = %6.2f at %6.2f hr Local Solar Time." % (maxvalue[i, 0], tmax[i, 0] % 24), file=fasc, ) print( " Semidiurnal maximum = %6.2f at %6.2f hr Local Solar Time." % (maxvalue[i, 1], tmax[i, 1] % 24), file=fasc, ) print( " Terdiurnal maximum = %6.2f at %6.2f hr Local Solar Time." % (maxvalue[i, 2], tmax[i, 2] % 24), file=fasc, ) print("Results sent to:", ascname)
alongxy = hasattr(u, 'long_name') and 'x' in us.long_name.lower() if alongxy: uname, vname = 'ux10m', 'vy10m' else: uname, vname = 'u10m', 'v10m' format_var(u, uname, format_axes=format_axes) format_var(v, vname, format_axes=format_axes) # Compute zero = us.filled(1)==0. zero &= vs.filled(1)==0. uvsmod = (us**2+vs**2)**-0.25 uvsmod /= N.sqrt(rhoa*cd) u.assignValue(uvsmod*us) v.assignValue(uvsmod*vs) u.assignValue(MV2.where(zero, 0., u)) v.assignValue(MV2.where(zero, 0., v)) del uvsmod return u, v if __name__=='__main__': import MV2 u = MV2.arange(3.) v = 2*u us, vs = wind_stress(u, v) U, V = ws2w(us, vs) print u, v print U, V
def compute(dm, do): """ Computes bias""" return MV.float(MV.average(MV.subtract(dm, do)))