def reconstructPressureFromHybrid(ps,A,B,Po): """ Reconstruct the Pressure field on sigma levels, from the surface pressure Input Ps : Surface pressure A,B,Po: Hybrid Convertion Coefficients, such as: p=B.ps+A.Po Ps: surface pressure B,A are 1D : sigma levels Po and Ps must have same units Output Pressure field Such as P=B*Ps+A*Po Example P=reconstructPressureFromHybrid(ps,A,B,Po) """ # Compute the pressure for the sigma levels ps,B=genutil.grower(ps,B) ps,A=genutil.grower(ps,A) p=ps*B p=p+A*Po p.setAxisList(ps.getAxisList()) p.id='P' try: p.units=ps.units except: pass t=p.getTime() if not t is None: p=p(order='tz...') else: p=p(order='z...') return p
def get(self, var, varInFile=None, region={}, *args, **kargs): if region is None: region = {} 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 masking anything? value = region.get("value", None) if value is not None: # Indeed we are if self.mask is None: if isinstance(self.file_mask_template, basestring): self.file_mask_template = Base( self.root, self.file_mask_template, {"domain": region.get("domain", None)}) try: oMask = self.file_mask_template.get("sftlf") # ok that failed falling back on autogenerate except: oMask = cdutil.generateLandSeaMask( out, regridTool=self.regridTool).filled(1.) * 100. oMask = MV2.array(oMask) oMask.setAxis(-1, out.getLongitude()) oMask.setAxis(-2, out.getLatitude()) self.mask = oMask if self.mask.shape != out.shape: dum, msk = genutil.grower(out, self.mask) else: msk = self.mask msk = MV2.not_equal(msk, value) 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) # Now are we looking at a region in particular? domain = region.get("domain", None) if domain is not None: # Ok we are subsetting if isinstance(domain, dict): out = out(**domain) elif isinstance(domain, (list, tuple)): out = out(*domain) elif isinstance(domain, cdms2.selectors.Selector): domain.id = region.get("id", "region") out = out(*[domain]) return out
def reconstructPressureFromHybrid(ps, A, B, Po): """ Reconstruct the Pressure field on sigma levels, from the surface pressure Input Ps : Surface pressure A,B,Po: Hybrid Convertion Coefficients, such as: p=B.ps+A.Po Ps: surface pressure B,A are 1D : sigma levels Po and Ps must have same units Output Pressure field Such as P=B*Ps+A*Po Example P=reconstructPressureFromHybrid(ps,A,B,Po) """ # Compute the pressure for the sigma levels ps, B = genutil.grower(ps, B) ps, A = genutil.grower(ps, A) p = ps * B p = p + A * Po p.setAxisList(ps.getAxisList()) p.id = 'P' try: p.units = ps.units except: pass t = p.getTime() if not t is None: p = p(order='tz...') else: p = p(order='z...') return p
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 model_land_mask_out(model, model_timeseries, model_lf_path): """ Note: Extract SST (mask out land region) """ try: # Read model's land fraction f_lf = cdms2.open(model_lf_path) lf = f_lf("sftlf", latitude=(-90, 90)) f_lf.close() except Exception: # Estimate landmask lf = estimate_landmask(model_timeseries) # Check land fraction variable to see if it meet criteria # (0 for ocean, 100 for land, no missing value) lf_axes = lf.getAxisList() lf_id = lf.id lf = MV2.array(lf.filled(0.0)) lf.setAxisList(lf_axes) lf.id = lf_id # In case landfraction is in range of 0-1 (ratio), convert it to 0-100 (%) if np.max(lf) == 1.0: lf = lf * 100 # Matching dimension model_timeseries, lf_timeConst = genutil.grower(model_timeseries, lf) # full_grid_only = True full_grid_only = False if full_grid_only: # Masking out partial land grids as well # Mask out land even fractional (leave only pure ocean grid) model_timeseries_masked = np.ma.masked_where(lf_timeConst > 0, model_timeseries) else: # Mask out only full land grid & use weighting for partial land grid model_timeseries_masked = np.ma.masked_where( lf_timeConst == 100, model_timeseries) # mask out pure land grids # Special case treatment if model == "EC-EARTH": # Mask out over 90% land grids for models those consider river as # part of land-sea fraction. So far only 'EC-EARTH' does.. model_timeseries_masked = np.ma.masked_where( lf_timeConst >= 90, model_timeseries) lf2 = (100.0 - lf) / 100.0 model_timeseries, lf2_timeConst = genutil.grower( model_timeseries, lf2) # Matching dimension model_timeseries_masked = ( model_timeseries_masked * lf2_timeConst ) # consider land fraction like as weighting # Retrive dimension coordinate --- model_axes = model_timeseries.getAxisList() model_timeseries_masked.setAxisList(model_axes) return model_timeseries_masked
def get_residual_timeseries(timeseries_ano, mode, region_subdomain, RmDomainMean=True): """ NOTE: Calculate residual by subtracting domain average (or global mean) Input - timeseries_ano: anomaly time series, cdms2 array, 3d (t, y, x) - mode: string, mode name, must be defined in regions_specs - RmDomainMean: bool (True or False). If True, remove domain mean of each time step. Ref: Bonfils and Santer (2011) https://doi.org/10.1007/s00382-010-0920-1 Bonfils et al. (2015) https://doi.org/10.1175/JCLI-D-15-0341.1 If False, remove global mean of each time step for PDO, or do nothing for other modes Default is True for this function. - region_subdomain: lat lon range of sub domain for given mode, which was extracted from regions_specs -- that is a dict contains domain lat lon ragne for given mode Output - timeseries_residual: cdms2 array, 3d (t, y, x) """ if RmDomainMean: # Get domain mean regional_ano_mean_timeseries = cdutil.averager( timeseries_ano(region_subdomain), axis='xy', weights='weighted') # Match dimension timeseries_ano, regional_ano_mean_timeseries = \ genutil.grower( timeseries_ano, regional_ano_mean_timeseries) # Subtract domain mean timeseries_residual = MV2.subtract(timeseries_ano, regional_ano_mean_timeseries) else: if mode in ['PDO', 'NPGO']: # Get global mean global_ano_mean_timeseries = cdutil.averager( timeseries_ano(latitude=(-60, 70)), axis='xy', weights='weighted') # Match dimension timeseries_ano, global_ano_mean_timeseries = \ genutil.grower( timeseries_ano, global_ano_mean_timeseries) # Subtract global mean timeseries_residual = MV2.subtract(timeseries_ano, global_ano_mean_timeseries) else: timeseries_residual = timeseries_ano # return result return timeseries_residual
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 reconstructPressureFromHybrid(ps, A, B, Po): """ Reconstruct the Pressure field on sigma levels, from the surface pressure :param Ps: Surface pressure :param A: Hybrid Conversion Coefficient, such as: p=B.ps+A.Po. :param B: Hybrid Conversion Coefficient, such as: p=B.ps+A.Po. :param Po: Hybrid Conversion Coefficient, such as: p=B.ps+A.Po :param Ps: surface pressure .. note:: A and B are 1d sigma levels. Po and Ps must have same units. :returns: Pressure field, such as P=B*Ps+A*Po. :Example: .. doctest:: vertical_reconstructPressureFromHybrid >>> P=reconstructPressureFromHybrid(ps,A,B,Po) """ # Compute the pressure for the sigma levels ps, B = genutil.grower(ps, B) ps, A = genutil.grower(ps, A) p = ps * B p = p + A * Po p.setAxisList(ps.getAxisList()) p.id = 'P' try: p.units = ps.units except BaseException: pass t = p.getTime() if t is not None: p = p(order='tz...') else: p = p(order='z...') return p
def apply_land_mask_v2(data): """ apply land mask (data): this will read in and reshape the land-sea mask to match data """ # Call the cdutil function to generate a mask, 0 for ocean, 1 for land. mask = cdutil.generateLandSeaMask(data) # Match dimension using "grower" function data, mask2 = grower(data, mask) ocean_data = MV.masked_where(mask2, data) land_data = MV.masked_where(mask2 == 0., data) return (ocean_data, land_data)
def set_target_grid_and_mask_in_var(self, var): if self.target_grid is not None: var = var.regrid(self.target_grid, regridTool=self.regrid_tool, regridMethod=self.regrid_method, coordSys='deg', diag={}, periodicity=1 ) if self.target_mask is not None: if self.target_mask.shape != var.shape: dummy, mask = genutil.grower(var, self.target_mask) else: mask = self.target_mask var = MV2.masked_where(mask, var) return var
def gain_pcs_fraction(full_field, eof_pattern, pcs, debug=False): """ NOTE: This function is designed for getting fraction of variace obtained by pseudo pcs Input: (dimension x, y, t should be identical for above inputs) - full_field (t,y,x) - eof_pattern (y,x) - pcs (t) Output: - fraction: cdms2 array but for 1 single number which is float. Preserve cdms2 array type for netCDF recording. fraction of explained variance """ # 1) Get total variacne --- variance_total = genutil.statistics.variance(full_field, axis="t") variance_total_area_ave = cdutil.averager( variance_total, axis="xy", weights="weighted" ) # 2) Get variance for pseudo pattern --- # 2-1) Reconstruct field based on pseudo pattern if debug: print("from gain_pcs_fraction:") print("full_field.shape (before grower): ", full_field.shape) print("eof_pattern.shape (before grower): ", eof_pattern.shape) # Extend eof_pattern (add 3rd dimension as time then copy same 2d value for all time step) reconstructed_field = genutil.grower(full_field, eof_pattern)[ 1 ] # Matching dimension (add time axis) for t in range(0, len(pcs)): reconstructed_field[t] = MV2.multiply(reconstructed_field[t], pcs[t]) # 2-2) Get variance of reconstructed field variance_partial = genutil.statistics.variance(reconstructed_field, axis="t") variance_partial_area_ave = cdutil.averager( variance_partial, axis="xy", weights="weighted" ) # 3) Calculate fraction --- fraction = MV2.divide(variance_partial_area_ave, variance_total_area_ave) # debugging if debug: print("full_field.shape (after grower): ", full_field.shape) print("reconstructed_field.shape: ", reconstructed_field.shape) print("variance_partial_area_ave: ", variance_partial_area_ave) print("variance_total_area_ave: ", variance_total_area_ave) print("fraction: ", fraction) print("from gain_pcs_fraction done") # return result return fraction
def pressure_to_plevs(var, plev): """Convert from pressure coordinate to desired pressure level(s).""" # Construct pressure level for interpolation var_plv = var.getLevel() levels_orig = MV2.array(var_plv[:]) levels_orig.setAxis(0, var_plv) # grow 1d levels_orig to mv dimention var, levels_orig = genutil.grower(var, levels_orig) # levels_orig.info() # logLinearInterpolation only takes positive down plevel: # "I : interpolation field (usually Pressure or depth) # from TOP (level 0) to BOTTOM (last level), i.e P value # going up with each level" if var.getLevel()[0] > var.getLevel()[-1]: var = var(lev=slice(-1, None, -1)) levels_orig = levels_orig(lev=slice(-1, None, -1)) var_p = cdutil.vertical.logLinearInterpolation( var(squeeze=1), levels_orig(squeeze=1), plev) return var_p
def normalize_by_median(stat_xy): """ NOTE: Input - stat_xy: cdms2 MV2 2D array with proper axes decorated, values to visualize. Output - stat_xy: stat_xy after normalized by median of each row """ # Get median median = genutil.statistics.median(stat_xy, axis=1)[0] # Match shapes stat_xy, median = genutil.grower(stat_xy, median) # Normalize by median value median = np.array(median) stat_xy_normalized = MV2.divide(MV2.subtract(stat_xy, median), median) # Decorate axes stat_xy_normalized.setAxisList(stat_xy.getAxisList()) stat_xy_normalized.id = stat_xy.id stat_xy = stat_xy_normalized return stat_xy
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 rank_nD(self, data, axis=0): if axis not 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 axis not 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): Indx = MV2.ones(sh) * i c = MV2.array(a0[i].filled(n - 1)) b = genutil.arrayindexing.set(b, c, Indx) m = data.mask if m is not 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 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(self, data, axis=0): if axis not 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 axis not 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): Indx = MV2.ones(sh) * i c = MV2.array(a0[i].filled(n - 1)) b = genutil.arrayindexing.set(b, c, Indx) m = data.mask if m is not 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 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 self.EV is not None: setattr(self.EV, 'cdmsArguments', self.cdmsArguments) # overwrite the defintion for the variableConditioners cdmsKeyowrds for k in list(self.cdmsKeywords.keys()): self.V1.cdmsKeywords[k] = self.cdmsKeywords[k] self.V2.cdmsKeywords[k] = self.cdmsKeywords[k] if self.EV is not 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 'time' not in self.V1.cdmsKeywords: if 'time' in self.V2.cdmsKeywords: 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 t is not None: t = t.asComponentTime() else: t = d2.getTime() if t is not None: t = t.asComponentTime() if t is not None: self.V1.cdmsKeywords['time'] = (t[0], t[-1]) d1 = self.V1(returnTuple=returnTuple) if returnTuple: t1 = d1[0].getTime() if t1 is not None: t1 = t1.asComponentTime() else: t1 = d1.getTime() if t1 is not None: t1 = t1.asComponentTime() if t1 is not 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 t1 is not None: del (self.V1.cdmsKeywords['time']) self.V2.cdmsKeywords['time'] = autotime d2 = self.V2(returnTuple=returnTuple) del (self.V2.cdmsKeywords['time']) elif 'time' not in self.V2.cdmsKeywords: d1 = self.V1(returnTuple=returnTuple) if returnTuple: t = d1[0].getTime().asComponentTime() else: t = d1.getTime().asComponentTime() if t is not None: self.V2.cdmsKeywords['time'] = (t[0], t[-1]) d2 = self.V2(returnTuple=returnTuple) if t is not 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()) if d1.shape != d2.shape: if d1.ndim > d2.ndim: 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 self.EV is not None: ed = None if 'time' not in self.EV.cdmsKeywords: t = d1.getTime().asComponentTime() if t is not 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()) 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.Horizontal(g1, g) d1, frc1 = rf(d1, mask=1. - frc1.filled(0.), returnTuple=1) g2 = d2.getGrid() rf = regrid2.Horizontal(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 g is not None: g1 = d1.getGrid() g2 = d2.getGrid() rf1 = regrid2.Horizontal(g1, g) rf2 = regrid2.Horizontal(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 m is not 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 m is not None: frc1 = numpy.where(m, 0., frc1) m = self.weightedGridMaker.weightsMaker(d2) if m is not 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 m is not numpy.ma.nomask: frc2 = numpy.where(m, 0., frc2) elif d1.getGrid() != d2.getGrid(): g1 = d1.getGrid() g2 = d2.getGrid() rf = regrid2.Horizontal(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 self.cdmsArguments is not None: d1 = d1(*self.cdmsArguments) d2 = d2(*self.cdmsArguments) frc1 = frc1(*self.cdmsArguments) frc2 = frc2(*self.cdmsArguments) if self.cdmsKeywords is not 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
import cdutil import genutil import MV2 # Read data var = 'pr' data = 'GPCP-2-3' period = '197901-201907' ver = 'v20200421' dir = '/p/user_pub/PCMDIobs/PCMDIobs2_clims/atmos/' + var + '/' + data + '/' nc = var + '_mon_' + data + '_BE_gn_' + period + '.' + ver + '.AC.nc' f = cdms.open(dir + nc) # Land/Sea masking d = f[var] mask = cdutil.generateLandSeaMask(d[0]) d, mask2 = genutil.grower(d, mask) d_ocean = MV2.masked_where(mask2 == 1., d) d_land = MV2.masked_where(mask2 == 0., d) # Write data out = cdms.open( var + '_mon_' + data + '_BE_gn_' + period + '.' + ver + '.AC_land.sea.mask.nc', 'w') out.write(mask2[0]) out.close() # In[2]: get_ipython().system('jupyter nbconvert --to script cdat_land.sea.mask.ipynb')
def model_land_only(model, model_timeseries, lf, debug=False): # ------------------------------------------------- # Mask out over ocean grid # - - - - - - - - - - - - - - - - - - - - - - - - - if debug: print('debug: plot for beforeMask start') import vcs x = vcs.init() x.plot(model_timeseries) x.png('_'.join(['test', model, 'beforeMask.png'])) print('debug: plot for beforeMask done') # Check land fraction variable to see if it meet criteria # (0 for ocean, 100 for land, no missing value) lat_c = lf.getAxis(0) lon_c = lf.getAxis(1) lf_id = lf.id lf = MV2.array(lf.filled(0.)) lf.setAxis(0, lat_c) lf.setAxis(1, lon_c) lf.id = lf_id if float(MV2.max(lf)) == 1.: lf = MV2.multiply(lf, 100.) # Matching dimension if debug: print('debug: match dimension in model_land_only') model_timeseries, lf_timeConst = genutil.grower(model_timeseries, lf) # Conserve axes time_c = model_timeseries.getAxis(0) lat_c2 = model_timeseries.getAxis(1) lon_c2 = model_timeseries.getAxis(2) opt1 = False if opt1: # Masking out partial ocean grids as well # Mask out ocean even fractional (leave only pure ocean grid) model_timeseries_masked = MV2.masked_where(lf_timeConst < 100, model_timeseries) else: # Mask out only full ocean grid & use weighting for partial ocean grid model_timeseries_masked = MV2.masked_where( lf_timeConst == 0, model_timeseries) # mask out pure ocean grids if model == 'EC-EARTH': # Mask out over 90% land grids for models those consider river as # part of land-sea fraction. So far only 'EC-EARTH' does.. model_timeseries_masked = MV2.masked_where(lf_timeConst < 90, model_timeseries) lf2 = MV2.divide(lf, 100.) model_timeseries, lf2_timeConst = genutil.grower( model_timeseries, lf2) # Matching dimension model_timeseries_masked = MV2.multiply( model_timeseries_masked, lf2_timeConst) # consider land fraction like as weighting # Make sure to have consistent axes model_timeseries_masked.setAxis(0, time_c) model_timeseries_masked.setAxis(1, lat_c2) model_timeseries_masked.setAxis(2, lon_c2) if debug: x.clear() x.plot(model_timeseries_masked) x.png('_'.join(['test', model, 'afterMask.png'])) x.close() print('debug: plot for afterMask done') return (model_timeseries_masked)
def get(self, var, varInFile=None, region={}, *args, **kargs): if region is None: region = {} 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 masking anything? value = region.get("value", None) if value is not None: # Indeed we are if self.mask is None: if isinstance(self.file_mask_template, basestring): self.file_mask_template = Base( self.root, self.file_mask_template, { "domain": region.get( "domain", None)}) try: oMask = self.file_mask_template.get("sftlf") # ok that failed falling back on autogenerate except: oMask = cdutil.generateLandSeaMask( out, regridTool=self.regridTool).filled(1.) * 100. oMask = MV2.array(oMask) oMask.setAxis(-1, out.getLongitude()) oMask.setAxis(-2, out.getLatitude()) self.mask = oMask if self.mask.shape != out.shape: dum, msk = genutil.grower(out, self.mask) else: msk = self.mask msk = MV2.not_equal(msk, value) 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) # Now are we looking at a region in particular? domain = region.get("domain", None) if domain is not None: # Ok we are subsetting if isinstance(domain, dict): out = out(**domain) elif isinstance(domain, (list, tuple)): out = out(*domain) elif isinstance(domain, cdms2.selectors.Selector): domain.id = region.get("id", "region") out = out(*[domain]) return out
dv3d.VerticalScaling = 4.0 dv3d.ScaleColormap = [-46.0, 46.0, 1] dv3d.ScaleTransferFunction = [10.0, 77.0, 1] elif demo_index == '2': varname = "vwnd" v = f[varname] dv3d.VerticalScaling = 4.0 dv3d.ScaleColormap = [-46.0, 46.0, 1] dv3d.ScaleTransferFunction = [10.0, 77.0, 1] elif demo_index == '3': varname = "tmpu" v0 = f[varname] va = cdutil.averager(v0, axis='x') v01, va1 = genutil.grower(v0, va) v = v01 - va1 dv3d.ScaleColormap = [-17.0, 14.7, 1] dv3d.ScaleTransferFunction = [3.64, 24, 1] # shp = list( va.shape ) # shp.append( 1 ) # va.data.reshape( shp ) # va.shape = shp # dv3d.VerticalScaling = 4.0 # dv3d.ScaleColormap = [-46.0, 46.0, 1] # dv3d.ScaleTransferFunction = [10.0, 77.0, 1] else:
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.astype("i").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.Horizontal(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.astype("i").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
cdutil.setTimeBoundsMonthly(d1) cdutil.setTimeBoundsMonthly(d2) cdutil.setTimeBoundsMonthly(d3) cdutil.setTimeBoundsMonthly(d4) start_time = cdtime.comptime(start_year) end_time = cdtime.comptime(end_year+1) da1 = cdutil.JJA.climatology(d1(time=(start_time,end_time))) da2 = cdutil.JJA.climatology(d2(time=(start_time,end_time))) da3 = cdutil.JJA.climatology(d3(time=(start_time,end_time))) da4 = cdutil.JJA.climatology(d4(time=(start_time,end_time))) # 500 GPH global anomaly from zonal mean da4_zonal_avg = cdutil.averager(da4,axis='x') da4,da4_zonal_avg = genutil.grower(da4,da4_zonal_avg) # Matching dimension for subtraction da4 = da4 - da4_zonal_avg #================================================= # PART 2 : GRAPHIC (plotting) #------------------------------------------------- # Create canvas canvas = vcs.init(geometry=(900,800)) canvas.open() #canvas.drawlogooff() template = canvas.createtemplate() # Turn off no-needed information template.blank(["title","mean","min","max","dataname","crdate","crtime", "units","zvalue","tvalue","xunits","yunits","xname","yname"])
def custom1D(x, filter, axis=0): """ Function: custom(x,filter,axis=0) Description of function: Apply a custom 1 dimensional filter to an array over a specified axis filter can be a list of numbers or a 1D array Usage: filtered = custom1D(x,filter) Options: axisoptions: 'x' | 'y' | 'z' | 't' | '(dimension_name)' | 0 | 1 ... | n default value = 0. You can pass the name of the dimension or index (integer value 0...n) over which you want to compute the statistic. """ isMV2 = cdms2.isVariable(x) if isMV2: xatt = x.attributes filter = MV2.array(filter) newx = MV2.array(x) initialorder = newx.getOrder(ids=1) n = len(filter) newx = newx(order=str(axis) + '...') sh = list(newx.shape) sh[0] = sh[0] - n + 1 out = numpy.ma.zeros(sh, dtype=newx.dtype.char) ax = [] bnds = [] nax = newx.getAxis(0) for i in range(sh[0]): sub = newx[i:i + n] if i == 0: filter.setAxis(0, sub.getAxis(0)) filter, sub = genutil.grower(filter, sub) out[i] = numpy.ma.average(sub, weights=filter, axis=0) if isMV2: a = nax.subAxis(i, i + n) try: b = a.getBounds() b1 = b[0][0] b2 = b[-1][1] ax.append((b1 + b2) / 2.) bnds.append([b1, b2]) except: # No bounds on this axis bnds = None ax.append(float(numpy.ma.average(a[:], axis=0))) out = MV2.array(out, id=newx.id) if isMV2: for k in xatt.keys(): setattr(out, k, xatt[k]) for i in range(1, len(sh)): out.setAxis(i, newx.getAxis(i)) if not bnds is None: bnds = numpy.ma.array(bnds) ax = cdms2.createAxis(ax, bounds=bnds) a = newx.getAxis(0) attr = a.attributes ax.id = a.id for k in attr.keys(): setattr(ax, k, attr[k]) out.setAxis(0, ax) out = out(order=initialorder) if not isMV2: out = numpy.ma.array(out) return out
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["rmsc_xy"] = pcmdi_metrics.pcmdi.rmsc_xy.compute(None, None) metrics_defs["bias_xy"] = pcmdi_metrics.pcmdi.bias_xy.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["mean_xy"] = pcmdi_metrics.pcmdi.mean_xy.compute(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 = 86400.0 else: conv = 1.0 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_xy.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 (centered and uncentered) rms_xy = pcmdi_metrics.pcmdi.rms_xy.compute(dm_am, do_am) rmsc_xy = pcmdi_metrics.pcmdi.rmsc_xy.compute(dm_am, do_am) # CALCULATE ANNUAL MEAN CORRELATION cor_xy = pcmdi_metrics.pcmdi.cor_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) # CALCULATE ANNUAL OBS and MOD MEAN meanObs_xy = pcmdi_metrics.pcmdi.mean_xy.compute(do_am) mean_xy = pcmdi_metrics.pcmdi.mean_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 = MV2.subtract(dm_am, dm_amzm_grown) do_amzm_grown, dummy = grower(do_amzm, do_am) do_am_devzm = MV2.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) for stat in [ "std-obs_xy", "std_xy", "std-obs_xyt", "std_xyt", "std-obs_xy_devzm", "mean_xy", "mean-obs_xy", "std_xy_devzm", "rms_xyt", "rms_xy", "rmsc_xy", "cor_xy", "bias_xy", "mae_xy", "rms_y", "rms_devzm", ]: metrics_dictionary[stat] = {} metrics_dictionary["mean-obs_xy"]["ann"] = format(meanObs_xy * conv, sig_digits) metrics_dictionary["mean_xy"]["ann"] = format(mean_xy * conv, sig_digits) 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["rmsc_xy"]["ann"] = format(rmsc_xy * conv, sig_digits) metrics_dictionary["cor_xy"]["ann"] = format(cor_xy, 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) rmsc_sea = pcmdi_metrics.pcmdi.rmsc_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_xy.compute(dm_sea, do_sea) # CALCULATE SEASONAL 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) # CALCULATE SEASONAL OBS and MOD MEAN meanObs_xy_sea = pcmdi_metrics.pcmdi.mean_xy.compute(do_sea) mean_xy_sea = pcmdi_metrics.pcmdi.mean_xy.compute(dm_sea) metrics_dictionary["bias_xy"][sea] = format(bias_sea * conv, sig_digits) metrics_dictionary["rms_xy"][sea] = format(rms_sea * conv, sig_digits) metrics_dictionary["rmsc_xy"][sea] = format(rmsc_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) metrics_dictionary["mean-obs_xy"][sea] = format( meanObs_xy_sea * conv, sig_digits ) metrics_dictionary["mean_xy"][sea] = format(mean_xy_sea * conv, sig_digits) rms_mo_l = [] rmsc_mo_l = [] cor_mo_l = [] mae_mo_l = [] bias_mo_l = [] stdObs_xy_mo_l = [] std_xy_mo_l = [] meanObs_xy_mo_l = [] mean_xy_mo_l = [] for n, mo in enumerate( [ "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec", ] ): dm_mo = dm[n] do_mo = do[n] # CALCULATE MONTHLY RMS AND CORRELATION rms_mo = pcmdi_metrics.pcmdi.rms_xy.compute(dm_mo, do_mo) rmsc_mo = pcmdi_metrics.pcmdi.rmsc_xy.compute(dm_mo, do_mo) cor_mo = pcmdi_metrics.pcmdi.cor_xy.compute(dm_mo, do_mo) mae_mo = pcmdi_metrics.pcmdi.meanabs_xy.compute(dm_mo, do_mo) bias_mo = pcmdi_metrics.pcmdi.bias_xy.compute(dm_mo, do_mo) # CALCULATE MONTHLY OBS and MOD STD stdObs_xy_mo = pcmdi_metrics.pcmdi.std_xy.compute(do_mo) std_xy_mo = pcmdi_metrics.pcmdi.std_xy.compute(dm_mo) # CALCULATE MONTHLY OBS and MOD MEAN meanObs_xy_mo = pcmdi_metrics.pcmdi.mean_xy.compute(do_mo) mean_xy_mo = pcmdi_metrics.pcmdi.mean_xy.compute(dm_mo) rms_mo_l.append(format(rms_mo * conv, sig_digits)) rmsc_mo_l.append(format(rmsc_mo * conv, sig_digits)) cor_mo_l.append(format(cor_mo, ".2f")) mae_mo_l.append(format(mae_mo * conv, sig_digits)) bias_mo_l.append(format(bias_mo * conv, sig_digits)) stdObs_xy_mo_l.append(format(stdObs_xy_mo * conv, sig_digits)) std_xy_mo_l.append(format(std_xy_mo * conv, sig_digits)) meanObs_xy_mo_l.append(format(meanObs_xy_mo * conv, sig_digits)) mean_xy_mo_l.append(format(mean_xy_mo * conv, sig_digits)) # metrics_dictionary['bias_xy'][mo] = format( bias_mo * conv, sig_digits) # metrics_dictionary['rms_xy'][mo] = format( rms_mo * conv, sig_digits) # metrics_dictionary['rmsc_xy'][mo] = format( rmsc_mo * conv, sig_digits) # metrics_dictionary['cor_xy'][mo] = format( cor_mo, '.2f') # metrics_dictionary['mae_xy'][mo] = format( mae_mo * conv, sig_digits) # metrics_dictionary['std-obs_xy'][mo] = format( stdObs_xy_mo * conv, sig_digits) # metrics_dictionary['std_xy'][mo] = format( std_xy_mo * conv, sig_digits) # metrics_dictionary['mean-obs_xy'][mo] = format( meanObs_xy_mo * conv, sig_digits) # metrics_dictionary['mean_xy'][mo] = format( mean_xy_mo * conv, sig_digits) metrics_dictionary["bias_xy"]["CalendarMonths"] = bias_mo_l metrics_dictionary["rms_xy"]["CalendarMonths"] = rms_mo_l metrics_dictionary["rmsc_xy"]["CalendarMonths"] = rmsc_mo_l metrics_dictionary["cor_xy"]["CalendarMonths"] = cor_mo_l metrics_dictionary["mae_xy"]["CalendarMonths"] = mae_mo_l metrics_dictionary["std-obs_xy"]["CalendarMonths"] = stdObs_xy_mo_l metrics_dictionary["std_xy"]["CalendarMonths"] = std_xy_mo_l metrics_dictionary["mean-obs_xy"]["CalendarMonths"] = meanObs_xy_mo_l metrics_dictionary["mean_xy"]["CalendarMonths"] = mean_xy_mo_l return metrics_dictionary
def compute_metrics(Var, dm_glb, do_glb): # Var is sometimes sent with level associated var = Var.split("_")[0] # Did we send data? Or do we just want the info? if dm_glb is None and do_glb 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["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' domains = ['GLB', 'NHEX', 'TROPICS', 'SHEX'] for dom in domains: dm = dm_glb do = do_glb if dom == 'NHEX': dm = dm_glb(latitude=(30., 90)) do = do_glb(latitude=(30., 90)) if dom == 'SHEX': dm = dm_glb(latitude=(-90., -30)) do = do_glb(latitude=(-90., -30)) if dom == 'TROPICS': dm = dm_glb(latitude=(-30., 30)) do = do_glb(latitude=(-30., 30)) # CALCULATE ANNUAL CYCLE SPACE-TIME RMS AND CORRELATIONS rms_xyt = pcmdi_metrics.pcmdi.rms_xyt.compute(dm, do) cor_xyt = pcmdi_metrics.pcmdi.cor_xyt.compute(dm, do) # 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) # 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) metrics_dictionary[ 'rms_xyt_ann_' + dom] = format( rms_xyt * conv, sig_digits) metrics_dictionary[ 'rms_xy_ann_' + dom] = format( rms_xy * conv, sig_digits) metrics_dictionary[ 'bias_xy_ann_' + dom] = format( bias_xy * conv, sig_digits) metrics_dictionary[ 'cor_xyt_ann_' + dom] = format( cor_xyt * conv, '.2f') metrics_dictionary[ 'mae_xy_ann_' + dom] = format( mae_xy * conv, sig_digits) # ZONAL MEAN CONTRIBUTIONS metrics_dictionary[ 'rms_y_ann_' + dom] = format( rms_y * conv, sig_digits) metrics_dictionary[ 'rms_devzm_ann_' + dom] = 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) # 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 + '_' + dom] = format( bias_sea * conv, sig_digits) metrics_dictionary[ 'rms_xy_' + sea + '_' + dom] = format( rms_sea * conv, sig_digits) metrics_dictionary[ 'cor_xy_' + sea + '_' + dom] = format( cor_sea, '.2f') metrics_dictionary[ 'mae_xy_' + sea + '_' + dom] = format( mae_sea * conv, sig_digits) # ZONAL AND SEASONAL MEAN CONTRIBUTIONS # metrics_dictionary[ # 'rms_y_' + sea + '_' + # dom] = format( # rms_y * # conv, # sig_digits) # metrics_dictionary[ # 'rms_devzm_' + sea + '_' + # dom] = format( # rms_xy_devzm * # conv, # sig_digits) return metrics_dictionary
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_xy.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 = 86400. 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_xy.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 MEAN CORRELATION cor_xy = pcmdi_metrics.pcmdi.cor_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 = MV2.subtract(dm_am, dm_amzm_grown) do_amzm_grown, dummy = grower(do_amzm, do_am) do_am_devzm = MV2.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) for stat in ["std-obs_xy", "std_xy", "std-obs_xyt", "std_xyt", "std-obs_xy_devzm", "std_xy_devzm", "rms_xyt", "rms_xy", "cor_xy", "bias_xy", "mae_xy", "rms_y", "rms_devzm"]: metrics_dictionary[stat] = {} 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[ 'cor_xy']['ann'] = format( cor_xy, 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_xy.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
def process(self, data): ## if self.symetric: ## data = symetric(data) # Make sure we have an even number of time steps t = data.getTime() # length of time axis nt = len(t) if nt % 2 != 0: print "Warning time wasn't even, removed last time step" data = data[:-1] t = data.getTime() ## get the new time axis nt = len(t) if len(t) < self._NTSub: raise Exception, "Error your data must have at least %i time steps, adjust frequency (currently: %i/day) or number_of_days (currently: %i processed at once) to reach that limit, or get more data" % ( self._NTSub, self.frequency, self.number_of_days) ## Computes PP, number of sub-domain PP = float(nt - self._NTSub) / self._NShift + 1 PP = int(PP) ## Number of longitudes lons = data.getLongitude() NL = len(lons) tt = cdms2.createAxis(numpy.arange(self._NTSub), id='sub_time') ## Should redo that with just an arange (eventually...)!!! ## Frequencies in cycles/day ff = numpy.arange(0, self._NTSub + 1, 1, numpy.float) for i in range(1, self._NTSub + 2): ff[i - 1] = float(i - 1 - self._NTSub / 2.) * self.frequency / float( self._NTSub) ## Should redo that with just an arange (eventually...)!!! ## Wave numbers ss = numpy.arange(0, NL + 1, 1, numpy.float) for i in range(1, NL + 2): ss[i - 1] = float(i - 1 - NL / 2.) ## print 'Frequencies:',ff ## print 'Wave numbers:',ss ## Ok, we now do the real stuff ## Creates the array of powers (Number of subtimes,fqcy,wave_numbers,latitudes) lats = data.getLatitude() Power = numpy.zeros((PP, self._NTSub + 1, NL + 1, len(lats)), numpy.float) ## LOOP through time sub domains prev = 0 # initialize the scrolling bar for Pcount in range(PP): if PP > 1: prev = genutil.statusbar(float(Pcount), PP - 1, prev=prev, tk=self.tkbar) ## Get the time subdomain EEo = data[Pcount * self._NShift:Pcount * self._NShift + self._NTSub](order='tx...') ## First does the symetric/antisymetric thing if needed if self.symetric: EEo = symetrick(EEo) ## Now detrending ## Step 1- Get the slope and intercept slope, intercept = genutil.statistics.linearregression( EEo, nointercept=0) ## Step 2- remove the trend ## Step 2a: Create an array with the time values a = EEo.getTime() A = MV2.array(a[:], typecode='d') A.setAxis(0, a) ## Step 2b: "Grows" it so it has the same shape than data A, EEo = genutil.grower(A, EEo) ## Step 2c: Actually remove the trend EE = EEo - A * slope - intercept ## we don't need A,EEo,slope,intercept anymore del (EEo) del (slope) del (intercept) del (A) ## Remove the time mean mean = MV2.average(EE, 0) EE = EE - mean del (mean) # could be big in memory ## Tapering time... tapertozero(EE, 1, len(EE) - 1, 5 * self.frequency) ## OK here Wheeler has some windowing on longitude, but it's commented out ## I'll pass it for now ## Ok the actuall FFT work EE = numpy.fft.fft2(EE, axes=(1, 0)) / NL / self._NTSub ## OK NOW THE LITTLE MAGIC WITH REORDERING ! A = numpy.absolute(EE[0:self._NTSub / 2 + 1, 1:NL / 2 + 1])**2 B = numpy.absolute(EE[self._NTSub / 2:self._NTSub, 1:NL / 2 + 1])**2 C = numpy.absolute(EE[self._NTSub / 2:self._NTSub, 0:NL / 2 + 1])**2 D = numpy.absolute(EE[0:self._NTSub / 2 + 1, 0:NL / 2 + 1])**2 Power[Pcount, self._NTSub / 2:, :NL / 2] = A[:, ::-1] Power[Pcount, :self._NTSub / 2, :NL / 2] = B[:, ::-1] Power[Pcount, self._NTSub / 2 + 1:, NL / 2:] = C[::-1, :] Power[Pcount, :self._NTSub / 2 + 1, NL / 2:] = D[::-1, :] ## End of Pcount loop if self.tkbar and PP > 1: prev[1].destroy() prev[0].destroy() ## Now generates the decorations ## first the time axis (subdomains) vals = [] bounds = [] pp = 0 for i in range(0, len(t) - self._NShift, self._NShift): st = t.subAxis(i, i + self._NTSub) if len(st[:]) == self._NTSub: pp += 1 vals.append((st[0] + st[-1]) / 2.) bds = st.getBounds() #print 'Bounds:',bds if bds is None: raise ValueError, "Data need to have bounds on time dimension" else: bounds.append([bds[0][0], bds[-1][1]]) ## Convert lists to arrays vals = numpy.array(vals) bounds = numpy.array(bounds) ## Creates the time axis dumt = cdms2.createAxis(vals, bounds=bounds) dumt.id = 'time' dumt.units = t.units dumt.designateTime() dumt.setCalendar(t.getCalendar()) ## Create the frequencies axis T = cdms2.createAxis(ff) T.id = 'frequency' T.units = 'cycles per day' ## Create the wave numbers axis S = cdms2.createAxis(ss) S.id = 'planetaryzonalwavenumber' S.units = '-' ## Makes it an MV2 with axis and id (id come sfrom orignal data id) Power = MV2.array(Power, axes=(dumt, T, S, lats), id=data.id + '_' + 'power') ## Adds a long name attribute Power.longname = 'Real power spectrum for the many different parts (i.e. over separate time divisions)' ## And return the whole thing ordered 'time', 'latitude', 'frequencies','wavenumbers' return Power(order='ty...')
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 Avg_PS_DomFrq(d, frequency, ntd, dat, mip, frc): """ Domain and Frequency average of spectral power Input - d: spectral power with lon, lat, and frequency dimensions (cdms) - ntd: number of time steps per day (daily: 1, 3-hourly: 8) - frequency: frequency - dat: model name - mip: mip name - frc: forced or unforced Output - psdmfm: Domain and Frequency averaged of spectral power (json) """ domains = [ "Total_50S50N", "Ocean_50S50N", "Land_50S50N", "Total_30N50N", "Ocean_30N50N", "Land_30N50N", "Total_30S30N", "Ocean_30S30N", "Land_30S30N", "Total_50S30S", "Ocean_50S30S", "Land_50S30S", ] if ntd == 8: # 3-hourly data frqs_forced = ["semi-diurnal", "diurnal", "semi-annual", "annual"] frqs_unforced = [ "sub-daily", "synoptic", "sub-seasonal", "seasonal-annual", "interannual", ] elif ntd == 1: # daily data frqs_forced = ["semi-annual", "annual"] frqs_unforced = [ "synoptic", "sub-seasonal", "seasonal-annual", "interannual" ] else: sys.exit("ERROR: ntd " + ntd + " is not defined!") if frc == "forced": frqs = frqs_forced elif frc == "unforced": frqs = frqs_unforced else: sys.exit("ERROR: frc " + frc + " is not defined!") mask = cdutil.generateLandSeaMask(d[0]) d, mask2 = genutil.grower(d, mask) d_ocean = MV.masked_where(mask2 == 1.0, d) d_land = MV.masked_where(mask2 == 0.0, d) psdmfm = {} for dom in domains: psdmfm[dom] = {} if "Ocean" in dom: dmask = d_ocean elif "Land" in dom: dmask = d_land else: dmask = d if "50S50N" in dom: am = cdutil.averager(dmask(latitude=(-50, 50)), axis="xy") if "30N50N" in dom: am = cdutil.averager(dmask(latitude=(30, 50)), axis="xy") if "30S30N" in dom: am = cdutil.averager(dmask(latitude=(-30, 30)), axis="xy") if "50S30S" in dom: am = cdutil.averager(dmask(latitude=(-50, -30)), axis="xy") am = np.array(am) for frq in frqs: if frq == "semi-diurnal": # pr=0.5day idx = prdday_to_frqidx(0.5, frequency, ntd) amfm = am[idx] elif frq == "diurnal": # pr=1day idx = prdday_to_frqidx(1, frequency, ntd) amfm = am[idx] elif frq == "semi-annual": # 180day=<pr=<183day idx2 = prdday_to_frqidx(180, frequency, ntd) idx1 = prdday_to_frqidx(183, frequency, ntd) amfm = np.amax(am[idx1:idx2 + 1]) elif frq == "annual": # 360day=<pr=<366day idx2 = prdday_to_frqidx(360, frequency, ntd) idx1 = prdday_to_frqidx(366, frequency, ntd) amfm = np.amax(am[idx1:idx2 + 1]) elif frq == "sub-daily": # pr<1day idx1 = prdday_to_frqidx(1, frequency, ntd) amfm = cdutil.averager(am[idx1 + 1:], weights="unweighted") elif frq == "synoptic": # 1day=<pr<20day idx2 = prdday_to_frqidx(1, frequency, ntd) idx1 = prdday_to_frqidx(20, frequency, ntd) amfm = cdutil.averager(am[idx1 + 1:idx2 + 1], weights="unweighted") elif frq == "sub-seasonal": # 20day=<pr<90day idx2 = prdday_to_frqidx(20, frequency, ntd) idx1 = prdday_to_frqidx(90, frequency, ntd) amfm = cdutil.averager(am[idx1 + 1:idx2 + 1], weights="unweighted") elif frq == "seasonal-annual": # 90day=<pr<365day idx2 = prdday_to_frqidx(90, frequency, ntd) idx1 = prdday_to_frqidx(365, frequency, ntd) amfm = cdutil.averager(am[idx1 + 1:idx2 + 1], weights="unweighted") elif frq == "interannual": # 365day=<pr idx2 = prdday_to_frqidx(365, frequency, ntd) amfm = cdutil.averager(am[:idx2 + 1], weights="unweighted") psdmfm[dom][frq] = amfm.tolist() print("Complete domain and frequency average of spectral power") return psdmfm
def custom1D(x,filter,axis=0): """ Function: custom(x,filter,axis=0) Description of function: Apply a custom 1 dimensional filter to an array over a specified axis filter can be a list of numbers or a 1D array Usage: filtered = custom1D(x,filter) Options: axisoptions: 'x' | 'y' | 'z' | 't' | '(dimension_name)' | 0 | 1 ... | n default value = 0. You can pass the name of the dimension or index (integer value 0...n) over which you want to compute the statistic. """ cdat_info.pingPCMDIdb("cdat","genutil.filters.custom1D") isMV2=cdms2.isVariable(x) if isMV2: xatt=x.attributes filter=MV2.array(filter) newx=MV2.array(x) initialorder=newx.getOrder(ids=1) n=len(filter) newx=newx(order=str(axis)+'...') sh=list(newx.shape) sh[0]=sh[0]-n+1 out=numpy.ma.zeros(sh,dtype=newx.dtype.char) ax=[] bnds=[] nax=newx.getAxis(0) for i in range(sh[0]): sub=newx[i:i+n] if i==0: filter.setAxis(0,sub.getAxis(0)) filter,sub=genutil.grower(filter,sub) out[i]=numpy.ma.average(sub,weights=filter, axis=0) if isMV2: a=nax.subAxis(i,i+n) try: b=a.getBounds() b1=b[0][0] b2=b[-1][1] ax.append((b1+b2)/2.) bnds.append([b1,b2]) except: # No bounds on this axis bnds=None ax.append(float(numpy.ma.average(a[:], axis=0))) out=MV2.array(out,id=newx.id) if isMV2: for k in xatt.keys(): setattr(out,k,xatt[k]) for i in range(1,len(sh)): out.setAxis(i,newx.getAxis(i)) if not bnds is None: bnds=numpy.ma.array(bnds) ax=cdms2.createAxis(ax,bounds=bnds) a=newx.getAxis(0) attr=a.attributes ax.id=a.id for k in attr.keys(): setattr(ax,k,attr[k]) out.setAxis(0,ax) out=out(order=initialorder) if not isMV2: out=numpy.ma.array(out) return out
def test_portrait(self): # CDAT MODULES import pcmdi_metrics.graphics.portraits import MV2 import numpy import genutil import vcs print print print print print "---------------------------------------------------" print "RUNNING: Portrait test" print "---------------------------------------------------" print print print print # CREATES VCS OBJECT AS A PORTAIT PLOT AND LOADS PLOT SETTINGS FOR # EXAMPLE x = vcs.init(geometry=(814,606),bg=bg) x.portrait() # Turn off antialiasing for test suite x.setantialiasing(0) # PARAMETERS STUFF P = pcmdi_metrics.graphics.portraits.Portrait() # Turn off verbosity P.verbose = False P.PLOT_SETTINGS.levels = [-1.e20, -.5, -.4, -.3, -.2, -.1, 0., .1, .2, .3, .4, .5, 1.e20] P.PLOT_SETTINGS.x1 = .1 P.PLOT_SETTINGS.x2 = .85 P.PLOT_SETTINGS.y1 = .12 P.PLOT_SETTINGS.y2 = .95 P.PLOT_SETTINGS.xtic2.y1 = P.PLOT_SETTINGS.y1 P.PLOT_SETTINGS.xtic2.y2 = P.PLOT_SETTINGS.y2 P.PLOT_SETTINGS.ytic2.x1 = P.PLOT_SETTINGS.x1 P.PLOT_SETTINGS.ytic2.x2 = P.PLOT_SETTINGS.x2 # P.PLOT_SETTINGS.missing_color = 3 P.PLOT_SETTINGS.logo = os.path.join(sys.prefix,"share","pmp","graphics","png","160915_PCMDI_logo_348x300px.png") P.PLOT_SETTINGS.logo.y = .95 P.PLOT_SETTINGS.logo.x = .93 P.PLOT_SETTINGS.time_stamp = None P.PLOT_SETTINGS.draw_mesh = 'n' # P.PLOT_SETTINGS.tictable.font = 3 x.scriptrun( os.path.join( sys.prefix, "share", "pmp", "graphics", 'vcs', 'portraits.scr')) P.PLOT_SETTINGS.colormap = 'bl_rd_12' # cols=vcs.getcolors(P.PLOT_SETTINGS.levels,range(16,40),split=1) cols = vcs.getcolors(P.PLOT_SETTINGS.levels, range(144, 156), split=1) P.PLOT_SETTINGS.fillareacolors = cols P.PLOT_SETTINGS.parametertable.expansion = 100 J = self.loadJSON() mods = sorted(J.getAxis("model")[:]) variables = sorted(J.getAxis("variable")[:]) print "MODELS:",len(mods),mods print "VARS:",len(variables),variables # Get what we need out1_rel = J(statistic=["rms_xyt"],season=["ann"],region="global")(squeeze=1) out1_rel, med = genutil.grower(out1_rel,genutil.statistics.median(out1_rel,axis=1)[0]) out1_rel[:] = (out1_rel.asma() - med.asma())/ med.asma() # ADD SPACES FOR LABELS TO ALIGN AXIS LABELS WITH PLOT modsAxis = mods variablesAxis = variables # LOOP THROUGH LISTS TO ADD SPACES for i in range(len(modsAxis)): modsAxis[i] = modsAxis[i] + ' ' for i in range(len(variablesAxis)): variablesAxis[i] = variablesAxis[i] + ' ' yax = [s.encode('utf-8') for s in mods] # CHANGE FROM UNICODE TO BYTE STRINGS # GENERATE PLOT P.decorate(out1_rel, variables, yax) # P.plot(out1_rel,x=x,multiple=1.1,bg=bg) # FOR PLOTTING TRIANGLES WHEN # USING TWO OR MORE REFERENCE DATA SETS P.plot(out1_rel, bg=bg, x=x) if not bg: raw_input("Press enter") # x.backend.renWin.Render() # END OF PLOTTING # SAVE PLOT src = os.path.join(os.path.dirname(__file__), "testPortrait.png") print src fnm = os.path.join(os.getcwd(), "testPortrait.png") x.png(fnm) ret = vcs.testing.regression.check_result_image( fnm, src) if ret != 0: sys.exit(ret)
def __init__(self, data): self.mask = cdutil.generateLandSeaMask(data[0]) self.d, self.mask2 = genutil.grower(data, self.mask)
def process(self,data): ## if self.symetric: ## data = symetric(data) # Make sure we have an even number of time steps t=data.getTime() # length of time axis nt=len(t) if nt%2!=0: print "Warning time wasn't even, removed last time step" data=data[:-1] t=data.getTime() ## get the new time axis nt=len(t) if len(t)<self._NTSub: raise Exception,"Error your data must have at least %i time steps, adjust frequency (currently: %i/day) or number_of_days (currently: %i processed at once) to reach that limit, or get more data" % (self._NTSub,self.frequency,self.number_of_days) ## Computes PP, number of sub-domain PP=float(nt-self._NTSub)/self._NShift+1 PP=int(PP) ## Number of longitudes lons=data.getLongitude() NL=len(lons) tt=cdms2.createAxis(numpy.arange(self._NTSub),id='sub_time') ## Should redo that with just an arange (eventually...)!!! ## Frequencies in cycles/day ff=numpy.arange(0,self._NTSub+1,1,numpy.float) for i in range(1,self._NTSub+2): ff[i-1]=float(i-1-self._NTSub/2.)*self.frequency/float(self._NTSub) ## Should redo that with just an arange (eventually...)!!! ## Wave numbers ss=numpy.arange(0,NL+1,1,numpy.float) for i in range(1,NL+2): ss[i-1]=float(i-1-NL/2.) ## print 'Frequencies:',ff ## print 'Wave numbers:',ss ## Ok, we now do the real stuff ## Creates the array of powers (Number of subtimes,fqcy,wave_numbers,latitudes) lats=data.getLatitude() Power=numpy.zeros((PP,self._NTSub+1,NL+1,len(lats)),numpy.float) ## LOOP through time sub domains prev=0 # initialize the scrolling bar for Pcount in range(PP): if PP>1: prev=genutil.statusbar(float(Pcount),PP-1,prev=prev,tk=self.tkbar) ## Get the time subdomain EEo=data[Pcount*self._NShift:Pcount*self._NShift+self._NTSub](order='tx...') ## First does the symetric/antisymetric thing if needed if self.symetric: EEo=symetrick(EEo) ## Now detrending ## Step 1- Get the slope and intercept slope,intercept=genutil.statistics.linearregression(EEo,nointercept=0) ## Step 2- remove the trend ## Step 2a: Create an array with the time values a=EEo.getTime() A=MV2.array(a[:],typecode='d') A.setAxis(0,a) ## Step 2b: "Grows" it so it has the same shape than data A,EEo=genutil.grower(A,EEo) ## Step 2c: Actually remove the trend EE=EEo-A*slope-intercept ## we don't need A,EEo,slope,intercept anymore del(EEo) del(slope) del(intercept) del(A) ## Remove the time mean mean=MV2.average(EE,0) EE=EE-mean del(mean) # could be big in memory ## Tapering time... tapertozero(EE,1,len(EE)-1,5*self.frequency) ## OK here Wheeler has some windowing on longitude, but it's commented out ## I'll pass it for now ## Ok the actuall FFT work EE=numpy.fft.fft2(EE,axes=(1,0))/NL/self._NTSub ## OK NOW THE LITTLE MAGIC WITH REORDERING ! A=numpy.absolute(EE[0:self._NTSub/2+1,1:NL/2+1])**2 B=numpy.absolute(EE[self._NTSub/2:self._NTSub,1:NL/2+1])**2 C=numpy.absolute(EE[self._NTSub/2:self._NTSub,0:NL/2+1])**2 D=numpy.absolute(EE[0:self._NTSub/2+1,0:NL/2+1])**2 Power[Pcount,self._NTSub/2:,:NL/2]=A[:,::-1] Power[Pcount,:self._NTSub/2,:NL/2]=B[:,::-1] Power[Pcount,self._NTSub/2+1:,NL/2:]=C[::-1,:] Power[Pcount,:self._NTSub/2+1,NL/2:]=D[::-1,:] ## End of Pcount loop if self.tkbar and PP>1: prev[1].destroy() prev[0].destroy() ## Now generates the decorations ## first the time axis (subdomains) vals=[] bounds=[] pp=0 for i in range(0,len(t)-self._NShift,self._NShift): st=t.subAxis(i,i+self._NTSub) if len(st[:])==self._NTSub: pp+=1 vals.append((st[0]+st[-1])/2.) bds=st.getBounds() #print 'Bounds:',bds if bds is None: raise ValueError, "Data need to have bounds on time dimension" else: bounds.append([bds[0][0],bds[-1][1]]) ## Convert lists to arrays vals=numpy.array(vals) bounds=numpy.array(bounds) ## Creates the time axis dumt=cdms2.createAxis(vals,bounds=bounds) dumt.id='time' dumt.units=t.units dumt.designateTime() dumt.setCalendar(t.getCalendar()) ## Create the frequencies axis T=cdms2.createAxis(ff) T.id='frequency' T.units='cycles per day' ## Create the wave numbers axis S=cdms2.createAxis(ss) S.id='planetaryzonalwavenumber' S.units='-' ## Makes it an MV2 with axis and id (id come sfrom orignal data id) Power=MV2.array(Power,axes=(dumt,T,S,lats),id=data.id+'_'+'power') ## Adds a long name attribute Power.longname='Real power spectrum for the many different parts (i.e. over separate time divisions)' ## And return the whole thing ordered 'time', 'latitude', 'frequencies','wavenumbers' return Power(order='ty...')
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.ndim>d2.ndim: 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.Horizontal(g1,g) d1,frc1=rf(d1,mask=1.-frc1.filled(0.),returnTuple=1) g2=d2.getGrid() rf=regrid2.Horizontal(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.Horizontal(g1,g) rf2=regrid2.Horizontal(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.Horizontal(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 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
def generate_portrait(stat_xy, imgName): # Get median median = genutil.statistics.median(stat_xy, axis=1)[0] print(median) print(median.shape) # Match shapes stat_xy, median = genutil.grower(stat_xy, median) print(stat_xy.shape) print(median.shape) # Normalize by median value median = np.array(median) stat_xy_normalized = MV2.divide(MV2.subtract(stat_xy, median), median) print(stat_xy_normalized.shape) stat_xy_normalized.setAxisList(stat_xy.getAxisList()) # # Plotting # # Set up VCS Canvas class VCSAddonsNotebook(object): def __init__(self, x): self.x = x def _repr_png_(self): fnm = tempfile.mktemp() + ".png" self.x.png(fnm) encoded = base64.b64encode(open(fnm, "rb").read()) return encoded def __call__(self): return self # VCS Canvas x = vcs.init(bg=True, geometry=(2600, 800)) show = VCSAddonsNotebook(x) # Load our "pretty" colormap x.scriptrun( os.path.join(sys.prefix, "share", "pmp", "graphics", 'vcs', 'portraits.scr')) # Set up Portrait Plot P = pcmdi_metrics.graphics.portraits.Portrait() xax = [t + ' ' for t in stat_xy_normalized.getAxis(1)[:]] yax = [t + ' ' for t in stat_xy_normalized.getAxis(0)[:]] # Preprocessing step to "decorate" the axis P.decorate(stat_xy_normalized, yax, xax) # # Customize # SET = P.PLOT_SETTINGS # Viewport on the Canvas SET.x1 = .05 SET.x2 = .88 SET.y1 = .25 SET.y2 = .9 # Both X (horizontal) and y (VERTICAL) ticks # Text table SET.tictable = vcs.createtexttable() SET.tictable.color = "black" # X (bottom) ticks tictextsize = 9 # Text Orientation SET.xticorientation = vcs.createtextorientation() SET.xticorientation.angle = -90 SET.xticorientation.halign = "right" SET.xticorientation.height = tictextsize # Y (vertical) ticks SET.yticorientation = vcs.createtextorientation() SET.yticorientation.angle = 0 SET.yticorientation.halign = "right" SET.yticorientation.height = tictextsize # We can turn off the "grid" SET.draw_mesh = "y" # Control color for missing SET.missing_color = "grey" # Tics length SET.xtic1.y1 = 0 SET.xtic1.y2 = 0 # Timestamp SET.time_stamp = None # Colormap SET.colormap = "bl_to_darkred" # level to use SET.levels = [-.5, -.4, -.3, -.2, -.1, 0, .1, .2, .3, .4, .5] SET.levels.insert(0, -1.e20) SET.levels.append(1.e20) # colors to use SET.fillareacolors = vcs.getcolors(SET.levels, split=0, colors=range(16, 240)) # Plot P.plot(stat_xy_normalized, x=x) # Save x.png(imgName + '.png') # # Annotated Plot # Annotated = False if Annotated: x.clear() SET.values.show = True SET.values.array = stat_xy P.plot(stat_xy_normalized, x=x, bg=0) x.png(imgName + '_annotated.png')
def test_portrait_values(self): print() print() print() print() print("---------------------------------------------------") print("RUNNING: Portrait test") print("---------------------------------------------------") print() print() print() print() # CREATES VCS OBJECT AS A PORTAIT PLOT AND LOADS PLOT SETTINGS FOR # EXAMPLE self.x.portrait() # PARAMETERS STUFF P = pcmdi_metrics.graphics.portraits.Portrait() # Turn off verbosity P.verbose = False P.PLOT_SETTINGS.levels = [ -1.e20, -.5, -.4, -.3, -.2, -.1, 0., .1, .2, .3, .4, .5, 1.e20 ] P.PLOT_SETTINGS.x1 = .1 P.PLOT_SETTINGS.x2 = .85 P.PLOT_SETTINGS.y1 = .12 P.PLOT_SETTINGS.y2 = .95 P.PLOT_SETTINGS.xtic2.y1 = P.PLOT_SETTINGS.y1 P.PLOT_SETTINGS.xtic2.y2 = P.PLOT_SETTINGS.y2 P.PLOT_SETTINGS.ytic2.x1 = P.PLOT_SETTINGS.x1 P.PLOT_SETTINGS.ytic2.x2 = P.PLOT_SETTINGS.x2 # P.PLOT_SETTINGS.missing_color = 3 P.PLOT_SETTINGS.logo = os.path.join( egg_pth, "graphics", "png", "PCMDILogo-old_348x300px_72dpi.png") P.PLOT_SETTINGS.logo.y = .95 P.PLOT_SETTINGS.logo.x = .93 P.PLOT_SETTINGS.logo.width = 85 P.PLOT_SETTINGS.time_stamp = None P.PLOT_SETTINGS.draw_mesh = 'n' # P.PLOT_SETTINGS.tictable.font = 3 self.x.scriptrun( os.path.join(egg_pth, "graphics", 'vcs', 'portraits.scr')) P.PLOT_SETTINGS.colormap = 'bl_rd_12' # cols=vcs.getcolors(P.PLOT_SETTINGS.levels,range(16,40),split=1) cols = vcs.getcolors(P.PLOT_SETTINGS.levels, list(range(144, 156)), split=1) P.PLOT_SETTINGS.fillareacolors = cols P.PLOT_SETTINGS.parametertable.expansion = 100 P.PLOT_SETTINGS.values.show = True P.PLOT_SETTINGS.values.text.color = "red" P.PLOT_SETTINGS.values.text.angle = -45 J = self.loadJSON() mods = sorted(J.getAxis("model")[:]) variables = sorted(J.getAxis("variable")[:]) print("MODELS:", len(mods), mods) print("VARS:", len(variables), variables) # Get what we need out1_rel = J(statistic=["rms_xyt"], season=["ann"], region="global")(squeeze=1) out1_rel, med = genutil.grower( out1_rel, genutil.statistics.median(out1_rel, axis=1)[0]) out1_rel[:] = (out1_rel.asma() - med.asma()) / med.asma() # ADD SPACES FOR LABELS TO ALIGN AXIS LABELS WITH PLOT modsAxis = mods variablesAxis = variables # LOOP THROUGH LISTS TO ADD SPACES for i in range(len(modsAxis)): modsAxis[i] = modsAxis[i] + ' ' for i in range(len(variablesAxis)): variablesAxis[i] = variablesAxis[i] + ' ' yax = [str(s) for s in mods] # GENERATE PLOT P.decorate(out1_rel, variables, yax) # USING TWO OR MORE REFERENCE DATA SETS P.PLOT_SETTINGS.values.array = out1_rel + 2. P.PLOT_SETTINGS.values.lightcolor = "green" P.PLOT_SETTINGS.values.darkcolor = "red" P.plot(out1_rel, x=self.x, multiple=1.3) fnm = os.path.join(os.getcwd(), "testValuesOnPortrait.png") self.checkImage(fnm)
select = cdms2.selectors.Selector(lon=slice(0, 3), time=('1950', cdtime.comptime(1960))) print u(equator)(select).shape # -> appliquez à la lecture du fichier # Le module genutil : utilitaires generiques # - contenu import genutil print dir(genutil) # - statistics standards print dir(genutil.statistics) ustd = genutil.statistics.std(u, axis=0) # testez les options ustd.info() print N.ma.allclose(ustd, u.std(axis=0)) # - salstat print dir(genutil.salstat) print genutil.salstat.kurtosis(u, axis='t') # essayez d'autres fonctions # - divers _, uu = genutil.grower(u, u[0]) # testez d'autres slices print uu.shape print genutil.minmax(u, u**2) print u[:, 0, 0](genutil.picker(time=['1960-01-03', '1965-05-03'])) # testez option match
def test_portrait_values(self): print() print() print() print() print("---------------------------------------------------") print("RUNNING: Portrait test") print("---------------------------------------------------") print() print() print() print() # CREATES VCS OBJECT AS A PORTAIT PLOT AND LOADS PLOT SETTINGS FOR # EXAMPLE self.x.portrait() # PARAMETERS STUFF P = pcmdi_metrics.graphics.portraits.Portrait() # Turn off verbosity P.verbose = False P.PLOT_SETTINGS.levels = [-1.e20, -.5, -.4, -.3, -.2, -.1, 0., .1, .2, .3, .4, .5, 1.e20] P.PLOT_SETTINGS.x1 = .1 P.PLOT_SETTINGS.x2 = .85 P.PLOT_SETTINGS.y1 = .12 P.PLOT_SETTINGS.y2 = .95 P.PLOT_SETTINGS.xtic2.y1 = P.PLOT_SETTINGS.y1 P.PLOT_SETTINGS.xtic2.y2 = P.PLOT_SETTINGS.y2 P.PLOT_SETTINGS.ytic2.x1 = P.PLOT_SETTINGS.x1 P.PLOT_SETTINGS.ytic2.x2 = P.PLOT_SETTINGS.x2 # P.PLOT_SETTINGS.missing_color = 3 P.PLOT_SETTINGS.logo = os.path.join(egg_pth, "graphics", "png", "PCMDILogo-old_348x300px_72dpi.png") P.PLOT_SETTINGS.logo.y = .95 P.PLOT_SETTINGS.logo.x = .93 P.PLOT_SETTINGS.logo.width = 85 P.PLOT_SETTINGS.time_stamp = None P.PLOT_SETTINGS.draw_mesh = 'n' # P.PLOT_SETTINGS.tictable.font = 3 self.x.scriptrun( os.path.join( egg_pth, "graphics", 'vcs', 'portraits.scr')) P.PLOT_SETTINGS.colormap = 'bl_rd_12' # cols=vcs.getcolors(P.PLOT_SETTINGS.levels,range(16,40),split=1) cols = vcs.getcolors(P.PLOT_SETTINGS.levels, list(range(144, 156)), split=1) P.PLOT_SETTINGS.fillareacolors = cols P.PLOT_SETTINGS.parametertable.expansion = 100 P.PLOT_SETTINGS.values.show = True P.PLOT_SETTINGS.values.text.color = "red" P.PLOT_SETTINGS.values.text.angle = -45 J = self.loadJSON() mods = sorted(J.getAxis("model")[:]) variables = sorted(J.getAxis("variable")[:]) print("MODELS:",len(mods),mods) print("VARS:",len(variables),variables) # Get what we need out1_rel = J(statistic=["rms_xyt"],season=["ann"],region="global")(squeeze=1) out1_rel, med = genutil.grower(out1_rel,genutil.statistics.median(out1_rel,axis=1)[0]) out1_rel[:] = (out1_rel.asma() - med.asma())/ med.asma() # ADD SPACES FOR LABELS TO ALIGN AXIS LABELS WITH PLOT modsAxis = mods variablesAxis = variables # LOOP THROUGH LISTS TO ADD SPACES for i in range(len(modsAxis)): modsAxis[i] = modsAxis[i] + ' ' for i in range(len(variablesAxis)): variablesAxis[i] = variablesAxis[i] + ' ' yax = [str(s) for s in mods] # GENERATE PLOT P.decorate(out1_rel, variables, yax) # USING TWO OR MORE REFERENCE DATA SETS P.PLOT_SETTINGS.values.array = out1_rel + 2. P.PLOT_SETTINGS.values.lightcolor = "green" P.PLOT_SETTINGS.values.darkcolor = "red" P.plot(out1_rel, x=self.x, multiple=1.3) fnm = os.path.join(os.getcwd(), "testValuesOnPortrait.png") self.checkImage(fnm)
def model_land_only(model, model_timeseries, lf, debug=False): # ------------------------------------------------- # Mask out over ocean grid # - - - - - - - - - - - - - - - - - - - - - - - - - if debug: print('debug: plot for beforeMask start') import vcs x = vcs.init() x.plot(model_timeseries) x.png('_'.join(['test', model, 'beforeMask.png'])) print('debug: plot for beforeMask done') # Check land fraction variable to see if it meet criteria # (0 for ocean, 100 for land, no missing value) lat_c = lf.getAxis(0) lon_c = lf.getAxis(1) lf_id = lf.id lf = MV2.array(lf.filled(0.)) lf.setAxis(0, lat_c) lf.setAxis(1, lon_c) lf.id = lf_id if float(MV2.max(lf)) == 1.: lf = MV2.multiply(lf, 100.) # Matching dimension if debug: print('debug: match dimension in model_land_only') model_timeseries, lf_timeConst = genutil.grower(model_timeseries, lf) # Conserve axes time_c = model_timeseries.getAxis(0) lat_c2 = model_timeseries.getAxis(1) lon_c2 = model_timeseries.getAxis(2) opt1 = False if opt1: # Masking out partial ocean grids as well # Mask out ocean even fractional (leave only pure ocean grid) model_timeseries_masked = MV2.masked_where( lf_timeConst < 100, model_timeseries) else: # Mask out only full ocean grid & use weighting for partial ocean grid model_timeseries_masked = MV2.masked_where( lf_timeConst == 0, model_timeseries) # mask out pure ocean grids if model == 'EC-EARTH': # Mask out over 90% land grids for models those consider river as # part of land-sea fraction. So far only 'EC-EARTH' does.. model_timeseries_masked = MV2.masked_where( lf_timeConst < 90, model_timeseries) lf2 = MV2.divide(lf, 100.) model_timeseries, lf2_timeConst = genutil.grower( model_timeseries, lf2) # Matching dimension model_timeseries_masked = MV2.multiply( model_timeseries_masked, lf2_timeConst) # consider land fraction like as weighting # Make sure to have consistent axes model_timeseries_masked.setAxis(0, time_c) model_timeseries_masked.setAxis(1, lat_c2) model_timeseries_masked.setAxis(2, lon_c2) if debug: x.clear() x.plot(model_timeseries_masked) x.png('_'.join(['test', model, 'afterMask.png'])) x.close() print('debug: plot for afterMask done') return(model_timeseries_masked)
dv3d.VerticalScaling = 4.0 dv3d.ScaleColormap = [-46.0, 46.0, 1] dv3d.ScaleTransferFunction = [10.0, 77.0, 1] elif demo_index == '2': varname = "vwnd" v = f[varname] dv3d.VerticalScaling = 4.0 dv3d.ScaleColormap = [-46.0, 46.0, 1] dv3d.ScaleTransferFunction = [10.0, 77.0, 1] elif demo_index == '3': varname = "tmpu" v0 = f[varname] va = cdutil.averager( v0, axis='x' ) v01,va1=genutil.grower(v0,va) v = v01 - va1 dv3d.ScaleColormap = [-17.0, 14.7, 1] dv3d.ScaleTransferFunction = [ 3.64, 24, 1] elif demo_index == '4': v0 = f["uwnd"] v1 = f["vwnd"] is_vector = True dv3d_v.VerticalScaling = 4.0 dv3d_v.BasemapOpacity = 0.0 elif demo_index == '5': varname = "tmpu" v = f[varname]
def test_portrait(self): # CDAT MODULES import pcmdi_metrics.graphics.portraits import MV2 import numpy import genutil import vcs print print print print print "---------------------------------------------------" print "RUNNING: Portrait test" print "---------------------------------------------------" print print print print # CREATES VCS OBJECT AS A PORTAIT PLOT AND LOADS PLOT SETTINGS FOR # EXAMPLE x = vcs.init(geometry=(814, 606), bg=bg) x.portrait() # Turn off antialiasing for test suite x.setantialiasing(0) # PARAMETERS STUFF P = pcmdi_metrics.graphics.portraits.Portrait() # Turn off verbosity P.verbose = False P.PLOT_SETTINGS.levels = [ -1.e20, -.5, -.4, -.3, -.2, -.1, 0., .1, .2, .3, .4, .5, 1.e20 ] P.PLOT_SETTINGS.x1 = .1 P.PLOT_SETTINGS.x2 = .85 P.PLOT_SETTINGS.y1 = .12 P.PLOT_SETTINGS.y2 = .95 P.PLOT_SETTINGS.xtic2.y1 = P.PLOT_SETTINGS.y1 P.PLOT_SETTINGS.xtic2.y2 = P.PLOT_SETTINGS.y2 P.PLOT_SETTINGS.ytic2.x1 = P.PLOT_SETTINGS.x1 P.PLOT_SETTINGS.ytic2.x2 = P.PLOT_SETTINGS.x2 # P.PLOT_SETTINGS.missing_color = 3 P.PLOT_SETTINGS.logo = os.path.join(sys.prefix, "share", "pmp", "graphics", "png", "160915_PCMDI_logo_348x300px.png") P.PLOT_SETTINGS.logo.y = .95 P.PLOT_SETTINGS.logo.x = .93 P.PLOT_SETTINGS.time_stamp = None P.PLOT_SETTINGS.draw_mesh = 'n' # P.PLOT_SETTINGS.tictable.font = 3 x.scriptrun( os.path.join(sys.prefix, "share", "pmp", "graphics", 'vcs', 'portraits.scr')) P.PLOT_SETTINGS.colormap = 'bl_rd_12' # cols=vcs.getcolors(P.PLOT_SETTINGS.levels,range(16,40),split=1) cols = vcs.getcolors(P.PLOT_SETTINGS.levels, range(144, 156), split=1) P.PLOT_SETTINGS.fillareacolors = cols P.PLOT_SETTINGS.parametertable.expansion = 100 J = self.loadJSON() mods = sorted(J.getAxis("model")[:]) variables = sorted(J.getAxis("variable")[:]) print "MODELS:", len(mods), mods print "VARS:", len(variables), variables # Get what we need out1_rel = J(statistic=["rms_xyt"], season=["ann"], region="global")(squeeze=1) out1_rel, med = genutil.grower( out1_rel, genutil.statistics.median(out1_rel, axis=1)[0]) out1_rel[:] = (out1_rel.asma() - med.asma()) / med.asma() # ADD SPACES FOR LABELS TO ALIGN AXIS LABELS WITH PLOT modsAxis = mods variablesAxis = variables # LOOP THROUGH LISTS TO ADD SPACES for i in range(len(modsAxis)): modsAxis[i] = modsAxis[i] + ' ' for i in range(len(variablesAxis)): variablesAxis[i] = variablesAxis[i] + ' ' yax = [s.encode('utf-8') for s in mods] # CHANGE FROM UNICODE TO BYTE STRINGS # GENERATE PLOT P.decorate(out1_rel, variables, yax) # P.plot(out1_rel,x=x,multiple=1.1,bg=bg) # FOR PLOTTING TRIANGLES WHEN # USING TWO OR MORE REFERENCE DATA SETS P.plot(out1_rel, bg=bg, x=x) if not bg: raw_input("Press enter") # x.backend.renWin.Render() # END OF PLOTTING # SAVE PLOT src = os.path.join(os.path.dirname(__file__), "testPortrait.png") print src fnm = os.path.join(os.getcwd(), "testPortrait.png") x.png(fnm) ret = vcs.testing.regression.check_result_image(fnm, src) if ret != 0: sys.exit(ret)