IODA Bundle
hgodas_adt2ioda.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 = "obs_absolute_dynamic_topography",
27 
28 locationKeyList = [
29  ("latitude", "float"),
30  ("longitude", "float"),
31  ("datetime", "string")
32 ]
33 
34 AttrData = {
35  'odb_version': 1,
36 }
37 
38 
39 class Observation(object):
40 
41  def __init__(self, filename, date, writer):
42  self.filenamefilename = filename
43  self.datedate = date
44  self.datadata = DefaultOrderedDict(lambda: DefaultOrderedDict(dict))
45  self.writerwriter = writer
46  self._read_read()
47 
48  def _read(self):
49  ncd = nc.Dataset(self.filenamefilename)
50  time = ncd.variables['time'][:]
51  lons = ncd.variables['lon'][:]
52  lats = ncd.variables['lat'][:]
53  hrs = ncd.variables['hr'][:]
54  vals = ncd.variables['val'][:]
55  errs = ncd.variables['err'][:]
56  qcs = ncd.variables['qc'][:]
57  ncd.close()
58 
59  base_date = datetime(1970, 1, 1) + timedelta(seconds=int(time[0]))
60 
61  valKey = vName, self.writerwriter.OvalName()
62  errKey = vName, self.writerwriter.OerrName()
63  qcKey = vName, self.writerwriter.OqcName()
64 
65  for i in range(len(hrs)):
66  # there shouldn't be any bad obs, but just in case remove them all
67  if qcs[i] != 0:
68  continue
69 
70  dt = base_date + timedelta(hours=float(hrs[i]))
71  locKey = lats[i], lons[i], dt.strftime("%Y-%m-%dT%H:%M:%SZ")
72  self.datadata[0][locKey][valKey] = vals[i]
73  self.datadata[0][locKey][errKey] = errs[i]
74  self.datadata[0][locKey][qcKey] = qcs[i]
75 
76 
77 def main():
78  parser = argparse.ArgumentParser(
79  description=(
80  'Read absolute dynamic topography (ADT) observations'
81  ' file(s) that have already been QCd and thinned for use in'
82  ' Hybrid-GODAS system.')
83  )
84 
85  required = parser.add_argument_group(title='required arguments')
86  required.add_argument(
87  '-i', '--input',
88  help="name of HGODAS observation input file(s)",
89  type=str, required=True)
90  required.add_argument(
91  '-o', '--output',
92  help="path of ioda output file",
93  type=str, required=True)
94  required.add_argument(
95  '-d', '--date',
96  help="base date for the center of the window",
97  metavar="YYYYMMDDHH", type=str, required=True)
98  args = parser.parse_args()
99  fdate = datetime.strptime(args.date, '%Y%m%d%H')
100 
101  writer = iconv.NcWriter(args.output, locationKeyList)
102 
103  # Read in the profiles
104  prof = Observation(args.input, fdate, writer)
105 
106  # write them out
107  AttrData['date_time_string'] = fdate.strftime("%Y-%m-%dT%H:%M:%SZ")
108 
109  (ObsVars, LocMdata, VarMdata) = writer.ExtractObsData(prof.data)
110  writer.BuildNetcdf(ObsVars, LocMdata, VarMdata, AttrData)
111 
112 
113 if __name__ == '__main__':
114  main()
def __init__(self, filename, date, writer)