IODA Bundle
glider2ioda.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 from __future__ import print_function
10 import sys
11 import argparse
12 import netCDF4 as nc
13 from datetime import datetime, timedelta
14 import numpy as np
15 import numpy.matlib
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 vName = [
27  "sea_water_temperature",
28  "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  dpth = (ncd.variables['ctd_depth'][:])
55  time = ncd.variables['ctd_time'][:]
56  lons = np.float32(ncd.variables['longitude'][:])
57  lats = np.float32(ncd.variables['latitude'][:])
58  with np.errstate(invalid='ignore'):
59  temperature = np.float32(ncd.variables['temperature'][:])
60  with np.errstate(invalid='ignore'):
61  salinity = np.float32(ncd.variables['salinity'][:])
62  errs = np.float32(np.matlib.repmat(0.2, len(lons), 1))
63  Tqcs = ncd.variables['temperature_qc'][:]-1
64  Sqcs = ncd.variables['salinity_qc'][:]-1
65  errs = np.squeeze(errs)
66  ncd.close()
67  base_date = datetime(1970, 1, 1)
68  for i in range(len(time)-1):
69  for j in [0, 1]:
70  valKey = vName[j], self.writerwriter.OvalName()
71  errKey = vName[j], self.writerwriter.OerrName()
72  qcKey = vName[j], self.writerwriter.OqcName()
73  dt = base_date + timedelta(seconds=int(time[i]))
74  locKey = lats[i], lons[i], dpth[i], dt.strftime(
75  "%Y-%m-%dT%H:%M:%SZ")
76  if j == 0:
77  self.datadata[0][locKey][valKey] = temperature[i]
78  self.datadata[0][locKey][errKey] = errs[i]
79  self.datadata[0][locKey][qcKey] = Tqcs[i]
80  else:
81  self.datadata[0][locKey][valKey] = salinity[i]
82  self.datadata[0][locKey][errKey] = errs[i]
83  self.datadata[0][locKey][qcKey] = Sqcs[i]
84 
85 
86 def main():
87 
88  parser = argparse.ArgumentParser(
89  description=(
90  'Read NOAA AOML Hurricane Glider Temperature and Salinity profile observation file(s) '
91  )
92  )
93 
94  required = parser.add_argument_group(title='required arguments')
95  required.add_argument(
96  '-i', '--input',
97  help="name of Glider observation input file(s)",
98  type=str, required=True)
99  required.add_argument(
100  '-o', '--output',
101  help="path of ioda output file",
102  type=str, required=True)
103  required.add_argument(
104  '-d', '--date',
105  help="base date for the center of the window",
106  metavar="YYYYMMDDHH", type=str, required=True)
107  args = parser.parse_args()
108  fdate = datetime.strptime(args.date, '%Y%m%d%H')
109 
110  writer = iconv.NcWriter(args.output, locationKeyList)
111 
112  prof = Profile(args.input, fdate, writer)
113  AttrData['date_time_string'] = fdate.strftime("%Y-%m-%dT%H:%M:%SZ")
114  (ObsVars, LocMdata, VarMdata) = writer.ExtractObsData(prof.data)
115  writer.BuildNetcdf(ObsVars, LocMdata, VarMdata, AttrData)
116 
117 
118 if __name__ == '__main__':
119  main()
def __init__(self, filename, date, writer)
Definition: glider2ioda.py:45
def main()
Definition: glider2ioda.py:86