Changeset 2443 in lmdz_wrf for trunk/tools


Ignore:
Timestamp:
Apr 16, 2019, 7:39:34 PM (6 years ago)
Author:
lfita
Message:

Fixing `impose_gregorian'
Adding 'calendar' on timref_datetime

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/generic_tools.py

    r2442 r2443  
    377377    return newstring
    378378
     379def remove_extraspaces(string, maxNspaces=30):
     380    """ Function to remove from a string any chain of more or equal than 2 spaces
     381      string: string to modify
     382      maxNspaces: maximum number of consecutive spaces to look for (30 default value)
     383    >>> remove_extraspaces('  87047 01011991    6  19.0 6 70 7   27    2  17.9   874.9  1471.0              1    2      4 5  1  0      ')
     384    87047 01011991 6 19.0 6 70 7 27 2 17.9 874.9 1471.0 1 2 4 5 1 0
     385    """
     386    fname = 'remove_extraspaces'
     387
     388    newstring = string + ''
     389    for i in range(maxNspaces,1,-1):
     390        spaces = Ntchar(' ',i)
     391        newstring = newstring.replace(spaces, ' ')
     392       
     393    return newstring
     394
    379395def string_dicvals_char(dictionary, string, char):
    380396    """ Function to provide a string taking values from a given [string] where each single character
     
    10721088
    10731089    return dateYmdHMS
     1090
     1091
     1092def impose_gregorian(timev, Tunits, cal):
     1093    """ Function to impose gregorian calendar to a series of times with a
     1094        non-standard calendar
     1095      timev: list of values
     1096      Tunits: CF units of time [Tunits] since [DateRef]
     1097      cal: non standard calendar
     1098      >>> impose_gregorian(np.range(800,10000,100), 'days since 1949-12-01 00:00:00',
     1099        'noleap')
     1100      [ 800. 901.]
     1101    """
     1102    import datetime as dt
     1103    fname = 'impose_gregorian'
     1104
     1105    availTu = ['weeks', 'days', 'hours', 'minutes', 'seconds']
     1106    availcalendar = ['noleap', '365d']
     1107
     1108    lTunits = Tunits.split(' ')
     1109    NTunits = len(lTunits)
     1110    Tu = lTunits[0]
     1111    if NTunits < 4:
     1112        print infmsg
     1113        print '  ' + fname + ": CF-time units without time, adding '00:00:00' !!"
     1114        Srefdate = lTunits[2] + ' 00:00:00'
     1115        refdate = dt.datetime.combine(dateStr_date(lTunits[2]),                      \
     1116          timeStr_time('00:00:00'))
     1117    else:
     1118        Srefdate = lTunits[2] + ' ' + lTunits[3]
     1119        refdate = dt.datetime.combine(dateStr_date(lTunits[2]),                      \
     1120          timeStr_time(lTunits[3]))
     1121
     1122    if type(timev) == type(range(2)):
     1123        dimt = len(timev)
     1124        timev = np.array(timev)
     1125    elif type(timev) == type(np.arange(2)):
     1126        dimt = timev.shape[0]
     1127    elif type(timev) == type(int(2)) or type(timev) == type(np.float(2.)) or         \
     1128      type(timev) == type(float(2.)) or type(timev) == type(np.float32(2.)) or       \
     1129      type(timev) == type(np.float64(2.)):
     1130        dimt = 1
     1131        timev = np.ones(dimt, dtype=type(timev))*timev
     1132    else:
     1133        print errormsg
     1134        print '  ' + fname + ": type of time values: '", type(timev), "' not ready !!"
     1135        print '    available ones:', type(range(2)), type(np.arange(2)),type(int(2)),\
     1136          type(np.float(2.)), type(float(2.)), type(np.float32(2.)),                 \
     1137          type(np.float64(2.))
     1138        quit(-1)
     1139
     1140    if Tu == 'weeks':
     1141        timevsecs = timev * 24. * 7 * 3600.
     1142    elif Tu == 'days':
     1143        timevsecs = timev * 24. * 3600.
     1144    elif Tu == 'hours':
     1145        timevsecs = timev * 3600.
     1146    elif Tu == 'minutes':
     1147        timevsecs = timev * 60.
     1148    elif Tu == 'seconds':
     1149        timevsecs = timev * 1.
     1150    else:
     1151        print errormsg
     1152        print '  ' + fname + ": CF time units '" + Tu + "' not ready !!"
     1153        print '    available ones:', availTu
     1154        quit(-1)
     1155
     1156    newtimes = np.zeros((dimt), dtype=np.float64)
     1157
     1158    yrref = refdate.year
     1159    if cal == 'noleap' or cal == '365d':
     1160        for it in range(dimt):
     1161            # Some issues in implementations/machines ...
     1162            # FROM: https://stackoverflow.com/questions/33566939/timedelta-error-with-numpy-longdouble-dtype
     1163            tv = int(timevsecs[it])
     1164            deltaT = dt.timedelta(seconds=tv)
     1165            datetime = refdate + deltaT
     1166            yr = datetime.year
     1167            Nleapd = leapdays(yrref, yr)
     1168            if datetime.month <= 2 and days_month(yr, 2) > 28: Nleapd = Nleapd - 1
     1169            newtimes[it] = timevsecs[it] + Nleapd*24*3600.
     1170    else:
     1171        print errormsg
     1172        print '  ' + fname + ": calendar '" + cal + "' not ready !!"
     1173        print '    available ones:', availcalendar
     1174        quit(-1)
     1175       
     1176    # Re-transforming to the original units
     1177    if Tu == 'weeks':
     1178        newtimes = newtimes/(24.*7*3600.)
     1179    elif Tu == 'days':
     1180        newtimes = newtimes/(24.*3600.)
     1181    elif Tu == 'hours':
     1182        newtimes = newtimes/(3600.)
     1183    elif Tu == 'minutes':
     1184        newtimes = newtimes/(60.)
     1185
     1186    return newtimes
    10741187
    10751188def period_information(idate, edate, totunits):
     
    30433156    return newdate
    30443157
    3045 def timeref_datetime(refd, timeval, tu):
     3158def timeref_datetime(refd, timeval, tu, cal='gregorian'):
    30463159    """ Function to transform from a [timeval] in [tu] units from the time referece [tref] to datetime object
    3047     refd: time of reference (as datetime object)
    3048     timeval: time value (as [tu] from [tref])
    3049     tu: time units
    3050     >>> timeref = date(1949,12,1,0,0,0)
    3051     >>> timeref_datetime(timeref, 229784.36, hours)
    3052     1976-02-17 08:21:36
     3160      refd: time of reference (as datetime object)
     3161      timeval: time value (as [tu] from [tref])
     3162      tu: time units
     3163      cal: calendar
     3164      >>> timeref_datetime(dt.datetime(1949,12,1,0,0,0), 229784.36, 'hours')
     3165        1976-02-17 08:21:36
     3166      >>> timeref_datetime(dt.datetime(1949,12,1,0,0,0), 230784.36, 'hours')
     3167        1976-03-30 00:21:36
     3168      >>> timeref_datetime(dt.datetime(1949,12,1,0,0,0), 230784.36, 'hours', 'noleap')
     3169        1976-04-06 00:21:36
    30533170    """
    30543171    import datetime as dt
    30553172    import numpy as np
     3173
     3174    availtu = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'miliseconds']
     3175
     3176    daterefS = str(refd.year).zfill(4) + '-' + str(refd.month).zfill(2) + '-' +      \
     3177      str(refd.day).zfill(2) + ' ' + str(refd.hour).zfill(2) + ':'+                  \
     3178      str(refd.minute).zfill(2) + ':' + str(refd.second).zfill(2)
     3179
     3180    # For non-gregorian calendars, we impose gregorian (since, we are using python)
     3181    if cal == 'noleap' or cal == '365d':
     3182        timev = impose_gregorian(timeval, tu + ' since ' + daterefS, cal)
     3183    else:
     3184        timev = timeval + 0.
    30563185
    30573186## Not in timedelta
     
    30613190#        realdate = refdate + dt.timedelta(months=float(timeval))
    30623191    if tu == 'weeks':
    3063         realdate = refd + dt.timedelta(weeks=float(timeval))
     3192        realdate = refd + dt.timedelta(weeks=float(timev))
    30643193    elif tu == 'days':
    3065         realdate = refd + dt.timedelta(days=float(timeval))
     3194        realdate = refd + dt.timedelta(days=float(timev))
    30663195    elif tu == 'hours':
    3067         realdate = refd + dt.timedelta(hours=float(timeval))
     3196        realdate = refd + dt.timedelta(hours=float(timev))
    30683197    elif tu == 'minutes':
    3069         realdate = refd + dt.timedelta(minutes=float(timeval))
     3198        realdate = refd + dt.timedelta(minutes=float(timev))
    30703199    elif tu == 'seconds':
    3071         realdate = refd + dt.timedelta(seconds=float(timeval))
     3200        realdate = refd + dt.timedelta(seconds=float(timev))
    30723201    elif tu == 'milliseconds':
    3073         realdate = refd + dt.timedelta(milliseconds=float(timeval))
     3202        realdate = refd + dt.timedelta(milliseconds=float(timev))
    30743203    else:
    3075           print errormsg
    3076           print '    timeref_datetime: time units "' + tu + '" not ready!!!!'
    3077           quit(-1)
     3204        print errormsg
     3205        print '  ' + fname + ": time units '" + tu + "' not ready!!!!"
     3206        print '    available ones:', availtu
     3207        quit(-1)
    30783208
    30793209    return realdate
     
    1566815798#        print '  ' , '(', inds[i,j,0], ',', inds[i,j,1], ')'
    1566915799
    15670 def remove_extraspaces(string, maxNspaces=30):
    15671     """ Function to remove from a string any chain of more or equal than 2 spaces
    15672       string: string to modify
    15673       maxNspaces: maximum number of consecutive spaces to look for (30 default value)
    15674     >>> remove_extraspaces('  87047 01011991    6  19.0 6 70 7   27    2  17.9   874.9  1471.0              1    2      4 5  1  0      ')
    15675     87047 01011991 6 19.0 6 70 7 27 2 17.9 874.9 1471.0 1 2 4 5 1 0
    15676     """
    15677     fname = 'remove_extraspaces'
    15678 
    15679     newstring = string + ''
    15680     for i in range(maxNspaces,1,-1):
    15681         spaces = Ntchar(' ',i)
    15682         newstring = newstring.replace(spaces, ' ')
    15683        
    15684     return newstring
    15685 
    15686 def impose_gregorian(timev, Tunits, cal):
    15687     """ Function to impose gregorian calendar to a series of times with a
    15688         non-standard calendar
    15689       timev: list of values
    15690       Tunits: CF units of time [Tunits] since [DateRef]
    15691       cal: non standard calendar
    15692       >>> impose_gregorian(np.range(800,10000,100), 'days since 1949-12-01 00:00:00',
    15693         'noleap')
    15694       [ 800. 901.]
    15695     """
    15696     import datetime as dt
    15697     fname = 'impose_gregorian'
    15698 
    15699     availTu = ['weeks', 'days', 'hours', 'minutes', 'seconds']
    15700     availcalendar = ['noleap', '365d']
    15701 
    15702     lTunits = Tunits.split(' ')
    15703     NTunits = len(lTunits)
    15704     Tu = lTunits[0]
    15705     if NTunits < 4:
    15706         print infmsg
    15707         print '  ' + fname + ": CF-time units without time, adding '00:00:00' !!"
    15708         Srefdate = lTunits[2] + ' 00:00:00'
    15709         refdate = dt.datetime.combine(dateStr_date(lTunits[2]),                      \
    15710           timeStr_time('00:00:00'))
    15711     else:
    15712         Srefdate = lTunits[2] + ' ' + lTunits[3]
    15713         refdate = dt.datetime.combine(dateStr_date(lTunits[2]),                      \
    15714           timeStr_time(lTunits[3]))
    15715 
    15716     if type(timev) == type(range(2)):
    15717         dimt = len(timev)
    15718         timev = np.array(timev)
    15719     elif type(timev) == type(np.arange(2)):
    15720         dimt = timev.shape[0]
    15721     else:
    15722         print errormsg
    15723         print '  ' + fname + ": type of time values: '", type(timev), "' not ready !!"
    15724         print '    available ones:', type(range(2)), type(np.arange(2))
    15725 
    15726     if Tu == 'weeks':
    15727         timevsecs = timev * 24. * 7 * 3600.
    15728     elif Tu == 'days':
    15729         timevsecs = timev * 24. * 3600.
    15730     elif Tu == 'hours':
    15731         timevsecs = timev * 3600.
    15732     elif Tu == 'minutes':
    15733         timevsecs = timev * 60.
    15734     elif Tu == 'seconds':
    15735         timevsecs = timev * 1.
    15736     else:
    15737         print errormsg
    15738         print '  ' + fname + ": CF time units '" + Tu + "' not ready !!"
    15739         print '    available ones:', availTu
    15740         quit(-1)
    15741 
    15742     newtimes = np.zeros((dimt), dtype=np.float64)
    15743 
    15744     yrref = refdate.year
    15745     if cal == 'noleap' or cal == '365d':
    15746         for it in range(dimt):
    15747             # Some issues in implementations/machines ...
    15748             # FROM: https://stackoverflow.com/questions/33566939/timedelta-error-with-numpy-longdouble-dtype
    15749             tv = int(timevsecs[it])
    15750             deltaT = dt.timedelta(seconds=tv)
    15751             datetime = refdate + deltaT
    15752             yr = datetime.year
    15753             Nleapd = leapdays(yrref, yr)
    15754             if datetime.month <= 2 and days_month(yr, 2) > 28: Nleapd = Nleapd - 1
    15755             newtimes[it] = timevsecs[it] + Nleapd*24*3600.
    15756     else:
    15757         print errormsg
    15758         print '  ' + fname + ": calendar '" + cal + "' not ready !!"
    15759         print '    available ones:', availcalendar
    15760         quit(-1)
    15761        
    15762     # Re-transforming to the original units
    15763     if Tu == 'weeks':
    15764         newtimes = newtimes/(24.*7*3600.)
    15765     elif Tu == 'days':
    15766         newtimes = newtimes/(24.*3600.)
    15767     elif Tu == 'hours':
    15768         newtimes = newtimes/(24.*3600.)
    15769     elif Tu == 'minutes':
    15770         newtimes = newtimes/(60.)
    15771 
    15772     return newtimes
    1577315800
    1577415801#quit()
Note: See TracChangeset for help on using the changeset viewer.