IODA Bundle
hgodas_insitu2ioda.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 
3 #
4 # (C) Copyright 2019 UCAR
5 #
6 # This software is licensed under the terms of the Apache Licence Version 2.0
7 # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
8 #
9 
10 from __future__ import print_function
11 import sys
12 import argparse
13 import netCDF4 as nc
14 from datetime import datetime, timedelta
15 from pathlib import Path
16 
17 IODA_CONV_PATH = Path(__file__).parent/"@SCRIPT_LIB_PATH@"
18 if not IODA_CONV_PATH.is_dir():
19  IODA_CONV_PATH = Path(__file__).parent/'..'/'lib-python'
20 sys.path.append(str(IODA_CONV_PATH.resolve()))
21 
22 import ioda_conv_ncio as iconv
23 from orddicts import DefaultOrderedDict
24 
25 
26 vName = {
27  2210: "sea_water_temperature",
28  2220: "sea_water_salinity",
29 }
30 
31 locationKeyList = [
32  ("latitude", "float"),
33  ("longitude", "float"),
34  ("depth", "float"),
35  ("datetime", "string")
36 ]
37 
38 AttrData = {
39  'odb_version': 1,
40 }
41 
42 
43 class Profile(object):
44 
45  def __init__(self, filename, date, writer):
46  self.filenamefilename = filename
47  self.datedate = date
48  self.datadata = DefaultOrderedDict(lambda: DefaultOrderedDict(dict))
49  self.writerwriter = writer
50  self._read_read()
51 
52  def _read(self):
53  ncd = nc.Dataset(self.filenamefilename)
54  time = ncd.variables['time'][:]
55  obid = ncd.variables['obid'][:]
56  dpth = ncd.variables['depth'][:]
57  lons = ncd.variables['lon'][:]
58  lats = ncd.variables['lat'][:]
59  hrs = ncd.variables['hr'][:]
60  vals = ncd.variables['val'][:]
61  errs = ncd.variables['err'][:]
62  qcs = ncd.variables['qc'][:]
63  ncd.close()
64 
65  base_date = datetime(1970, 1, 1) + timedelta(seconds=int(time[0]))
66 
67  for i in range(len(hrs)):
68  # there shouldn't be any bad obs, but just in case remove them all
69  if qcs[i] != 0:
70  continue
71 
72  valKey = vName[obid[i]], self.writerwriter.OvalName()
73  errKey = vName[obid[i]], self.writerwriter.OerrName()
74  qcKey = vName[obid[i]], self.writerwriter.OqcName()
75 
76  dt = base_date + timedelta(hours=float(hrs[i]))
77  locKey = lats[i], lons[i], dpth[i], dt.strftime(
78  "%Y-%m-%dT%H:%M:%SZ")
79  self.datadata[0][locKey][valKey] = vals[i]
80  self.datadata[0][locKey][errKey] = errs[i]
81  self.datadata[0][locKey][qcKey] = qcs[i]
82 
83 
84 def main():
85 
86  parser = argparse.ArgumentParser(
87  description=(
88  'Read insitu T/S profile observation file(s) that have already'
89  ' been QCd and thinned for use in Hybrid-GODAS system.')
90  )
91 
92  required = parser.add_argument_group(title='required arguments')
93  required.add_argument(
94  '-i', '--input',
95  help="name of HGODAS observation input file(s)",
96  type=str, required=True)
97  required.add_argument(
98  '-o', '--output',
99  help="path of ioda output file",
100  type=str, required=True)
101  required.add_argument(
102  '-d', '--date',
103  help="base date for the center of the window",
104  metavar="YYYYMMDDHH", type=str, required=True)
105  args = parser.parse_args()
106  fdate = datetime.strptime(args.date, '%Y%m%d%H')
107 
108  writer = iconv.NcWriter(args.output, locationKeyList)
109 
110  # Read in the profiles
111  prof = Profile(args.input, fdate, writer)
112 
113  # write them out
114  AttrData['date_time_string'] = fdate.strftime("%Y-%m-%dT%H:%M:%SZ")
115  (ObsVars, LocMdata, VarMdata) = writer.ExtractObsData(prof.data)
116  writer.BuildNetcdf(ObsVars, LocMdata, VarMdata, AttrData)
117 
118 
119 if __name__ == '__main__':
120  main()
def __init__(self, filename, date, writer)