From 3d5aca3662d15ea7e66c1ac358c83fc86fd319b2 Mon Sep 17 00:00:00 2001 From: miniufo Date: Sat, 11 Apr 2020 10:59:13 +0800 Subject: [PATCH 1/2] fix dt is mo or yr --- .gitignore | 3 +++ ctls/test10.ctl | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 ctls/test10.ctl diff --git a/.gitignore b/.gitignore index 285ea6c..28ddbd2 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,6 @@ dmypy.json .pyre/ .idea + +# private things +private/ diff --git a/ctls/test10.ctl b/ctls/test10.ctl new file mode 100644 index 0000000..88cb9b8 --- /dev/null +++ b/ctls/test10.ctl @@ -0,0 +1,23 @@ +dset ^EMI_2019_monthly.grd +byteswapped +title CUACE_emi_index data +undef -9999. +pdef 360 320 lcc 35.00 103.50 180.50 160.50 30.00 60.00 103.50 15000. 15000. +xdef 1220 linear 62.33 .0676 +ydef 682 linear 11.18 .0676 +zdef 1 levels 1 +tdef 12 linear JAN2019 1mo +vars 12 +emi_index 0 99 pm u2/m3 +demi_index 0 99 pm u2/m3 +emisdep_index 0 99 pm u2/m3 +diff_index 0 99 pm u2/m3 +trans_index 0 99 pm u2/m3 +trans_in 0 99 pm u2/m3 +trans_out 0 99 pm u2/m3 +surf_index 0 99 pm 1/1 +semi_index 0 99 pm u2/m3 +sdemi_index 0 99 pm u2/m3 +emitest_index 0 99 pm u2/m3 +deptest_index 0 99 pm u2/m3 +endvars From b47e8c43445eb129ef9fa902c4af8f8129fb4d94 Mon Sep 17 00:00:00 2001 From: miniufo Date: Sat, 11 Apr 2020 10:59:52 +0800 Subject: [PATCH 2/2] fix dt is mo or yr --- tests/test_CtlDescriptor.py | 6 +-- tests/test_openDataset.py | 4 +- xgrads/core.py | 80 ++++++++++++++++++++++++++++++++----- 3 files changed, 76 insertions(+), 14 deletions(-) diff --git a/tests/test_CtlDescriptor.py b/tests/test_CtlDescriptor.py index bcc0b0a..d891923 100644 --- a/tests/test_CtlDescriptor.py +++ b/tests/test_CtlDescriptor.py @@ -5,7 +5,7 @@ @author: MiniUFO Copyright 2018. All rights reserved. Use is subject to license terms. """ -from xgrads.core import CtlDescriptor +from xgrads.xgrads import CtlDescriptor content=\ @@ -23,7 +23,7 @@ print(CtlDescriptor(content=content)) -for i in range(9): - print(CtlDescriptor(file='../ctls/test'+str(i+1)+'.ctl')) +for i in range(10): + print(CtlDescriptor(file='./xgrads/ctls/test'+str(i+1)+'.ctl')) print('\n') diff --git a/tests/test_openDataset.py b/tests/test_openDataset.py index f829dde..dd890e9 100644 --- a/tests/test_openDataset.py +++ b/tests/test_openDataset.py @@ -5,7 +5,7 @@ @author: MiniUFO Copyright 2018. All rights reserved. Use is subject to license terms. """ -from xgrads.core import open_CtlDataset +from xgrads.xgrads import open_CtlDataset import xarray as xr #dset = open_CtlDataset('D:/Data/ULFI/output/2017101712_1721.ctl') @@ -16,7 +16,7 @@ # dset = open_CtlDataset('D:/Data/MITgcm/flt/float/Stat.ctl') # dset = open_CtlDataset('../ctls/test8.ctl') -dset = open_CtlDataset('../ctls/test9.ctl') +dset = open_CtlDataset('./xgrads/ctls/test9.ctl') dset2 = xr.tutorial.open_dataset('air_temperature') diff --git a/xgrads/core.py b/xgrads/core.py index f5c535d..7d02b08 100644 --- a/xgrads/core.py +++ b/xgrads/core.py @@ -321,12 +321,10 @@ def _processTDef(self, oneline): if tokens[2]!='linear': raise Exception('nonlinear tdef is not supported') - start = GrADStime_to_datetime64(tokens[3]) - intv = GrADS_increment_to_timedelta64(tokens[4]) - - self.incre = intv - self.tdef = Coordinate('tdef', np.arange(start, - start + intv * tnum, intv)) + times = self._times_to_array(tokens[3], tokens[4], tnum) + + self.incre = GrADS_increment_to_timedelta64(tokens[4]) + self.tdef = Coordinate('tdef', times) def _processVars(self, oneline, fileContent): if (self.dtype != 'station' and @@ -510,6 +508,52 @@ def _split_by_len(self, s, size): return [s[i:i + size] for i in range(0, chunks, size)] + + def _times_to_array(self, strTime, incre, tnum): + """ + Convert GrADS time string of strart time and increment + to an array of numpy.datetime64. + + Parameters + ---------- + strTime : str + Grads start time e.g., 00:00z01Jan2000. + incre : str + Grads time increment in str format e.g., 1dy. + tnum : int + Grads time increment in str format e.g., 1dy. + + Returns + ---------- + re : numpy array of datetime64 + """ + if 'mo' in incre: + start = GrADStime_to_datetime(strTime) + + lst = [] + for l in range(tnum): + y, m = start.year, start.month + y, m = y+int((m+l-1)/12), int((m+l-1)%12)+1 + lst.append(start.replace(year=y, month=m)) + + return np.asarray(lst, dtype='datetime64[s]') + + elif 'yr' in incre: + start = GrADStime_to_datetime(strTime) + + lst = [] + for l in range(tnum): + y = start.year + l + lst.append(start.replace(year=y)) + + return np.asarray(lst, dtype='datetime64[s]') + + else: + start = GrADStime_to_datetime64(strTime) + intv = GrADS_increment_to_timedelta64(incre) + + return np.arange(start, start + intv * tnum, intv) + def __str__(self): """ Print this class as a string. @@ -530,7 +574,7 @@ def __str__(self): ' periodicX: ' + str(self.periodicX) + '\n'\ ' cal365Days: ' + str(self.cal365Days)+ '\n'\ ' sequential: ' + str(self.hasData) + '\n'\ - ' byteOrder: ' + str(self.hasData) + '\n'\ + ' byteOrder: ' + str(self.byteOrder) + '\n'\ ' xdef: ' + str(self.xdef) + '\n'\ ' ydef: ' + str(self.ydef) + '\n'\ ' zdef: ' + str(self.zdef) + '\n'\ @@ -761,7 +805,7 @@ def open_CtlDataset(desfile): return dset -def GrADStime_to_datetime64(gradsTime): +def GrADStime_to_datetime(gradsTime): """ Convert GrADS time string e.g., 00:00z01Jan2000 to numpy.datetime64 @@ -772,7 +816,7 @@ def GrADStime_to_datetime64(gradsTime): Returns ---------- - re : datetime64 + re : datetime """ lens = len(gradsTime) @@ -787,6 +831,24 @@ def GrADStime_to_datetime64(gradsTime): else: raise Exception('invalid length of GrADS date/time string') + return time + + +def GrADStime_to_datetime64(gradsTime): + """ + Convert GrADS time string e.g., 00:00z01Jan2000 to numpy.datetime64 + + Parameters + ---------- + gradsTime : str + Grads time in str format e.g., 00:00z01Jan2000. + + Returns + ---------- + re : datetime64 + """ + time = GrADStime_to_datetime(gradsTime) + return datetime64(time.strftime('%Y-%m-%dT%H:%M:%S'))