10 from __future__
import print_function
13 from datetime
import datetime
14 from scipy.io
import FortranFile
15 from argparse
import ArgumentParser, ArgumentDefaultsHelpFormatter
16 from pathlib
import Path
18 IODA_CONV_PATH = Path(__file__).parent/
"@SCRIPT_LIB_PATH@"
19 if not IODA_CONV_PATH.is_dir():
20 IODA_CONV_PATH = Path(__file__).parent/
'..'/
'lib-python'
21 sys.path.append(
str(IODA_CONV_PATH.resolve()))
23 import ioda_conv_ncio
as iconv
24 from orddicts
import DefaultOrderedDict
42 Based on subroutine rd_trak in ocn_obs.f
46 fh = FortranFile(self.
filenamefilename, mode=
'r', header_dtype=
'>u4')
48 raise IOError(
'%s file not found!' % self.
filenamefilename)
50 raise Exception(
'Unknown error opening %s' % self.
filenamefilename)
55 data[
'n_obs'], data[
'n_lvl'], data[
'n_vrsn'] = fh.read_ints(
'>i4')
57 print(
' number trak obs: %d' % data[
'n_obs'])
58 print(
' max number levels: %d' % data[
'n_lvl'])
59 print(
'file version number: %d' % data[
'n_vrsn'])
61 if data[
'n_obs'] <= 0:
62 print(
'No trak observations to process from %s' % self.
filenamefilename)
65 data[
'ob_wm'] = fh.read_reals(
'>i4')
66 data[
'ob_gsal'] = fh.read_reals(
'>f4')
67 data[
'ob_gsst'] = fh.read_reals(
'>f4')
68 data[
'ob_lat'] = fh.read_reals(
'>f4')
69 data[
'ob_lon'] = fh.read_reals(
'>f4')
70 data[
'ob_age'] = fh.read_reals(
'>f4')
71 data[
'ob_csal'] = fh.read_reals(
'>f4')
72 data[
'ob_csst'] = fh.read_reals(
'>f4')
73 data[
'ob_qc_sal'] = fh.read_reals(
'>f4')
74 data[
'ob_qc_sst'] = fh.read_reals(
'>f4')
75 data[
'ob_qc_vel'] = fh.read_reals(
'>f4')
76 data[
'ob_rsal'] = fh.read_reals(
'>f4')
77 data[
'ob_rsst'] = fh.read_reals(
'>f4')
78 data[
'ob_sal'] = fh.read_reals(
'>f4')
79 data[
'ob_sst'] = fh.read_reals(
'>f4')
80 data[
'ob_typ'] = fh.read_reals(
'>i4')
81 data[
'ob_uuu'] = fh.read_reals(
'>f4')
82 data[
'ob_vvv'] = fh.read_reals(
'>f4')
83 data[
'ob_dtg'] = fh.read_record(
'>S12').astype(
'U12')
84 data[
'ob_rcpt'] = fh.read_record(
'>S12').astype(
'U12')
85 data[
'ob_scr'] = fh.read_record(
'>S1').astype(
'U1')
86 data[
'ob_sgn'] = fh.read_record(
'>S6').astype(
'U6')
87 data[
'ob_csgm'] = fh.read_reals(
'>f4')
88 data[
'ob_gsgm'] = fh.read_reals(
'>f4')
89 data[
'ob_rsgm'] = fh.read_reals(
'>f4')
100 def __init__(self, filename, date, varDict, obsList):
102 Initialize IODA writer class,
103 transform to IODA data structure and,
104 write out to IODA file.
112 (
"latitude",
"float"),
113 (
"longitude",
"float"),
114 (
"datetime",
"string")
119 'date_time_string': self.
datedate.strftime(
"%Y-%m-%dT%H:%M:%SZ")
125 for key
in self.
varDictvarDict.keys():
126 value = self.
varDictvarDict[key]
127 self.
keyDictkeyDict[key][
'valKey'] = value, self.
writerwriter.OvalName()
128 self.
keyDictkeyDict[key][
'errKey'] = value, self.
writerwriter.OerrName()
129 self.
keyDictkeyDict[key][
'qcKey'] = value, self.
writerwriter.OqcName()
138 if obs.data[
'n_obs'] <= 0:
139 print(
'No trak observations for IODA!')
142 for n
in range(obs.data[
'n_obs']):
144 lat = obs.data[
'ob_lat'][n]
145 lon = obs.data[
'ob_lon'][n]
146 dtg = datetime.strptime(obs.data[
'ob_dtg'][n],
'%Y%m%d%H%M')
148 locKey = lat, lon, dtg.strftime(
"%Y-%m-%dT%H:%M:%SZ")
150 for key
in self.
varDictvarDict.keys():
152 if key
in [
'ob_uuu',
'ob_vvv']:
155 varName = key.split(
'_')[-1]
157 val = obs.data[key][n]
159 qc = (100*obs.data[
'ob_qc_'+varName][n]).astype(
'i4')
161 valKey = self.
keyDictkeyDict[key][
'valKey']
162 errKey = self.
keyDictkeyDict[key][
'errKey']
163 qcKey = self.
keyDictkeyDict[key][
'qcKey']
165 self.
datadata[recKey][locKey][valKey] = val
166 self.
datadata[recKey][locKey][errKey] = err
167 self.
datadata[recKey][locKey][qcKey] = qc
169 (ObsVars, LocMdata, VarMdata) = self.
writerwriter.ExtractObsData(self.
datadata)
170 self.
writerwriter.BuildNetcdf(ObsVars, LocMdata, VarMdata, self.
AttrDataAttrData)
177 desc =
'Convert GODAE binary track data to IODA netCDF4 format'
178 parser = ArgumentParser(
180 formatter_class=ArgumentDefaultsHelpFormatter)
182 '-i',
'--input', help=
'name of the binary GODAE track file',
183 type=str, nargs=
'+', required=
True)
185 '-o',
'--output', help=
'name of the output netCDF GODAE ship file',
186 type=str, required=
True, default=
None)
188 '-d',
'--date', help=
'file date',
189 type=str, metavar=
'YYYYMMDDHH', required=
True)
191 args = parser.parse_args()
194 foutput = args.output
195 fdate = datetime.strptime(args.date,
'%Y%m%d%H')
199 obsList.append(
trak(fname, fdate))
202 'ob_sst':
'sea_surface_temperature',
203 'ob_sal':
'sea_surface_salinity',
204 'ob_uuu':
'sea_surface_zonal_wind',
205 'ob_vvv':
'sea_surface_meriodional_wind'
208 IODA(foutput, fdate, varDict, obsList)
211 if __name__ ==
'__main__':
def __init__(self, filename, date, varDict, obsList)
def __init__(self, filename, date)