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


Ignore:
Timestamp:
Mar 26, 2019, 3:42:24 PM (6 years ago)
Author:
lfita
Message:

Adding 'cfTimeCal' into datetimeStr_conversion' in order to take into account the calendar attribute in cfTimes'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/generic_tools.py

    r2419 r2421  
    106106# DateTimeStr_date: Function to transform a string date-time ([YYYY][MM][DD][HH][MI][SS] format) to a date object
    107107# datetimeStr_datetime: Function to transform a string date-time ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object
     108# days_month: Function to give the number of days of a month of a given year
    108109# DegMinSec_angle: Function to transform Degrees Minutes Seconds to an angle
    109110# dictionary_key: Function to provide the first key in a dictionay with a given value
     
    490491    return combos
    491492
     493def days_month(year,month):
     494    """ Function to give the number of days of a month of a given year
     495    >>> days_month(1976,2)
     496    29
     497    """
     498    import datetime as dt
     499
     500    date1=dt.date(year,month,1)
     501    if month+1 > 12:
     502        date2=dt.date(year+1,1,1)
     503    else:
     504        date2=dt.date(year,month+1,1)
     505
     506    diffdate = date2-date1
     507    return diffdate.days
     508
    492509def datetimeStr_datetime(StringDT):
    493510    """ Function to transform a string date ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object
     
    529546      [typeSi/o]
    530547        'cfTime',[units]: time in CF-convention format [units] = [tunits] since [refdate]
     548        'cfTimeCal',[units],[calendar]: time in CF-convention format
     549           [units] = [tunits] since [refdate] taking into account the [calendar]
     550            attribute (available values:
     551              * leap years: 'leap', '365d', 'gregorian', 'Gregorian', 'standard',
     552                'Standard'
     553              * no-leap years: 'noleap', '360d'
    531554        'matYmdHMS': numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]]
    532555        'YmdHMS': [YYYY][MM][DD][HH][MI][SS] format
     
    551574    availableSio = {'cfTime,[units]': 'time in CF-convention format [units] = ' +    \
    552575        '[tunits] since [refdate]',                                                  \
     576        'cfTimeCal,[units],[calendar]': 'time in CF-convention format [units] = ' +  \
     577        '[tunits] since [refdate] & [calendar]',                                     \
    553578        'matYmdHMS': 'numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]]', \
    554579        'YmdHMS': '[YYYY][MM][DD][HH][MI][SS] format',                               \
     
    562587
    563588    availcftimeu = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']
     589    availcalendar = ['leap', '366d', 'gregorian', 'Gregorian', 'standard',           \
     590      'Standard', 'noleap', '365d', '360d']
    564591
    565592    if StringDT[0:1] == 'h':
     
    607634            newdate = refdate + dt.timedelta(seconds=float(timeval))
    608635        elif tunits == 'milliseconds':
     636            newdate = refdate + dt.timedelta(milliseconds=float(timeval))
     637        else:
     638              print errormsg
     639              print '  ' + fname + ': time units"' + tunits + '" not ready!!!!'
     640              print '    available ones:', availcftimeu
     641              quit(-1)
     642
     643        yr = newdate.year
     644        mo = newdate.month
     645        da = newdate.day
     646        ho = newdate.hour
     647        mi = newdate.minute
     648        se = newdate.second
     649    elif typeSi[0:6] == 'cfTimeCal':
     650        timeval = np.float(StringDT)
     651        tunits = typeSi.split(',')[1].split(' ')[0]
     652        Srefdate = typeSi.split(',')[1].split(' ')[2]
     653        calendar = typeSi.split(',')[2]
     654
     655        if not gen.searchInlist(availcalendar , calendar):
     656            print errormsg
     657            print '  ' + fname + ": calendar '" + + "' not ready !!"
     658            print '    avaialable ones:', availcalendar
     659            quit(-1)
     660
     661# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
     662##
     663        yrref=Srefdate[0:4]
     664        monref=Srefdate[5:7]
     665        dayref=Srefdate[8:10]
     666
     667        trefT = typeSi.split(',')[1].find(':')
     668        if not trefT == -1:
     669            if len(typeSi.split(',')[1].split(' ')) == 3:
     670                horref=Srefdate[11:13]
     671                minref=Srefdate[14:16]
     672                secref=Srefdate[17:19]
     673            else:
     674                Sreftime = typeSi.split(',')[1].split(' ')[3]
     675                horref=Sreftime[0:2]
     676                minref=Sreftime[3:5]
     677                secref=Sreftime[6:8]               
     678            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
     679              '_' + horref + ':' + minref + ':' + secref)
     680        else:
     681            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
     682              '_00:00:00')
     683
     684        if calendar == 'noleap' or calendar == '365d':
     685            removeleap = False
     686            newdate = refdate + dt.timedelta(weeks=float(timeval))
     687            if days_month(newdate.year,2) == 29:
     688                if newdate.mon == 2 and newdate.day == 28:
     689                    removeleap = True
     690                elif newdate.mon > 2: removeleap = True
     691
     692        if tunits == 'weeks':
     693            if removeleap: timeval = timeval - 1./7.
     694            newdate = refdate + dt.timedelta(weeks=float(timeval))
     695        elif tunits == 'days':
     696            if removeleap: timeval = timeval - 1.
     697            newdate = refdate + dt.timedelta(days=float(timeval))
     698        elif tunits == 'hours':
     699            if removeleap: timeval = timeval - 1.*24.
     700            newdate = refdate + dt.timedelta(hours=float(timeval))
     701        elif tunits == 'minutes':
     702            if removeleap: timeval = timeval - 1.*24.*60.
     703            newdate = refdate + dt.timedelta(minutes=float(timeval))
     704        elif tunits == 'seconds':
     705            if removeleap: timeval = timeval - 1.*24.*3600.
     706            newdate = refdate + dt.timedelta(seconds=float(timeval))
     707        elif tunits == 'milliseconds':
     708            if removeleap: timeval = timeval - 1.*24.*3600.*1000.
    609709            newdate = refdate + dt.timedelta(milliseconds=float(timeval))
    610710        else:
     
    737837        else:
    738838            totsecs = difft.days()*24*3600. + difft.seconds()
     839
     840        if tunits == 'weeks':
     841            cfdt = totsecs / (7*24*3600)
     842        elif tunits == 'days':
     843            cfdt = totsecs / (24*3600)
     844        elif tunits == 'hours':
     845            cfdt = totsecs / (3600)
     846        elif tunits == 'minutes':
     847            cfdt = totsecs / (60)
     848        elif tunits == 'seconds':
     849            cfdt = totsecs
     850        elif tunits == 'milliseconds':
     851            cfdt = totsecs*100.
     852        else:
     853              print errormsg
     854              print '  ' + fname + ': time units"' + tunits + '" not ready!!!!'
     855              print '    available ones:', availcftimeu
     856              quit(-1)
     857        dateYmdHMS = cfdt
     858       
     859    elif typeSo[0:6] == 'cfTimeCal':
     860        tunits = typeSo.split(',')[1].split(' ')[0]
     861        Srefdate = typeSo.split(',')[1].split(' ')[2]
     862        calendar = typeSo.split(',')[2]
     863
     864        if not gen.searchInlist(availcalendar , calendar):
     865            print errormsg
     866            print '  ' + fname + ": calendar '" + + "' not ready !!"
     867            print '    avaialable ones:', availcalendar
     868            quit(-1)
     869
     870# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
     871##
     872        yrref=Srefdate[0:4]
     873        monref=Srefdate[5:7]
     874        dayref=Srefdate[8:10]
     875
     876        trefT = typeSo.split(',')[1].find(':')
     877        if not trefT == -1:
     878#            print '  ' + fname + ': refdate with time!'
     879            if len(typeSo.split(',')[1].split(' ')) == 3:
     880                horref=Srefdate[11:13]
     881                minref=Srefdate[14:16]
     882                secref=Srefdate[17:19]
     883            else:
     884                Sreftime = typeSo.split(',')[1].split(' ')[3]
     885                horref=Sreftime[0:2]
     886                minref=Sreftime[3:5]
     887                secref=Sreftime[6:8]               
     888
     889            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
     890              '_' + horref + ':' + minref + ':' + secref)
     891        else:
     892            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
     893              '_00:00:00')
     894        datei = dt.datetime(yr, mo, da, ho, mi, se)
     895        difft = datei - refdate
     896
     897        if searchInlist(dir(difft),'total_seconds'):
     898            totsecs = difft.total_seconds()
     899        else:
     900            totsecs = difft.days()*24*3600. + difft.seconds()
     901
     902        if calendar == 'noleap' or calendar == '365d':
     903            removeleap = False
     904            if days_month(newdate.year,2) == 29:
     905                if datei.mon == 2 and datei.day == 28:
     906                    totsecs = totsecs - 24.*3600.
     907                if datei.mon > 2:
     908                    totsecs = totsecs - 24.*3600.
    739909
    740910        if tunits == 'weeks':
     
    52155385    return diffunits
    52165386
    5217 def days_month(year,month):
    5218     """ Function to give the number of days of a month of a given year
    5219     >>> days_month(1976,2)
    5220     29
    5221     """
    5222     import datetime as dt
    5223 
    5224     date1=dt.date(year,month,1)
    5225     if month+1 > 12:
    5226         date2=dt.date(year+1,1,1)
    5227     else:
    5228         date2=dt.date(year,month+1,1)
    5229 
    5230     diffdate = date2-date1
    5231     return diffdate.days
    5232 
    52335387def mid_period(yr1,mon1,day1,hour1,min1,sec1,yr2,mon2,day2,hour2,min2,sec2):
    52345388    """ Function to give the mid poiint of a period
Note: See TracChangeset for help on using the changeset viewer.