10 from __future__
import print_function
14 from datetime
import datetime
17 from argparse
import ArgumentParser, ArgumentDefaultsHelpFormatter
18 from pathlib
import Path
20 IODA_CONV_PATH = Path(__file__).parent/
"@SCRIPT_LIB_PATH@"
21 if not IODA_CONV_PATH.is_dir():
22 IODA_CONV_PATH = Path(__file__).parent/
'..'/
'lib-python'
23 sys.path.append(
str(IODA_CONV_PATH.resolve()))
25 import ioda_conv_ncio
as iconv
26 from orddicts
import DefaultOrderedDict
31 def __init__(self, filename, begindate=None, enddate=None):
44 Read and store the data.
45 This file can be downloaded from:
46 http://www.argo.ucsd.edu/Gridded_fields.html
47 Global gridded NetCDF Argo only dataset produced by optimal interpolation
48 doi:10.1002/2017GL073426
52 nc = nc4.Dataset(self.
filenamefilename,
'r')
54 raise IOError(
'%s file not found!' % self.
filenamefilename)
56 raise Exception(
'Unknown error opening %s' % self.
filenamefilename)
59 res = [x
for x
in list(nc.variables.keys())
if re.search(
"^ARGO_.*MEAN$", x)]
62 self.
varnamevarname = res[0].split(
'_')[1]
63 print(
"%s contains the variable: %s" % (self.
filenamefilename, self.
varnamevarname))
65 raise NameError(
"No useable variable was found in the file %s" % self.
filenamefilename)
67 assert self.
varnamevarname
in [
'TEMPERATURE',
'SALINITY'],\
68 "%s is not a valid variable name" % self.
varnamevarname
70 lon = nc.variables[
'LONGITUDE'][:]
71 lat = nc.variables[
'LATITUDE'][:]
72 pres = nc.variables[
'PRESSURE'][:]
75 dtime = nc.variables[
'TIME']
76 time360day = nc4.num2date(dtime[:], dtime.units, calendar=
'360_day')
79 timeArray = np.array([datetime.strptime(x.strftime(
'%Y%m%d%H'),
'%Y%m%d%H')
for x
in time360day])
82 if self.
begindatebegindate
is not None and timeArray[0] <= self.
begindatebegindate <= timeArray[-1]:
83 bI = bisect.bisect_left(timeArray, self.
begindatebegindate)
86 if self.
enddateenddate
is not None and timeArray[0] <= self.
enddateenddate <= timeArray[-1]:
87 eI = bisect.bisect_left(timeArray, self.
enddateenddate) + 1
89 if bI == 0
and eI == -1:
90 anomaly = nc.variables[
'ARGO_%s_ANOMALY' % self.
varnamevarname][:]
92 elif bI == 0
and eI > -1:
93 anomaly = nc.variables[
'ARGO_%s_ANOMALY' % self.
varnamevarname][:eI, :]
95 elif bI > 0
and eI == -1:
96 anomaly = nc.variables[
'ARGO_%s_ANOMALY' % self.
varnamevarname][bI:, :]
98 elif bI > 0
and eI > -1:
99 anomaly = nc.variables[
'ARGO_%s_ANOMALY' % self.
varnamevarname][bI:eI, :]
100 time = timeArray[bI:eI]
102 mean = nc.variables[
'ARGO_%s_MEAN' % self.
varnamevarname][:]
105 fullField = anomaly + np.tile(mean, (anomaly.shape[0], 1, 1, 1))
110 raise IOError(
'%s file could not be closed!' % self.
filenamefilename)
112 raise Exception(
'Unknown error closing %s' % self.
filenamefilename)
116 self.
datadata[
'lat'] = lat
117 self.
datadata[
'lon'] = lon
118 self.
datadata[
'pres'] = pres
119 self.
datadata[
'time'] = time
120 self.
datadata[
'field'] = fullField.data
129 Initialize IODA writer class,
130 transform to IODA data structure and,
131 write out to IODA file.
138 (
"latitude",
"float"),
139 (
"longitude",
"float"),
140 (
"pressure",
"float"),
141 (
"datetime",
"string")
146 'date_time_string': self.
datedate.strftime(
"%Y-%m-%dT%H:%M:%SZ")
155 valKey = argo.varname, self.
writerwriter.OvalName()
156 errKey = argo.varname, self.
writerwriter.OerrName()
157 qcKey = argo.varname, self.
writerwriter.OqcName()
160 for t, time
in enumerate(argo.data[
'time']):
161 for y, lat
in enumerate(argo.data[
'lat']):
162 for x, lon
in enumerate(argo.data[
'lon']):
163 for z, pres
in enumerate(argo.data[
'pres']):
165 locKey = lat, lon, pres, time.strftime(
'%Y-%m-%dT%H:%M:%SZ')
167 val = argo.data[
'field'][t, z, y, x]
171 self.
datadata[recKey][locKey][valKey] = val
172 self.
datadata[recKey][locKey][errKey] = err
173 self.
datadata[recKey][locKey][qcKey] = qc
177 (ObsVars, LocMdata, VarMdata) = self.
writerwriter.ExtractObsData(self.
datadata)
178 self.
writerwriter.BuildNetcdf(ObsVars, LocMdata, VarMdata, self.
AttrDataAttrData)
185 desc =
'Convert ARGO gridded global data to IODA netCDF4 format'
186 parser = ArgumentParser(
188 formatter_class=ArgumentDefaultsHelpFormatter)
190 '-i',
'--input', help=
'name of the Global ARGO file',
191 type=str, required=
True)
193 '-o',
'--output', help=
'name of the output IODA netCDF ARGO file',
194 type=str, required=
True, default=
None)
196 '-d',
'--date', help=
'file date', metavar=
'YYYYMMDDHH',
197 type=str, required=
True)
199 '-b',
'--begindate', help=
'end date for data time window', metavar=
'YYYYMMDDHH',
200 type=str, required=
False, default=
None)
202 '-e',
'--enddate', help=
'end date for data time window', metavar=
'YYYYMMDDHH',
203 type=str, required=
False, default=
None)
205 args = parser.parse_args()
207 filename = args.input
208 foutput = args.output
209 fdate = datetime.strptime(args.date,
'%Y%m%d%H')
210 bdate =
None if args.begindate
is None else datetime.strptime(args.begindate,
'%Y%m%d%H')
211 edate =
None if args.enddate
is None else datetime.strptime(args.enddate,
'%Y%m%d%H')
213 argo =
argoClim(filename, begindate=bdate, enddate=edate)
215 IODA(foutput, fdate, argo)
218 if __name__ ==
'__main__':
def __init__(self, filename, date, argo)
def __init__(self, filename, begindate=None, enddate=None)