Changeset 2467 in lmdz_wrf for trunk/tools/generic_tools.py


Ignore:
Timestamp:
Apr 24, 2019, 4:52:18 PM (6 years ago)
Author:
lfita
Message:

Adding:

  • `change_CFcalendar': Changing CF-time values to a new calendar
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/generic_tools.py

    r2466 r2467  
    8686# chainSnum_levnext: Function to provide the next value for a given level from a chainStrnum hirerarchy of numbers
    8787# chainSnum_num: Function to pass a `ChainStrNum' string to a number
     88# change_CFcalendar: Changing CF-time values to a new calendar
    8889# change_CFRefdate: Change CF-time values with a new reference date
     90# change_CFTunits: Change CF-time values to a new temporal units
    8991# changedate360: Class to change a date  on a 360 days/yr (or 12 30-days months) calendar
    9092# check_timestep: Function to check if a time-units are 'timestep' based. If it's the case, transform them
     
    1624516247      newSrefdate: new CF refDate [YYYY]-[MM]-[HH] [HH]:[MM]:[SS]
    1624616248    >>> times = [15.5, 45, 74.5, 105, 135.5, 166, 196.5, 227.5, 258, 288.5, 319]
    16247     >>> change_CFRefdate(times, '1850-01-01 00:00:00', '1949-12-01 00:00:00')
    16248     [-36478.5 -36449.  -36419.5 -36389.  -36358.5 -36328.  -36297.5 -36266.5
    16249       -36236.  -36205.5 -36175. ]
     16249    >>> change_CFRefdate(times, 'days since 1850-01-01 00:00:00', '1949-12-01 00:00:00')
     16250    array([-36478.5 -36449.  -36419.5 -36389.  -36358.5 -36328.  -36297.5 -36266.5
     16251      -36236.  -36205.5 -36175. ]), 'days since 1949-12-01 00:00:00'
    1625016252    """
    1625116253    fname = 'change_CFRefedate'
     
    1634216344    newtimevals = newtimevals - newdays
    1634316345
     16346    newcftimeu = origtunits + ' since ' + newSrefdate
     16347
     16348    return newtimevals, newcftimeu
     16349
     16350def change_CFTunits(timevals, origcftimeu, newtunits):
     16351    """ Change CF-time values to a new temporal units
     16352       NOTE: CF-times does not authorize timeu = 'month'
     16353      timevals: actual CF time-values
     16354      origcftimeu: current original CF-time values [timeu] since [Refdate]
     16355      newtunits: new time units. Accepted ones: 'weeks', 'days', 'hours', 'minutes',
     16356        'seconds'
     16357    >>> times = [15.5, 45, 74.5, 105, 135.5, 166, 196.5, 227.5, 258, 288.5, 319]
     16358    >>> change_CFTunits(times, 'days since 1850-01-01 00:00:00', 'minutes')
     16359    array([  22320.,   64800.,  107280.,  151200.,  195120.,  239040.,
     16360      282960.,  327600.,  371520.,  415440.,  459360.]), 'minutes since 1850-01-01 00:00:00'
     16361    """
     16362    fname = 'change_CFTunits'
     16363
     16364    availtu = ['weeks', 'days', 'hours', 'minutes', 'seconds']
     16365
     16366    # original
     16367    origtv = origcftimeu.split(' ')
     16368    origtunits = origtv[0]
     16369    if len(origtv) == 4:
     16370        origSrefdate = origtv[2] + ' ' + origtv[3]
     16371    else:
     16372        print warnmsg
     16373        print '  ' + fname + ": original time units wihout time !!"
     16374        print "   adding it as '00:00:00'"
     16375        origSrefdate = origtv[2] + ' 00:00:00'
     16376
     16377    # From original to days
     16378    if origtunits == 'weeks':
     16379        odaysdtr = 7.
     16380    elif origtunits == 'days':
     16381        odaysdtr = 1.
     16382    elif origtunits == 'hours':
     16383        odaysdtr = 1./24.
     16384    elif origtunits == 'minutes':
     16385        odaysdtr = 1./(24.*60.)
     16386    elif origtunits == 'seconds':
     16387        odaysdtr = 1./(24.*3600.)
     16388    else:
     16389        print errormsg
     16390        print '  ' + fname + ": original time-units '" + origtunits + "' not ready !!"
     16391        print '    available ones: ', availtu
     16392        quit(-1)
     16393
     16394    # From days to new
     16395    if newtunits == 'weeks':
     16396        ndaysdtr = 1. / 7.
     16397    elif newtunits == 'days':
     16398        ndaysdtr = 1.
     16399    elif newtunits == 'hours':
     16400        ndaysdtr = 24.
     16401    elif newtunits == 'minutes':
     16402        ndaysdtr = 24. * 60.
     16403    elif newtunits == 'seconds':
     16404        ndaysdtr = 24. * 3600.
     16405    else:
     16406        print errormsg
     16407        print '  ' + fname + ": new time-units '" + newtunits + "' not ready !!"
     16408        print '    available ones: ', availtu
     16409        quit(-1)
     16410
     16411    # Conversion orig-new
     16412    conversion = odaysdtr*ndaysdtr
     16413
     16414    if type(timevals) != type(np.ones((2), dtype=int)):
     16415        newtimevals = np.array(timevals, dtype=np.float64)
     16416        newtimevals = newtimevals*conversion
     16417    else:
     16418        newtimevals = timevals*conversion
     16419
     16420    newcftimeu = newtunits + ' since ' + origSrefdate
     16421
     16422    return newtimevals, newcftimeu,
     16423
     16424def change_CFcalendar(timevals, origcftimeu, origcal, newcal='gregorian'):
     16425    """ Changing CF-time values to a new calendar
     16426      timevals: actual CF time-values
     16427      origcftimeu: current original CF-time values [timeu] since [Refdate]
     16428      newcal: new calendar. Accepted ones: 'gregorian', 'standard'
     16429    >>> times = [15.5, 45, 74.5, 105, 135.5, 166, 196.5, 227.5, 258, 288.5, 319]
     16430    >>> change_CFcalendar(times, 'days since 1850-01-01 00:00:00', 'noleap', 'gregorian')
     16431    [  15.5   45.    74.5  105.   135.5  166.   196.5  227.5  258.   288.5
     16432      319. ]
     16433    >>> times = [56649.5, 56680, 56710.5, 56741, 56771.5, 56802.5, 56833, 56863.5, 56894, 56924.5]
     16434    >>> change_CFcalendar(times, 'days since 1850-01-01 00:00:00', 'noleap', 'gregorian')
     16435    [ 56687.5  56718.   56748.5  56779.   56809.5  56840.5  56871.   56901.5
     16436      56932.   56962.5]
     16437    """
     16438    fname = 'change_CFcalendar'
     16439    availorigcal = ['noleap', '365d']
     16440    availnewcal = ['gregorian', 'standard']
     16441
     16442    # If the calendar is not gregorian, it needs to be fixed from origSrefdate!
     16443    if origcal == 'noleap' or origcal == '365d':
     16444        print '  ' + fname + ": found non-standard calendar '" + origcal + "' !!"
     16445        if newcal == 'gregorian' or newcal == 'standard':
     16446            # Imposing to gregorian calendar
     16447            newtimevals = gen_impose_gregorian(timevals, origcftimeu, origcal)     
     16448        else:
     16449            print errormsg
     16450            print '  ' + fname + ": new calendar '" + newcal + "' not ready !!"
     16451            print '    avaialable ones:', availnewcal
     16452            quit(-1)
     16453
     16454    else:
     16455        print errormsg
     16456        print '  ' + fname + ": original calendar '" + origcal + "' not ready !!"
     16457        print '    avaialable ones:', availorigcal
     16458        quit(-1)
     16459
    1634416460    return newtimevals
    1634516461
    16346 times = [15.5, 45, 74.5, 105, 135.5, 166, 196.5, 227.5, 258, 288.5, 319]
    16347 print change_CFRefdate(times, 'days since 1850-01-01 00:00:00', '1949-12-01 00:00:00')
    16348 
    1634916462#quit()
    1635016463
Note: See TracChangeset for help on using the changeset viewer.