Ejemplo n.º 1
0
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]
Ejemplo n.º 2
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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
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
        #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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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