Changeset 333 in lmdz_wrf for trunk


Ignore:
Timestamp:
Feb 27, 2015, 4:09:03 PM (10 years ago)
Author:
lfita
Message:

Working and tested version for 'single-station'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/validation_sim.py

    r330 r333  
    11
    22# L. Fita, LMD-Jussieu. February 2015
    3 ## e.g. # validation_sim.py -d X@west_east@None,Y@south_north@None,T@Time@time -D X@XLONG@longitude,Y@XLAT@latitude,T@time@time -k single-station -l 4.878773,43.915876,12. -o /home/lluis/DATA/obs/HyMeX/IOP15/sfcEnergyBalance_Avignon/OBSnetcdf.nc -s /home/lluis/PY/wrfout_d01_2012-10-18_00:00:00.tests -v HFX@H 
     3## e.g. # validation_sim.py -d X@west_east@None,Y@south_north@None,T@Time@time -D X@XLONG@longitude,Y@XLAT@latitude,T@time@time -k single-station -l 4.878773,43.915876,12. -o /home/lluis/DATA/obs/HyMeX/IOP15/sfcEnergyBalance_Avignon/OBSnetcdf.nc -s /home/lluis/PY/wrfout_d01_2012-10-18_00:00:00.tests -v HFX@H,LH@LE,GRDFLX@G
    44import numpy as np
    55import os
     
    1919fillValueI = -99999
    2020fillValueS = '---'
     21
     22StringLength = 50
     23
     24def searchInlist(listname, nameFind):
     25    """ Function to search a value within a list
     26    listname = list
     27    nameFind = value to find
     28    >>> searInlist(['1', '2', '3', '5'], '5')
     29    True
     30    """
     31    for x in listname:
     32      if x == nameFind:
     33        return True
     34    return False
     35
     36def set_attribute(ncvar, attrname, attrvalue):
     37    """ Sets a value of an attribute of a netCDF variable. Removes previous attribute value if exists
     38    ncvar = object netcdf variable
     39    attrname = name of the attribute
     40    attrvalue = value of the attribute
     41    """
     42    import numpy as np
     43    from netCDF4 import Dataset as NetCDFFile
     44
     45    attvar = ncvar.ncattrs()
     46    if searchInlist(attvar, attrname):
     47        attr = ncvar.delncattr(attrname)
     48
     49    attr = ncvar.setncattr(attrname, attrvalue)
     50
     51    return ncvar
     52
     53def basicvardef(varobj, vstname, vlname, vunits):
     54    """ Function to give the basic attributes to a variable
     55    varobj= netCDF variable object
     56    vstname= standard name of the variable
     57    vlname= long name of the variable
     58    vunits= units of the variable
     59    """
     60    attr = varobj.setncattr('standard_name', vstname)
     61    attr = varobj.setncattr('long_name', vlname)
     62    attr = varobj.setncattr('units', vunits)
     63
     64    return
     65
     66def writing_str_nc(varo, values, Lchar):
     67    """ Function to write string values in a netCDF variable as a chain of 1char values
     68    varo= netCDF variable object
     69    values = list of values to introduce
     70    Lchar = length of the string in the netCDF file
     71    """
     72
     73    Nvals = len(values)
     74    for iv in range(Nvals):   
     75        stringv=values[iv] 
     76        charvals = np.chararray(Lchar)
     77        Lstr = len(stringv)
     78        charvals[Lstr:Lchar] = ''
     79
     80        for ich in range(Lstr):
     81            charvals[ich] = stringv[ich:ich+1]
     82
     83        varo[iv,:] = charvals
     84
     85    return
    2186
    2287def index_3mat(matA,matB,matC,val):
     
    314379    return tB
    315380
     381
     382def slice_variable(varobj, dimslice):
     383    """ Function to return a slice of a given variable according to values to its
     384      dimensions
     385    slice_variable(varobj, dimslice)
     386      varobj= object wit the variable
     387      dimslice= [[dimname1]:[value1]|[[dimname2]:[value2], ...] pairs of dimension
     388        [value]:
     389          * [integer]: which value of the dimension
     390          * -1: all along the dimension
     391          * -9: last value of the dimension
     392          * [beg]@[end] slice from [beg] to [end]
     393    """
     394    fname = 'slice_variable'
     395
     396    if varobj == 'h':
     397        print fname + '_____________________________________________________________'
     398        print slice_variable.__doc__
     399        quit()
     400
     401    vardims = varobj.dimensions
     402    Ndimvar = len(vardims)
     403
     404    Ndimcut = len(dimslice.split('|'))
     405    dimsl = dimslice.split('|')
     406
     407    varvalsdim = []
     408    dimnslice = []
     409
     410    for idd in range(Ndimvar):
     411        for idc in range(Ndimcut):
     412            dimcutn = dimsl[idc].split(':')[0]
     413            dimcutv = dimsl[idc].split(':')[1]
     414            if vardims[idd] == dimcutn:
     415                posfrac = dimcutv.find('@')
     416                if posfrac != -1:
     417                    inifrac = int(dimcutv.split('@')[0])
     418                    endfrac = int(dimcutv.split('@')[1])
     419                    varvalsdim.append(slice(inifrac,endfrac))
     420                    dimnslice.append(vardims[idd])
     421                else:
     422                    if int(dimcutv) == -1:
     423                        varvalsdim.append(slice(0,varobj.shape[idd]))
     424                        dimnslice.append(vardims[idd])
     425                    elif int(dimcutv) == -9:
     426                        varvalsdim.append(int(varobj.shape[idd])-1)
     427                    else:
     428                        varvalsdim.append(int(dimcutv))
     429                break
     430
     431    varvalues = varobj[tuple(varvalsdim)]
     432
     433    return varvalues, dimnslice
     434
     435
    316436####### ###### ##### #### ### ## #
    317437
     
    323443  "(e.g., lightning strikes), 'single-station': single station on a fixed position,"+\
    324444  "'trajectory': following a trajectory"
     445simopers =['sumc','subc','mulc','divc']
    325446#sumc,[constant]: add [constant] to variables values
    326447#subc,[constant]: substract [constant] to variables values
     
    372493            quit(-1)
    373494        dims[dsecs[0]] = [dsecs[1], dsecs[2]]
    374         print dsecs[0],':',dsecs[1],',',dsecs[2]
     495        print '  ',dsecs[0],':',dsecs[1],',',dsecs[2]
    375496       
    376 
    377497if opts.vardims is None:
    378498    print errormsg
     
    393513            quit(-1)
    394514        vardims[dsecs[0]] = [dsecs[1], dsecs[2]]
    395         print dsecs[0],':',dsecs[1],',',dsecs[2]
     515        print '  ',dsecs[0],':',dsecs[1],',',dsecs[2]
    396516
    397517if opts.obskind is None:
     
    437557else:
    438558    valvars = []
    439     vs = opts.dims.split(',')
     559    vs = opts.vars.split(',')
    440560    for v in vs:
    441561        vsecs = v.split('@')
    442         if len(dsecs) < 2:
     562        if len(vsecs) < 2:
    443563            print errormsg
    444564            print '  ' + main + ': wrong number of values in:',vsecs,                \
     
    446566            print '    [varsim]@[varobs]@[[oper][val]]'
    447567            quit(-1)
     568        if len(vsecs) > 2:
     569            if not searchInlist(simopers,vsecs[2]):
     570                print errormsg
     571                print main + ": operation on simulation values '" + vsecs[2] +       \
     572                  "' not ready !!"
     573                quit(-1)
     574
    448575        valvars.append(vsecs)
    449576
     
    503630        trajpos[:,it] = index_2mat(valdimsim['X'],valdimsim['Y'],                    \
    504631          [valdimobs['X'][it],valdimobss['Y'][it]])
    505 
    506632elif obskind == 'single-station':
    507633    stsimpos = index_2mat(valdimsim['Y'],valdimsim['X'],[valdimobs['Y'],             \
    508634      valdimobs['X']])
    509     print main + ': station point in simulation:', stsimpos
     635    stationpos = np.zeros((2), dtype=int)
     636    iid = 0
     637    for idn in osim.variables[vardims['X'][0]].dimensions:
     638        if idn == dims['X'][0]:
     639            stationpos[1] = stsimpos[iid]
     640        elif idn == dims['Y'][0]:
     641            stationpos[0] = stsimpos[iid]
     642
     643        iid = iid + 1
     644    print main + ': station point in simulation:', stationpos
    510645    print '    station position:',valdimobs['X'],',',valdimobs['Y']
    511646    print '    simulation coord.:',valdimsim['X'][tuple(stsimpos)],',',              \
    512647      valdimsim['Y'][tuple(stsimpos)]
     648
    513649elif obskind == 'trajectory':
    514650    if dims.has_key('Z'):
    515651        trajpos = np.zeros((3,dimt),dtype=int)
    516652        for it in dimtobs:
    517             trajpos[0:1,it] = index_2mat(valdimsim['X'],valdimsim['Y'],              \
    518               [valdimobs['X'][it],valdimobss['Y'][it]])
     653            trajpos[0:1,it] = index_2mat(valdimsim['Y'],valdimsim['X'],              \
     654              [valdimobs['Y'][it],valdimobss['X'][it]])
    519655            trajpos[2,it] = index_mat(valdimsim['Z'],valdimobs['Z'][it])
    520656    else:
    521657        trajpos = np.zeros((2,dimt),dtype=int)
    522658        for it in dimtobs:
    523             trajpos[:,it] = index_2mat(valdimsim['X'],valdimsim['Y'],                \
    524               [valdimobs['X'][it],valdimobss['Y'][it]])
     659            trajpos[:,it] = index_2mat(valdimsim['Y'],valdimsim['X'],                \
     660              [valdimobs['Y'][it],valdimobss['X'][it]])
    525661
    526662# Getting times
     
    532668simobstimes = coincident_CFtimes(valdimsim['T'], obstunits, simtunits)
    533669
    534 print 'Lluis:',simobstimes
    535 
     670# Concident times
     671##
     672coindtvalues = []
     673for it in range(dimtsim):   
     674    ot = 0
     675    for ito in range(ot,dimtobs-1):
     676        if valdimobs['T'][ito] < simobstimes[it] and valdimobs['T'][ito+1] >         \
     677          simobstimes[it]:
     678            ot = ito
     679            tdist = simobstimes[it] - valdimobs['T'][ito]
     680            coindtvalues.append([it,ito,simobstimes[it],valdimobs['T'][ito],tdist])
     681
     682Ncoindt = len(coindtvalues)
     683print main + ': found',Ncoindt,'coincident times between simulation and observations'
     684
     685# Validating
     686##
     687
     688onewnc = NetCDFFile(ofile, 'w')
     689
     690# Dimensions
     691newdim = onewnc.createDimension('time',None)
     692newdim = onewnc.createDimension('couple',2)
     693newdim = onewnc.createDimension('StrLength',StringLength)
     694
     695# Variable dimensions
     696##
     697newvar = onewnc.createVariable('simtime','f8',('time'))
     698basicvardef(newvar, 'simtime', 'time simulation', obstunits )
     699set_attribute(newvar, 'calendar', 'standard')
     700newvar[:] = coindtvalues[:][2]
     701
     702newvar = onewnc.createVariable('obstime','f8',('time'))
     703basicvardef(newvar, 'obstime', 'time observations', obstunits )
     704set_attribute(newvar, 'calendar', 'standard')
     705newvar[:] = coindtvalues[:][3]
     706
     707newvar = onewnc.createVariable('couple', 'c', ('couple','StrLength'))
     708basicvardef(newvar, 'couple', 'couples of values', '-')
     709writing_str_nc(newvar, ['sim','obs'], StringLength)
     710
     711Nvars = len(valvars)
     712for ivar in range(Nvars):
     713    simobsvalues = []
     714
     715    varsimobs = valvars[ivar][0] + '_' + valvars[ivar][1]
     716
     717    if not oobs.variables.has_key(valvars[ivar][1]):
     718        print errormsg
     719        print '  ' + main + ": observations file has not '" + valvars[ivar][1] +     \
     720          "' !!"
     721        quit(-1)
     722    if not osim.variables.has_key(valvars[ivar][0]):
     723        print errormsg
     724        print '  ' + main + ": simulation file has not '" + valvars[ivar][0] + "' !!"
     725        quit(-1)
     726
     727    ovobs = oobs.variables[valvars[ivar][1]]
     728    ovsim = osim.variables[valvars[ivar][0]]
     729
     730    if obskind == 'multi-points':
     731        for it in range(Ncoindt):
     732            slicev = dims['X'][0]+':'+str(trajpos[2,it]) + '|' +                     \
     733              dims['Y'][0]+':'+str(trajpos[1,it]) + '|' +                            \
     734              dims['T'][0]+':'+str(coindtvalues[it][0])
     735            slicevar, dimslice = slice_variable(ovsim, slicev)
     736            simobsvalues.append([ ovsim[slicevar], ovobs[coindtvalues[it][1]]])
     737    elif obskind == 'single-station':
     738        for it in range(Ncoindt):
     739            slicev = dims['X'][0]+':'+str(stationpos[1]) + '|' +                       \
     740              dims['Y'][0]+':'+str(stationpos[0]) + '|' +                              \
     741              dims['T'][0]+':'+str(coindtvalues[it][0])
     742            slicevar, dimslice = slice_variable(ovsim, slicev)
     743            simobsvalues.append([ slicevar, ovobs[coindtvalues[it][1]]])
     744    elif obskind == 'trajectory':
     745        if dims.has_key('Z'):
     746            for it in range(Ncoindt):
     747                slicev = dims['X'][0]+':'+str(trajpos[2,it]) + '|' +                 \
     748                  dims['Y'][0]+':'+str(trajpos[1,it]) + '|' +                        \
     749                  dims['Z'][0]+':'+str(trajpos[0,it]) + '|' +                        \
     750                  dims['T'][0]+':'+str(coindtvalues[it][0])
     751                slicevar, dimslice = slice_variable(ovsim, slicev)
     752                simobsvalues.append([ ovsim[slicevar], ovobs[coindtvalues[it][1]]])
     753                print simobsvalues[varsimobs][:][it]
     754        else:
     755            for it in range(Ncoindt):
     756                slicev = dims['X'][0]+':'+str(trajpos[2,it]) + '|' +                 \
     757                  dims['Y'][0]+':'+str(trajpos[1,it]) + '|' +                        \
     758                  dims['T'][0]+':'+str(coindtvalues[it][0])
     759                slicevar, dimslice = slice_variable(ovsim, slicev)
     760                simobsvalues.append([ ovsim[slicevar], ovobs[coindtvalues[it][1]]])
     761                print simobsvalues[varsimobs][:][it]
     762
     763    newvar = onewnc.createVariable(varsimobs, 'f', ('time','couple'))
     764    descvar = 'couples of simulated: ' + valvars[ivar][0] + ' and observed ' +        \
     765      valvars[ivar][1]
     766    basicvardef(newvar, varsimobs, descvar, ovobs.getncattr('units'))
     767 
     768    newvar[:] = np.array(simobsvalues)
     769
     770    onewnc.sync()
     771
     772# Global attributes
     773##
     774set_attribute(onewnc,'author_nc','Lluis Fita')
     775set_attribute(onewnc,'institution_nc','Laboratoire de Meteorology Dynamique, ' +    \
     776  'LMD-Jussieu, UPMC, Paris')
     777set_attribute(onewnc,'country_nc','France')
     778set_attribute(onewnc,'script_nc',main)
     779set_attribute(onewnc,'version_script',version)
     780set_attribute(onewnc,'information',                                                 \
     781  'http://www.lmd.jussieu.fr/~lflmd/ASCIIobs_nc/index.html')
     782set_attribute(onewnc,'simfile',opts.fsim)
     783set_attribute(onewnc,'obsfile',opts.fobs)
     784
     785onewnc.sync()
     786onewnc.close()
     787
     788print main + ": successfull writting of '" + ofile + "' !!"
Note: See TracChangeset for help on using the changeset viewer.