def getbounds(ifile, dimkey): dim = ifile.dimensions[dimkey] dimboundkey = dimkey + '_bounds' dimbndkey = dimkey + '_bnds' if dimboundkey in ifile.variables: db = ifile.variables[dimboundkey] elif dimbndkey in ifile.variables: db = ifile.variables[dimbndkey] elif dimkey in ifile.variables: d = ifile.variables[dimkey] dd = np.diff(d) ddm = dd.mean() if not (ddm == dd).all(): warn('Bounds is an approximation assuming ' + '%s variable is cell centers' % dimkey) db = (d[:-1] + d[1:]) / 2. db = np.append(np.append(d[0] - dd[0] / 2., db), d[-1] + dd[-1] / 2) return db else: return np.arange(0, len(dim) + 1) if len(dim) == db.shape[0] and db.shape[1] == 2: return np.append(db[:, 0], db[-1, 1]) elif db.ndim == 1: return db else: return db[:, 0]
def getlatbnds(ifile): if 'latitude_bounds' in ifile.variables: latb = ifile.variables['latitude_bounds'] unit = latb.units.strip() if 'nv' in latb.dimensions: if latb[:].ndim == 2 and len(ifile.dimensions['nv']) == 2: latb = np.append(latb[:][:, 0], latb[:][-1, 1]) elif latb[:].ndim == 2 and len(ifile.dimensions['nv']) == 4: latb = np.append(latb[:][:, 0], latb[:][-1, 1]) elif latb.ndim == 3: latb = latb[:, :, 0] elif 'latitude' in ifile.variables: latb = ifile.variables['latitude'] unit = latb.units.strip() latb = latb[:] latdiff = np.diff(latb, axis=0) if not (latdiff == latdiff[[0]]).all(): warn('Latitude bounds are approximate') latb = np.apply_along_axis(np.convolve, 0, latb, [0.5, 0.5]) latb[0] *= 2 latb[-1] *= 2 if latb.ndim == 2: latb = np.append(latb, latb[:, [-1]], axis=1) elif 'ROW' in ifile.dimensions: unit = 'x (m)' latb = (np.arange(len(ifile.dimensions['ROW']) + 1) * getattr(ifile, 'YCELL', 1) / 1000.) else: raise KeyError('latitude bounds not found') return latb, unit
def getsigmabnds(ifile): if hasattr(ifile, 'VGLVLS'): return ifile.VGLVLS[:] elif 'etai_pressure' in ifile.variables: etai_pressure = ifile.variables['etai_pressure'] return ((etai_pressure - etai_pressure[-1]) / (etai_pressure[0] - etai_pressure[-1])) elif 'layer_bounds' in ifile.variables: lay = ifile.variables['layer_bounds'] if lay.units.strip() in ('Pa', 'hPa'): sigma = (lay[:] - lay[-1]) / (lay[0] - lay[-1]) return sigma else: warn("Unknown tranform of layer to sigma; " + "sigma units %s" % lay.units) return lay else: warn("Unknown vertical coordinate") if hasattr(ifile, 'NLAYS'): nlays = ifile.NLAYS elif 'LAY' in ifile.dimensions: nlays = len(ifile.dimensions['LAY']) elif 'lev' in ifile.dimensions: nlays = len(ifile.dimensions['lev']) elif 'layer' in ifile.dimensions: nlays = len(ifile.dimensions['layer']) else: nlays = 1 return np.arange(nlays)
def getsigmabnds(ifile): if hasattr(ifile, 'VGLVLS'): return ifile.VGLVLS[:] elif 'etai_pressure' in ifile.variables: etai_pressure = ifile.variables['etai_pressure'] return (etai_pressure - etai_pressure[-1]) / (etai_pressure[0] - etai_pressure[-1]) elif 'layer_bounds' in ifile.variables: lay = ifile.variables['layer_bounds'] if lay.units.strip() in ('Pa', 'hPa'): sigma = (lay[:] -lay[-1]) / (lay[0] - lay[-1]) return sigma else: warn("Unknown tranform of layer to sigma; sigma units %s" % lay.units) return lay else: warn("Unknown vertical coordinate") if hasattr(ifile, 'NLAYS'): nlays = ifile.NLAYS elif 'LAY' in ifile.dimensions: nlays = len(ifile.dimensions['LAY']) elif 'lev' in ifile.dimensions: nlays = len(ifile.dimensions['lev']) elif 'layer' in ifile.dimensions: nlays = len(ifile.dimensions['layer']) else: nlays = 1 return np.arange(nlays)
def getlonbnds(ifile): if 'longitude_bounds' in ifile.variables: lonb = ifile.variables['longitude_bounds'] unit = lonb.units.strip() if 'nv' in lonb.dimensions: if lonb[:].ndim == 2 and len(ifile.dimensions['nv']) == 2: lonb = np.append(lonb[:][:, 0], lonb[:][-1, 1]) elif lonb[:].ndim == 3: lonb = lonb[:][:, :, 0] elif 'longitude' in ifile.variables: lonb = ifile.variables['longitude'] unit = lonb.units.strip() lonb = lonb[:] if lonb.ndim > 1: londiff = np.diff(lonb, axis = 1) alldiffsame = (londiff == londiff[:, [0]]).all() elif lonb.ndim == 1: alldiffsame = True londiff = np.diff(lonb) else: raise ValueError("Cannot infer longitude bounds when dimensions >2") if not alldiffsame: londiff = np.diff(lonb, axis = 1) if not (londiff == londiff[:, [0]]).all(): warn('Longitude bounds are approximate') lonb = np.concatenate([lonb, lonb[:, [-1]]], axis = 1) - .5 * np.concatenate([londiff[:, :], londiff[:, [-1]], -londiff[:, [-1]]], axis = 1) lonb = np.append(lonb, lonb[[-1], :], axis = 0) else: londiff = np.diff(lonb, axis = 0) lonb = np.concatenate([lonb, lonb[[-1]]], axis = 0) - .5 * np.concatenate([londiff[:], londiff[[-1]], -londiff[[-1]]], axis = 0) else: raise KeyError('longitude bounds not found') return lonb, unit
def getlatbnds(ifile): if 'latitude_bounds' in ifile.variables: latb = ifile.variables['latitude_bounds'] unit = latb.units.strip() if 'nv' in latb.dimensions: if latb[:].ndim == 2 and len(ifile.dimensions['nv']) == 2: latb = np.append(latb[:][:, 0], latb[:][-1, 1]) elif latb[:].ndim == 2 and len(ifile.dimensions['nv']) == 4: latb = np.append(latb[:][:, 0], latb[:][-1, 1]) elif latb.ndim == 3: latb = latb[:, :, 0] elif 'latitude' in ifile.variables: latb = ifile.variables['latitude'] unit = latb.units.strip() latb = latb[:] latdiff = np.diff(latb, axis = 0) if not (latdiff == latdiff[[0]]).all(): warn('Latitude bounds are approximate') latb = np.apply_along_axis(np.convolve, 0, latb, [0.5, 0.5]) latb[0] *= 2 latb[-1] *= 2 #latb = np.concatenate([latb, latb[[-1]]], axis = 0) - .5 * np.concatenate([latdiff[:], latdiff[[-1]], -latdiff[[-1]]], axis = 0) #latb = np.minimum(90, latb) #latb = np.maximum(-90, latb) if latb.ndim == 2: latb = np.append(latb, latb[:, [-1]], axis = 1) elif 'ROW' in ifile.dimensions: unit = 'x (m)' latb = np.arange(len(ifile.dimensions['ROW']) + 1) * getattr(ifile, 'YCELL', 1) / 1000. else: raise KeyError('latitude bounds not found') return latb, unit
def getproj4_from_cf_var(gridmapping, withgrid=False): mapstr_bits = OrderedDict() gname = getattr(gridmapping, 'grid_mapping_name') pv4s = dict(lambert_conformal_conic='lcc', rotated_latitude_longitude='ob_tran', latitude_longitude='lonlat', transverse_mercator='tmerc', equatorial_mercator='merc', mercator='merc', polar_stereographic='stere') pv4name = pv4s[gname] for pk in gridmapping.ncattrs(): pv = getattr(gridmapping, pk) if pk == 'grid_mapping_name': pv4 = pv4s[pv] mapstr_bits['proj'] = pv4 if pv == 'rotated_latitude_longitude': mapstr_bits['o_proj'] = 'eqc' elif pk == 'standard_parallel': if pv4name == 'stere': mapstr_bits['lat_ts'] = pv[0] else: mapstr_bits['lat_1'] = pv[0] if len(pv) > 1: mapstr_bits['lat_2'] = pv[1] elif pk == 'longitude_of_central_meridian': mapstr_bits['lon_0'] = pv elif pk == 'latitude_of_projection_origin': mapstr_bits['lat_0'] = pv elif pk == 'false_easting': mapstr_bits['x_0'] = pv elif pk == 'false_northing': mapstr_bits['y_0'] = pv elif pk == 'scale_factor_at_projection_origin': mapstr_bits['k_0'] = pv elif pk == 'earth_radius': mapstr_bits['a'] = pv mapstr_bits['b'] = pv elif pk == 'semi_major_axis': mapstr_bits['a'] = pv elif pk == 'semi_minor_axis': mapstr_bits['b'] = pv elif pk == 'inverse_flattening': mapstr_bits['f'] = 1 / pv elif pk == 'grid_north_pole_latitude': mapstr_bits['o_lat_p'] = pv elif pk == 'grid_north_pole_longitude': mapstr_bits['lon_0'] = pv else: warn('Currently not using:' + str(pk) + ' ' + str(pv)) # repr is required to prevent rounding of numpy array values mapstr = ' '.join([ '+%s=%s' % (k, v if isinstance(v, str) else repr(v)) for k, v in mapstr_bits.items() ]) return mapstr
def getpresbnds(ifile, pref=101325., ptop=None): if 'etai_pressure' in ifile.variables: return ifile.variables['etai_pressure'][:] elif 'layer_bounds' in ifile.variables: return ifile.variables['layer_bounds'][:] else: sigma = getsigmabnds(ifile) if ptop is None: if hasattr(ifile, 'VGTOP'): ptop = ifile.VGTOP else: warn("Assuming VGTOP = 10000 Pa") ptop = 10000 return pres_from_sigma(sigma, pref=pref, ptop=ptop)
def getpresbnds(ifile, pref = 101325., ptop = None): if 'etai_pressure' in ifile.variables: return ifile.variables['etai_pressure'][:] elif 'layer_bounds' in ifile.variables: return ifile.variables['layer_bounds'][:] else: sigma = getsigmabnds(ifile) if ptop is None: if hasattr(ifile, 'VGTOP'): ptop = ifile.VGTOP else: warn("Assuming VGTOP = 10000 Pa") ptop = 10000 return pres_from_sigma(sigma, pref = pref, ptop = ptop)
def getproj4(ifile, withgrid=False): """ Arguments: ifile - PseudoNetCDF file withgrid - True to include gridding parameters Returns: proj4str - string with proj4 parameters """ from .conventions.ioapi import getmapdef if (getattr(ifile, 'GDTYP', 0) in (1, 2, 6, 7) and all([ hasattr(ifile, k) for k in 'P_GAM P_ALP P_BET XORIG YORIG XCELL YCELL'.split() ])): gridmapping = getmapdef(ifile, add=False) mapstr = getproj4_from_cf_var(gridmapping, withgrid=withgrid) if withgrid: mapstr += ' +to_meter=%s' % ifile.XCELL elif (getattr(ifile, 'Conventions', getattr(ifile, 'CONVENTIONS', ''))[:2].upper() == 'CF'): gridmappings = [] for k, v in ifile.variables.items(): if hasattr(v, 'grid_mapping'): gridmappings.append(getattr(v, 'grid_mapping')) if len(gridmappings) == 0: warn('No known grid mapping; assuming lonlat') mapstr = '+proj=lonlat' else: gridmappings = list(set(gridmappings)) if len(gridmappings) > 1: warn('Using first grid mapping of ' + str(gridmappings)) if not gridmappings[0] in ifile.variables: warn(gridmappings[0] + ' could not be found; assuming lonlat') mapstr = '+proj=lonlat' else: gridmapping = ifile.variables[gridmappings[0]] mapstr = getproj4_from_cf_var(gridmapping, withgrid=withgrid) else: warn('No known grid mapping; assuming lonlat') mapstr = '+proj=lonlat' mapstr += ' +no_defs' return mapstr
def getproj4(ifile, withgrid=False): """ Arguments: ifile - PseudoNetCDF file withgrid - True to include gridding parameters Returns: proj4str - string with proj4 parameters """ from .conventions.ioapi import get_ioapi_sphere if getattr(ifile, 'GDTYP', 0) in (2, 7) and all([ hasattr(ifile, k) for k in 'P_GAM P_ALP P_BET XORIG YORIG XCELL YCELL'.split() ]): semi_major_axis, semi_minor_axis = get_ioapi_sphere() if ifile.GDTYP == 2: mapstr = '+proj=lcc +a=%s +b=%s +lon_0=%s +lat_1=%s +lat_2=%s +lat_0=%s' % ( semi_major_axis, semi_minor_axis, ifile.P_GAM, ifile.P_ALP, ifile.P_BET, ifile.YCENT) elif ifile.GDTYP == 7: mapstr = '+proj=merc +a=%s +b=%s +lat_ts=0 +lon_0=%s' % ( semi_major_axis, semi_minor_axis, ifile.XCENT) if withgrid: mapstr += ' +x_0=%s +y_0=%s +to_meter=%sm' % ( -ifile.XORIG, -ifile.YORIG, ifile.XCELL) elif getattr(ifile, 'Conventions', getattr(ifile, 'CONVENTIONS', ''))[:2].upper() == 'CF': gridmappings = [] for k, v in ifile.variables.items(): if hasattr(v, 'grid_mapping'): gridmappings.append(getattr(v, 'grid_mapping')) if len(gridmappings) == 0: warn('No known grid mapping; assuming lonlat') mapstr = '+proj=lonlat' else: gridmappings = list(set(gridmappings)) if len(gridmappings) > 1: warn('Using first grid mapping of ' + str(gridmappings)) if not gridmappings[0] in ifile.variables: warn(gridmappings[0] + ' could not be found; assuming lonlat') mapstr = '+proj=lonlat' else: gridmapping = ifile.variables[gridmappings[0]] mapstr = getproj4_from_cf_var(gridmapping, withgrid=withgrid) mapstr += ' +no_defs' return mapstr
def getproj4(ifile, withgrid=False): """ Arguments: ifile - PseudoNetCDF file withgrid - True to include gridding parameters Returns: proj4str - string with proj4 parameters """ from .conventions.ioapi import getmapdef if (getattr(ifile, 'GDTYP', 0) in (1, 2, 6, 7) and all([ hasattr(ifile, k) for k in 'P_GAM P_ALP P_BET XORIG YORIG XCELL YCELL'.split() ])): gridmapping = getmapdef(ifile, add=False) mapstr = getproj4_from_cf_var(gridmapping, withgrid=withgrid) if withgrid: dx = min(ifile.XCELL, ifile.YCELL) if ifile.XCELL != ifile.YCELL: warn('Grid is not regular: using minimum {}'.format(dx)) if gridmapping.grid_mapping_name == 'latitude_longitude': er = min(gridmapping.semi_minor_axis, gridmapping.semi_major_axis) if (gridmapping.semi_minor_axis != gridmapping.semi_major_axis): warn('Earth not a perfect sphere: using minimum ' + '{}'.format(er)) mapstr += ' +to_meter=%s' % (np.radians(1) * er * dx) else: mapstr += ' +to_meter=%s' % ifile.XCELL elif (getattr(ifile, 'Conventions', getattr(ifile, 'CONVENTIONS', ''))[:2].upper() == 'CF'): gridmappings = [] for k, v in ifile.variables.items(): if hasattr(v, 'grid_mapping'): gridmappings.append(getattr(v, 'grid_mapping')) if len(gridmappings) == 0: warn('No known grid mapping; assuming lonlat') mapstr = '+proj=lonlat' else: gridmappings = list(set(gridmappings)) if len(gridmappings) > 1: warn('Using first grid mapping of ' + str(gridmappings)) if not gridmappings[0] in ifile.variables: warn(gridmappings[0] + ' could not be found; assuming lonlat') mapstr = '+proj=lonlat' else: gridmapping = ifile.variables[gridmappings[0]] mapstr = getproj4_from_cf_var(gridmapping, withgrid=withgrid) else: warn('No known grid mapping; assuming lonlat') mapstr = '+proj=lonlat' mapstr += ' +no_defs' return mapstr