def select_CF(sCF, wCF, idx, *i): if idx == 1.: masked_sCF = np.ceil(sCF) masked_wCF = np.ceil(wCF) s_avg_tmp = cdutil.averager(sCF, axis='yx') w_avg_tmp = cdutil.averager(wCF, axis='yx') elif idx == 2.: # set threshold; # you can change this values based on needs; s_thresholds = 0.26 w_thresholds = 0.26 # set grids with values lower than the threshold to 0; sCF[sCF < s_thresholds] = 0. wCF[wCF < w_thresholds] = 0. # mask grids with a value of 0 (grids that are not needed); masked_sCF = set_axes(MV.masked_equal(sCF, 0.) * 0. + 1) masked_wCF = set_axes(MV.masked_equal(wCF, 0.) * 0. + 1) s_avg_tmp = cdutil.averager(masked_sCF * sCF, axis='yx') w_avg_tmp = cdutil.averager(masked_wCF * wCF, axis='yx') elif idx == 3.: # set threshold, top X%; # you can change this values based on needs; p_threshold_s = 0.25 p_threshold_w = 0.25 # sort all grids, values for grids that are # outside the interested region are set to -1; s_reshape = np.sort(np.array(MV.filled(sCF, -1)).ravel())[::-1] w_reshape = np.sort(np.array(MV.filled(wCF, -1)).ravel())[::-1] # remove grids with values of -1; s_no_minus1 = s_reshape[s_reshape != -1] w_no_minus1 = w_reshape[w_reshape != -1] # find the threshold for the top X% num_s = int(len(s_no_minus1) * p_threshold_s) num_w = int(len(w_no_minus1) * p_threshold_w) s_thresholds = s_no_minus1[num_s - 1] w_thresholds = w_no_minus1[num_w - 1] # mask grids with a value lower than the derived thresholds (grids that are not needed); masked_sCF = set_axes(MV.masked_less(sCF, s_thresholds) * 0. + 1) masked_wCF = set_axes(MV.masked_less(wCF, w_thresholds) * 0. + 1) s_avg_tmp = cdutil.averager(masked_sCF * sCF, axis='yx') w_avg_tmp = cdutil.averager(masked_wCF * wCF, axis='yx') print( f"For method {idx}, averaged solar capacity factor for the filtered grids is: {s_avg_tmp}" ) print( f"For method {idx}, averaged wind capacity factor for the filtered grids is: {w_avg_tmp}" ) print( f"Selected grid cells solar {np.ceil(masked_sCF).sum()}\nSelected grid cells wind {np.ceil(masked_wCF).sum()}" ) return masked_sCF, masked_wCF
def testMaskingFunctions(self): xouter = MV2.outerproduct(MV2.arange(5.), [1] * 10) masked = MV2.masked_greater(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[2:], True)) self.assertTrue(MV2.allequal(masked.mask[:2], False)) masked = MV2.masked_greater_equal(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[1:], True)) self.assertTrue(MV2.allequal(masked.mask[:1], False)) masked = MV2.masked_less(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[:1], True)) self.assertTrue(MV2.allequal(masked.mask[1:], False)) masked = MV2.masked_less_equal(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[:2], True)) self.assertTrue(MV2.allequal(masked.mask[2:], False)) masked = MV2.masked_not_equal(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[1], False)) self.assertTrue(MV2.allequal(masked.mask[0], True)) self.assertTrue(MV2.allequal(masked.mask[2:], True)) masked = MV2.masked_equal(xouter, 1) self.assertTrue(MV2.allequal(masked.mask[1], True)) self.assertTrue(MV2.allequal(masked.mask[0], False)) self.assertTrue(MV2.allequal(masked.mask[2:], False)) masked = MV2.masked_outside(xouter, 1, 3) self.assertTrue(MV2.allequal(masked.mask[0:1], True)) self.assertTrue(MV2.allequal(masked.mask[1:4], False)) self.assertTrue(MV2.allequal(masked.mask[4:], True)) masked = MV2.masked_where( MV2.logical_or(MV2.greater(xouter, 3), MV2.less(xouter, 2)), xouter) self.assertTrue(MV2.allequal(masked.mask[0:2], True)) self.assertTrue(MV2.allequal(masked.mask[2:4], False)) self.assertTrue(MV2.allequal(masked.mask[4:], True))
def mask_power(power,wvnb,fqcy): w=power.getAxis(1) f=power.getAxis(0) ## print w ## print f iw=-1 for i in range(len(w)): #print w[i],wvnb if w[i]==wvnb: iw=i break if iw==-1: raise 'Could not find wave number:'+str(wvnb) ifq=-1 for i in range(len(f)): #print f[i],fqcy,numpy.ma.subtract(f[i],fqcy) if numpy.ma.allclose(f[i],fqcy): ifq=i break if ifq==-1: print 'Could not find frequency:'+str(fqcy) else: power[ifq,iw]=-999 power=MV2.masked_equal(power,-999) return power
def mask_power(power, wvnb, fqcy): w = power.getAxis(1) f = power.getAxis(0) # print w # print f iw = -1 for i in range(len(w)): # print w[i],wvnb if w[i] == wvnb: iw = i break if iw == -1: raise 'Could not find wave number:' + str(wvnb) ifq = -1 for i in range(len(f)): # print f[i],fqcy,numpy.ma.subtract(f[i],fqcy) if numpy.ma.allclose(f[i], fqcy): ifq = i break if ifq == -1: print('Could not find frequency:' + str(fqcy)) else: power[ifq, iw] = -999 power = MV2.masked_equal(power, -999) return power
def select_CF(sCF, wCF, idx, *i): if idx == 1.: s_avg_tmp = cdutil.averager(sCF, axis='yx') w_avg_tmp = cdutil.averager(wCF, axis='yx') elif idx == 2.: # The numbers of 0.15 for solar and wind come from Sterl et al., 2018 # The numders of 0.01 for solar 0.10 for wind come from Jacobson et al., 2017 s_thresholds = 0.10 w_thresholds = 0.10 sCF[sCF < s_thresholds] = 0. wCF[wCF < w_thresholds] = 0. masked_sCF = set_axes(MV.masked_equal(sCF, 0.)) masked_wCF = set_axes(MV.masked_equal(wCF, 0.)) s_avg_tmp = cdutil.averager(masked_sCF, axis='yx') w_avg_tmp = cdutil.averager(masked_wCF, axis='yx') elif idx == 3.: # thresholds are selected to produce similar US annual mean values with EIA data p_threshold_s = (int(i[0]) + 1) * 0.1 p_threshold_w = (int(i[0]) + 1) * 0.1 print p_threshold_s, p_threshold_w s_reshape = np.sort(np.array(MV.filled(sCF, 0)).ravel())[::-1] w_reshape = np.sort(np.array(MV.filled(wCF, 0)).ravel())[::-1] s_no_zero = s_reshape[s_reshape != 0.] w_no_zero = w_reshape[w_reshape != 0.] num_s = int(len(s_no_zero) * p_threshold_s) num_w = int(len(w_no_zero) * p_threshold_w) s_thresholds = s_no_zero[num_s - 1] w_thresholds = w_no_zero[num_w - 1] sCF[sCF < s_thresholds] = 0. wCF[wCF < w_thresholds] = 0. masked_sCF = set_axes(MV.masked_equal(sCF, 0.)) masked_wCF = set_axes(MV.masked_equal(wCF, 0.)) s_avg_tmp = cdutil.averager(masked_sCF, axis='yx') w_avg_tmp = cdutil.averager(masked_wCF, axis='yx') masked_sCF2 = MV.array(masked_sCF / masked_sCF) masked_sCF2.id = 'us_mask_sCF_' + str(p_threshold_s) masked_wCF2 = MV.array(masked_wCF / masked_wCF) masked_wCF2.id = 'us_mask_wCF_' + str(p_threshold_w) g.write(masked_sCF2) g.write(masked_wCF2) return s_avg_tmp, w_avg_tmp
def post(self,fetched,slab,axes,specifications,confined_by,aux,axismap): ''' Post processing retouches the bounds and later will deal with the mask''' import cdms2 as cdms fetched=cdms.createVariable(fetched,copy=1) faxes=fetched.getAxisList() a=None for i in range(len(faxes)): if confined_by[i] is self: newaxvals=[] bounds=[] a=None sh=list(fetched.shape) sh[i]=1 for l in self.aux[i]: try: tmp=fetched(**{faxes[i].id:(l,l)}) ax=tmp.getAxis(i) #print ax newaxvals.append(ax[0]) if ax.getBounds()!=None: bounds.append(ax.getBounds()[0]) else: bounds=None except Exception,err: #print 'err:',err,'match:',self.match if self.match==1: raise Exception,'Error axis value :'+str(l)+' was requested but is not present in slab\n(more missing might exists)' elif self.match==0: tmp=MV2.ones(sh,typecode=MV2.float) tmp=MV2.masked_equal(tmp,1) if type(l)==type(cdtime.comptime(1999)) or type(l)==type(cdtime.reltime(0,'days since 1999')) or type(l)==type(''): if type(l)!=type(''): newaxvals.append(l.torel(faxes[i].units).value) else: newaxvals.append(cdtime.s2r(l,faxes[i].units).value) else: newaxvals.append(l) if bounds is not None: bounds.append([ax[-1]-1.,ax[-1]+1]) else: tmp=None if not tmp is None: if a is None: a=tmp elif not tmp is None: a=MV2.concatenate((a,tmp),i) if bounds is not None: newax=cdms.createAxis(numpy.array(newaxvals),bounds=numpy.array(bounds),id=ax.id) else: newax=cdms.createAxis(numpy.array(newaxvals),id=ax.id) for att in faxes[i].attributes.keys(): setattr(newax,att,faxes[i].attributes.get(att)) for j in range(len(fetched.shape)): if j==i: a.setAxis(i,newax) else: a.setAxis(j,faxes[j]) fetched=a.astype(fetched.dtype.char) faxes=fetched.getAxisList()
def test_thresholds(sCF, wCF): s_avg_tmp = np.zeros([len(p_threshold_list)]) w_avg_tmp = np.zeros([len(p_threshold_list)]) for i in range(len(p_threshold_list)): tmp1 = np.copy(sCF) tmp2 = np.copy(wCF) p_threshold = p_threshold_list[i] s_reshape = np.sort(tmp1.ravel())[::-1] w_reshape = np.sort(tmp2.ravel())[::-1] s_no_zero = s_reshape[s_reshape != 0.] w_no_zero = w_reshape[w_reshape != 0.] num_s = int(len(s_no_zero) * p_threshold) num_w = int(len(w_no_zero) * p_threshold) s_thresholds = s_no_zero[num_s - 1] w_thresholds = w_no_zero[num_w - 1] tmp1[tmp1 < s_thresholds] = 0. tmp2[tmp2 < w_thresholds] = 0. masked_sCF = set_axes(MV.masked_equal(tmp1, 0.)) masked_wCF = set_axes(MV.masked_equal(tmp2, 0.)) s_avg_tmp[i] = cdutil.averager(masked_sCF, axis='yx') w_avg_tmp[i] = cdutil.averager(masked_wCF, axis='yx') return s_avg_tmp, w_avg_tmp
def _get(self): if 'relative' in self.portrait_types.keys(): d=self.portrait_types['relative'] vals=d[1] real_value=getattr(self,d[0]) real=self.__get() setattr(self,d[0],vals[0]) a0=self.__get() sh=list(a0.shape) sh.insert(0,1) a0=MV2.reshape(a0,sh) for v in vals[1:]: setattr(self,d[0],v) tmp=self.__get() tmp=MV2.reshape(tmp,sh) a0=MV2.concatenate((a0,tmp)) a0=MV2.sort(a0,0).filled() real2=real.filled() a0=MV2.reshape(a0,(a0.shape[0],sh[1]*sh[2])) real2=MV2.reshape(real2,(sh[1]*sh[2],)) a0=MV2.transpose(a0) indices=[] for i in range(len(real2)): indices.append(MV2.searchsorted(a0[i],real2[i])) indices=MV2.array(indices) indices=MV2.reshape(indices,(sh[1],sh[2])) if not ((real.mask is None) or (real.mask is MV2.nomask)): indices=MV2.masked_where(real.mask,indices) a=MV2.masked_equal(a0,1.e20) a=MV2.count(a,1) a=MV2.reshape(a,indices.shape) indices=indices/a*100 setattr(self,d[0],real_value) indices.setAxisList(real.getAxisList()) ## print indices.shape return indices else: return self.__get()
def _get(self): if 'relative' in self.portrait_types.keys(): d = self.portrait_types['relative'] vals = d[1] real_value = getattr(self, d[0]) real = self.__get() setattr(self, d[0], vals[0]) a0 = self.__get() sh = list(a0.shape) sh.insert(0, 1) a0 = MV2.reshape(a0, sh) for v in vals[1:]: setattr(self, d[0], v) tmp = self.__get() tmp = MV2.reshape(tmp, sh) a0 = MV2.concatenate((a0, tmp)) a0 = MV2.sort(a0, 0).filled() real2 = real.filled() a0 = MV2.reshape(a0, (a0.shape[0], sh[1] * sh[2])) real2 = MV2.reshape(real2, (sh[1] * sh[2], )) a0 = MV2.transpose(a0) indices = [] for i in range(len(real2)): indices.append(MV2.searchsorted(a0[i], real2[i])) indices = MV2.array(indices) indices = MV2.reshape(indices, (sh[1], sh[2])) if not ((real.mask is None) or (real.mask is MV2.nomask)): indices = MV2.masked_where(real.mask, indices) a = MV2.masked_equal(a0, 1.e20) a = MV2.count(a, 1) a = MV2.reshape(a, indices.shape) indices = indices / a * 100 setattr(self, d[0], real_value) indices.setAxisList(real.getAxisList()) ## print indices.shape return indices else: return self.__get()
def logLinearInterpolation(A, P, levels=[ 100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000 ], status=None): """ Log-linear interpolation to convert a field from sigma levels to pressure levels Value below surface are masked Input A : array on sigma levels P : pressure field from TOP (level 0) to BOTTOM (last level) levels : pressure levels to interplate to (same units as P), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000] P and levels must have same units Output array on pressure levels (levels) Examples: A=logLinearInterpolation(A,P),levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]) """ try: nlev = len(levels) # Number of pressure levels except: nlev = 1 # if only one level len(levels) would breaks levels = [ levels, ] order = A.getOrder() A = A(order='z...') P = P(order='z...') sh = list(P.shape) nsigma = sh[0] #number of sigma levels sh[0] = nlev t = MV2.zeros(sh, typecode=MV2.float32) sh2 = P[0].shape prev = -1 for ilev in range(nlev): # loop through pressure levels if status is not None: prev = genutil.statusbar(ilev, nlev - 1., prev) lev = levels[ilev] # get value for the level Pabv = MV2.ones(sh2, MV2.float) Aabv = -1 * Pabv # Array on sigma level Above Abel = -1 * Pabv # Array on sigma level Below Pbel = -1 * Pabv # Pressure on sigma level Below Pabv = -1 * Pabv # Pressure on sigma level Above Peq = MV2.masked_equal(Pabv, -1) # Area where Pressure == levels for i in range(1, nsigma): # loop from second sigma level to last one a = MV2.greater_equal( P[i], lev) # Where is the pressure greater than lev b = MV2.less_equal(P[i - 1], lev) # Where is the pressure less than lev # Now looks if the pressure level is in between the 2 sigma levels # If yes, sets Pabv, Pbel and Aabv, Abel a = MV2.logical_and(a, b) Pabv = MV2.where(a, P[i], Pabv) # Pressure on sigma level Above Aabv = MV2.where(a, A[i], Aabv) # Array on sigma level Above Pbel = MV2.where(a, P[i - 1], Pbel) # Pressure on sigma level Below Abel = MV2.where(a, A[i - 1], Abel) # Array on sigma level Below Peq = MV2.where(MV2.equal(P[i], lev), A[i], Peq) val = MV2.masked_where( MV2.equal(Pbel, -1), numpy.ones(Pbel.shape) * lev) # set to missing value if no data below lev if there is tl = MV2.log(val / Pbel) / MV2.log( Pabv / Pbel) * (Aabv - Abel) + Abel # Interpolation if ((Peq.mask is None) or (Peq.mask is MV2.nomask)): tl = Peq else: tl = MV2.where(1 - Peq.mask, Peq, tl) t[ilev] = tl.astype(MV2.float32) ax = A.getAxisList() autobnds = cdms2.getAutoBounds() cdms2.setAutoBounds('off') lvl = cdms2.createAxis(MV2.array(levels).filled()) cdms2.setAutoBounds(autobnds) try: lvl.units = P.units except: pass lvl.id = 'plev' try: t.units = P.units except: pass ax[0] = lvl t.setAxisList(ax) t.id = A.id for att in A.listattributes(): setattr(t, att, getattr(A, att)) return t(order=order)
class PVCDMSReader(): def __init__(self): self.grid_bounds = None self.zscale = 1 self.output_type = None self.lon = None self.lat = None self.lev = None self.time = None pass def is_level_axis(self, axis): if axis.isLevel(): return True #// @note: What's so special about isobaric? if (axis.id == 'isobaric'): axis.designateLevel(1) return True return False def is_three_dimensional(self, cdms_var): dim = 0 if cdms_var is not None: axes_list = cdms_var.var.getAxisList() for axis in axes_list: if axis.isLongitude(): dim += 1 if axis.isLatitude(): dim += 1 if self.is_level_axis(axis): dim += 1 return (True if (dim == 3) else False) def get_coord_type(self, axis): icoord = -2 if axis.isLongitude(): self.lon = axis icoord = 0 if axis.isLatitude(): self.lat = axis icoord = 1 if self.is_level_axis(axis): self.lev = axis icoord = 2 #// @todo: Not sure if this is needed here if axis.isTime(): self.time = axis icoord = 2 return icoord def get_axis_values(self, axis, roi): values = axis.getValue() bounds = None if roi: if axis.isLongitude(): bounds = [roi[0], roi[2]] elif axis.isLatitude(): bounds = [roi[1], roi[3]] if bounds: if axis.isLongitude() and (values[0] > values[-1]): values[-1] = values[-1] + 360.0 value_bounds = [ min(values[0], values[-1]), max(values[0], values[-1]) ] mid_value = (value_bounds[0] + value_bounds[1]) / 2.0 mid_bounds = (bounds[0] + bounds[1]) / 2.0 offset = (360.0 if mid_bounds > mid_value else -360.0) trans_val = mid_value + offset if (trans_val > bounds[0]) and (trans_val < bounds[1]): value_bounds[0] = value_bounds[0] + offset value_bounds[1] = value_bounds[1] + offset bounds[0] = max([bounds[0], value_bounds[0]]) bounds[1] = min([bounds[1], value_bounds[1]]) return bounds, values def new_list(self, size, init_value): return [init_value for i in range(size)] def get_new_vtk_data_array(self, scalar_dtype): if scalar_dtype == np.int32: return vtk.vtkIntArray() if scalar_dtype == np.ushort: return vtk.vtkUnsignedShortArray() if scalar_dtype == np.ubyte: return vtk.vtkUnsignedCharArray() if scalar_dtype == np.float32: return vtk.vtkFloatArray() print >> sys.stderr, '[ERROR] ' + str( scalar_dtype) + ' is not supported ' return None def get_grid_specs(self, var, roi, zscale): gridOrigin = self.new_list(3, 0.0) outputOrigin = self.new_list(3, 0.0) gridBounds = self.new_list(6, 0.0) gridSpacing = self.new_list(3, 1.0) gridExtent = self.new_list(6, 0) outputExtent = self.new_list(6, 0) gridShape = self.new_list(3, 0) gridSize = 1 self.lev = var.getLevel() axis_list = var.getAxisList() for axis in axis_list: size = len(axis) iCoord = self.get_coord_type(axis) roiBounds, values = self.get_axis_values(axis, roi) if iCoord >= 0: iCoord2 = 2 * iCoord gridShape[iCoord] = size gridSize = gridSize * size outputExtent[iCoord2 + 1] = gridExtent[iCoord2 + 1] = size - 1 if iCoord < 2: lonOffset = 0.0 #360.0 if ( ( iCoord == 0 ) and ( roiBounds[0] < -180.0 ) ) else 0.0 outputOrigin[iCoord] = gridOrigin[ iCoord] = values[0] + lonOffset spacing = (values[size - 1] - values[0]) / (size - 1) if roiBounds: if (roiBounds[1] < 0.0) and (roiBounds[0] >= 0.0): roiBounds[1] = roiBounds[1] + 360.0 gridExtent[iCoord2] = int( round((roiBounds[0] - values[0]) / spacing)) gridExtent[iCoord2 + 1] = int( round((roiBounds[1] - values[0]) / spacing)) if gridExtent[iCoord2] > gridExtent[iCoord2 + 1]: geTmp = gridExtent[iCoord2 + 1] gridExtent[iCoord2 + 1] = gridExtent[iCoord2] gridExtent[iCoord2] = geTmp outputExtent[iCoord2 + 1] = gridExtent[iCoord2 + 1] - gridExtent[iCoord2] outputOrigin[iCoord] = lonOffset + roiBounds[0] roisize = gridExtent[iCoord2 + 1] - gridExtent[iCoord2] + 1 gridSpacing[iCoord] = spacing gridBounds[ iCoord2] = roiBounds[0] if roiBounds else values[0] gridBounds[iCoord2 + 1] = ( roiBounds[0] + roisize * spacing) if roiBounds else values[size - 1] else: gridSpacing[iCoord] = 1.0 # gridSpacing[ iCoord ] = zscale gridBounds[iCoord2] = values[0] # 0.0 gridBounds[iCoord2 + 1] = values[size - 1] # float( size-1 ) if gridBounds[2] > gridBounds[3]: tmp = gridBounds[2] gridBounds[2] = gridBounds[3] gridBounds[3] = tmp gridSpecs = {} md = { 'bounds': gridBounds, 'lat': self.lat, 'lon': self.lon, 'lev': self.lev, 'time': self.time } gridSpecs['gridOrigin'] = gridOrigin gridSpecs['outputOrigin'] = outputOrigin gridSpecs['gridBounds'] = gridBounds gridSpecs['gridSpacing'] = gridSpacing gridSpecs['gridExtent'] = gridExtent gridSpecs['outputExtent'] = outputExtent gridSpecs['gridShape'] = gridShape gridSpecs['gridSize'] = gridSize gridSpecs['md'] = md #// @todo: How we get the attributes? #if dset: gridSpecs['attributes'] = dset.dataset.attributes return gridSpecs def convert(self, cdms_var, **args): '''Convert a cdms data to vtk image data ''' trans_var = cdms_var.var level_axis = trans_var.getLevel() time_axis = trans_var.getTime() if level_axis: values = level_axis.getValue() ascending_values = (values[-1] > values[0]) invert_z = ((level_axis.attributes.get('positive', '') == 'down') and ascending_values) or ((levaxis.attributes.get( 'positive', '') == 'up') and not ascending_values) time_bounds = args.get('time', None) [time_value, time_index, use_time_index] = time_bounds if time_bounds else [None, None, None] raw_data_array = None #// @todo: Pass decimation required decimation_factor = 1 #// @todo: Worry about order later data_args = {} try: if (time_index != None and use_time_index): data_args['time'] = slice(time_index, time_index + 1) elif time_value: data_args['time'] = time_value except: pass try: raw_data_array = trans_var(**data_args) except Exception, err: print >> sys.stderr, "Error Reading Variable " + str(err) return None # @note: Why masked_equal? try: raw_data_array = MV2.masked_equal(raw_data_array, raw_data_array.fill_value) except: pass data_array = raw_data_array var_data_specs = self.get_grid_specs(data_array, None, 1) #// @todo: Handle attributes later #// Now create a vtk image data image_data = vtk.vtkImageData() #// @note: What's the difference between gridOrigin and outputOrigin scalar_dtype = cdms_var.var.dtype if scalar_dtype == np.ushort: image_data.SetScalarType(vtk.VTK_UNSIGNED_SHORT, image_data.GetInformation()) if scalar_dtype == np.int32: image_data.SetScalarType(vtk.VTK_INT, image_data.GetInformation()) if scalar_dtype == np.ubyte: image_data.SetScalarType(vtk.VTK_UNSIGNED_CHAR, image_data.GetInformation()) if scalar_dtype == np.float32: image_data.SetScalarType(vtk.VTK_FLOAT, image_data.GetInformation()) origin = var_data_specs['outputOrigin'] image_data.SetOrigin(origin[0], origin[1], origin[2]) spacing = var_data_specs['gridSpacing'] image_data.SetSpacing(spacing[0], spacing[1], spacing[2]) extents = var_data_specs['outputExtent'] extents = image_data.SetExtent(extents[0], extents[1], extents[2], extents[3], extents[4], extents[5]) no_tuples = data_array.size #// @note: Assuming number of components always equal to 1 vtk_data_array = self.get_new_vtk_data_array(scalar_dtype) vtk_data_array.SetNumberOfComponents(1) vtk_data_array.SetNumberOfTuples(no_tuples) vtk_data_array.SetVoidArray(data_array, data_array.size, 1) vtk_data_array.SetName(cdms_var.varname) image_point_data = image_data.GetPointData() image_point_data.SetScalars(vtk_data_array) # writer = vtk.vtkDataSetWriter() # writer.SetFileName("/home/aashish/Desktop/foo.vtk") # writer.SetInput(image_data) # writer.Write() image_data_copy = vtk.vtkImageData() image_data_copy.DeepCopy(image_data) return image_data_copy
# [1] D. G. Erbs, S. A. Klein and J. A. Duffie, Estimation of the diffuse radiation fraction for hourly, # daily and monthly-average global radiation, Solar Energy 28(4), pp 293-302, 1982. Eq. 1 kt = np.zeros([24,lat_num,lon_num]) kt[swtdn_tmp != 0.] = (swgdn_tmp[swtdn_tmp != 0.]/swtdn_tmp[swtdn_tmp != 0.]) kt[kt<0.] = 0. df = np.zeros([24,lat_num,lon_num]) # error1 df = np.where( kt<= 0.22, 1 - 0.09 * kt, df) df = np.where((kt > 0.22) & (kt <= 0.8), 0.9511 - 0.1604*kt + 4.388*kt**2 - 16.638*kt**3 + 12.336*kt**4, df) df = np.where( kt > 0.8, 0.165, df) # df = np.where( kt== 0.0, 1.0, df) # where no TOA SW, all diffuse flux dhi = df * swgdn_tmp # diffuse radiation dni = (swgdn_tmp - dhi) # direct radiation for hr_idx in range(24): zenith, solar_azi, ha = cal_solar_angles(lat, lon, days_ord, hr_idx) # All in radius mask1 = MV.filled(MV.masked_equal(swtdn_tmp[hr_idx],0)*0+1,0) mask2 = MV.filled(MV.masked_greater_equal(zenith,np.pi/2)*0+1,0) # Based on Braun and Mitchell, 1983 # Solar geometry for fixed and tracking surface, Solar Energy, 1983 incidence_rad, panel_tilt_rad = cal_incidence_angles(zenith, solar_azi, tilt_pv, azim_pv, 'h') cosine_zenith = np.cos(zenith)* mask1*mask2 cosine_incide = np.cos(incidence_rad) * mask1*mask2 adjust_factor_dni = replace_nan(cosine_incide / cosine_zenith) adjust_factor_dni[(adjust_factor_dni<1.)]=1. # Adjust dni and dhi based on Pfenninger and Staffell, 2016[3] # Long-term patterns of European PV output using 30 years of validated hourly reanalysis and satellite data, Energy, 2016 # The calculation of adjuated direct sunlight is corrected dni_adjust = dni[hr_idx] * adjust_factor_dni dhi_adjust = dhi[hr_idx]*(1+np.cos(panel_tilt_rad))/2. + 0.3*(dni[hr_idx]+dhi[hr_idx])*(1-np.cos(panel_tilt_rad))/2.
v = f_axis('SWGDN') lat = v.getAxis(1) # latitude lon = v.getAxis(2) # longitude f_axis.close() ### Step 1 # Seprate land and ocean grids; f_land_mask = cdms.open('data/land_sea_mask_merra.nc4') land_mask_tmp = f_land_mask('FRLAND', squeeze=1) # land fraction # We set grids with "FRLAND" >= 0.5 as land, and have a value of 1; # Other grids ("FRLAND" < 0.5) are treated as ocean, and have a value of 0; land_mask_tmp[land_mask_tmp >= 0.5] = 1. land_mask_tmp[land_mask_tmp < 0.5] = 0. # Masked all ocean grids, and the returned ocean grids have no value at all ("-"); # To faciliate average process later, we set the lat/lon to the returned array; land_mask = MV.array(MV.masked_equal(land_mask_tmp, 0.)) land_mask.setAxis(0, lat) land_mask.setAxis(1, lon) f_land_mask.close() ### Step 2 # Depends on the shapefiles downloaded, this section could be slightly different; # From regionmask and Nature Earth, create NYS and Texas masks; states = regionmask.defined_regions.natural_earth.us_states_50 mask = np.array(states.mask(lon, lat, wrap_lon=False)) NY = np.ma.masked_not_equal(mask, 34) * 0. + 1. TX = np.ma.masked_not_equal(mask, 43) * 0. + 1. """ # Tyler was not having success with this section of the code. See alternative # example below for making masks from shapefiles and other geometries
class CDMSDatasetRecord(): def __init__(self, id, dataset=None, dataFile=None): self.id = id self.lev = None self.dataset = dataset self.cdmsFile = dataFile # self.cachedFileVariables = {} def getTimeValues(self, dsid): return self.dataset['time'].getValue() def getVariable(self, varName): return self.dataset[varName] # def clearDataCache( self ): # self.cachedFileVariables = {} def getLevAxis(self): for axis in self.dataset.axes.values(): if axis.isLevel() or PlotType.isLevelAxis(axis): return axis return None def getLevBounds(self, levaxis): levbounds = None if levaxis: values = levaxis.getValue() ascending_values = (values[-1] > values[0]) if levaxis: if levaxis.attributes.get('positive', '') == 'down' and ascending_values: levbounds = slice(None, None, -1) elif levaxis.attributes.get( 'positive', '') == 'up' and not ascending_values: levbounds = slice(None, None, -1) return levbounds def getVarDataTimeSlice(self, varName, timeValue, gridBounds, decimation, referenceVar=None, referenceLev=None): """ This method extracts a CDMS variable object (varName) and then cuts out a data slice with the correct axis ordering (returning a NumPy masked array). """ # cachedFileVariableRec = self.cachedFileVariables.get( varName ) # if cachedFileVariableRec: # cachedTimeVal = cachedFileVariableRec[ 0 ] # if cachedTimeVal.value == timeValue.value: # return cachedFileVariableRec[ 1 ] rv = CDMSDataset.NullVariable varData = self.dataset[varName] # print "Reading Variable %s, attributes: %s" % ( varName, str(varData.attributes) ) refFile = self.cdmsFile refVar = varName refGrid = None if referenceVar: referenceData = referenceVar.split('*') refDsid = referenceData[0] refFileRelPath = referenceData[1] refVar = referenceData[2] try: refFile = getFullPath(refFileRelPath) f = cdms2.open(refFile) refGrid = f[refVar].getGrid() except cdms2.error.CDMSError, err: print >> sys.stderr, " --- Error[1] opening dataset file %s: %s " % ( refFile, str(err)) if not refGrid: refGrid = varData.getGrid() if not refGrid: mb = QtGui.QMessageBox.warning( None, "DV3D Error", "CDAT is unable to create a grid for this dataset.") return None refLat = refGrid.getLatitude() refLon = refGrid.getLongitude() nRefLat, nRefLon = len(refLat) - 1, len(refLon) - 1 LatMin, LatMax = float(refLat[0]), float(refLat[-1]) LonMin, LonMax = float(refLon[0]), float(refLon[-1]) if LatMin > LatMax: tmpLatMin = LatMin LatMin = LatMax LatMax = tmpLatMin args1 = {} gridMaker = None decimationFactor = 1 if decimation: decimationFactor = decimation[0] + 1 # try: args1['time'] = timeValue if gridBounds[0] < LonMin and gridBounds[0] + 360.0 < LonMax: gridBounds[0] = gridBounds[0] + 360.0 if gridBounds[2] < LonMin and gridBounds[2] + 360.0 < LonMax: gridBounds[2] = gridBounds[2] + 360.0 if gridBounds[0] > LonMax and gridBounds[0] - 360.0 > LonMin: gridBounds[0] = gridBounds[0] - 360.0 if gridBounds[2] > LonMax and gridBounds[2] - 360.0 > LonMin: gridBounds[2] = gridBounds[2] - 360.0 if decimationFactor == 1: args1['lon'] = (gridBounds[0], gridBounds[2]) args1['lat'] = (gridBounds[1], gridBounds[3]) else: varGrid = varData.getGrid() if varGrid: varLonInt = varGrid.getLongitude().mapIntervalExt( [gridBounds[0], gridBounds[2]]) latAxis = varGrid.getLatitude() latVals = latAxis.getValue() latBounds = [gridBounds[3], gridBounds[1] ] if latVals[0] > latVals[1] else [ gridBounds[1], gridBounds[3] ] varLatInt = latAxis.mapIntervalExt(latBounds) args1['lon'] = slice(varLonInt[0], varLonInt[1], decimationFactor) args1['lat'] = slice(varLatInt[0], varLatInt[1], decimationFactor) print " ---- Decimate(%d) grid %s: varLonInt=%s, varLatInt=%s, lonSlice=%s, latSlice=%s" % ( decimationFactor, str(gridBounds), str(varLonInt), str(varLatInt), str(args1['lon']), str(args1['lat'])) # args1['squeeze'] = 1 start_t = time.time() # if (gridMaker == None) or ( gridMaker.grid == varData.getGrid() ): if ((referenceVar == None) or ((referenceVar[0] == self.cdmsFile) and (referenceVar[1] == varName))) and (decimationFactor == 1): levbounds = self.getLevBounds(referenceLev) if levbounds: args1['lev'] = levbounds args1['order'] = 'xyz' rv = varData(**args1) else: refDelLat = (LatMax - LatMin) / nRefLat refDelLon = (LonMax - LonMin) / nRefLon # nodataMask = cdutil.WeightsMaker( source=self.cdmsFile, var=varName, actions=[ MV2.not_equal ], values=[ nodata_value ] ) if nodata_value else None gridMaker = cdutil.WeightedGridMaker( flat=LatMin, flon=LonMin, nlat=int(nRefLat / decimationFactor), nlon=int(nRefLon / decimationFactor), dellat=(refDelLat * decimationFactor), dellon=(refDelLon * decimationFactor)) # weightsMaker=nodataMask ) vc = cdutil.VariableConditioner(source=self.cdmsFile, var=varName, cdmsKeywords=args1, weightedGridMaker=gridMaker) regridded_var_slice = vc.get(returnTuple=0) if referenceLev: regridded_var_slice = regridded_var_slice.pressureRegrid( referenceLev) args2 = {'order': 'xyz', 'squeeze': 1} levbounds = self.getLevBounds(referenceLev) if levbounds: args2['lev'] = levbounds rv = regridded_var_slice(**args2) try: rv = MV2.masked_equal(rv, rv.fill_value) except: pass # max_values = [ regridded_var_slice.max(), rv.max() ] # print " Regrid variable %s: max values = %s " % ( varName, str(max_values) ) end_t = time.time() # self.cachedFileVariables[ varName ] = ( timeValue, rv ) # print "Reading variable %s, shape = %s, base shape = %s, time = %s (%s), args = %s, slice duration = %.4f sec." % ( varName, str(rv.shape), str(varData.shape), str(timeValue), str(timeValue.tocomp()), str(args1), end_t-start_t ) # except Exception, err: # print>>sys.stderr, ' Exception getting var slice: %s ' % str( err ) return rv
def linearInterpolation(A, Idx, levels=[ 100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000 ], status=None, axis='z'): """ Linear interpolation to interpolate a field from some levels to another set of levels Values below "surface" are masked. :param A: array to interpolate :type A: :param I: interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level) i.e P value going up with each level. :type I: :param levels: levels to interpolate to (same units as I). Default levels:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000] :type levels: :param axis: Axis over which to do the linear interpolation. Can provide either an int representing axis index, or the axis name. Default: 'z'. :type axis: str or int .. note:: I and levels must have same units :returns: array on new levels (levels) :Examples: .. doctest:: vertical_linearInterpolation >>> A=interpolate(A,I) # interpolates A over default levels """ try: nlev = len(levels) # Number of pressure levels except BaseException: nlev = 1 # if only one level len(levels) would breaks levels = [ levels, ] order = A.getOrder() A = A(order='%s...' % axis) Idx = Idx(order='%s...' % axis) sh = list(Idx.shape) nsigma = sh[0] # number of sigma levels sh[0] = nlev t = MV2.zeros(sh, typecode=MV2.float32) sh2 = Idx[0].shape prev = -1 for ilev in range(nlev): # loop through pressure levels if status is not None: prev = genutil.statusbar(ilev, nlev - 1., prev) lev = levels[ilev] # get value for the level Iabv = MV2.ones(sh2, MV2.float) Aabv = -1 * Iabv # Array on sigma level Above Abel = -1 * Iabv # Array on sigma level Below Ibel = -1 * Iabv # Pressure on sigma level Below Iabv = -1 * Iabv # Pressure on sigma level Above Ieq = MV2.masked_equal(Iabv, -1) # Area where Pressure == levels for i in range(1, nsigma): # loop from second sigma level to last one a = MV2.greater_equal( Idx[i], lev) # Where is the pressure greater than lev b = MV2.less_equal(Idx[i - 1], lev) # Where is the pressure less than lev # Now looks if the pressure level is in between the 2 sigma levels # If yes, sets Iabv, Ibel and Aabv, Abel a = MV2.logical_and(a, b) Iabv = MV2.where(a, Idx[i], Iabv) # Pressure on sigma level Above Aabv = MV2.where(a, A[i], Aabv) # Array on sigma level Above Ibel = MV2.where(a, Idx[i - 1], Ibel) # Pressure on sigma level Below Abel = MV2.where(a, A[i - 1], Abel) # Array on sigma level Below Ieq = MV2.where(MV2.equal(Idx[i], lev), A[i], Ieq) val = MV2.masked_where(MV2.equal(Ibel, -1.), numpy.ones(Ibel.shape) * lev) # set to missing value if no data below lev if # there is tl = (val - Ibel) / (Iabv - Ibel) * \ (Aabv - Abel) + Abel # Interpolation if ((Ieq.mask is None) or (Ieq.mask is MV2.nomask)): tl = Ieq else: tl = MV2.where(1 - Ieq.mask, Ieq, tl) t[ilev] = tl.astype(MV2.float32) ax = A.getAxisList() autobnds = cdms2.getAutoBounds() cdms2.setAutoBounds('off') lvl = cdms2.createAxis(MV2.array(levels).filled()) cdms2.setAutoBounds(autobnds) try: lvl.units = Idx.units except BaseException: pass lvl.id = 'plev' try: t.units = Idx.units except BaseException: pass ax[0] = lvl t.setAxisList(ax) t.id = A.id for att in A.listattributes(): setattr(t, att, getattr(A, att)) return t(order=order)
def zm_msf(data,ps,latitude=None,level=None): """ Compute a Zonal Mean Meridional Strema Function Input: Data: 3D, dimensions are: longitude, latidue, level PS: (Surface Pressure) in Pa (or has untis attached to it) Optional (if not containe din data) level: Level values (from top to bottom) latitude: latitude values Output zm_msf: Dimensions: latitude, level """ if MV2.rank(data)!=3: raise Exception,"data input must be of rank 3" try: orderin = data.getAxisList() # remember axes for later data=data(order='xyz') except: orderin = None # Could not reorder, dimensions info not sufficent pass try: ps=ps(order='xy') except: # Could not reorder, dimensions info not sufficent pass if MV2.rank(ps)!=2: raise Exception,"surface pressure (ps) input must be of rank 2" ps = convert(ps,'Pa') if level is None: try: level = data.getLevel() # We need to test the level ordering here too, so we can reorder data if needed if level is None: raise Exception # to go to the error statement if level[0]>level[-1]: # we need to revert data data=data(level=(0,1.E20)) # gets the data in right order level=data.getLevel() level = convert(level,'Pa') except: raise Exception,"Could not determine levels!" if level[0]>level[-1]: # need to invert levels raise Exception,"Error: levels must be from top to bottom" if latitude is None: try: latitude = data.getLatitude() except: raise Exception,"Could not determine latitude!" # Now we need to convert axes to numpy if not isinstance(data,(numpy.ndarray,list)): if isinstance(data,(cdms2.tvariable.TransientVariable,numpy.core.ma.MaskedArray)): data=data.filled() else: raise Exception, "wrong type for data" if not isinstance(ps,(numpy.ndarray,list)): if isinstance(ps,(cdms2.tvariable.TransientVariable,numpy.core.ma.MaskedArray)): ps=ps.filled() else: raise Exception, "wrong type for ps" if not isinstance(latitude,(numpy.ndarray,list)): if isinstance(latitude,(cdms2.tvariable.TransientVariable,numpy.core.ma.MaskedArray)): latitude=latitude.filled() elif isinstance(latitude,cdms2.axis.TransientAxis): # axis! latitude=latitude[:] else: raise Exception, "wrong type for latitude" if not isinstance(level,(numpy.ndarray,list)): if isinstance(level,(cdms2.tvariable.TransientVariable,numpy.core.ma.MaskedArray)): level=level.filled() elif isinstance(level,cdms2.axis.TransientAxis): # axis! level=level[:] else: raise Exception, "wrong type for level" msg = 1.E20 zm_mpsi = streamfunction.ccmp_zm_mspi(data,latitude,level,ps,msg) # Mask where missing zm_mpsi = MV2.masked_equal(zm_mpsi,msg) zm_mpsi.id = 'zm_msf' # creates the axes lev = cdms2.createAxis(level) try: l=data.getLevel() id = l.id except: id='level' lev.id=id lev.units='Pa' lat = cdms2.createAxis(latitude) try: lat=data.getLatitude() id = lat.id units = lat.units except: id='latitude' units='degrees_north' lat.id=id lat.units=units # And now sets the axis onto output zm_mpsi.setAxisList([lat,lev]) if orderin is not None: ## ok we had a transient variable in orderout="" for ax in orderin: if ax.isLatitude(): # latitude? orderout+='y' elif ax.isLevel(): orderout+='z' zm_mpsi=zm_mpsi(order=orderout) return zm_mpsi
def msu(array, weights, max_pct_missing=50.): """ This subroutine processes temperature data at discrete pressure levels, and computes from this data an "equivalent MSU" temperature. The MSU weighting function is assumed to be in pressure coordinates (with 5 mb vertical resolution). Usage msu=MSU.msu(array,weights,max_pct_missing) Where: array Input temperature data weights Input MSU weighting function max_pct_missing Maximum amount of missing weights in % (default 50) """ inorder = array.getOrder() axes = array.getAxisList() if not 'z' in inorder: raise 'error you must have a level axis on your input array' order = weights.getOrder() levs = array.getLevel()[:].astype('f') if not 0. <= max_pct_missing <= 100.: raise 'Error max_pct_missing must be between 0 and 100' if not 'z' in order: raise 'error you must have a level axis on your weights array' if not array.getAxis(-1).isLevel(): array = array(order='...z') if levs[0] > levs[1]: array = array[..., ::-1] levs = array.getLevel()[:].astype('f') if not weights.rank() == 2: raise 'Error weights must be 2D (msu_lev and channels)' if not weights.getAxis(-1).isLevel(): weights = weights(order='...z') ch_levs = weights.getAxis(0) msu_levs = weights.getLevel()[:].astype('f') sh = array.shape n = 1 for i in sh[:-1]: n *= i array = MV2.reshape(array, (n, array.shape[-1])) array = array.filled(1.e20) weights = weights.filled() if array.dtype.char != 'f': array = array.astype('f') if weights.dtype.char != 'f': weights = weights.astype('f') ## print msu_levs.shape,levs.shape,max_pct_missing,array.shape,weights.shape tmp1 = numpy.zeros(levs.shape, 'f') tmp2 = numpy.zeros(levs.shape, 'f') tmp3 = numpy.zeros(msu_levs.shape, 'f') out = eqmsu.loop_thru_dims( (1. - max_pct_missing / 100.), numpy.transpose(array), numpy.transpose(weights), levs, msu_levs, tmp1, tmp2, tmp3) out = numpy.transpose(out) ax = [] sh = [] for x in axes: if not x.isLevel(): sh.append(len(x)) ax.append(x) ax.append(ch_levs) sh.append(len(ch_levs)) out = MV2.masked_equal(out, 1.e20) out = MV2.reshape(out, sh) out.id = 'equiv_msu' out.setAxisList(ax) return out
def linearInterpolation(A, I, levels=[ 100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000 ], status=None): """ Linear interpolation to interpolate a field from some levels to another set of levels Value below "surface" are masked Input A : array to interpolate I : interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level), i.e P value going up with each level levels : levels to interplate to (same units as I), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000] I and levels must have same units Output array on new levels (levels) Examples: A=interpolate(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]) """ try: nlev = len(levels) # Number of pressure levels except: nlev = 1 # if only one level len(levels) would breaks levels = [ levels, ] order = A.getOrder() A = A(order='z...') I = I(order='z...') sh = list(I.shape) nsigma = sh[0] #number of sigma levels sh[0] = nlev t = MV2.zeros(sh, typecode=MV2.float32) sh2 = I[0].shape prev = -1 for ilev in range(nlev): # loop through pressure levels if status is not None: prev = genutil.statusbar(ilev, nlev - 1., prev) lev = levels[ilev] # get value for the level Iabv = MV2.ones(sh2, MV2.float) Aabv = -1 * Iabv # Array on sigma level Above Abel = -1 * Iabv # Array on sigma level Below Ibel = -1 * Iabv # Pressure on sigma level Below Iabv = -1 * Iabv # Pressure on sigma level Above Ieq = MV2.masked_equal(Iabv, -1) # Area where Pressure == levels for i in range(1, nsigma): # loop from second sigma level to last one a = MV2.greater_equal( I[i], lev) # Where is the pressure greater than lev b = MV2.less_equal(I[i - 1], lev) # Where is the pressure less than lev # Now looks if the pressure level is in between the 2 sigma levels # If yes, sets Iabv, Ibel and Aabv, Abel a = MV2.logical_and(a, b) Iabv = MV2.where(a, I[i], Iabv) # Pressure on sigma level Above Aabv = MV2.where(a, A[i], Aabv) # Array on sigma level Above Ibel = MV2.where(a, I[i - 1], Ibel) # Pressure on sigma level Below Abel = MV2.where(a, A[i - 1], Abel) # Array on sigma level Below Ieq = MV2.where(MV2.equal(I[i], lev), A[i], Ieq) val = MV2.masked_where( MV2.equal(Ibel, -1.), numpy.ones(Ibel.shape) * lev) # set to missing value if no data below lev if there is tl = (val - Ibel) / (Iabv - Ibel) * (Aabv - Abel) + Abel # Interpolation if ((Ieq.mask is None) or (Ieq.mask is MV22.nomask)): tl = Ieq else: tl = MV2.where(1 - Ieq.mask, Ieq, tl) t[ilev] = tl.astype(MV2.float32) ax = A.getAxisList() autobnds = cdms2.getAutoBounds() cdms2.setAutoBounds('off') lvl = cdms2.createAxis(MV2.array(levels).filled()) cdms2.setAutoBounds(autobnds) try: lvl.units = I.units except: pass lvl.id = 'plev' try: t.units = I.units except: pass ax[0] = lvl t.setAxisList(ax) t.id = A.id for att in A.listattributes(): setattr(t, att, getattr(A, att)) return t(order=order)
def getAllBoundaryOfClosedAreas(data, **kwarg): """ Input : cdms data with proper lat, lon axis. Note : This is not actual real data. we need to pass fake data (no starting from 1 to mxn) with mask of original data. eg: >>> dummy = MV2.arange(1, data.size+1, 1) >>> dummy.mask = data.mask >>> dummy.setAxisList(data.getAxisList()) >>> outdict = getAllBoundaryOfClosedAreas(dummy) Kwarg : update_mask : Takes boolean True | False (by default) If it is True, then the data's mask will be updated with masked array over out side regions other than closed boundaries pixels or (lats, lons) domain. condition : User can passed any MV2 condition over input data to mask out unwanted values in the resultant region data. Return : It returns dictionary whose keys are 'region%d' % area_number starting from 1 to N (available irregular closed regions) Each key ['regionN'] contains another dictionary which contains following keys & values 'area' -> lat, lon weighted area value in m^2 of that particular closed domain/region 'unit' -> area unit is m^2 'bpixels' -> list of tuples contain (i, j) or (x, y) or (row, col) of boundary pixels of closed domain 'blatlons' -> list of tuples contain actual (lat, lon) of boundary pixels of closed domain [i.e equivalent (lats, lons) to `bpixels` (rows, cols) ] 'cpixels' -> contains dictionary whose keys are 'row' & 'col'. 'row' has (min boundary row, max boundary row) tuple, 'col' has (min boundary col, max boundary col) tuple of corner pixels of closed irregular domain/region. # Using this user can extract regular rectangle # shaped data by slicing input data. 'clatlons' -> contains dictionary whose keys are 'lat' & 'lon'. 'lat' has (min boundary lat, max boundary lat) tuple, 'lon' has (min boundary lon, max boundary lon) tuple of corner pixels of closed irregular domain/region. [i.e. equivalent to 'cpixels' (row, col)] # Using this user can extract regular rectangle # shaped data by passing argument to input cdms var # data(latitude=lat, longitude=lon). 'region' -> cdms selector variable (At this moment no use !) 'totalPixelsCount' -> total no of pixels in that particular closed domain/region Author : Arulalan.T Date : 08.07.2014 """ update_mask = kwarg.get('update_mask', False) latAxis = data.getLatitude() lonAxis = data.getLongitude() lat, lon = data.shape min_val = -1 areadic = {} if update_mask: # assign mask of selectedRectDomain into original dataset mask. # so in original dataset itself outside of closed boundary pixels # will be masked. dmask = data.mask if not dmask.all(): # i.e. data mask is single False. So lets make data shaped False. dmask = MV2.make_mask(data) # end of if not dmask.all(): # end of if update_mask: # counter for regions count = 0 while (True): dic = {} count += 1 if MV2.masked_equal(data, 0).mask.all(): break min_val = MV2.masked_equal(data, 0).min() row = min_val / lon col = min_val - (lon * row) if col > 0: col -= 1 bPixels = _getBoundaryClosedAreaPixels(data, row, col) # store boundary pixels dic['bpixels'] = bPixels # convert pixels (i, j) into corresponding lat, lon bLatLons = _rowcol2latlon_(bPixels, latAxis, lonAxis) # store boundary lat, lons dic['blatlons'] = bLatLons # split list of tuples into corresponding lats,lons bLats, bLons = zip(*bLatLons) # pixels list of tuples into corresponding rows, cols bRows, bCols = zip(*bPixels) minBRow, maxBRow = min(bRows), max(bRows) minBCol, maxBCol = min(bCols), max(bCols) # corner row, col pixels to extract squared/rectangle shaped area # to extract correct boundaries dic['cpixels'] = {'row': (minBRow, maxBRow), 'col': (minBCol, maxBCol)} # corner lat, lon points to extract squared/rectangle shaped area # to extract correct boundaries dic['clatlons'] = {'lat': (latAxis[minBRow], latAxis[maxBRow]), 'lon':(lonAxis[minBCol], lonAxis[maxBCol])} # create selector region with latitudes & longitudes of closed area region = cdms2.selectors.Selector(cdutil.region.domain(latitude=bLats, longitude=bLons)) # store the above region into dictionary dic['region'] = region # get the irregularSelector data (i.e. masked outside this # irregular closed area) selectedRegionData = irregularClosedRegionSelector(data, latitude=bLats, longitude=bLons, overwrite=False, **kwarg) # counting the no of pixel contains value other than masked pixels. dic['totalPixelsCount'] = selectedRegionData.count() # compute region area oneRegionData = MV2.ones(selectedRegionData.shape) oneRegionData = cdms2.createVariable(oneRegionData, mask=selectedRegionData.mask) oneRegionData.setAxisList(selectedRegionData.getAxisList()) # get the weighted area by sum action and multiply with (111km)^2 area = cdutil.averager(oneRegionData, axis='xy', weight='weighted', action='sum').data * 1.2321e10 dic['area'] = area dic['unit'] = 'm^2' # store dic into global dictionary whose key is no of pixels # in the selected region. areadic['region'+str(count)] = dic zeroRegionData = numpy.zeros(selectedRegionData.shape) # fills with 0s in the selected area / region in full dataset, # so that we can find next min element index in full dataset. data[minBRow: maxBRow+1, minBCol: maxBCol+1] = zeroRegionData if update_mask: # update dmask boolean array with each closed domain's mask dmask[minBRow: maxBRow+1, minBCol: maxBCol+1] = selectedRegionData.mask # end of if update_mask: # end of while (min_val == 0): if update_mask: # and finally set the altered mask to original dataset data.mask = dmask.data # end of if update_mask: # return dictionary return areadic
def irregularClosedRegionSelector(data, latitude, longitude, overwrite=False, **kwarg): """ Inputs : data : 2Dimensional data with proper latAxis and lonAxis. latitude : List of latitudes (each represents single lat position, jointly with corresponding lon position) longitude : List of longitude (each represents single lon position, jointly with corresponding lat position) Both latitude & longitudes maked sense to point single pixel in the passed data. overwrite : Takes boolean True | False (by default) If it is True, then the data's mask will be overwrite with updated mask array out side regions other than passed latitudes, longitudes and its inner pixels of closed latitudes, longitudes (i.e. inside of passed latitude, longitude list). Kwarg: condition : User can passed any MV2 condition over input data to mask out unwanted values in the resultant region data. Output : It returns sliced data from original input data with proper masked for the irregular selector with latAxis, lonAxis. e.g.1 : FUNCTION LIMITATION without 'condition' keyword arg: *************************************************** PS : User can override this limitation by passing 'condition' kwarg. See below docstring. e.g.2: Input :- data and boundary latitudes & longitudes are passed to this function. data = ([[ 0 0 0 0 0 0 0 ] [ 0 0 0 366 0 0 0 ] [ 0 0 0 726 0 0 0 ] [ 0 0 1085 1086 1087 0 0 ] [ 0 1444 1445 1446 1447 1448 0 ] [ 0 1804 1805 1806 1807 1808 0 ] [ 0 2164 2165 2166 2167 2168 0 ] [ 0 0 2525 2526 2527 0 0 ] [ 0 0 2885 0 2887 0 0 ] [ 0 0 3245 0 3247 0 0 ] [ 0 0 0 0 0 0 0 ]], mask = False, fill_value = 1e+20) Actual Output By This Function :- ***************************** This function assumes that passed latitudes, longitudes co-ordinates pointing the closed boundary out layer path. So it retains everything inside in between two longitudes (columns) at any latitude's (row's). In the below actual output of this program to the above input, (9th row, 4th column) and (10th rows, 4th column) we will end up with input value itself. (here 0s). User may not expected any values in 9th and 10th rows Vs 4th column. data = ([[ -- -- -- -- -- -- -- ] [ -- -- -- 366 -- -- -- ] [ -- -- -- 726 -- -- -- ] [ -- -- 1085 1086 1087 -- -- ] [ -- 1444 1445 1446 1447 1448 -- ] [ -- 1804 1805 1806 1807 1808 -- ] [ -- 2164 2165 2166 2167 2168 -- ] [ -- -- 2525 2526 2527 -- -- ] [ -- -- 2885 0 2887 -- -- ] [ -- -- 3245 0 3247 -- -- ] [ -- -- -- -- -- -- -- ]], mask = [[True True True True True True True] [True True True False True True True] [True True True False True True True] [True True False False False True True] [True False False False False False True] [True False False False False False True] [True False False False False False True] [True True False False False True True] [True True False False False True True] [True True False False False True True] [True True True True True True True]], fill_value = 1e+20) But Expected Output By User :- ************************** User may expect the result as follows. But this function can return only as shown in above. data = ([[ -- -- -- -- -- -- -- ] [ -- -- -- 366 -- -- -- ] [ -- -- -- 726 -- -- -- ] [ -- -- 1085 1086 1087 -- -- ] [ -- 1444 1445 1446 1447 1448 -- ] [ -- 1804 1805 1806 1807 1808 -- ] [ -- 2164 2165 2166 2167 2168 -- ] [ -- -- 2525 2526 2527 -- -- ] [ -- -- 2885 -- 2887 -- -- ] [ -- -- 3245 -- 3247 -- -- ] [ -- -- -- -- -- -- -- ]], mask = [[True True True True True True True] [True True True False True True True] [True True True False True True True] [True True False False False True True] [True False False False False False True] [True False False False False False True] [True False False False False False True] [True True False False False True True] [True True False True False True True] [True True False True False True True] [True True True True True True True]], fill_value = 1e+20) FUNCTION LIMITATION OVERRIDE WITH 'condition' keyword arg: ********************************************************** User can override the above limitation by passing 'condition' kwarg. e.g.3: Input :- data and boundary latitudes & longitudes are passed to this function. data = ([[ 0 0 0 0 0 0 0 ] [ 0 0 0 366 0 0 0 ] [ 0 0 0 726 0 0 0 ] [ 0 0 1085 1086 1087 0 0 ] [ 0 1444 1445 1446 1447 1448 0 ] [ 0 1804 1805 1806 1807 1808 0 ] [ 0 2164 2165 2166 2167 2168 0 ] [ 0 0 2525 2526 2527 0 0 ] [ 0 0 2885 0 2887 0 0 ] [ 0 0 3245 0 3247 0 0 ] [ 0 0 0 0 0 0 0 ]], mask = False, fill_value = 1e+20) >>> c = MV2.masked_equal(data, 0) >>> selectedData = irregularClosedRegionSelector(data, lattides, longitudes, condition=c) >>> print selectedData data = ([[ -- -- -- -- -- -- -- ] [ -- -- -- 366 -- -- -- ] [ -- -- -- 726 -- -- -- ] [ -- -- 1085 1086 1087 -- -- ] [ -- 1444 1445 1446 1447 1448 -- ] [ -- 1804 1805 1806 1807 1808 -- ] [ -- 2164 2165 2166 2167 2168 -- ] [ -- -- 2525 2526 2527 -- -- ] [ -- -- 2885 -- 2887 -- -- ] [ -- -- 3245 -- 3247 -- -- ] [ -- -- -- -- -- -- -- ]], mask = [[True True True True True True True] [True True True False True True True] [True True True False True True True] [True True False False False True True] [True False False False False False True] [True False False False False False True] [True False False False False False True] [True True False False False True True] [True True False True False True True] [True True False True False True True] [True True True True True True True]], fill_value = 1e+20) # As expected values in (9th row, 4th column) and # (10th rows, 4th column) are masked. Author : Arulalan.T Date : 10.07.2014 """ condition = kwarg.get('condition', MV2.array([])) minBLat, maxBLat = min(latitude), max(latitude) minBLon, maxBLon = min(longitude), max(longitude) selectedRectDomain = data(latitude=(minBLat, maxBLat, 'ccb'), longitude=(minBLon, maxBLon, 'ccb')) selectedRectDomainOriginalMask = selectedRectDomain.mask.copy() dummy = MV2.zeros(selectedRectDomain.size, dtype=int) dummy = dummy.reshape(selectedRectDomain.shape) dummy.setAxisList(selectedRectDomain.getAxisList()) for lat, lon in zip(latitude, longitude): # fills closed boundary pixels with -1 dummy(latitude=(lat, lat, 'ccb'), longitude=(lon, lon, 'ccb'))[0] = -1 # end of for lat,lon in zip(latitude, longitude): for lat in latitude: row = dummy(latitude=(lat, lat, 'ccb'), squeeze=1).tolist() if isinstance(row, int): continue con = row.count(-1) if con >= 2: # get first index of -1 in longitudes of particular lat first = row.index(-1) # get last index of -1 in longitudes of particular lat # (here it may has more than two -1s, so get last most index # of -1 value) end = len(row) - row[::-1].index(-1) # fills with -1s in b/w first and last indecies dummy(latitude=(lat, lat, 'ccb'), squeeze=1)[first: end] = \ numpy.array([-1] * (end - first)) # end of if con >= 2: # end of for lat in latitude: if condition.any(): # apply user passed condition and fill with our dummy data whereever # mask is false (i.e. actual data) and fill with 0s whereever mask # is true (i.e. no data in those pixels) dummy = MV2.where(condition(latitude=(minBLat, maxBLat, 'ccb'), longitude=(minBLon, maxBLon, 'ccb')), dummy, 0) # end of if condition.any(): # Now make mask equal to 0. i.e. mask other than -1s # (where -1 pointing actual boundary pixels. other than closed boundary # region, we can mask those pixels) dummy = MV2.masked_equal(dummy, 0) # get mask of above dummy array and set to actual selectedRectDomain # dataset selectedRectDomain.mask = dummy.mask # make memory free del dummy if overwrite: # since we set mask to part of cdms2 variable, # its already overwritten in the passed data mask itself. # So return selectedRectDomain with masked outside of # closed boundary pixels return selectedRectDomain else: # here we should not overwritten the passed data's mask. # so lets create copy of selectedRectDomain data,mask,axes variable selectedRectMaskedDomain = selectedRectDomain.clone() # and finally revert back mask to original selectedRectDomain.mask = selectedRectDomainOriginalMask # lets return copy of selectedRectDomain with masked outside of # closed boundary pixels return selectedRectMaskedDomain
pft_biome = np.where(((kg_biome == 5) | (kg_biome == 7) | (kg_biome == 8) | (kg_biome == 11) | (kg_biome == 14)), 2, pft_biome) # Temperate (cold) pft_biome = np.where(((kg_biome == 9) | (kg_biome == 10) | (kg_biome == 12) | (kg_biome == 13) | (kg_biome == 15) | (kg_biome == 16)), 3, pft_biome) # Boreal (warm) pft_biome = np.where(((kg_biome == 17) | (kg_biome == 21) | (kg_biome == 25)), 4, pft_biome) # Boreal (cold) pft_biome = np.where( (((kg_biome >= 18) & (kg_biome <= 20)) | ((kg_biome >= 22) & (kg_biome <= 24)) | (kg_biome >= 26)), 5, pft_biome) #C3 climatic zones are pft_biome =3,4,5 and c4 climatic zones are pft_biome=1,2 pft_biome = MV2.array((pft_biome)) pft_biome = MV2.masked_equal(pft_biome, -9999) #************************************************************************************************** #************************************************************************************************** # Parameters # Interpolation years year_start = 2010 year_end = 1850 nyears = (year_start - year_end) + 1 # 1 is added to include end year # Latitude and longitude range latrange = (90., -90.) lonrange = (-180, 180, 'co') #select time period time = ('1850-01-01', '2010-01-01') time_trans = ('1849-01-01', '2009-01-01') #time for transitions
# time_values, dt, time_units = getRelativeTimeValues ( cdms2.open( self.cdmsFile ) ) vc = cdutil.VariableConditioner( source=self.cdmsFile, var=varName, cdmsKeywords=args1, weightedGridMaker=gridMaker ) print " regridded_var_slice(%s:%s): %s " % ( self.dataset.id, varName, str( args1 ) ) regridded_var_slice = vc.get( returnTuple=0 ) # if (referenceLev <> None) and ( referenceLev.shape[0] <> currentLevel.shape[0] ): # regridded_var_slice = regridded_var_slice.pressureRegrid( referenceLev ) args2 = { 'order' : order, 'squeeze' : 1 } if levBounds <> None: args2['lev'] = levBounds[0] if ( len( levBounds ) == 1 ) else levBounds else: levBounds = self.getLevBounds( currentLevel ) if levBounds: args2['lev'] = levBounds rv = regridded_var_slice( **args2 ) try: rv = MV2.masked_equal( rv, rv.fill_value ) except: pass # max_values = [ regridded_var_slice.max(), rv.max() ] # print " Regrid variable %s: max values = %s " % ( varName, str(max_values) ) end_t = time.time() # self.cachedFileVariables[ varName ] = ( timeValue, rv ) # print "Reading variable %s, shape = %s, base shape = %s, args = %s" % ( varName, str(rv.shape), str(varData.shape), str(args1) ) # except Exception, err: # print>>sys.stderr, ' Exception getting var slice: %s ' % str( err ) return rv # def init( self, timeRange, roi, zscale ): # self.timeRange = timeRange # self.roi = roi
def logLinearInterpolation(A,P,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000],status=None): """ Log-linear interpolation to convert a field from sigma levels to pressure levels Value below surface are masked Input A : array on sigma levels P : pressure field from TOP (level 0) to BOTTOM (last level) levels : pressure levels to interplate to (same units as P), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000] P and levels must have same units Output array on pressure levels (levels) Examples: A=logLinearInterpolation(A,P),levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]) """ try: nlev=len(levels) # Number of pressure levels except: nlev=1 # if only one level len(levels) would breaks levels=[levels,] order=A.getOrder() A=A(order='z...') P=P(order='z...') sh=list(P.shape) nsigma=sh[0] #number of sigma levels sh[0]=nlev t=MV2.zeros(sh,typecode=MV2.float32) sh2=P[0].shape prev=-1 for ilev in range(nlev): # loop through pressure levels if status is not None: prev=genutil.statusbar(ilev,nlev-1.,prev) lev=levels[ilev] # get value for the level Pabv=MV2.ones(sh2,MV2.float) Aabv=-1*Pabv # Array on sigma level Above Abel=-1*Pabv # Array on sigma level Below Pbel=-1*Pabv # Pressure on sigma level Below Pabv=-1*Pabv # Pressure on sigma level Above Peq=MV2.masked_equal(Pabv,-1) # Area where Pressure == levels for i in range(1,nsigma): # loop from second sigma level to last one a=MV2.greater_equal(P[i], lev) # Where is the pressure greater than lev b= MV2.less_equal(P[i-1],lev) # Where is the pressure less than lev # Now looks if the pressure level is in between the 2 sigma levels # If yes, sets Pabv, Pbel and Aabv, Abel a=MV2.logical_and(a,b) Pabv=MV2.where(a,P[i],Pabv) # Pressure on sigma level Above Aabv=MV2.where(a,A[i],Aabv) # Array on sigma level Above Pbel=MV2.where(a,P[i-1],Pbel) # Pressure on sigma level Below Abel=MV2.where(a,A[i-1],Abel) # Array on sigma level Below Peq= MV2.where(MV2.equal(P[i],lev),A[i],Peq) val=MV2.masked_where(MV2.equal(Pbel,-1),numpy.ones(Pbel.shape)*lev) # set to missing value if no data below lev if there is tl=MV2.log(val/Pbel)/MV2.log(Pabv/Pbel)*(Aabv-Abel)+Abel # Interpolation if ((Peq.mask is None) or (Peq.mask is MV2.nomask)): tl=Peq else: tl=MV2.where(1-Peq.mask,Peq,tl) t[ilev]=tl.astype(MV2.float32) ax=A.getAxisList() autobnds=cdms2.getAutoBounds() cdms2.setAutoBounds('off') lvl=cdms2.createAxis(MV2.array(levels).filled()) cdms2.setAutoBounds(autobnds) try: lvl.units=P.units except: pass lvl.id='plev' try: t.units=P.units except: pass ax[0]=lvl t.setAxisList(ax) t.id=A.id for att in A.listattributes(): setattr(t,att,getattr(A,att)) return t(order=order)
# # Monthly transformation if os.path.exists(outFile): os.remove(outFile) outFile_f = cdm.open(outFile, 'w') # Define dimensions N_i = int(tos.shape[2]) N_j = int(tos.shape[1]) N_t = int(tos.shape[0]) print ' ==> dimensions N_t, N_j, N_i:', N_t, N_j, N_i try: valmask = tos.missing_value if valmask == None: print 'EC-EARTH missing_value fix' valmask = 1.e20 sos = mv.masked_equal(sos, 0.) print sos.count() sos.data[:] = sos.filled(valmask) tos.mask = sos.mask tos.data[:] = tos.filled(valmask) qnet.mask = sos.mask qnet.data[:] = qnet.filled(valmask) emp.mask = sos.mask emp.data[:] = emp.filled(valmask) except Exception, err: print 'Exception: ', err if 'EC-EARTH' == modeln: print 'EC-EARTH missing_value fix' valmask = 1.e20 sos = mv.masked_equal(sos, 0.) print sos.count()
def msu(array,weights,max_pct_missing=50.): """ This subroutine processes temperature data at discrete pressure levels, and computes from this data an "equivalent MSU" temperature. The MSU weighting function is assumed to be in pressure coordinates (with 5 mb vertical resolution). Usage msu=MSU.msu(array,weights,max_pct_missing) Where: array Input temperature data weights Input MSU weighting function max_pct_missing Maximum amount of missing weights in % (default 50) """ inorder=array.getOrder() axes=array.getAxisList() if not 'z' in inorder: raise 'error you must have a level axis on your input array' order=weights.getOrder() levs=array.getLevel()[:].astype('f') if not 0.<=max_pct_missing<=100.: raise 'Error max_pct_missing must be between 0 and 100' if not 'z' in order: raise 'error you must have a level axis on your weights array' if not array.getAxis(-1).isLevel(): array=array(order='...z') if levs[0]>levs[1]: array=array[...,::-1] levs=array.getLevel()[:].astype('f') if not weights.rank()==2: raise 'Error weights must be 2D (msu_lev and channels)' if not weights.getAxis(-1).isLevel(): weights=weights(order='...z') ch_levs=weights.getAxis(0) msu_levs=weights.getLevel()[:].astype('f') sh=array.shape n=1 for i in sh[:-1]: n*=i array=MV2.reshape(array,(n,array.shape[-1])) array=array.filled(1.e20) weights=weights.filled() if array.dtype.char!='f': array=array.astype('f') if weights.dtype.char!='f': weights=weights.astype('f') ## print msu_levs.shape,levs.shape,max_pct_missing,array.shape,weights.shape tmp1 = numpy.zeros(levs.shape,'f') tmp2 = numpy.zeros(levs.shape,'f') tmp3 = numpy.zeros(msu_levs.shape,'f') out = eqmsu.loop_thru_dims( (1.-max_pct_missing/100.), numpy.transpose(array), numpy.transpose(weights), levs, msu_levs, tmp1, tmp2, tmp3) out = numpy.transpose(out) ax=[] sh=[] for x in axes: if not x.isLevel(): sh.append(len(x)) ax.append(x) ax.append(ch_levs) sh.append(len(ch_levs)) out=MV2.masked_equal(out,1.e20) out=MV2.reshape(out,sh) out.id='equiv_msu' out.setAxisList(ax) return out
def linearInterpolation(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000], status=None): """ Linear interpolation to interpolate a field from some levels to another set of levels Value below "surface" are masked Input A : array to interpolate I : interpolation field (usually Pressure or depth) from TOP (level 0) to BOTTOM (last level), i.e P value going up with each level levels : levels to interplate to (same units as I), default levels are:[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000] I and levels must have same units Output array on new levels (levels) Examples: A=interpolate(A,I,levels=[100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000, 10000, 7000, 5000, 3000, 2000, 1000]) """ try: nlev=len(levels) # Number of pressure levels except: nlev=1 # if only one level len(levels) would breaks levels=[levels,] order=A.getOrder() A=A(order='z...') I=I(order='z...') sh=list(I.shape) nsigma=sh[0] #number of sigma levels sh[0]=nlev t=MV2.zeros(sh,typecode=MV2.float32) sh2=I[0].shape prev=-1 for ilev in range(nlev): # loop through pressure levels if status is not None: prev=genutil.statusbar(ilev,nlev-1.,prev) lev=levels[ilev] # get value for the level Iabv=MV2.ones(sh2,MV2.float) Aabv=-1*Iabv # Array on sigma level Above Abel=-1*Iabv # Array on sigma level Below Ibel=-1*Iabv # Pressure on sigma level Below Iabv=-1*Iabv # Pressure on sigma level Above Ieq=MV2.masked_equal(Iabv,-1) # Area where Pressure == levels for i in range(1,nsigma): # loop from second sigma level to last one a = MV2.greater_equal(I[i], lev) # Where is the pressure greater than lev b = MV2.less_equal(I[i-1],lev) # Where is the pressure less than lev # Now looks if the pressure level is in between the 2 sigma levels # If yes, sets Iabv, Ibel and Aabv, Abel a=MV2.logical_and(a,b) Iabv=MV2.where(a,I[i],Iabv) # Pressure on sigma level Above Aabv=MV2.where(a,A[i],Aabv) # Array on sigma level Above Ibel=MV2.where(a,I[i-1],Ibel) # Pressure on sigma level Below Abel=MV2.where(a,A[i-1],Abel) # Array on sigma level Below Ieq= MV2.where(MV2.equal(I[i],lev),A[i],Ieq) val=MV2.masked_where(MV2.equal(Ibel,-1.),numpy.ones(Ibel.shape)*lev) # set to missing value if no data below lev if there is tl=(val-Ibel)/(Iabv-Ibel)*(Aabv-Abel)+Abel # Interpolation if ((Ieq.mask is None) or (Ieq.mask is MV22.nomask)): tl=Ieq else: tl=MV2.where(1-Ieq.mask,Ieq,tl) t[ilev]=tl.astype(MV2.float32) ax=A.getAxisList() autobnds=cdms2.getAutoBounds() cdms2.setAutoBounds('off') lvl=cdms2.createAxis(MV2.array(levels).filled()) cdms2.setAutoBounds(autobnds) try: lvl.units=I.units except: pass lvl.id='plev' try: t.units=I.units except: pass ax[0]=lvl t.setAxisList(ax) t.id=A.id for att in A.listattributes(): setattr(t,att,getattr(A,att)) return t(order=order)
# # Monthly transformation if os.path.exists(outFile): os.remove(outFile) outFile_f = cdm.open(outFile,'w') # Define dimensions N_i = int(tos.shape[2]) N_j = int(tos.shape[1]) N_t = int(tos.shape[0]) print ' ==> dimensions N_t, N_j, N_i:', N_t, N_j, N_i try: valmask = tos.missing_value if valmask == None: print 'EC-EARTH missing_value fix' valmask = 1.e20 sos = mv.masked_equal(sos,0.) print sos.count() sos.data[:] = sos.filled(valmask) tos.mask = sos.mask tos.data[:] = tos.filled(valmask) qnet.mask = sos.mask qnet.data[:] = qnet.filled(valmask) emp.mask = sos.mask emp.data[:] = emp.filled(valmask) except Exception,err: print 'Exception: ',err if 'EC-EARTH' == modeln: print 'EC-EARTH missing_value fix' valmask = 1.e20 sos = mv.masked_equal(sos,0.) print sos.count()
def __get(self): nfree=0 names=[] for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v=getattr(self,p) if v is None \ or \ (isinstance(v,(list,tuple)) and len(v)>1): already=0 for pn in names: if p==pn : already=1 elif isinstance(pn,list): if p in pn: already=1 if already==0: nfree+=1 added=0 for g in self.grouped: if p in g: names.append(g) added=1 if added==0: names.append(p) if nfree!=2: raise 'Error MUST end up with 2 multiple values ! (we have '+str(nfree)+':'+str(names)+')' # Now determines length of each axis axes_length=[1,1] # First make sure with have 2 list of parameters for i in range(2): if not isinstance(names[i],list): names[i]=[names[i]] for n in names[i]: v=getattr(self,n) if v is None: if n == 'component' : axes_length[i]*=28 elif n == 'time_domain': axes_length[i]*=19 else: raise 'Error, '+n+' is not defined correctly, please specify which values you wish to extract' else: axes_length[i]*=len(v) # Creates the dummy array output=MV2.ones((axes_length[0],axes_length[1])) # Now mask everywhere output=MV2.masked_equal(output,1) # Indices for filling i=0 j=0 # First creates the filler object and sets all the fixed values ! F=StringConstructor(self.files_structure) # Ok let's fill it for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v=getattr(self,p) if isinstance(v,(list,tuple)): if len(v)==1: v=v[0] if p in self.slaves.keys(): vslvs=v[1:] v=v[0] setattr(F,p,v) if p in self.slaves.keys(): slvs=self.slaves[p] for js in range(len(slvs)): s=slsvs[js] setattr(F,s,vslvs[js]) else: setattr(F,p,'*') else: if p in self.slaves.keys(): vslvs=v[1:] v=v[0] setattr(F,p,v) if p in self.slaves.keys(): slvs=self.slaves[p] for js in range(len(slvs)): s=slsvs[js] setattr(F,s,vslvs[js]) else: setattr(F,p,'*') #fnms=F() nms=names[0]+names[1] t1,t2,t3=self.string_construct(nms) output=output.ravel() sp1=t1.split() n=len(sp1) for i in range(len(t2)): sp2=t2[i].split() for j in range(n): v=sp2[j] if sp1[j]=='time_domain': try: v=int(v) except: pass if v == 'NONE': v='' setattr(F,sp1[j],v) #print 'Search string is:',fnms #f=os.popen('ls '+F()).readlines() #ip,op,ep=os.popen3('ls '+F()) if self.verbose : print 'command line:',F() #f=op.readlines() f=glob.glob(F()) #print 'F is:',f files=[] for file in f: files.append(file) for e in self.exclude: if file.find(e)>-1: files.pop(-1) break if self.verbose : print 'files:',files try: # now we get the one value needed in this file f=cdms2.open(files[0]) V=f[F.statistic] component=F.component time_domain=F.time_domain if isinstance(component,str): dic=eval(f.components) for k in dic.keys(): if dic[k]==F.component: component=k if isinstance(F.time_domain,str): dic=eval(f.time_domain) for k in dic.keys(): if dic[k]==F.time_domain: time_domain=k value=V(time_domain=time_domain,component=component,squeeze=1) output[i]=value # In case sometihng goes wrong (like modle not processed or inexsitant for this var, etc...) f.close() except Exception,err: #print 'Error:',err pass
print " regridded_var_slice(%s:%s): %s " % (self.dataset.id, varName, str(args1)) regridded_var_slice = vc.get(returnTuple=0) # if (referenceLev <> None) and ( referenceLev.shape[0] <> currentLevel.shape[0] ): # regridded_var_slice = regridded_var_slice.pressureRegrid( referenceLev ) args2 = {'order': order, 'squeeze': 1} if levBounds <> None: args2['lev'] = levBounds[0] if (len(levBounds) == 1) else levBounds else: levBounds = self.getLevBounds(currentLevel) if levBounds: args2['lev'] = levBounds rv = regridded_var_slice(**args2) try: rv = MV2.masked_equal(rv, rv.fill_value) except: pass # max_values = [ regridded_var_slice.max(), rv.max() ] # print " Regrid variable %s: max values = %s " % ( varName, str(max_values) ) end_t = time.time() # self.cachedFileVariables[ varName ] = ( timeValue, rv ) # print "Reading variable %s, shape = %s, base shape = %s, args = %s" % ( varName, str(rv.shape), str(varData.shape), str(args1) ) # except Exception, err: # print>>sys.stderr, ' Exception getting var slice: %s ' % str( err ) return rv # def init( self, timeRange, roi, zscale ): # self.timeRange = timeRange
def __get(self): nfree = 0 names = [] for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if v is None \ or \ (isinstance(v,(list,tuple)) and len(v)>1): already = 0 for pn in names: if p == pn: already = 1 elif isinstance(pn, list): if p in pn: already = 1 if already == 0: nfree += 1 added = 0 for g in self.grouped: if p in g: names.append(g) added = 1 if added == 0: names.append(p) if nfree != 2: raise 'Error MUST end up with 2 multiple values ! (we have ' + str( nfree) + ':' + str(names) + ')' # Now determines length of each axis axes_length = [1, 1] # First make sure with have 2 list of parameters for i in range(2): if not isinstance(names[i], list): names[i] = [names[i]] for n in names[i]: v = getattr(self, n) if v is None: if n == 'component': axes_length[i] *= 28 elif n == 'time_domain': axes_length[i] *= 19 else: raise 'Error, ' + n + ' is not defined correctly, please specify which values you wish to extract' else: axes_length[i] *= len(v) # Creates the dummy array output = MV2.ones((axes_length[0], axes_length[1])) # Now mask everywhere output = MV2.masked_equal(output, 1) # Indices for filling i = 0 j = 0 # First creates the filler object and sets all the fixed values ! F = StringConstructor(self.files_structure) # Ok let's fill it for p in self.parameters_list: if not p in self.dummies and not p in self.auto_dummies: v = getattr(self, p) if isinstance(v, (list, tuple)): if len(v) == 1: v = v[0] if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') else: if p in self.slaves.keys(): vslvs = v[1:] v = v[0] setattr(F, p, v) if p in self.slaves.keys(): slvs = self.slaves[p] for js in range(len(slvs)): s = slsvs[js] setattr(F, s, vslvs[js]) else: setattr(F, p, '*') #fnms=F() nms = names[0] + names[1] t1, t2, t3 = self.string_construct(nms) output = output.ravel() sp1 = t1.split() n = len(sp1) for i in range(len(t2)): sp2 = t2[i].split() for j in range(n): v = sp2[j] if sp1[j] == 'time_domain': try: v = int(v) except: pass if v == 'NONE': v = '' setattr(F, sp1[j], v) #print 'Search string is:',fnms #f=os.popen('ls '+F()).readlines() #ip,op,ep=os.popen3('ls '+F()) if self.verbose: print 'command line:', F() #f=op.readlines() f = glob.glob(F()) #print 'F is:',f files = [] for file in f: files.append(file) for e in self.exclude: if file.find(e) > -1: files.pop(-1) break if self.verbose: print 'files:', files try: # now we get the one value needed in this file f = cdms2.open(files[0]) V = f[F.statistic] component = F.component time_domain = F.time_domain if isinstance(component, str): dic = eval(f.components) for k in dic.keys(): if dic[k] == F.component: component = k if isinstance(F.time_domain, str): dic = eval(f.time_domain) for k in dic.keys(): if dic[k] == F.time_domain: time_domain = k value = V(time_domain=time_domain, component=component, squeeze=1) output[i] = value # In case sometihng goes wrong (like modle not processed or inexsitant for this var, etc...) f.close() except Exception, err: #print 'Error:',err pass
lat = cdms2.createAxis(lat, id='latitude') lon = numpy.arange(-179.5, 180) lon = cdms2.createAxis(lon, id='longitude') data = cdms2.createVariable(a, id='dummy') data.setAxisList([lat, lon]) del a print "slice of input data " d = data[0:11, 2:9] print d #print d.getLatitude(), d.getLongitude(), d.mask condition = MV2.masked_equal(data, 0) dic = getAreaOfAllClosedDomains(data, condition, update_mask=0) print "dictionary", dic latlon = dic['region2']['blatlons'] lat, lon = zip(*latlon) print data[0:11, 2:9] sd = irregularClosedRegionSelector(data, latitude=lat, longitude=lon, overwrite=1, condition=condition) print "Extracted irregular Selector data" print sd