def maskin(data, mask, x=None, y=None): """ Maskin data by polygons - NaN values of elements inside polygons. :param data: (*array_like*) Array data for maskout. :param mask: (*list*) Polygon list as maskin borders. :param x: (*array_like*) X coordinate array. :param y: (*array_like*) Y coordinate array. :returns: (*array_like*) Maskined data array. """ if mask is None: return data elif isinstance(mask, MIArray): r = ArrayMath.maskin(data.array, mask.array) if isinstance(data, DimArray): return DimArray(r, data.dims, data.fill_value, data.proj) else: return MIArray(r) if x is None or y is None: if isinstance(data, DimArray): x = data.dimvalue(data.ndim - 1) y = data.dimvalue(data.ndim - 2) else: return None if not isinstance(mask, (list, ArrayList)): mask = [mask] r = ArrayMath.maskin(data.array, x.array, y.array, mask) if isinstance(data, DimArray): return DimArray(r, data.dims, data.fill_value, data.proj) else: return MIArray(r)
def qair2rh(qair, temp, press=1013.25): """ Specific humidity to relative humidity qair: DimArray or MIArray or number Specific humidity - dimensionless (e.g. kg/kg) ratio of water mass / total air mass temp: DimArray or MIArray or number Temperature - degree c press: DimArray or MIArray or number Pressure - hPa (mb) return: DimArray or MIArray or number Relative humidity - % """ if isinstance(press, MIArray) or isinstance(press, DimArray): p = press.asarray() else: p = press if isinstance(qair, MIArray): return MIArray(ArrayMath.qair2rh(qair.asarray(), temp.asarray(), p)) elif isinstance(qair, DimArray): return DimArray( MIArray(ArrayMath.qair2rh(qair.asarray(), temp.asarray(), p)), qair.dims, qair.fill_value, qair.proj) else: return MeteoMath.qair2rh(qair, temp, press)
def get_slp(wrfin, timeidx=0, units='hPa'): ''' Return the sea level pressure in the specified units. This function extracts the necessary variables from the NetCDF file object in order to perform the calculation. :param wrfin: (*DimDataFile*) Data file. :param timeidx: (*int*) Time index. :param units: (*string*) The desired units. :returns: (*array*) Sea level pressure. ''' t = wrfin['T'][timeidx, :, :, :] p = wrfin['P'][timeidx, :, :, :] pb = wrfin['PB'][timeidx, :, :, :] qvapor = wrfin['QVAPOR'][timeidx, :, :, :] ph = wrfin['PH'][timeidx, :, :, :] phb = wrfin['PHB'][timeidx, :, :, :] full_t = t + constants.T_BASE full_p = p + pb qvapor[qvapor < 0] = 0. full_ph = (ph + phb) / constants.g destag_ph = destagger(full_ph, -3) tk = meteo.temperature_from_potential_temperature(full_p * 0.01, full_t) slp = MeteoMath.calSeaPrs(destag_ph.array, tk.array, full_p.array, qvapor.array) return DimArray(slp, dims=t.dims[1:])
def ds2uv(d, s): ''' Calculate U/V from wind direction and wind speed. :param d: (*array_like*) Wind direction. :param s: (*array_like*) Wind speed. :returns: Wind U/V. ''' if isinstance(d, MIArray): r = ArrayMath.ds2uv(d.asarray(), s.asarray()) u = MIArray(r[0]) v = MIArray(r[1]) if isinstance(d, DimArray) and isinstance(s, DimArray): u = DimArray(u, d.dims, d.fill_value, d.proj) v = DimArray(v, d.dims, d.fill_value, d.proj) return u, v else: r = ArrayMath.ds2uv(d, s) return r[0], r[1]
def uv2ds(u, v): ''' Calculate wind direction and wind speed from U/V. :param u: (*array_like*) U component of wind field. :param v: (*array_like*) V component of wind field. :returns: Wind direction and wind speed. ''' if isinstance(u, MIArray): r = ArrayMath.uv2ds(u.asarray(), v.asarray()) d = MIArray(r[0]) s = MIArray(r[1]) if isinstance(u, DimArray) and isinstance(v, DimArray): d = DimArray(d, u.dims, u.fill_value, u.proj) s = DimArray(s, u.dims, u.fill_value, u.proj) return d, s else: r = ArrayMath.uv2ds(u, v) return r[0], r[1]
def h2p(height): """ Height to pressure :param height: (*float*) Height - meter. :returns: (*float*) Pressure - hPa. """ if isinstance(height, MIArray): return MIArray(ArrayMath.height2Press(height.asarray())) elif isinstance(height, DimArray): return DimArray(MIArray(ArrayMath.height2Press(height.asarray())), height.dims, height.fill_value, height.proj) else: return MeteoMath.height2Press(height)
def p2h(press): """ Pressure to height :param press: (*float*) Pressure - hPa. :returns: (*float*) Height - meter. """ if isinstance(press, MIArray): return MIArray(ArrayMath.press2Height(press.asarray())) elif isinstance(press, DimArray): return DimArray(MIArray(ArrayMath.press2Height(press.asarray())), press.dims, press.fill_value, press.proj) else: return MeteoMath.press2Height(press)
def tc2tf(tc): """ Celsius temperature to Fahrenheit temperature tc: DimArray or MIArray or number Celsius temperature - degree c return: DimArray or MIArray or number Fahrenheit temperature - degree f """ if isinstance(tc, MIArray): return MIArray(ArrayMath.tc2tf(tc.asarray())) elif isinstance(tc, DimArray): return DimArray(MIArray(ArrayMath.tc2tf(tc.asarray())), tc.dims, tc.fill_value, tc.proj) else: return MeteoMath.tc2tf(tc)
def tf2tc(tf): """ Fahrenheit temperature to Celsius temperature tf: DimArray or MIArray or number Fahrenheit temperature - degree f return: DimArray or MIArray or number Celsius temperature - degree c """ if isinstance(tf, MIArray): return MIArray(ArrayMath.tf2tc(tf.asarray())) elif isinstance(tf, DimArray): return DimArray(MIArray(ArrayMath.tf2tc(tf.asarray())), tf.dims, tf.fill_value, tf.proj) else: return MeteoMath.tf2tc(tf)
def dewpoint2rh(dewpoint, temp): """ Dew point to relative humidity dewpoint: DimArray or MIArray or number Dew point - degree c temp: DimArray or MIArray or number Temperature - degree c return: DimArray or MIArray or number Relative humidity - % """ if isinstance(dewpoint, MIArray): return MIArray(ArrayMath.dewpoint2rh(dewpoint.asarray(), temp.asarray())) elif isinstance(dewpoint, DimArray): return DimArray(MIArray(ArrayMath.dewpoint2rh(dewpoint.asarray(), temp.asarray())), dewpoint.dims, dewpoint.fill_value, dewpoint.proj) else: return MeteoMath.dewpoint2rh(temp, dewpoint)
def rh2dewpoint(rh, temp): """ Calculate dewpoint from relative humidity and temperature rh: DimArray or MIArray or number Relative humidity - % temp: DimArray or MIArray or number Temperature - degree c return: DimArray or MIArray or number Relative humidity - % """ if isinstance(rh, MIArray): r = MIArray(MeteoMath.rh2dewpoint(rh.asarray(), temp.asarray())) if isinstance(rh, DimArray): r = DimArray(r, rh.dims, rh.fill_value, rh.proj) return r else: return MeteoMath.rh2dewpoint(rh, temp)
def __getitem__(self, indices): if isinstance(indices, slice): k = indices if k.start is None and k.stop is None and k.step is None: r = self.dataset.dataset.read(self.name) return DimArray(r, self.dims, self.fill_value, self.proj) if isinstance(indices, tuple): allnone = True for k in indices: if isinstance(k, slice): if (not k.start is None) or (not k.stop is None) or (not k.step is None): allnone = False break else: allnone = False break if allnone: r = self.dataset.dataset.read(self.name) return DimArray(r, self.dims, self.fill_value, self.proj) if indices is None: inds = [] for i in range(self.ndim): inds.append(slice(None)) indices = tuple(inds) if isinstance(indices, str): #metadata rr = self.dataset.read(self.name) m = rr.findMember(indices) data = rr.getArray(0, m) return NDArray(data) if not isinstance(indices, tuple): inds = [] inds.append(indices) indices = inds if len(indices) != self.ndim: print 'indices must be ' + str(self.ndim) + ' dimensions!' return None if not self.proj is None and not self.proj.isLonLat(): xlim = None ylim = None xidx = -1 yidx = -1 for i in range(0, self.ndim): dim = self.dims[i] if dim.getDimType() == DimensionType.X: k = indices[i] if isinstance(k, basestring): xlims = k.split(':') if len(xlims) == 1: xlim = [float(xlims[0])] else: xlim = [float(xlims[0]), float(xlims[1])] xidx = i elif dim.getDimType() == DimensionType.Y: k = indices[i] if isinstance(k, basestring): ylims = k.split(':') if len(ylims) == 1: ylim = [float(ylims[0])] else: ylim = [float(ylims[0]), float(ylims[1])] yidx = i if not xlim is None and not ylim is None: fromproj=KnownCoordinateSystems.geographic.world.WGS1984 inpt = PointD(xlim[0], ylim[0]) outpt1 = Reproject.reprojectPoint(inpt, fromproj, self.proj) if len(xlim) == 1: xlim = [outpt1.X] ylim = [outpt1.Y] else: inpt = PointD(xlim[1], ylim[1]) outpt2 = Reproject.reprojectPoint(inpt, fromproj, self.proj) xlim = [outpt1.X, outpt2.X] ylim = [outpt1.Y, outpt2.Y] indices1 = [] for i in range(0, self.ndim): if i == xidx: if len(xlim) == 1: indices1.append(str(xlim[0])) else: indices1.append(str(xlim[0]) + ':' + str(xlim[1])) elif i == yidx: if len(ylim) == 1: indices1.append(str(ylim[0])) else: indices1.append(str(ylim[0]) + ':' + str(ylim[1])) else: indices1.append(indices[i]) indices = indices1 origin = [] size = [] stride = [] ranges = [] dims = [] flips = [] onlyrange = True for i in range(0, self.ndim): isrange = True dimlen = self.dimlen(i) k = indices[i] if isinstance(k, int): if k < 0: k = self.dims[i].getLength() + k sidx = k eidx = k step = 1 elif isinstance(k, slice): if isinstance(k.start, basestring): sv = float(k.start) sidx = self.dims[i].getValueIndex(sv) elif isinstance(k.start, datetime.datetime): sv = miutil.date2num(k.start) sidx = self.dims[i].getValueIndex(sv) else: sidx = 0 if k.start is None else k.start if sidx < 0: sidx = self.dimlen(i) + sidx if isinstance(k.stop, basestring): ev = float(k.stop) eidx = self.dims[i].getValueIndex(ev) elif isinstance(k.stop, datetime.datetime): ev = miutil.date2num(k.stop) eidx = self.dims[i].getValueIndex(ev) else: eidx = self.dimlen(i) if k.stop is None else k.stop if eidx < 0: eidx = self.dimlen(i) + eidx eidx -= 1 if isinstance(k.step, basestring): nv = float(k.step) + self.dims[i].getDimValue()[0] nidx = self.dims[i].getValueIndex(nv) step = nidx - sidx elif isinstance(k.step, datetime.timedelta): nv = miutil.date2num(k.start + k.step) nidx = self.dims[i].getValueIndex(nv) step = nidx - sidx else: step = 1 if k.step is None else k.step if sidx > eidx: iidx = eidx eidx = sidx sidx = iidx elif isinstance(k, list): onlyrange = False isrange = False if not isinstance(k[0], datetime.datetime): ranges.append(k) else: tlist = [] for tt in k: sv = miutil.date2num(tt) idx = self.dims[i].getValueIndex(sv) tlist.append(idx) ranges.append(tlist) k = tlist elif isinstance(k, basestring): dim = self.variable.getDimension(i) kvalues = k.split(':') sv = float(kvalues[0]) sidx = dim.getValueIndex(sv) if len(kvalues) == 1: eidx = sidx step = 1 else: ev = float(kvalues[1]) eidx = dim.getValueIndex(ev) if len(kvalues) == 2: step = 1 else: step = int(float(kvalues[2]) / dim.getDeltaValue()) if sidx > eidx: iidx = eidx eidx = sidx sidx = iidx else: print k return None if isrange: if eidx >= dimlen: print 'Index out of range!' return None origin.append(sidx) n = eidx - sidx + 1 size.append(n) if n > 1: dim = self.variable.getDimension(i) if dim.isReverse(): step = -step dim = dim.extract(sidx, eidx, step) dim.setReverse(False) dims.append(dim) stride.append(step) if step < 0: step = abs(step) flips.append(i) rr = Range(sidx, eidx, step) ranges.append(rr) else: if len(k) > 1: dim = self.variable.getDimension(i) dim = dim.extract(k) dim.setReverse(False) dims.append(dim) #rr = self.dataset.read(self.name, origin, size, stride).reduce() if onlyrange: rr = self.dataset.dataset.read(self.name, ranges) else: rr = self.dataset.dataset.take(self.name, ranges) if rr.getSize() == 1: return rr.getObject(0) else: for i in flips: rr = rr.flip(i) rr = rr.reduce() ArrayMath.missingToNaN(rr, self.fill_value) if len(flips) > 0: rrr = Array.factory(rr.getDataType(), rr.getShape()) MAMath.copy(rrr, rr) array = NDArray(rrr) else: array = NDArray(rr) data = DimArray(array, dims, self.fill_value, self.dataset.proj) return data
def __getitem__(self, indices): if len(indices) != self.ndim: print 'indices must be ' + str(self.ndim) + ' dimensions!' return None k = indices[0] if isinstance(k, int): sidx = k eidx = k step = 1 elif isinstance(k, slice): sidx = 0 if k.start is None else k.start if sidx < 0: sidx = self.tnum + sidx eidx = self.tnum if k.stop is None else k.stop if eidx < 0: eidx = self.tnum + eidx eidx -= 1 step = 1 if k.step is None else k.step elif isinstance(k, list): sidx = self.dataset.timeindex(k[0]) if len(k) == 1: eidx = sidx step = 1 else: eidx = self.dataset.timeindex(k[1]) if len(k) == 3: tt = self.dataset.timeindex(k[0] + k[3]) step = tt - sidx else: step = 1 sfidx = self.dataset.datafileindex(sidx) si = sidx isfirst = True times = [] fidx = sfidx aa = None var = None for i in range(sidx, eidx + 1, step): times.append(miutil.date2num(self.dataset.gettime(i))) fidx = self.dataset.datafileindex(i) if fidx > sfidx: ei = i - step ddf = self.dataset[sfidx] var = ddf[self.name] ii, ssi = self.dataset.dftindex(si) ii, eei = self.dataset.dftindex(ei) eei += 1 nindices = list(indices) nindices[0] = slice(ssi, eei, step) nindices = tuple(nindices) aa = var.__getitem__(nindices) if si == ei: aa.addtdim(self.dataset.gettime(si)) if isfirst: data = aa isfirst = False else: data = minum.concatenate([data, aa]) si = i sfidx = fidx if si < eidx + 1: ei = eidx + 1 - step ddf = self.dataset[sfidx] var = ddf[self.name] ii, ssi = self.dataset.dftindex(si) ii, eei = self.dataset.dftindex(ei) eei += 1 nindices = list(indices) nindices[0] = slice(ssi, eei, step) nindices = tuple(nindices) aa = var.__getitem__(nindices) if si == ei and eidx != sidx: aa.addtdim(self.dataset.gettime(si)) if isfirst: data = aa isfirst = False else: data = minum.concatenate([data, aa]) if aa is None: sfidx = self.dataset.datafileindex(sidx) ddf = self.dataset[sfidx] var = ddf[self.name] ii, ssi = self.dataset.dftindex(sidx) nindices = list(indices) nindices[0] = slice(ssi, ssi, step) nindices = tuple(nindices) aa = var.__getitem__(nindices) return aa if isinstance(data, DimArray): return data else: dims = aa.dims dims[0].setDimValues(times) r = DimArray(data, dims, aa.fill_value, aa.proj) return r