Changeset 1845 in lmdz_wrf for trunk/tools/nc_var_tools.py


Ignore:
Timestamp:
Mar 22, 2018, 9:30:10 PM (7 years ago)
Author:
lfita
Message:

Introducing into the flow of:

  • `CFmorzization': Function to provide a CF-compilation version of a variable within a file
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/nc_var_tools.py

    r1837 r1845  
    3030# basicvardef: Function to give the basic attributes to a variable (std_name, long_name, units)
    3131# CDO_toCF: Function to pass a CDO output file to CF-conventions
     32# CFmorzization: Function to provide a CF-compilation version of a variable within a file
    3233# changevartype: Function to change the type of a variable (when possible)
    3334# chdimname: Changing the name of the dimension
     
    2267622677        - Christensen, Gutowski, Nikulin, and Legutke; 2013. CORDEX Archive Design
    2267722678          (http://cordex.org/publications/report-and-document-archives/)
    22678         - Taylor, K., and C. Doutriaux, 2011. “CMIP5 Model Output Requirements: File
    22679           Contents and Format, Data Structure and Meta Data”
     22679        - Taylor, K., and C. Doutriaux, 2011. CMIP5 Model Output Requirements: File
     22680          Contents and Format, Data Structure and Meta Data
    2268022681          (http://cmip-pcmdi.llnl.gov/cmip5/output_req.html#metadata)
    2268122682
    22682         values=[dimvarns]:[globattrfile]
     22683        values=[dimvarns]:[globattrfile]:[projectfile]
    2268322684          [dimvarns]: ',' separated list for identification of axes, dimensions and
    2268422685            variable-dimensions as '[AXIS]|[dimn]|[vardimn]'
     
    2269322694              institution  [value]
    2269422695              model_id [value] (CORDEX starts with <institute_id>-)
    22695               experiment_id     [value] (same CV as CMIP5 with "evaluation" in addition)
     22696              experiment_id [value] (same CV as CMIP5 with "evaluation" in addition)
    2269622697              experiment [value] (long version of "experiment_id")
    2269722698              contact [value] ([Name], [email] of contact person)
    22698               product   [value] (single value: "output")
     22699              product [value] (single value: "output")
    2269922700              Conventions [value] (later than CF1.4 if present / single value: "CF-1.4")
    22700               creation_date     [YYYY-MM-DDTHH:MM:SSZ] (format according to UNIDATA conventions, same in CMIP5 & CORDEX)
    22701               frequency [value] (same CV as CMIP5 with "sem" in addition; 3hr highest freq. in CORDEX; no "yr")
     22701              creation_date [YYYY-MM-DDTHH:MM:SSZ] (format according to UNIDATA conventions, same in CMIP5 & CORDEX)
     22702              frequency [value] (same CV as CMIP5 with "sem" in addition; 3hr highest freq. in CORDEX; no "yr")
    2270222703              driving_model_id [value] (CMIP5 institute_id, <CMIP5 institute_id>-<member in CMIP5 CV list of model_id>)
    2270322704              driving_model_ensemble_member [value] (CMIP5 CV, e.g. "r1i1p1")
     
    2270622707                members of the CMIP5 list of forcing agents are not necessarily forcing agents of RCM (besides implicitly
    2270722708                in driving_experimnt)
    22708               rcm_version_ID [value] (<free text string>; valid characters only indicates model modifs during the project
     22709              rcm_version_ID [value] (<free text string>; valid characters only indicates model modifs during the project
    2270922710                e.g.: parameterizations, small upgrades)
    2271022711              project_id [value] (single value)
    22711               CORDEX_domain     [value] ((e.g.: "AFR-44", "AFR-44i", includes resolution acronym)
     22712              CORDEX_domain [value] ((e.g.: "AFR-44", "AFR-44i", includes resolution acronym)
    2271222713              tracking_id [value] (not required or explained in ADD; it is, however, strongly recommended to include it
    2271322714                as prescribed CMIP5.)
    22714               basetime  [value] (reference time "1949-12-01T00:00:00Z" formatted acording to UNIDATA conventions)
    22715               calendar  [value] (CF conventions as in driving model)
     22715              basetime [value] (reference time "1949-12-01T00:00:00Z" formatted acording to UNIDATA conventions)
     22716              calendar [value] (CF conventions as in driving model)
    2271622717              grid [value] (according to CF conventions
     22718          [projectfile]: ASCII file with all the CF-mandatory projection information. A line for each attribute. Name of
     22719            the variable to be used to refer the projection inside the file will be the same as global attribute `grid'
     22720            See more information from: http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/ch05s06.html
     22721             (...) (specific projection attributes and values)
     22722             [name] [value] [kind] ('I': integer, 'R': float, 'D': double float, 'S': string)
    2271722723        ncfile= netCDF file to use
    2271822724        variable= ',' list of variables to CF transform ('all' for all variables). A separated file will be created
     
    2272422730    if values == 'h':
    2272522731        print fname + '_____________________________________________________________'
    22726         print CFmorzizarion.__doc__
     22732        print CFmorzization.__doc__
    2272722733        quit()
    2272822734
    22729     expectargs = '[dimvarns]:[globattrfilen]'
     22735    expectargs = '[dimvarns]:[globattrfilen]:[projectfile]'
    2273022736    gen.check_arguments(fname, values, expectargs, ':')
    2273122737
    2273222738    dimvarns = values.split(':')[0].split(',')
    2273322739    globalattrfilen = values.split(':')[1]
     22740    projfilen = values.split(':')[2]
    2273422741
    2273522742    # CF Mandatory global attributes
     
    2277022777            quit(-1)
    2277122778
     22779    # Getting projection
     22780    if not os.path.isfile(projfilen):
     22781        print errormsg
     22782        print '  '+fname+ "': ASCII file with projection information '" + projfilen+ \
     22783          + "' does not exist !!"
     22784        quit(-1)
     22785
     22786    pinf = {}
     22787    opinff = open(projfilen, 'r')
     22788    for line in opinff:
     22789        if line[0:1] != '#' and len(line) > 1:
     22790            linevals = line.replace('\n','').replace('\t','').split(' ')
     22791            pinf[linevals[0]] = [linevals[1].replace('!',' '), linevals[2]]
     22792    opinff.close()
     22793
    2277222794    # Getting variables to process
    2277322795    onc = NetCDFFile(ncfile,'r')
     
    2278722809    # VariableName: from `variables_values.dat'
    2278822810    # Domain: CORDEX_domain
    22789     # GCMModelName:     driving_model_id
     22811    # GCMModelName: driving_model_id
    2279022812    # CMIP5ExperimentName: driving_experiment_name
    2279122813    # CMIP5EnsembleMember: driving_model_ensemble_member
     
    2279722819    #   CMIP5EnsembleMember_RCMModelName_RCMVersionID_Frequency_StartTime-EndTime.nc
    2279822820
     22821    # Expected axes
     22822    axes = ['X', 'Y', 'Z', 'T']
     22823
     22824    oncvars = onc.variables.keys()
     22825    oncvars.sort()
     22826
     22827    # Axes information
     22828    CFdimvals = {}
     22829    filedimvals = {}
     22830    CFaxisvardimvals = {}
     22831    for axn in axisinf.keys():
     22832        axisv = axisinf[axn]
     22833        dimn = axisv[0]
     22834        vardimn = axisv[1]
     22835
     22836        # Axis values from file
     22837        if vardimn != 'WRFtime':
     22838            if not onc.variables.has_key(vardimn):
     22839                print errormsg
     22840                print '  '+fname+"': netcdf file '"+ ncfile + "' does not contain "+ \
     22841                  "variable '" + vardimn + "' !!"
     22842                print '    available ones:', oncvars
     22843                onc.close()
     22844                quit(-1)
     22845            oaxisv = onc.variables[vardimn]
     22846        else:
     22847            print infmsg
     22848            print '    ' + fname + ": creation of variable 'time' from WRF 'Times' !!"
     22849            odimvar = onc.variables['Times']
     22850            timewrfv = odimvar[:]
     22851            refT = gen.datetimeStr_conversion(gattr['basetime'], 'Y-m-dTH:M:SZ',     \
     22852              'YmdHMS')
     22853            tvals, urefvals = compute_WRFtime(timewrfv, refdate=refT,                \
     22854              tunitsval='minutes')
     22855            oaxisv = tvals
     22856     
     22857
     22858        # CF values of axis
     22859        CFdimvalues = gen.CFcorValues(axn)
     22860        print '  ' + axn + " ..."
     22861        print '    dimension in file:', dimn, ' variable in file:', vardimn
     22862        print '    CF-values _______'
     22863        print '    dimn:', CFdimvalues['dimn']
     22864        print '    variable-dimension. standard_name:', CFdimvalues['stdn'],         \
     22865          'long_name:', CFdimvalues['longname'], 'units', CFdimvalues['longname'],   \
     22866          'max, allowed rank:', CFdimvalues['maxrank']
     22867        print '    others:'
     22868        for ivn in CFdimvalues.keys():
     22869            if ivn != 'dimn' and ivn != 'stdn' and ivn != 'longname' and             \
     22870              ivn != 'units' and ivn != 'maxrank':
     22871                print ivn, ':', CFdimvalues[ivn]
     22872
     22873        # File values of the axis and assigning dimension length from rank in file
     22874        CFvardimvalues = []
     22875        if len(oaxisv.shape) == CFdimvalues['maxrank']:
     22876            axisv = oaxisv[:]
     22877            if CFdimvalues['length'] != -1:CFdimvalues['length'] = oaxisv.shape[0]
     22878            CFvardimvalues.append[dimn]
     22879        elif len(oaxisv.shape) == CFdimvalues['maxrank'] + 1:
     22880            print warnmsg
     22881            print '  '+ fname + ": dimension variable '" + vardimn + "' for axis '"+ \
     22882              axn + "' has a rank 1 unit higher that the maximum CF allowed:",       \
     22883              CFdimvalues['maxrank']
     22884            print '    assuming extra-dimension due to temporal values. ' +          \
     22885              'dimensions of variable:', oaxisv.dimensions
     22886            dimTn = axisinf['T'][0]
     22887            varslice = []
     22888            for dn in oaxisv.dimensions:
     22889                if dn == dimTn: varslice.append(0)
     22890                else:
     22891                    CFvardimvalues.append(dn)
     22892                    varslice.append(slice(0,len(onc.dimensions[dn])))
     22893                    if dn == dimn and CFdimvalues['length'] != -1:
     22894                        CFdimvalues['length'] = len(onc.dimensions[dn])
     22895            axsiv = oaxisv[tuple(varslice)]
     22896        else:
     22897            print errormsg
     22898            print '  ' + fname + ": axis-dimension '" + axn, ' of var: ', vardimn +  \
     22899              "' has maximum allowed rank of '", CFdimvalues['maxrank'],             \
     22900              ' while variable:', len(oaxisv.shape), ' and file-dimensions:',        \
     22901              oaxisv.dimensions, '!!'
     22902            print '    I do not know what to do'
     22903            onc.close()
     22904            quit(-1)
     22905        if CFdimvalues['length'] == -1: CFdimvalues['length'] = None
     22906        CFdimvals[axn] = CFdimvalues
     22907        filedimvals[axn] = axsiv[:]
     22908        CFaxisvardimvals[axn] = CFvardimvalues
     22909
     22910        # Some extra axis-stuff...
     22911        if axn == 'T':
     22912            dimt = len(axisv)
     22913            CFitime = axisv[0]
     22914            CFetime = axisv[dimt]
     22915            tunits = oaxisv.units
     22916            tcal = oaxisv.calendar
     22917            Sinit=datetimeStr_conversion(str(CFitime),'cftime,'+tunits,'Y-m-dTH:M:SZ')
     22918            Sendt=datetimeStr_conversion(str(CFetime),'cftime,'+tunits,'Y-m-dTH:M:SZ')
     22919            secfreq = CFtime_freq(axisv[0], axisv[1], tunits)
     22920            # Labelling frequency
     22921            if np.mod(secfreq, 100 * 365 * 24 * 3600.) == 0.:
     22922                Sfreq = str(int(secfreq/(100 * 365 * 24 * 3600.))) + 'C'
     22923            elif np.mod(secfreq, 365 * 24 * 3600.) == 0.:
     22924                Sfreq = str(int(secfreq/(365 * 24 * 3600.))) + 'Y'
     22925            elif np.mod(secfreq, 7 * 24 * 3600.) == 0.:
     22926                Sfreq = str(int(secfreq/(7 * 24 * 3600.))) + 'W'
     22927            elif np.mod(secfreq, 24 * 3600.) == 0.:
     22928                Sfreq = str(int(secfreq/(24.*3600.))) + 'D'
     22929            elif np.mod(secfreq,3600.) == 0.:
     22930                Sfreq = str(int(secfreq/3600.)) + 'H'
     22931            elif np.mod(secfreq,60.) == 0.:
     22932                Sfreq = str(int(secfreq/60.)) + 'M'
     22933            else: Sfreq = 'UNKNOWN'
     22934
     22935    # Processing variables in file
     22936    ##
    2279922937    for vn in varns:
    2280022938        # getting CF information
     
    2280322941        stdvarn = varinf[1]
    2280422942        longvarn = varinf[4].replace('|', ' ')
    22805 
     22943        utsvarn = varinf[5]
     22944
     22945        # getting variable from file
    2280622946        if not onc.variables.has_key(vn):
    2280722947            print errormsg
    2280822948            print '  '+fname+ "': netcdf file '" + ncfile + "' does not contain " +  \
    2280922949              "variable '" + vn + "' !!"
     22950            print '    available ones:', oncvars
    2281022951            onc.close()
    2281122952            quit(-1)
    22812 
     22953        ovar = onc.variables[vn]
     22954        # Looking for dimensions of variable
     22955        varaxes = []
     22956        CFvardims = []
     22957        for axn in axes:
     22958            axisv = axisinf[axn]
     22959            dimn = axisv[0]
     22960            if gen.searchInfile(ovar.dimensions, dimn):
     22961                varaxes.append[axn]
     22962                CFvardims.append(CFdimvals[axn]['dimn'])
     22963               
    2281322964        filen = gattr['institude_id'] + '_' + cfvarn + '_' + gattr['CORDEX_domain'] +\
    2281422965          '_' + gattr['driving_model_id'] + '_' + gattr['driving_experiment_name'] + \
    2281522966          '_' + gattr['driving_model_ensemble_member'] + '_' + gattr['model_id'] +   \
    22816           '_' + gattr['rcm_version_id'] + '_' + Sfrequency + '_' StartTime-EndTime + \
     22967          '_' + gattr['rcm_version_id'] + '_' + Sfreq + '_' + Sinit + '-' + Sendt + \
    2281722968          '.nc'
     22969
     22970        onewnc = NetCDFFile(filen,'w')
     22971        # Definition only of that coordinates from the variable
     22972        for axn in varaxes:
     22973            dvals = CFdimvals[axn]
     22974            newdim = onewnc.createDimension(dvals['dimn'], dvals['legnth'])
     22975
     22976        # Definition only of that variables-coordinates from the axes in the variable
     22977        for axn in varaxes:
     22978            dvals = CFdimvals[axn]
     22979            newvar = onewnc.createVariable(dvals['dimn'], 'f8',                      \
     22980              tuple(CFaxesdimvarvals[axn]))
     22981            basicvardef(newvar, dvals['stdn'], dvals['longname'], dvals['units'])
     22982            for ivn in dvals.keys():
     22983                if ivn != 'dimn' and ivn != 'stdn' and ivn != 'longname' and         \
     22984                  ivn != 'units' and ivn != 'maxrank' and ivn != 'length':
     22985                    set_attribute(newvar,ivn,dvals[ivn])
     22986
     22987        # Variable
     22988        newvar=onewnc.createVariable(cfvarn, 'f4', tuple(CFvardims),                 \
     22989          fill_Value=gen.fillValueR)
     22990        basicvardef(newvar, stdvarn, longvarn, utsvarn)
     22991        set_attribute(newvar, 'coordinates', ' '.join(CFvardims))
     22992        # Setting values, but taking into account pre-existing masked values
     22993        varv = ovar[:]
     22994        if type(varv) == type(gen.mamat):
     22995            imaskv = varv.fill_value
     22996            varv = np.where(varv == fill_value, gen.fillValueR, varv)
     22997
     22998        newvar[:] = varv[:]
     22999        onewnc.sync()
     23000
     23001        # Global attributes
     23002        for attrn in gattrN:
     23003            set_attribute(onewnc, attrn, gattr[attrn])
     23004
     23005        onewnc.sync()
     23006        add_global_PyNCplot(onewnc, 'PyNCplot', fname, '1.0')
     23007        onewnc.sync()
     23008
     23009        print "Successfull output of file '" + filen + "' !!"
     23010       
    2281823011
    2281923012    onc.close()
Note: See TracChangeset for help on using the changeset viewer.