Changeset 2476 in lmdz_wrf


Ignore:
Timestamp:
Apr 26, 2019, 9:21:12 PM (6 years ago)
Author:
lfita
Message:

Adding:

  • `from360d_reg': Function to transform from 360d = 12 * 30d calendar to a regular one
Location:
trunk/tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/generic_tools.py

    r2474 r2476  
    1616from cStringIO import StringIO
    1717import sys
     18import module_ForGen as gen
    1819
    1920main = 'nc_var_tools.py'
     
    123124# fill_Narray: Function to fill a n-dimensional array with an arrary of lesser rank
    124125# fix_CFdates: Fixing CF-time values with wrong setting
     126# from360d_reg: Function to transform from 360d = 12 * 30d calendar to a regular one
    125127# fromanydate_CFYmd: Function to transform from any string format of date to Y-m-d used in
    126128#   CF-conventions
     
    638640    2443510.0
    639641    >>> juliandate(1978,7,21,15,0,0)
    640     2443712.625
     642    2443711.625
    641643    >>> juliandate(2000,1,1,0,0,0)
    642644    2451545.0
     
    644646    fname = 'juliandate'
    645647
    646     sec1 = dd - 32075.
    647     sec2 = 1461.*(yr+4800.+(mo-14)/12.)/4.
    648     sec3 = 367.*(mo-2-(mo-14)/12.*12)/12.
    649     sec4 = 3.*((yr+4900.+(mo-14.)/12.)/100.)/4.
    650  
    651     juliand = int(sec1 + sec2 + sec3 - sec4)
     648    I= int(yr)
     649    J= int(mo)
     650    K= int(dd)
     651
     652    # With python it is not working!!
     653    #sec1 = K - 32075.
     654    #sec2 = 1461.*(I+4800.+(J-14.)/12.)/4.
     655    #sec3 = 367.*(J-2.-(J-14.)/12.*12.)/12.
     656    #sec4 = 3.*((I+4900.+(J-14.)/12.)/100.)/4.
     657    #juliand = int(sec1 + sec2 + sec3 - sec4)
     658    juliand = gen.module_generic.jd(I,J,K)
    652659
    653660    juliand = juliand*1. + (hr + mi/60. + ss/3600.)/24.
    654 
    655     # Alternative (without full agreement, just kept in case)
    656     #K = yr + 0
    657     #M = mo + 0
    658     #I = dd + 0
    659     #UT = hr*1. + mi/60. + ss/3600.
    660 
    661     #sec1 = 367.*K
    662     #sec2 = int((7.*(K+int((M+9)/12.)))/4.)
    663     #sec3 = int((275.*M)/9.)
    664     #sec4 = I*1.
    665     #sec5 = 1721013.5
    666     #sec6 = UT/24.
    667     #sec7 = 0.5*sign(100.*K+M*1.-190002.5)
    668     #sec8 = 0.5
    669 
    670     #juliand = sec1 - sec2 + sec3 + sec4 + sec5 + sec6 - sec7 + sec8
    671     #print '  juliand:', juliand
    672661
    673662    return juliand
     
    687676    >>> juliandate_gregorian(2443510.0)
    688677    [1978, 1.0, 1, 0, 0, 0.0]
    689     >>> juliandate_gregorian(2443712.625)
    690     [1978, 7.0, 22, 15, 0, 0.0]
     678    >>> juliandate_gregorian(2443711.625)
     679    [1978, 7.0, 21, 15, 0, 0.0]
    691680    """
    692681    fname = 'juliandate_gregorian'
     
    703692    I = 100*(N-49)+I+L
    704693
    705     yr = I
    706     mo = J
    707     dd = K
     694    yr = int(I)
     695    mo = int(J)
     696    dd = int(K)
    708697
    709698    # hr, mi, ss
     
    1647316462    """ Classs to provide information of CFtime units
    1647416463      cftimeu: CF time units to provide information for [Timeu] since [RefDate]
     16464      * attributes:
     16465        refdate: reference date in Y-m-d H:M:S format
     16466        refdateYMHdms = reference date in YmdHMS format
     16467        refdatemat = reference date in matricial format
     16468        refdatejuliand = reference date as julian date (days since -4712 January 1st
     16469          00 UTC)
     16470        refdateDT = reference date as datetime object
     16471        Tunits = origtunits
     16472        utoweeks = Factor to convert values from original temporal units to weeks
     16473        utodays = Factor to convert values from original temporal units to days
     16474        utohours = Factor to convert values from original temporal units to hours
     16475        utominutes = Factor to convert values from original temporal units to minutes
     16476        utoseconds = Factor to convert values from original temporal units to seconds
    1647516477    """
    1647616478
    1647716479    def __init__(self, cftimeu):
     16480        import datetime as dt
    1647816481        fname = 'CFtimeU_inf'
     16482
     16483        availtu = ['weeks', 'days', 'hours', 'minutes', 'seconds']
     16484
    1647916485        origtv = cftimeu.split(' ')
    1648016486        origtunits = origtv[0]
     
    1650916515        secrefS = str(secref).zfill(2)
    1651016516
     16517        # Transforming factors
     16518        if origtunits == 'weeks':
     16519            self.utoweeks = 1.
     16520            self.utodays = 7.
     16521            self.utohours = 7. * 24.
     16522            self.utominutes = 7. * 24. * 60.
     16523            self.utoseconds = 7. * 24. * 3600.
     16524        elif origtunits == 'days':
     16525            self.utoweeks = 1. / 7.
     16526            self.utodays = 1.
     16527            self.utohours = 24.
     16528            self.utominutes = 24. * 60.
     16529            self.utoseconds = 24. * 3600.
     16530        elif origtunits == 'hours':
     16531            self.utoweeks = 1. / ( 7. * 24.)
     16532            self.utodays = 1. / 24.
     16533            self.utohours = 1.
     16534            self.utominutes = 60.
     16535            self.utoseconds = 3600.
     16536        elif origtunits == 'minutes':
     16537            self.utoweeks = 1. / ( 7. * 24. * 60.)
     16538            self.utodays = 1. / ( 24. * 60.)
     16539            self.utohours = 1. / 60.
     16540            self.utominutes = 1.
     16541            self.utoseconds = 60.
     16542        elif origtunits == 'seconds':
     16543            self.utoweeks = 1. / ( 7. * 24. * 3600.)
     16544            self.utodays = 1. / ( 24. * 3600.)
     16545            self.utohours = 1. / 3600.
     16546            self.utominutes = 1. / 60.
     16547            self.utoseconds = 1.
     16548        else:
     16549            print errormsg
     16550            print '  ' + fname + ": new time-units '" + origtunits + "' not ready !!"
     16551            print '    available ones: ', availtu
     16552            quit(-1)
     16553
    1651116554        self.refdate = origSrefdate + ' ' + horrefS + ':' + minrefS + ':' + secrefS
    1651216555        self.refdateYMHdms = origSrefdate[0:4] + origSrefdate[5:7] +                 \
    1651316556          origSrefdate[8:10] + horrefS + ':' + minrefS + ':' + secrefS
    1651416557        self.refdatemat = [yrref, monref, dayref, horref, minref, secref]
     16558        self.refdatejuliand = juliandate(yrref,monref,dayref,horref,minref,secref)
     16559        if yrref >= 1900: self.refdateDT = dt.datetime(yrref,monref,dayref,horref,   \
     16560          minref,secref)
     16561        else: self.refdateDT = None
     16562
    1651516563        self.Tunits = origtunits
    1651616564
    16517 def from360d_reg(tvals, tunits):
     16565def from360d_reg(tvals, tunits, kind='right'):
    1651816566    """ Function to transform from 360d = 12 * 30d calendar to a regular one
    1651916567      tvals: temporal values
    1652016568      tunits: units of the values in CF format [Tunits] since [RefDate]
    16521     """
     16569      kind: kind of transformation to apply
     16570        'right': only transforming the right days of each month
     16571        'monpercen': transforming using the day as the percentage of month
     16572        'spread': spreading the dates to a regular year leaving the last 5 days empty
     16573    >>> from360d_reg(np.arange(15.5, 120+15.5,30), 'days since 1970-01-01 00:00:00', kind='right')
     16574    [  15.5   46.5   74.5  105.5]
     16575    >>> from360d_reg(np.arange(15.5, 120+15.5,30), 'days since 1970-01-01 00:00:00', kind='monpercen')
     16576    [  15.5   45.5   74.5  105.5]
     16577    """
     16578    import numpy.ma as ma
     16579    import datetime as dt
     16580
    1652216581    fname = 'from360d_reg'
    1652316582
     16583    availkinds = ['right', 'monpercen']
     16584
    1652416585    inftunits = CFtimeU_inf(tunits)
    1652516586
    1652616587    refdate = inftunits.refdatemat
     16588
     16589    if type(tvals) == type(range(2)):
     16590        dimt = len(tvals)
     16591        tvals = np.array(tvals)
     16592        dT = tvals[1] - tvals[0]
     16593    elif type(tvals) == type(np.arange(2)):
     16594        dimt = tvals.shape[0]
     16595        dT = tvals[1] - tvals[0]
     16596    elif type(tvals) == type(int(2)) or type(tvals) == type(np.float(2.)) or         \
     16597      type(tvals) == type(float(2.)) or type(tvals) == type(np.float32(2.)) or       \
     16598      type(tvals) == type(np.float64(2.)):
     16599        dimt = 1
     16600        tvals = np.ones(dimt, dtype=type(tvals))*tvals
     16601        dT = 30.
     16602    else:
     16603        print errormsg
     16604        print '  ' + fname + ": type of time values: '", type(tvals), "' not ready !!"
     16605        print '    available ones:', type(range(2)), type(np.arange(2)),type(int(2)),\
     16606          type(np.float(2.)), type(float(2.)), type(np.float32(2.)),                 \
     16607          type(np.float64(2.))
     16608        quit(-1)
     16609
     16610    # Transforming to days
     16611    dtvals = tvals*inftunits.utodays
     16612    dyear = 12.*30
    1652716613   
    16528 
     16614    newtvals = tvals*0.
     16615
     16616    if kind == 'right':
     16617        # Here only the 'correct' dates will be transformed (right day of the month)
     16618        for it in range(dimt):
     16619
     16620            # Getting year, month and day
     16621            Nyears = int(tvals[it] / dyear)
     16622            yd = refdate[0] + Nyears
     16623            jd = tvals[it] - Nyears*dyear
     16624            md = int(jd/30) + 1
     16625            dd = int(jd - (md-1)*30)
     16626
     16627            # Getting hour, minute, second
     16628            tt = jd - int(jd)
     16629            tsecs = tt*24.*3600.
     16630            hh = int(tsecs/(3600.))
     16631            mi = int((tsecs - hh*3600.)/60.)
     16632            ss = tsecs - hh*3600. - mi*60.
     16633
     16634            # Number days of the month in the regular calendar
     16635            Nd_regmon = days_month(yd,md)
     16636            if dd > Nd_regmon: mewtvals[it] = fillvalueF
     16637            else:
     16638                juliand = juliandate(yd,md,dd,hh,mi,ss)
     16639                newtvals[it] = juliand - inftunits.refdatejuliand + 1
     16640                # Transforming to original units
     16641                newtvals[it] = newtvals[it]/inftunits.utodays
     16642    elif kind == 'monpercen':
     16643        # Here only the 'correct' dates will be transformed (day as percentage of the month)
     16644        for it in range(dimt):
     16645
     16646            # Getting year, month and day
     16647            Nyears = int(tvals[it] / dyear)
     16648            yd = int(refdate[0] + Nyears)
     16649            jd = tvals[it] - Nyears*dyear
     16650            md = int(jd/30) + 1
     16651            dd = int(jd - (md-1)*30)
     16652
     16653            # Getting hour, minute, second
     16654            tt = jd - int(jd)
     16655            tsecs = tt*24.*3600.
     16656            hh = int(tsecs/(3600.))
     16657            mi = int((tsecs - hh*3600.)/60.)
     16658            ss = tsecs - hh*3600. - mi*60.
     16659
     16660            # Number days of the month in the regular calendar
     16661            Nd_regmon = days_month(yd,md)
     16662            dd = int(dd*Nd_regmon/30.)
     16663            ddt = dt.datetime(yd,md,dd,hh,mi,int(ss)) - inftunits.refdateDT
     16664            juliand = juliandate(yd,md,dd,hh,mi,ss)
     16665            newtvals[it] = juliand - inftunits.refdatejuliand + 1
     16666            # Transforming to original units
     16667            newtvals[it] = newtvals[it]/inftunits.utodays
     16668    else:
     16669        print errormsg
     16670        print '  ' + fname + ": kind of transformtion '" + kind + "' not ready !!"
     16671        print '    available ones:', availkinds
     16672        quit(-1)
     16673
     16674    if dimt == 1:
     16675        newtt = newtvals[0] + 0.
     16676        newtvals = None
     16677        newtvals = newtt + 0.
     16678    else:
     16679        newtvals = ma.masked_equal(newtvals, fillValueF)
     16680   
    1652916681    return newtvals
    1653016682
  • trunk/tools/module_generic.f90

    r2475 r2476  
    11601160  K= day
    11611161
    1162   PRINT *,1461*(I+4800+(J-14)/12)/4, 1461*(I+4800+(J-14)/12)/4.
    1163 
    11641162  JD= K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)/12-3*((I+4900+(J-14)/12)/100)/4
    11651163
Note: See TracChangeset for help on using the changeset viewer.