Example #1
0
def getLevs(dat, zmin=0, zmax=100000, convertPressureUnit=None):
    """
    TBD
    """
    from climaf.anynetcdf import ncf
    filename = cfile(dat)
    fileobj = ncf(filename)
    min_lev = zmin
    max_lev = zmax
    my_levs = None
    levname = None
    for varname in fileobj.variables:
        if varname.lower() in ['level', 'levels', 'lev', 'levs', 'depth', 'deptht',
                               'plev'] or 'plev' in varname.lower():
            levname = varname
    levunits = fileobj.variables[levname].units
    try:
        levValues = fileobj.variables[levname].getValue()
    except:
        levValues = fileobj[levname][0:len(fileobj[levname])]
    for lev in levValues:
        if min_lev <= lev <= max_lev:
            if convertPressureUnit:
                if convertPressureUnit == 'hPaToPa':
                    lev = lev * 100
                if convertPressureUnit == 'PaTohPa':
                    lev = lev / 100
            if my_levs:
                my_levs = my_levs + ',' + str(lev)
            else:
                my_levs = str(lev)
    return my_levs
Example #2
0
def whichORCAGrid(file):
    from climaf.anynetcdf import ncf
    fileobj=ncf(file)
    dims=fileobj.dimensions
    # -- First, scan and try to find y (or Y)
    dimY = None
    if 'y' in dims: dimY = 'y'
    if 'Y' in dims: dimY = 'Y'
    if dimY:
        y_size = dims[dimY].size
    else:
        return 'no y/Y dimension found in '+file
    #
    # -- Identify ORCA grid
    if y_size==149: return 'ORCA2'
    if y_size==292: return 'ORCA1'
    if y_size==332: return 'eORCA1'
Example #3
0
def lonlatvert_interpolation(dat1, dat2=None, vertical_levels=None, cdo_horizontal_grid='r1x90',
                             horizontal_regridding=True):
    """
    Interpolates a lon/lat/pres field dat1 via two possible ways:
    - either by providing a target lon/lat/pres field dat2 => dat1 is regridded both horizontally and vertically on dat2
    - or by providing a list of vertical levels => dat1 is regridded horizontally on the cdo_horizontal_grid
    (default='r1x90'), and vertically on the list of vertical levels
    The user can provide the vertical levels (in Pa) like this:
    vertical_levels=[100000,85000,50000,20000,...] # or
    vertical_levels='100000,85000,50000,20000'
    Before the computations, the function checks the unit of the vertical axis;
    it is converted to Pa if necessary directly in the netcdf file(s) corresponding to dat1(2).

       >>> dat = ds(project='CMIP5',model='IPSL-CM5A-LR',variable='ua',period='1980-1985',
                    experiment='historical',table='Amon')
       >>> ref = ds(project='ref_pcmdi',variable='ua',product='ERAINT')

       >>> zonmean_dat = zonmean(time_average(dat))
       >>> zonmean_ref = zonmean(time_average(ref))

       >>> dat_interpolated_on_ref = lonlatvert_interpolation(zonmean_dat,zonmean_ref)
       >>> dat_interpolated_on_list_of_levels = lonlatvert_interpolation(zonmean_dat,vertical_levels='100000,85000,50000,20000,10000,5000,2000,1000')

    """

    from climaf.anynetcdf import ncf
    from climaf import cachedir

    file1 = cfile(dat1)
    clogger.debug('file1 = %s' % file1)
    ncfile1 = ncf(file1)

    # -- First, we check the unit of the vertical dimension of file1
    levname1 = None
    for varname in ncfile1.variables:
        if varname.lower() in ['level', 'levels', 'lev', 'levs', 'depth', 'deptht',
                               'olevel'] or 'plev' in varname.lower():
            levname1 = varname
    if not levname1:
        clogger.debug('Name of the vertical axis not found for dat1')
    levunits1 = ncfile1.variables[levname1].units
    if levunits1.lower() in ['hpa', 'millibar', 'mbar', 'hectopascal']:
        # -- Multiplier par 100
        cscript('convert_plev_hPa_to_Pa',
                'ncap2 -As "' + levname1 + '=' + levname1 + '*100" ${in} ' + cachedir +
                '/convert_to_Pa_tmp.nc ; ncatted -O -a units,' + levname1 + ',o,c,Pa ' + cachedir +
                '/convert_to_Pa_tmp.nc ; mv ' + cachedir + '/convert_to_Pa_tmp.nc ${out}')
        dat1 = climaf.operators.convert_plev_hPa_to_Pa(dat1)
    # -> The vertical axis of file1 is now set to Pa
    #
    # -- Second, we check the unit of the vertical dimension of file2
    if dat2:
        file2 = cfile(dat2)
        clogger.debug('file2 = %s' % file2)
        ncfile2 = ncf(file2)

        levname2 = None
        for varname in ncfile2.variables:
            if varname.lower() in ['level', 'levels', 'lev', 'levs', 'depth', 'deptht',
                                   'olevel'] or 'plev' in varname.lower():
                levname2 = varname
        clogger.debug('levname2 = %s' % levname2)
        if not levname2:
            clogger.debug('Name of the vertical axis not found for dat2')
        levunits2 = ncfile2.variables[levname2].units
        clogger.debug('ncfile2 = %s' % ncfile2)
        try:
            levValues2 = ncfile2.variables[levname2].getValue()
        except:
            try:
                levValues2 = ncfile2.variables[levname2].data
            except:
                levValues2 = ncfile2[levname2][0:len(ncfile2[levname2])]
        if levunits2.lower() in ['hpa', 'millibar', 'mbar', 'hectopascal']:
            # -- Multiplier par 100
            cscript('convert_plev_hPa_to_Pa',
                    'ncap2 -As "' + levname2 + '=' + levname2 + '*100" ${in} ' + cachedir +
                    '/convert_to_Pa_tmp.nc ; ncatted -O -a units,' + levname2 + ',o,c,Pa ' + cachedir +
                    '/convert_to_Pa_tmp.nc ; mv ' + cachedir + '/convert_to_Pa_tmp.nc ${out}')
            dat2 = climaf.operators.convert_plev_hPa_to_Pa(dat2)

            # -> The vertical axis of file2 is now set to Pa in the netcdf file
            scale = 100.0
        else:
            scale = 1.0
        #
        # --> We get the values of the vertical levels of dat2 (from the original file, that's why we apply a scale)
        levels = ''
        for lev in levValues2:
            levels = levels + ',' + str(lev * scale)
        #
        # --> We can now interpolate dat1 on dat2 verticaly and horizontally
        if horizontal_regridding:
            regridded_dat1 = ccdo(regrid(dat1, dat2, option='remapdis'), operator='intlevel' + levels)
        else:
            regridded_dat1 = ccdo(dat1, operator='intlevel' + levels)
    else:
        if vertical_levels:
            if isinstance(vertical_levels, list):
                levels = ''
                for lev in vertical_levels:
                    levels = levels + ',' + str(lev)
            else:
                levels = ',' + vertical_levels
            if horizontal_regridding:
                regridded_dat1 = ccdo(regridn(dat1, cdogrid=cdo_horizontal_grid), operator='intlevel' + levels)
            else:
                regridded_dat1 = ccdo(dat1, operator='intlevel' + levels)
        else:
            clogger.error('--> Provide a list of vertical levels with vertical_levels')
    return regridded_dat1