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
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'
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