Changeset 2165 in lmdz_wrf for trunk


Ignore:
Timestamp:
Oct 4, 2018, 10:44:41 PM (7 years ago)
Author:
lfita
Message:

Adding:

  • `temporal_stats': Function to compute temporal statistics. Rank of the variables are preserved along other non-temporal dimensions
Location:
trunk/tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/nc_var.py

    r2061 r2165  
    6060## e.g. # nc_var.py -o curve_section -f /home/lluis/PY/test.nc -S 'gridline,x,y,8.,8.,16.,16.,32' -v all
    6161## e.g. # nc_var.py -o merge_files -S 'plev|plev,time|time:merged.nc' -f 'ncobs/AliceSprings/snd_94326_198201-198201.nc,ncobs/AliceSprings/snd_94326_198202-198202.nc' -v 'plev,time'
     62## e.g. # nc_var.py -o temporal_stats -S 'Time:WRFtime:day@1@min,LTday@-3@1@min:bottom_top@ZNU,south_north@XLAT,west_east@XLONG' -f wrfout_d01_1995-01-01_00:00:00 -v T2,Q2
    6263
    6364from optparse import OptionParser
     
    171172# submns: Function to retrieve a series of months from a file
    172173# subyrs: Function to retrieve a series of years from a file
     174# temporal_stats: Function to compute temporal statistics. Rank of the variables are
     175#   preserved along other non-temporal dimensions
    173176# TimeInf: Function to print all the information from the variable time
    174177# time_reset: Function to re-set the time axis of a file
     
    220223  'setvar_nc', 'sorttimesmat', 'spacemean', 'SpatialWeightedMean',                   \
    221224  'splitfile_dim', 'statcompare_files',                                              \
    222   'subbasin', 'submns', 'subyrs', 'TimeInf', 'time_reset',                           \
     225  'subbasin', 'submns', 'subyrs', 'temporal_stats', 'TimeInf', 'time_reset',         \
    223226  'TimeSplitmat', 'timemean', 'valmod', 'valmod_dim','varaddattrk', 'varaddattr',    \
    224227  'varaddref',                                                                       \
     
    497500elif oper == 'subyrs':
    498501    ncvar.subyrs(opts.values, opts.ncfile, opts.varname)
     502elif oper == 'temporal_stats':
     503    ncvar.temporal_stats(opts.values, opts.ncfile, opts.varname)
    499504elif oper == 'TimeInf':
    500505    ncvar.TimeInf(opts.ncfile, opts.varname)
  • trunk/tools/nc_var_tools.py

    r2157 r2165  
    158158# subyrs: Function to retrieve a series of years from a file
    159159# testvarinfile: Check existence of a variable inside a netCDF file
     160# temporal_stats: Function to compute temporal statistics. Rank of the variables are
     161#   preserved along other non-temporal dimensions
    160162# TimeInf: Function to print all the information from the variable time
    161163# time_information: Function to provide information about variable time
     
    1766317665    dimvarns = {}
    1766417666    for vardn in dimvars:
     17667
    1766517668        dimn = vardn.split('@')[0]
    1766617669        dimvn = vardn.split('@')[1]
     
    2526925272    return [minval, maxval, meanval, stdval], [isw, jsw, ine, jne]
    2527025273
     25274def temporal_stats(values, ncfile, variable):
     25275    """ Function to compute temporal statistics. Rank of the variables are preserved
     25276          along other non-temporal dimensions
     25277      values=[timedimn]:[timevarn]:[timestats]:[dimndimvarn]
     25278        [timedimn]: name of the dimension time
     25279        [timevarn]: name of the variable with CFtimes ('WRFtime' for times in WRF
     25280          model format)
     25281        [timestats]:  ',' separated list of [period]@[amount]@[stat] periods and
     25282            statistics
     25283          [period]: period to compute the statistics
     25284            'year': statistics within full years [01/01 00:00:00 - 12/31 23:59:59]
     25285            'month': statistics within full months [01 00:00:00 -
     25286              [31,30,28/29] 23:59:59]
     25287            'day': statistics within full days [00:00:00 - 23:59:59]
     25288            'dayLT'@[UTCshift]: statistics within full local-time ([UTshift] local
     25289              shift in hours from UTC) days [00:00:00+UTCshift - 23:59:59+UTCshift]
     25290            'hour': statistics within full hours [00:00 - 59:59]
     25291            'minute': statistics within full minutes [00 - 59]
     25292          [amount]: quantity of periods to group
     25293          [statn]: statistics to compute
     25294            'min': minimum value within [amunt]*[period]
     25295            'max': maximum value within [amunt]*[period]
     25296            'mean': mean value within [amunt]*[period]
     25297            'mean2': quadratic mean value within [amunt]*[period]
     25298            'std': stanard deviation value within [amunt]*[period]
     25299            'pecentiles'@[Npercen]: [Npercen] percentiles within [amunt]*[period]     
     25300          [dimndimvarn]: ',' list of [dimn]@[dimvarn] dimension and its associated
     25301            variable dimension
     25302      ncfile= file from which provide the information
     25303      variable= ',' list of values to compute statistics ('all' for all variables
     25304        only that ones with [timedimn])
     25305    """
     25306    fname = 'temporal_stats'
     25307
     25308    Lperiodn = {'year': 'yearly', 'month': 'monthly', 'day': 'daily',                \
     25309      'LTday': 'local-time daily', 'hour': 'hourly', 'minute': 'minutely'}
     25310    Lstatn = {'min': 'minimum', 'max': 'maximum', 'mean': 'mean',                    \
     25311      'mean2': 'quadratic mean', 'std': 'standard deviation',                        \
     25312      'percentiles': 'percentiles'}
     25313    availcftunits = ['days', 'hours', 'minutes', 'seconds']
     25314
     25315    if values == 'h':
     25316        print fname + '_____________________________________________________________'
     25317        print tepmoral_stats.__doc__
     25318        quit()
     25319
     25320    expectargs = '[timedimn]:[timevarn]:[timestats]:[dimndimvarn]'
     25321    gen.check_arguments(fname, values, expectargs, ':')
     25322
     25323    timedimn = values.split(':')[0]
     25324    timevarn = values.split(':')[1]
     25325    timestatsS = gen.str_list(values.split(':')[2], ',')
     25326    dimndimvarn = gen.str_list(values.split(':')[3], ',')
     25327
     25328    # Getting dim/dimvar correspondences
     25329    dimvarns = {}
     25330    for dvn in dimndimvarn:
     25331        dn = dvn.split('@')[0]
     25332        dvn = dvn.split('@')[1]
     25333        dimvarns[dn] = dvn
     25334       
     25335    onc = NetCDFFile(ncfile, 'r')
     25336
     25337    # Getting time values
     25338    if not gen.searchInlist(onc.dimensions, timedimn):
     25339        print errormsg
     25340        print '  ' +fname+ ": file '" + ncfile + "' does not have dimension time '"+ \
     25341          timedimn + "' !!"
     25342        dimns = onc.dimensions
     25343        dimns.sort()
     25344        print '    avaialble ones:', dimns
     25345        quit(-1)
     25346
     25347    if timevarn != 'WRFtime' and not onc.variables.has_key(timevarn):
     25348        print errormsg
     25349        print '  ' +fname+ ": file '" + ncfile + "' does not have variable time '" + \
     25350          timevarn + "' !!"
     25351        varns = onc.variables.keys()
     25352        varns.sort()
     25353        print '    avaialble ones:', varns
     25354        quit(-1)
     25355
     25356    if timevarn != 'WRFtime':
     25357        otimev = onc.variables[timevarn]
     25358        timev = otimev[:]
     25359        timeu = otimev.units
     25360        if gen.searchInlist(otimev.ncattrs(), 'calendar'): timec = otimev.calendar
     25361        else:
     25362            print warnsmg
     25363            print '    ' + fname + ": variable time without calendar attribute !"
     25364            print "    assuming 'standard/greogorian'"
     25365            timec = 'standard'
     25366    else:
     25367        otimev = onc.variables['Times']
     25368        timewrfv = otimev[:]
     25369        timev, timeu = compute_WRFtime(timewrfv, refdate='19491201000000',           \
     25370          tunitsval='minutes')
     25371        timec = 'standard'
     25372
     25373    tunits = timeu.split(' ')[0]
     25374    trefdate = timeu.split(' ')[2] + '_' + timeu.split(' ')[3]
     25375
     25376    # Getting periods
     25377    timestats = {}
     25378    iTst = 0
     25379    periods = []
     25380    amounts = []
     25381    stats = []
     25382    for timest in timestatsS:
     25383        timestatsv = []
     25384        period = timest.split('@')[0]
     25385        timestatsv.append(period)
     25386        if period == 'LTday':
     25387            UTCshift = int(timest.split('@')[1])
     25388            periods.append(period + '(' + str(UTCshift) + ')')
     25389            if tunits == 'days': UTCshift = UTCshift / 24.
     25390            elif tunits == 'hours': UTCshift = UTCshift / 1.
     25391            elif tunits == 'minutes': UTCshift = UTCshift * 60.
     25392            elif tunits == 'seconds': UTCshift = UTCshift * 3600.
     25393            else:
     25394                print errormsg
     25395                print '  ' + fname + ": CF temporal units '" + tunits +              \
     25396                  "' not ready to transform 'UTCshift' !!"
     25397                print '    available ones:', availcftunits
     25398                quit(-1)
     25399            timestatsv.append(UTCshift)
     25400            iamount = 2
     25401        else:
     25402            periods.append(period)
     25403            iamount = 1
     25404
     25405        amount = int(timest.split('@')[iamount])
     25406        amounts.append(amount)
     25407
     25408        timestatsv.append(amount)
     25409        statn = timest.split('@')[iamount+1]
     25410        timestatsv.append(statn)
     25411        if statn == 'percentiles':
     25412            Npercen = int(timest.split('@')[iamount+2])
     25413            timestatsv.append(Npercen)
     25414            stats.append(statn + '(' + str(Npercen) + ')')
     25415        else:
     25416            stats.append(statn)
     25417
     25418        timestats[iTst] = timestatsv
     25419
     25420        iTst = iTst + 1
     25421
     25422    NTsts = iTst
     25423    print infmsg
     25424    print '    ' + fname + ': ', NTsts, 'Temporal statistics to compute _______'
     25425    for iTst in range(NTsts):
     25426        print timestats[iTst]
     25427
     25428    # Getting tempral time-slices for each period
     25429    statslices = {}
     25430    for iTst in range(NTsts):
     25431        timestatv = timestats[iTst]
     25432        period = timestatv[0]
     25433        if period == 'LTday':
     25434            UTCshift = timestatv[1]
     25435            timevc = timev + UTCshift
     25436            period = 'day'
     25437            iamount = 2
     25438        else:
     25439            timevc = timev + 0
     25440            iamount = 1
     25441        amount = timestatv[iamount]
     25442
     25443        timeslice, Ntimeslice = gen.time_slices(timevc, timeu, timec, period, amount)
     25444        statslices[iTst] = [Ntimeslice, timeslice]
     25445 
     25446    # Creation of output file
     25447    ofile = fname + '.nc'
     25448    onewnc = NetCDFFile(ofile, 'w')
     25449
     25450    # Creation of dimensions
     25451    newdim = onewnc.createDimension('Tstat', NTsts)
     25452    newdim = onewnc.createDimension('Lstring', 256)
     25453    newdim = onewnc.createDimension('bounds', 2)
     25454
     25455    # Creation of variables
     25456    newvar = onewnc.createVariable('period', 'c', ('Tstat', 'Lstring'))
     25457    newvals = writing_str_nc(newvar, periods, 256)
     25458    basicvardef(newvar, 'period', 'Name of the time-period', '-')
     25459
     25460    newvar = onewnc.createVariable('statn', 'c', ('Tstat', 'Lstring'))
     25461    newvals = writing_str_nc(newvar, stats, 256)
     25462    basicvardef(newvar, 'statn', 'Name of the time-statistics', '-')
     25463
     25464    newvar = onewnc.createVariable('amount', 'i', ('Tstat'))
     25465    newvar[:] = amounts
     25466    basicvardef(newvar, 'amount', 'amount of the time-period', '1')
     25467
     25468    # Computing statistics
     25469    if variable == 'all':
     25470        varnames = onc.variables.keys()
     25471    else:
     25472        varnames = variable.split(',')
     25473
     25474    # Removing non-temporal variables
     25475    vartdim = {}
     25476    for varn in varnames:
     25477        ovar = onc.variables[varn]
     25478        if not gen.searchInlist(ovar.dimensions, timedimn):
     25479            varnames.remove(varn)
     25480        else:
     25481            vartdim[varn] = gen.index_vec(ovar.dimensions, timedimn)
     25482       
     25483    for iTst in range(NTsts):
     25484        statinf = timestats[iTst]
     25485        sliceinf = statslices[iTst]
     25486
     25487        Ntslc = sliceinf[0]
     25488        tslcs = sliceinf[1]
     25489
     25490        periodn = statinf[0]
     25491        if periodn == 'LTday':
     25492            UTCshift = statinf[1]
     25493            iamount = 2
     25494        else:
     25495            iamount = 1
     25496        amount = statinf[iamount]
     25497        statn = statinf[iamount+1]
     25498
     25499        if statn == 'percentiles': Npercen = statinf[iamount+2]
     25500
     25501        print '    ' + fname + ": period '" + periodn + "' amount:", amount,         \
     25502          'statistics:', statn, " ..."
     25503
     25504        # Adding period dimension and variables
     25505        newdim = onewnc.createDimension(periodn+'_time', Ntslc)
     25506        newvart = onewnc.createVariable(periodn+'_time', 'f8',                       \
     25507          (periodn+'_time'))
     25508        basicvardef(newvart, periodn+'_time', 'time for ' + periodn, timeu)
     25509        newvart.setncattr('calendar', timec)
     25510        newvart.setncattr('bounds', periodn+'_time_bounds')
     25511        newvarb = onewnc.createVariable(periodn+'_time_bounds', 'f8',                \
     25512          (periodn+'_time', 'bounds'))
     25513        basicvardef(newvarb, periodn+'_time_bounds', 'time boundaries for '+ periodn,\
     25514          timeu)
     25515        newvarb.setncattr('calendar', timec)
     25516        for it in range(Ntslc):
     25517            timeslcev = tslcs[it]
     25518            islc = timevc[timeslcev[0]]
     25519            eslc = timevc[timeslcev[1]]
     25520
     25521            newvart[it] = (eslc + islc) / 2.
     25522            newvarb[it,:] = [islc, eslc]
     25523        onewnc.sync()
     25524
     25525        for varn in varnames:
     25526            print '      variable:', varn
     25527            ovar = onc.variables[varn]
     25528            vardims = ovar.dimensions
     25529
     25530            # Shaping statistics variable
     25531            shapetstat = []
     25532            dimntstat = []
     25533            iid = 0
     25534            for dn in vardims:
     25535                if dn == timedimn:
     25536                    dimntstat.append(periodn+'_time')
     25537                    shapetstat.append(Ntslc)
     25538                    itdim = iid
     25539                else:
     25540                    dimntstat.append(dn)
     25541                    Ldim = len(onc.dimensions[dn])
     25542                    shapetstat.append(Ldim)
     25543                    # inserting dimension and its variable
     25544                    if not gen.searchInlist(onewnc.dimensions, dn):
     25545                        od = onc.dimensions[dn]
     25546                        Ldim = len(od)
     25547                        if od.isunlimited(): newdim = onewnc.createDimension(dn,None)
     25548                        else: newdim = onewnc.createDimension(dn,Ldim)
     25549
     25550                    dimvn = dimvarns[dn]
     25551                    if not onewnc.variables.has_key(dimvn):
     25552                        add_vars(onc,onewnc,[dimvn])
     25553                           
     25554                iid = iid + 1
     25555
     25556            if amount == 1:
     25557                newvarn = varn+periodn+statn
     25558            else:
     25559                newvarn = varn+str(amount)+periodn+statn
     25560
     25561            newvar = onewnc.createVariable(newvarn, 'f', tuple(dimntstat),          \
     25562              fill_value=gen.fillValueR)
     25563            varunits = get_varunits(ovar)
     25564            if statn == 'std': varunits = '(' + varunits + ')**2)'
     25565            CFvarattr = gen.variables_values(varn)
     25566            Lname = Lstatn[statn] + ' ' + Lperiodn[periodn] + ' ' +                  \
     25567              CFvarattr[4].replace('|',' ')
     25568            add_varattrs(onc,onewnc,[varn],[newvarn])
     25569            basicvardef(newvar, newvarn, Lname, varunits)
     25570            newvar.setncattr('cell_method', 'time: ' + Lstatn[statn])
     25571            newvar.setncattr('bounds', periodn+'_time_bounds')
     25572            if periodn == 'LTday': set_attributek(newvar, 'UTCshift', UTCshift, 'I')
     25573
     25574            tstat = np.ones(tuple(shapetstat), dtype=np.float)*gen.fillValueR
     25575
     25576            # Looping into the period
     25577            for islc in range(Ntslc):
     25578                timeslcv = tslcs[islc]
     25579               
     25580                timeslc = []
     25581                shapetimeslc = []
     25582                tstatslc = []
     25583                for dn in vardims:
     25584                    if dn == timedimn:
     25585                        timeslc.append(slice(timeslcv[0],timeslcv[1],timeslcv[2]))
     25586                        shapetimeslc.append(timeslcv[1]-timeslcv[0]+1)
     25587                        tstatslc.append(islc)
     25588                    else:
     25589                        Ldim = len(onc.dimensions[dn])
     25590                        timeslc.append(slice(0,Ldim))
     25591                        shapetimeslc.append(Ldim)
     25592                        tstatslc.append(slice(0,Ldim))
     25593
     25594                tvals = ovar[tuple(timeslc)]
     25595                if statn == 'min':
     25596                    tstat[tuple(tstatslc)] = np.min(tvals, axis=itdim)
     25597                elif statn == 'max':
     25598                    tstat[tuple(tstatslc)] = np.max(tvals, axis=itdim)
     25599                elif statn == 'mean':
     25600                    tstat[tuple(tstatslc)] = np.mean(tvals, axis=itdim)
     25601                elif statn == 'mean2':
     25602                    tstat[tuple(tstatslc)] = np.mean(tvals**2, axis=itdim)
     25603                elif statn == 'std':
     25604                    tstat[tuple(tstatslc)] = np.std(tvals, axis=itdim)
     25605                else:
     25606                    print errormsg
     25607                    print '  ' + fname + ": statisitcs '" + statn + "' not ready !!"
     25608                    statnor = Lstatn.keys()
     25609                    statnor.sort()
     25610                    print '    available ones:', statnor
     25611                    quit(-1)
     25612
     25613            newvar[:] = tstat
     25614            onewnc.sync()
     25615
     25616    # Adding PyNCplot
     25617    add_global_PyNCplot(onewnc, 'nc_var_tools', fname, '1.0')
     25618    onewnc.sync()
     25619
     25620    add_globattrs(onc, onewnc, 'all')
     25621    onewnc.sync()
     25622
     25623    onewnc.close()
     25624    print fname + ": successfull creation of file '" + ofile + "' !!"
     25625
     25626    return
     25627
     25628#vals = 'Time:WRFtime:day@1@min:bottom_top@ZNU,south_north@XLAT,west_east@XLONG'
     25629#temporal_stats(vals, '/home/lluis/PY/wrfout_d01_1995-01-01_00:00:00', 'T2')
     25630
    2527125631#quit()
Note: See TracChangeset for help on using the changeset viewer.