Changeset 2462 in lmdz_wrf for trunk/tools/generic_tools.py
- Timestamp:
- Apr 23, 2019, 7:43:12 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/generic_tools.py
r2461 r2462 118 118 # files_folder_HMT: Function to retrieve a list of files from a folder [fold] and files with [head]*[middle]*[tail] 119 119 # fill_Narray: Function to fill a n-dimensional array with an arrary of lesser rank 120 # gen_leapdays: Function to provide how many leap days are between two years avoiding datetime 121 # generate_CFtimes: Function to generate CFtimes for a given period, frequency and units 120 122 # get_configuration: Function to get the configuration from an ASCII external file 121 123 # get_right_CFtimeunits: Function to get the right CFtime units from any given format 122 124 # get_specdictionary_HMT: Function to get specific values from a dictionary by selcting that keys with H*M*T 123 125 # getting_fixedline: Function to get the values from a line of text with fixed lenght of different values 124 # generate_CFtimes: Function to generate CFtimes for a given period, frequency and units125 126 # grib_CFequiv: Function to provide the CF name of a GRIB variable code number 126 127 # inf_operSlist: Function to provide information from a string as a list separated by … … 142 143 # juliandate: Function to provide the julian date (in days since -4712 January 1st 00 UTC) 143 144 # for any greogiran date 145 # juliandate_gregorian: Function to convert from julian date (days since -4712 146 # January 1st 00 UTC) to the equivalent greogiran date 144 147 # latex_fig_array: Function to add an array of figures to an existing tex file 145 148 # latex_text: Function to transform a text to LaTeX following style rules … … 546 549 for iyr in range(yeari,yeare+1): 547 550 if days_month(iyr,2) == 29: Nleapdays=Nleapdays+1 551 552 return Nleapdays 553 554 def leapyr(yr): 555 """ Function to determine if it is a leap year (independently of datetime) 556 FROM: https://en.wikipedia.org/wiki/Leap_year 557 yr: year to check 558 >>> leapyr(2019) 559 False 560 >>> leapyr(1976) 561 True 562 >>> leapyr(1800) 563 False 564 >>> leapyr(1850) 565 False 566 """ 567 fname = 'leapyr' 568 569 isleap = False 570 if np.mod(yr,4) == 0: isleap = True 571 if np.mod(yr,100) == 0: isleap = False 572 if np.mod(yr,400) == 0: isleap = True 573 574 return isleap 575 576 def gen_leapdays(yeari, yeare): 577 """ Function to provide how many leap days are between two years avoiding datetime 578 yeari: initial year from [yeari] Jan 01 579 yeare: end year until [yearf] Dec 12 580 >>> gen_leapdays(1970,1980) 581 3 582 >>> gen_leapdays(1976,1976) 583 1 584 >>> gen_leapdays(1850,1976) 585 31 586 """ 587 fname = 'gen_leapdays' 588 589 Nleapdays = 0 590 for iyr in range(yeari,yeare+1): 591 if leapyr(iyr): Nleapdays=Nleapdays+1 548 592 549 593 return Nleapdays … … 1976 2020 1977 2021 yrref = refdate.year 2022 if cal == 'noleap' or cal == '365d': 2023 for it in range(dimt): 2024 # Some issues in implementations/machines ... 2025 # FROM: https://stackoverflow.com/questions/33566939/timedelta-error-with-numpy-longdouble-dtype 2026 tv = int(timevsecs[it]) 2027 deltaT = dt.timedelta(seconds=tv) 2028 datetime = refdate + deltaT 2029 yr = datetime.year 2030 if yr > yrref: 2031 Nleapd = leapdays(yrref, yr) 2032 else: 2033 Nleapd = leapdays(yr, yrref) 2034 if datetime.month <= 2 and days_month(yr, 2) > 28: Nleapd = Nleapd - 1 2035 newtimes[it] = timevsecs[it] + Nleapd*24*3600. 2036 else: 2037 print errormsg 2038 print ' ' + fname + ": calendar '" + cal + "' not ready !!" 2039 print ' available ones:', availcalendar 2040 quit(-1) 2041 2042 # Re-transforming to the original units 2043 if Tu == 'weeks': 2044 newtimes = newtimes/(24.*7*3600.) 2045 elif Tu == 'days': 2046 newtimes = newtimes/(24.*3600.) 2047 elif Tu == 'hours': 2048 newtimes = newtimes/(3600.) 2049 elif Tu == 'minutes': 2050 newtimes = newtimes/(60.) 2051 2052 return newtimes 2053 2054 def gen_impose_gregorian(timev, Tunits, cal): 2055 """ Function to impose gregorian calendar to a series of times with a 2056 non-standard calendar independently from datetime (imposes yr > 1900) 2057 timev: list of values 2058 Tunits: CF units of time [Tunits] since [DateRef] 2059 cal: non standard calendar 2060 >>> gen_impose_gregorian(np.range(800,10000,100), 'days since 1850-01-01 00:00:00', 2061 'noleap') 2062 [ 800. 901.] 2063 >>> gen_impose_gregorian(-7277.460938, 'days since 1949-12-01 00:00:00', 'noleap') 2064 [-7272.460938] 2065 """ 2066 fname = 'gen_impose_gregorian' 2067 2068 availTu = ['weeks', 'days', 'hours', 'minutes', 'seconds'] 2069 availcalendar = ['noleap', '365d'] 2070 2071 lTunits = Tunits.split(' ') 2072 NTunits = len(lTunits) 2073 Tu = lTunits[0] 2074 2075 if NTunits < 4: 2076 print infmsg 2077 print ' ' + fname + ": CF-time units without time, adding '00:00:00' !!" 2078 Srefdate = lTunits[2] + ' 00:00:00' 2079 else: 2080 Srefdate = lTunits[2] + ' ' + lTunits[3] 2081 refdate = [int(Srefdate[0:4]), int(Srefdate[5:7]), int(Srefdate[8:10]), \ 2082 int(Srefdate[11:13]), int(Srefdate[14,16]), int(Srefdate[17:19]) ] 2083 2084 if type(timev) == type(range(2)): 2085 dimt = len(timev) 2086 timev = np.array(timev) 2087 elif type(timev) == type(np.arange(2)): 2088 dimt = timev.shape[0] 2089 elif type(timev) == type(int(2)) or type(timev) == type(np.float(2.)) or \ 2090 type(timev) == type(float(2.)) or type(timev) == type(np.float32(2.)) or \ 2091 type(timev) == type(np.float64(2.)): 2092 dimt = 1 2093 timev = np.ones(dimt, dtype=type(timev))*timev 2094 else: 2095 print errormsg 2096 print ' ' + fname + ": type of time values: '", type(timev), "' not ready !!" 2097 print ' available ones:', type(range(2)), type(np.arange(2)),type(int(2)),\ 2098 type(np.float(2.)), type(float(2.)), type(np.float32(2.)), \ 2099 type(np.float64(2.)) 2100 quit(-1) 2101 2102 if Tu == 'weeks': 2103 timevsecs = timev * 24. * 7 * 3600. 2104 elif Tu == 'days': 2105 timevsecs = timev * 24. * 3600. 2106 elif Tu == 'hours': 2107 timevsecs = timev * 3600. 2108 elif Tu == 'minutes': 2109 timevsecs = timev * 60. 2110 elif Tu == 'seconds': 2111 timevsecs = timev * 1. 2112 else: 2113 print errormsg 2114 print ' ' + fname + ": CF time units '" + Tu + "' not ready !!" 2115 print ' available ones:', availTu 2116 quit(-1) 2117 2118 newtimes = np.zeros((dimt), dtype=np.float64) 2119 2120 refsecs = juliandate(refdate[0], refdate[1], refdate[2], refdate[3], refdate[4], refdate[5]) 2121 refsecs = refsecs*3600. 2122 2123 yrref = refdate[0] 1978 2124 if cal == 'noleap' or cal == '365d': 1979 2125 for it in range(dimt): … … 15808 15954 # print ' ' , '(', inds[i,j,0], ',', inds[i,j,1], ')' 15809 15955 15810 def leapyr(yr):15811 """ Function to determine if it is a leap year (independently of datetime)15812 FROM: https://en.wikipedia.org/wiki/Leap_year15813 yr: year to check15814 >>> leapyr(2019)15815 False15816 >>> leapyr(1976)15817 True15818 >>> leapyr(1800)15819 False15820 >>> leapyr(1850)15821 False15822 """15823 fname = 'leapyr'15824 15825 isleap = False15826 if np.mod(yr,4) == 0: isleap = True15827 if np.mod(yr,100) == 0: isleap = False15828 if np.mod(yr,400) == 0: isleap = True15829 15830 return isleap15831 15832 15956 def sign(number): 15833 15957 """ Function to provide the sign of a number … … 15891 16015 15892 16016 return juliand 16017 16018 def juliandate_gregorian(juliand): 16019 """ Function to convert from julian date (days since -4712 January 1st 00 UTC) 16020 to the equivalent greogiran date 16021 juliand: julian date to convert 16022 FROM: https://aa.usno.navy.mil/faq/docs/JD_Formula.php 16023 after 1990 edition of the U.S. Naval Observatory's Almanac for Computers 16024 >>> juliandate_gregorian(2406843.3125) 16025 [1877, 8.0, 11, 7, 30, 0.0] 16026 >>> juliandate_gregorian(2041601.3125) 16027 [877, 8.0, 11, 7, 30, 0.0] 16028 >>> juliandate_gregorian(2440588.0) 16029 [1970, 1.0, 1, 0, 0, 0.0] 16030 >>> juliandate_gregorian(2443510.0) 16031 [1978, 1.0, 1, 0, 0, 0.0] 16032 >>> juliandate_gregorian(2443712.625) 16033 [1978, 7.0, 22, 15, 0, 0.0] 16034 """ 16035 fname = 'juliandate_gregorian' 16036 16037 L = int(juliand+68569) 16038 N = 4*L/146097 16039 L = L-(146097*N+3)/4 16040 I = 4000*(L+1)/1461001 16041 L = L-1461*I/4+31 16042 J = 80*L/2447 16043 K = L-2447*J/80 16044 L = J/11 16045 J = J+2.-12.*L 16046 I = 100*(N-49)+I+L 16047 16048 yr = I 16049 mo = J 16050 dd = K 16051 16052 # hr, mi, ss 16053 ut = juliand - int(juliand) 16054 utsecs = ut*24.*3600. 16055 hh = int(utsecs/3600.) 16056 mi = int((utsecs - hh*3600.)/60.) 16057 ss = utsecs - hh*3600. - mi*60. 16058 16059 return [yr, mo, dd, hh, mi, ss] 15893 16060 15894 16061 def fix_CFdates(timevals, origcftimeu, origcal, \ … … 15943 16110 secref = 0 15944 16111 15945 addsecs = horref*3600 + minref*60 + secref 15946 addsS = str(addsecs) 15947 15948 # Using shell date `coreutil' 15949 seconds = sub.Popen('/bin/date +%s -u -d"' + origSrefdate[0:10] + ' ' + addsS + \ 15950 ' seconds"', shell=True, stdout=sub.PIPE) 15951 origsecondsdiff = np.float64(seconds.communicate()[0].replace('\n','')) 16112 seconds = juliandate(yrref,monref,dayref,horref,minref,secref) 16113 seconds = seconds*24.*3600. 15952 16114 15953 16115 # new … … 15956 16118 newSrefdate = newtv[2] 15957 16119 15958 yr ref=newSrefdate[0:4]15959 mon ref=newSrefdate[5:7]15960 day ref=newSrefdate[8:10]15961 15962 if int(yr ref) < 1970: newsing = -1.16120 yrnew=newSrefdate[0:4] 16121 monnew=newSrefdate[5:7] 16122 daynew=newSrefdate[8:10] 16123 16124 if int(yrnew) < 1970: newsing = -1. 15963 16125 else: newsing = 1. 15964 16126 15965 16127 # Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] 15966 16128 ## 15967 t refT = newcftimeu.find(':')15968 if not t refT == -1:16129 tnewT = newcftimeu.find(':') 16130 if not tnewT == -1: 15969 16131 if len(newtv) == 3: 15970 hor ref=int(newSrefdate[11:13])15971 min ref=int(newSrefdate[14:16])15972 sec ref=int(newSrefdate[17:19])16132 hornew=int(newSrefdate[11:13]) 16133 minnew=int(newSrefdate[14:16]) 16134 secnew=int(newSrefdate[17:19]) 15973 16135 else: 15974 16136 newSreftime = newtv[3] 15975 hor ref=int(newSreftime[0:2])15976 min ref=int(newSreftime[3:5])15977 sec ref=int(newSreftime[6:8])16137 hornew=int(newSreftime[0:2]) 16138 minnew=int(newSreftime[3:5]) 16139 secnew=int(newSreftime[6:8]) 15978 16140 else: 15979 horref = 0 15980 minref = 0 15981 secref = 0 15982 15983 addsecs = horref*3600 + minref*60 + secref 15984 addsS = str(addsecs) 15985 15986 # Using shell date `coreutil' 15987 seconds = sub.Popen('/bin/date +%s -u -d"' + newSrefdate[0:10] + ' ' + addsS + \ 15988 ' seconds"', shell=True, stdout=sub.PIPE) 15989 newsecondsdiff = np.float64(seconds.communicate()[0].replace('\n','')) 16141 hornew = 0 16142 minnew = 0 16143 secnew = 0 16144 16145 seconds = juliandate(yrnew,monnew,daynew,hornew,minnew,secnew) 16146 16147 # Using shell date `coreutil' (a relic of the past...) 16148 #seconds = sub.Popen('/bin/date +%s -u -d"' + newSrefdate[0:10] + ' ' + addsS + \ 16149 # ' seconds"', shell=True, stdout=sub.PIPE) 16150 #newsecondsdiff = np.float64(seconds.communicate()[0].replace('\n','')) 16151 16152 # If the calendar is not gregorian, it needs to be fixed from origSrefdate! 16153 if origcal == 'noleap' or origcal == '365d': 16154 print ' ' + fname + ": found non-standard calendar '" + origcal + "' !!" 16155 # Imposing to gregorian calendar 16156 newtimevals = gen_impose_gregorian(timevals, origcftimeu, origcal) 15990 16157 15991 16158 # Seconds difference respect new date … … 16015 16182 else: 16016 16183 newtimevals = timevals*secsdtr 16184 16017 16185 newtimevals = newtimevals + origsecondsdiff 16018 16186 newtimevals = newtimevals - newsecondsdiff … … 16038 16206 newtimevals = newtimevals / secsdtr 16039 16207 16040 if origcal == 'noleap3' or origcal == '365d':16041 print ' ' + fname + ": found non-standard calendar '" + origcal + "' !!"16042 # Imposing to gregorian calendar16043 newtimevals = impose_gregorian(newtimevals, newcftimeu, origcal)16044 16045 16208 return newtimevals 16046 16209
Note: See TracChangeset
for help on using the changeset viewer.