IODA Bundle
rads_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 import dateutil.parser
16 from pathlib import Path
17 
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()))
22 
23 import ioda_conv_ncio as iconv
24 from orddicts import DefaultOrderedDict
25 
26 
27 class Observation(object):
28 
29  def __init__(self, filename, date, writer):
30 
31  self.filenamefilename = filename
32  self.datedate = date
33  self.datadata = DefaultOrderedDict(lambda: DefaultOrderedDict(dict))
34  self.writerwriter = writer
35  self._read_read()
36 
37  def _read(self):
38 
39  ncd = nc.MFDataset(self.filenamefilename)
40  time = ncd.variables['time_mjd'][:]
41  lons = ncd.variables['lon'][:]
42  lats = ncd.variables['lat'][:]
43  vals = ncd.variables['adt_xgm2016'][:]
44  units = ncd.variables['time_mjd'].units[-23:-4]
45  reftime = dateutil.parser.parse(units)
46  ncd.close()
47 
48  valKey = vName, self.writerwriter.OvalName()
49  errKey = vName, self.writerwriter.OerrName()
50  qcKey = vName, self.writerwriter.OqcName()
51 
52  count = 0
53  for i in range(len(lons)):
54 
55  count += 1
56  obs_date = reftime + timedelta(days=time[i])
57 
58  locKey = lats[i], lons[i], obs_date.strftime("%Y-%m-%dT%H:%M:%SZ")
59  self.datadata[0][locKey][valKey] = vals[i]
60  self.datadata[0][locKey][errKey] = 0.1
61  self.datadata[0][locKey][qcKey] = 0
62 
63 
64 vName = "obs_absolute_dynamic_topography"
65 
66 locationKeyList = [
67  ("latitude", "float"),
68  ("longitude", "float"),
69  ("datetime", "string")
70 ]
71 
72 AttrData = {
73  'odb_version': 1,
74 }
75 
76 
77 def main():
78 
79  # Get command line arguments
80  parser = argparse.ArgumentParser(
81  description=(
82  'Reads absolute dynamic topography (ADT) observations'
83  ' from NESDIS file(s) and converts into IODA formatted'
84  ' output files')
85  )
86 
87  required = parser.add_argument_group(title='required arguments')
88  required.add_argument(
89  '-i', '--input',
90  help="RADS observation input file(s)",
91  type=str, nargs='+', required=True)
92  required.add_argument(
93  '-o', '--output',
94  help="path of ioda output file",
95  type=str, required=True)
96  required.add_argument(
97  '-d', '--date',
98  help="base date for the center of the window",
99  metavar="YYYYMMDDHH", type=str, required=True)
100 
101  args = parser.parse_args()
102  fdate = datetime.strptime(args.date, '%Y%m%d%H')
103  writer = iconv.NcWriter(args.output, locationKeyList)
104 
105  # Read in the altimeter
106  altim = Observation(args.input, fdate, writer)
107 
108  # write them out
109  AttrData['date_time_string'] = fdate.strftime("%Y-%m-%dT%H:%M:%SZ")
110 
111  (ObsVars, LocMdata, VarMdata) = writer.ExtractObsData(altim.data)
112  writer.BuildNetcdf(ObsVars, LocMdata, VarMdata, AttrData)
113 
114 
115 if __name__ == '__main__':
116  main()
def __init__(self, filename, date, writer)