Changeset 575 in lmdz_wrf for trunk/tools


Ignore:
Timestamp:
Jul 7, 2015, 11:52:59 AM (10 years ago)
Author:
lfita
Message:

Adding `DataSetSection_multivars', to slice a dataset according to values from a variable

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/nc_var_tools.py

    r574 r575  
    1650916509    return
    1651016510
    16511 vals='20.5:36.0:west_east,south_north:XLONG_M,XLAT_M'
    16512 ncf='/home/lluis/etudes/domains/medic051215_2km/geo_em.d01.nc'
    16513 
    16514 getvalues_lonlat(vals, ncf)
    16515 quit()
     16511#vals='20.5:36.0:west_east,south_north:XLONG_M,XLAT_M'
     16512#ncf='/home/lluis/etudes/domains/medic051215_2km/geo_em.d01.nc'
     16513
     16514def put_variable_slice(inc, onc, vn, sliced):
     16515    """ Function to add a variable from a netcdf object to a new one following a slice
     16516      inc= input netcdf object
     16517      onc= output netcdf object
     16518      vn= variable name to include
     16519      sliced= dictioary with the dimension name as key and [beg, end, int] as values
     16520    """
     16521    fname = 'put_variable_slice'
     16522
     16523    if not searchInlist(inc.variables,vn):
     16524        print errormsg
     16525        print ' ' + fname + ": variable '" + vn + "' is not in file!!"
     16526        quit(-1)
     16527
     16528    ov = inc.variables[vn]
     16529
     16530    dnvs = ov.dimensions
     16531    varslice = []
     16532# Getting variable's dimensions
     16533    for dnv in dnvs:
     16534        if not searchInlist(onc.dimensions,dnv):
     16535            od = inc.dimensions[dnv]
     16536            if od.isunlimited():
     16537                dsize = None
     16538            else:
     16539                dsize = len(od)
     16540            newdim = onc.createDimension(dnv, dsize)
     16541        if searchInlist(sliced.keys(),dnv):
     16542            varslice.append(slice(sliced[dnv][0], sliced[dnv][1], sliced[dnv][2]))
     16543        else:
     16544            varslice.append(slice(0,len(inc.dimensions[dnv])))
     16545# Getting variable
     16546    varattrs = ov.ncattrs()
     16547    if searchInlist(varattrs, '_FillValue'):
     16548        varfil = ov._FillValue
     16549    else:
     16550        varfil = False
     16551    vartype = ov.dtype
     16552
     16553    newvar = onc.createVariable(vn, vartype, dnvs, fill_value=varfil)
     16554#    print 'Lluis shapes newvar:',newvar.shape,'slice:',varslice
     16555    newvar[:] = ov[tuple(varslice)]
     16556
     16557    for attrs in varattrs:
     16558        if not attrs == '_FillValue':
     16559            attrv = ov.getncattr(attrs)
     16560            attr = set_attribute(newvar, attrs, attrv)
     16561
     16562    return
     16563
     16564def DataSetSection_multivars(values, filen, varn):
     16565    """ Function to get a section (values along multiple variables) of a given data-set
     16566      values= [varn1],[beg1],[end1],[int1]@[...[[varnM],[begM],[endM],[intM]]]
     16567        [varni]: name of the variable ('WRFt', for WRF time varibale)
     16568        [begi],[endi],[inti]: beginning, end and interval along the dimension-axis
     16569          [endi] = -1, maximum value
     16570          [inti] = -1, all the values within the range
     16571          NOTE: dimensions without section by the variables are taken allover their size
     16572      filen= netCDF with the data-set
     16573      varn= ',' list of variables ('all', for all variables)
     16574    """
     16575    import numpy.ma as ma
     16576    fname = 'DataSetSection_multivars'
     16577
     16578# Variables not to check in the file
     16579    NOcheck = ['WRFt']
     16580
     16581    if values == 'h':
     16582        print fname + '_____________________________________________________________'
     16583        print DataSetSection_multivars.__doc__
     16584        quit()
     16585
     16586    Nvars = len(values.split('@'))
     16587
     16588# Slicing variables
     16589    varns = []
     16590    ofiletile = ''
     16591    slicevalS = ''
     16592
     16593    begvs = np.zeros((Nvars), dtype=int)
     16594    endvs = np.zeros((Nvars), dtype=int)
     16595    intvs = np.zeros((Nvars), dtype=int)
     16596
     16597    for ivar in range(Nvars):
     16598        val = values.split('@')[ivar]
     16599        varns.append(val.split(',')[0])
     16600        begvs[ivar] = np.float(val.split(',')[1])
     16601        endvs[ivar] = np.float(val.split(',')[2])
     16602        intvs[ivar] = np.float(val.split(',')[3])
     16603        ofiletile = ofiletile + '_' + varns[ivar] + '_B' + str(begvs[ivar]) + '-E' + \
     16604          str(endvs[ivar]) + '-I' + str(intvs[ivar])
     16605        if intvs[ivar] != -1:
     16606            slicevalS = slicevalS + varns[ivar] + ' (' + str(begvs[ivar]) + ',' +    \
     16607              str(endvs[ivar]) + ',' + str(intvs[ivar]) + '); '
     16608        else:
     16609            slicevalS = slicevalS + varns[ivar] + ' (' + str(begvs[ivar]) + ',' +    \
     16610              str(endvs[ivar]) + ',1); '
     16611
     16612    ofile = ofile=filen.split('.')[0] + ofiletile + '.nc'
     16613
     16614    nciobj = NetCDFFile(filen,'r')
     16615    ncoobj = NetCDFFile(ofile,'w')
     16616
     16617# Output variables
     16618##
     16619    if varn == 'all':
     16620        variables = nciobj.variables
     16621    else:
     16622        if varn.find(',') != -1:
     16623            variables = varn.split(',')
     16624        else:
     16625            variables = [varn]
     16626
     16627# Looking for limits due to the variables
     16628##
     16629    for ivar in range(Nvars):
     16630        print '  ' + fname + ": masking with '" + varns[ivar] + "':",  begvs[ivar],  \
     16631          ',', endvs[ivar], ',', intvs[ivar]
     16632        if not searchInlist(nciobj.variables,varns[ivar]) and not                    \
     16633          searchInlist(NOcheck,varns[ivar]):
     16634            print errormsg
     16635            print ' ' + fname + ": variable '" + varns[ivar] + "' is not in ' +      \
     16636              'input file!!"
     16637            quit(-1)
     16638
     16639        if varns[ivar] == 'WRFt':
     16640            ovar = nciobj.variables['Times'][:]
     16641            vals = []
     16642            for it in range(ovar.shape[0]):
     16643                vals.append(datetimeStr_conversion(ovar[it,:], 'WRFdatetime',        \
     16644                  'YmdHMS'))
     16645                vals[it] = int(vals[it])
     16646                begvs[ivar] = int(begvs[ivar])
     16647                endvs[ivar] = int(endvs[ivar])
     16648                intvs[ivar] = int(intvs[ivar])
     16649
     16650            vals = np.array(vals)
     16651            vardims = ['Time']
     16652        else:
     16653            ovar = nciobj.variables[varns[ivar]]
     16654            vals = ovar[:]
     16655            vardims = ovar.dimensions
     16656
     16657        if endvs[ivar] == -1: endvs[ivar] = np.max(vals)
     16658        maskinf = ma.masked_less(vals, begvs[ivar])
     16659        masksup = ma.masked_greater(vals, endvs[ivar])
     16660
     16661        if intvs[ivar] != -1:
     16662            print errormsg
     16663            print '  ' + fname + ': non-consecutive slices not ready!!'
     16664            quit(-1)
     16665        finalmask = maskinf + masksup
     16666        idn = 0
     16667
     16668        slicedims = {}
     16669       
     16670        for dn in vardims:
     16671            ddn = len(nciobj.dimensions[dn])
     16672            dinds = np.arange(ddn)
     16673            rightvals = np.where(finalmask.mask, False, True)
     16674            slicedims[dn]=[np.min(dinds[rightvals]), np.max(dinds[rightvals])+1, None]
     16675
     16676        print '  ' + fname + ': slicing variables with______'
     16677        print slicedims
     16678 
     16679# Creating dimensions
     16680##
     16681    print '  ' + fname + ': adding dimensions...'
     16682    for nd in slicedims.keys():
     16683        objdim = nciobj.dimensions[nd]
     16684        if objdim.isunlimited():
     16685            dimsize = None
     16686        else:
     16687            dimsize = slicedims[nd][1] - slicedims[nd][0] + 1
     16688        newdim = ncoobj.createDimension(nd, dimsize)
     16689    ncoobj.sync()
     16690
     16691    for var in variables:
     16692        put_variable_slice(nciobj, ncoobj, var, slicedims)
     16693
     16694# Global attributes
     16695##
     16696    for attrs in nciobj.ncattrs():
     16697        attrv = nciobj.getncattr(attrs)
     16698        attr = set_attribute(ncoobj, attrs, attrv)
     16699
     16700    attr = set_attribute(ncoobj, 'sliced_variables', slicevalS)
     16701
     16702    nciobj.close()
     16703
     16704    ncoobj.sync()
     16705    ncoobj.close()
     16706
     16707    print '  ' + fname + ' succesfull creation of file "' + ofile + '" !!!'
     16708
     16709    return
     16710
     16711#DataSetSection_multivars('XTIME,4380,4800,-1','/home/lluis/PY/wrfout_d01_2001-11-11_00:00:00','all')
     16712#DataSetSection_multivars('WRFt,20011111060000,20011111180000,-1','/home/lluis/PY/wrfout_d01_2001-11-11_00:00:00','all')
     16713
     16714#quit()
    1651616715
    1651716716"""operation to make:
Note: See TracChangeset for help on using the changeset viewer.