Beispiel #1
0
def from_era(ident, alt=0, lon=0, lat=0, savename='extract_ERA', verbose=0):
    """ Updated Version of profiles and surface
    # Can read ERA data from retrieved and converted MARS Requests

    ERADIR

    Parameters
    ----------
    ident       str/int/float   Radiosonde ID
    alt         int/float       Radiosonde Station Altitude
    lon         int/float       Radiosonde Station Longitude
    lat         int/float       Radiosonde Station Latitude
    savename    str             Extract savename
    verbose     int             verboseness

    Returns
    -------

    """
    from raso.support import print_verbose, panel_to_database
    from raso.met.conversion import sh2ppmv, sh2vap, bolton_inverse, vap2sh
    from raso.met.esat_functions import foeewm
    from raso.config import rasodir # eradir
    from raso.qc import profile_limits
    # read new era file
    if isinstance(ident, (int, float)):
        ident = "%06d" % ident

    filename = rasodir + "/%s/%s.h5" % (ident, savename)

    cnames = ['t2m', 'q2m', 'msl', 'u10', 'v10', 'fetch', 'skt', 'FASTEM_1', 'FASTEM_2', 'FASTEM_3',
              'FASTEM_4', 'FASTEM_5', 'surf_type', 'water_type', 'elev', 'lat', 'lon', 'sat_zen', 'sat_azi',
              'sol_zen', 'sol_azi', 'cltp', 'clf']

    surface = {}  # pd.DataFrame(columns=cnames)
    era = {}
    if not os.path.isfile(filename):
        raise IOError('File not found: %s' % filename)

    with pd.HDFStore(filename, 'r') as store:
        for ikey in store.keys():
            iname = ikey.replace('/', '')
            if ikey[1:] in ['t', 'q', 'o3']:
                # profile data
                tmp = store[ikey]
                tmp.index.name = 'date'
                tmp.columns.name = 'p'
                # tmp = tmp.reset_index().drop_duplicates('date').set_index('date')  # remove duplicates
                era[iname] = tmp  # DataFrame (time x p)

            else:
                # surface data
                if iname == 'sp':
                    surface['msl'] = store[ikey][0] / 100.  # [dates] / 100.  # hPa

                elif iname == 'ci':
                    # sea ice cover
                    surface['surf_type'] = store[ikey][0]

                elif iname == 'u10':
                    surface['u10'] = store[ikey][0]

                elif iname == 'v10':
                    surface['v10'] = store[ikey][0]

                else:
                    surface[iname] = store[ikey][0]

    era = pd.Panel(era)
    era = panel_to_database(era, remove=False)
    # ERA can have negative Q values !?
    qerror = era.query('q<=0').q.count()
    print_verbose("[%s] Found %d negative Q-values!" % (ident, qerror), verbose)
    # Interpolate limits
    rt = profile_limits(tohpa=True, simple_names=True)
    rt['qmin'] = vap2sh(rt.vpmin.values, rt.p.values)  # both missing hPa factor
    qmins = np.interp(np.log(era.p.values), np.log(rt.p.values*100.), rt.qmin.values, left=rt.qmin.min(), right=rt.qmin.max())  # Interpolate Minimum Q
    era['q'] = np.where(era.q < qmins, qmins, era.q)  # replace with RTTOV limit
    # Make a dataframe
    surface = pd.DataFrame(surface)
    surface['q2m'] = sh2ppmv(era.query('p==100000')['q'], 100000.)  # ppmv
    surface['fetch'] = 100000.  # m
    # FASTEM Surface model Parameters:
    surface['FASTEM_1'] = 3.0
    surface['FASTEM_2'] = 5.0
    surface['FASTEM_3'] = 15.0
    surface['FASTEM_4'] = 0.1
    surface['FASTEM_5'] = 0.3
    # surface properties
    if 'surf_type' in surface.columns:
        if surface['surf_type'].isnull().any(0):
            if surface['surf_type'].count() > 0:
                surface['surf_type'].fillna(method='bfill')  # backwards fill
                surface['surf_type'].fillna(method='ffill')  # forward fill

            else:
                surface['surf_type'] = 0.  # surface type (0=land, 1=sea, 2=sea-ice)

    else:
        surface['surf_type'] = 0.  # surface type (0=land, 1=sea, 2=sea-ice)

    surface['water_type'] = 0.  # water type (0=fresh, 1=ocean)
    surface['elev'] = alt / 1000.  # ELEVATION km
    surface['lat'] = lat  # LAT
    surface['lon'] = lon  # LON
    surface['sat_azi'] = 0.  # Satellite Azimuth Angle
    surface['sat_zen'] = 53.1  # OSCAR , SSMIS
    surface['sol_zen'] = 0.  # Solar Zenith Angle
    surface['sol_azi'] = 0.  # Solar Azimuth Angle
    surface['cltp'] = 500.  # Cloud top pressure
    surface['clf'] = 0.  # Cloud fraction

    # right order
    surface = surface[cnames].copy()

    # CONVERT TO WATER VAPOR PRESSURE in Pa
    era['vp'] = sh2vap(era['q'], era['p'])  # formula
    era['td'] = bolton_inverse(era.vp.values)  # default method from Murphy and Koop (iterative)
    logic = era['td'] > era['t']  # impossible
    era.loc[:, 'td'] = np.where(logic, era['t'].values, era['td'].values)
    era.loc[:, 'vp'] = np.where(logic, foeewm(era['t'].values), era['vp'].values)  # ? fixes some problems ?
    return surface, era