Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
1a7cd53
Staging branch
rhoneyager Mar 7, 2022
59a9f1e
Retarget ioda clone to the sprint branch
rhoneyager Mar 8, 2022
b19a123
Merge branch 'develop' into feature/sprint-ioda-converters
rhoneyager Mar 8, 2022
83c521b
Merge branch 'develop' into feature/sprint-ioda-converters
rhoneyager Mar 8, 2022
38a37f0
nlocs to locations (#825)
CoryMartin-NOAA Mar 8, 2022
80b45dd
Merge branch 'develop' into feature/sprint-ioda-converters
rhoneyager Mar 10, 2022
30a65aa
SPRINT: Change METAR converter to align variable names with JEDI nami…
gthompsnJCSDA Mar 10, 2022
5bf58ef
Convert ISO date string to Python datetime object (#840)
CoryMartin-NOAA Mar 11, 2022
8d967fe
Merge branch 'develop' into feature/sprint-ioda-converters
rhoneyager Mar 11, 2022
b272ba7
Feature/ioda sprint atms hdf5 (#844)
BenjaminRuston Mar 16, 2022
1774305
Sprint: Upgrade converters that use bufr2ioda.x to follow the JEDI Da…
gthompsnJCSDA Mar 16, 2022
2f8ae50
SPRINT: Update a series of converters (bufr2ioda.x, see list below) …
gthompsnJCSDA Mar 16, 2022
cc8ccca
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Mar 16, 2022
b36c190
Modify gsidiag converter to follow JEDI data convention and update th…
emilyhcliu Mar 16, 2022
72b9fe2
Feature/sprint ioda converters yan (#853)
YanHao-NOAA Mar 16, 2022
e4e69b8
SPRINT: Upgrade conventional data BUFR-to-IODA converters (shown belo…
gthompsnJCSDA Mar 18, 2022
6a1ef48
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Mar 21, 2022
a11b680
Create Feature/sprint ghcn for 6 land converters during the ioda-conv…
YoulongXia-NOAA Mar 22, 2022
13b6a41
Feature/argo clim2ioda changes ne (#857)
nicholasesposito Mar 22, 2022
dfc14bb
Modify marine/smos_sss, marine/smap_sss, and marine/hgodas_sst conve…
PraveenKumar-NOAA Mar 22, 2022
215e42f
Merge branch 'develop' into feature/sprint-ioda-converters
rhoneyager Mar 22, 2022
c2c7fec
Feature/sprint modis aod converters hb (#851)
bhuang95 Mar 23, 2022
cceb60e
Remove two land converters with grib input (#883)
YoulongXia-NOAA Mar 23, 2022
d1c60a7
SPRINT: Upgrade many converters of satellite data bufr2ioda.x to ali…
gthompsnJCSDA Mar 29, 2022
b9041ee
Feature/sprint ioda greg bufr2ioda3 (#891)
gthompsnJCSDA Mar 30, 2022
91b728e
SPRINT: upgrade radiosonde python-eccodes bufr (WMO) converter to JE…
gthompsnJCSDA Apr 7, 2022
c07577f
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Apr 13, 2022
e5dd0a3
Feature/sprint aeronet converters hb (#849)
bhuang95 Apr 13, 2022
e566512
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Apr 13, 2022
5cd9713
Feature/sprint viirs aod converters (#850)
bhuang95 Apr 13, 2022
75848f7
Sprint: Update the GODAE (marine) converters listed below to adopt t…
gthompsnJCSDA Apr 14, 2022
45a0af1
Feature/sprint ioda converters fcvdb (#848)
fcvdb Apr 14, 2022
5c41d2b
Update three marine converters for ioda-converters code sprint (#896)
YoulongXia-NOAA Apr 14, 2022
d509115
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Apr 15, 2022
cc6f944
SPRINT: update 3 marine converters to follow JEDI Data Conventions (…
gthompsnJCSDA Apr 15, 2022
daa1dca
Update the SatWinds AMV (from SSEC) ascii2ioda convert to follow JEDI…
gthompsnJCSDA Apr 18, 2022
52bbd7e
Remove bias files from validation
rhoneyager Apr 18, 2022
016ab9a
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Apr 19, 2022
0789858
Update gsidiag converter conventional data and satellite winds to com…
emilyhcliu Apr 20, 2022
4481007
Bugfix/ascii satwind datetime fix for SPRINT (#926)
BenjaminRuston Apr 28, 2022
285883a
Feature/sprint ioda converters ne viirs modis l2 oc2ioda (#873)
nicholasesposito May 4, 2022
f44990d
Feature/sprint ioda converters ne viirs modis l3 oc2ioda (#929)
nicholasesposito May 5, 2022
44de6a1
Sprint: update src/marine/gds2_sst2ioda.py code for JEDI Data Convent…
gthompsnJCSDA May 6, 2022
c59882c
Changes to resolve conflicts with develop branch.
srherbener May 12, 2022
ae108a9
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener May 12, 2022
4504cff
Fixed errors introduced with the prior commit containing the resoluti…
srherbener May 12, 2022
e8324ae
Updated smap9k test reference file.
srherbener May 13, 2022
7bf40a0
Removed units attribute from vegetationOpacity variable according to …
srherbener May 18, 2022
f15fc68
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener May 28, 2022
e60ba6c
Update sfc_tv_obs_2018041500.nc4 to be consistent with #953 (#954)
FanHan-NOAA Jun 1, 2022
6a82ed7
Make dateTime fill value consistent across platforms (#968)
srherbener Jun 24, 2022
a941c9c
When BUFR-formatted sonde data has "subsets" the prior code wasn't ab…
gthompsnJCSDA Jul 19, 2022
ab14da4
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Aug 1, 2022
669d6ba
Needed to go with feature/sprint-ioda-converters branch code for sett…
srherbener Aug 1, 2022
62f4105
Update the sprint branch with as much of ```develop``` branch as poss…
gthompsnJCSDA Nov 14, 2022
be4cd94
Sprint: Updating two GOES and three marine converters for naming con…
gthompsnJCSDA Jan 3, 2023
4e93cfb
Merge branch 'develop' into feature/sprint-ioda-converters
srherbener Jan 6, 2023
3a7af98
More cleanup from merging in develop.
srherbener Jan 6, 2023
47d3397
Update the sprint branch again with develop changes mostly for BUFR (…
gthompsnJCSDA Jan 11, 2023
198310f
Fix a collection of bufr2ioda.x YAML files and test-ref files for nam…
gthompsnJCSDA Jan 11, 2023
ec47029
make L2 trace gas converters work and be consistent with what the upg…
Jan 12, 2023
48eacbe
changes for L2 trace gas varnames to follow conventions (#1145)
Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ namespace Ingester

for (size_t idx = 0; idx < referenceObj->size(); idx++)
{
std::cout << "idx = " << idx << std::endl;
for (auto nameIt = includedFields.rbegin(); nameIt != includedFields.rend(); ++nameIt)
{
const auto& fieldName = *nameIt;
Expand All @@ -102,14 +101,12 @@ namespace Ingester
{
aircraftAlts[idx] =
11000.0f - (std::log1p(value / 22630.0f) / 0.0001576106f);
std::cout << "section 1" << std::endl;
}
else
{
aircraftAlts[idx] =
(1.0f - powf((value / 101325.0f),
(1.0f / 5.256f))) * (288.15f / 0.0065f);
std::cout << "section 2" << std::endl;
}
}
else if (includedFieldMap.find(ConfKeys::AircraftIndicatedAltitude)
Expand All @@ -119,24 +116,20 @@ namespace Ingester
{
aircraftAlts[idx] =
includedFieldMap[ConfKeys::AircraftIndicatedAltitude]->getAsFloat(idx);
std::cout << "section 3" << std::endl;
}
}
}
else if (fieldName == ConfKeys::AircraftIndicatedAltitude)
{
// This variable is only used in conjunction with pressure.
continue;
std::cout << "section 4" << std::endl;
}
else if (!fieldValues->isMissing(idx))
{
std::cout << " fieldValues = " << fieldValues << std::endl;
aircraftAlts[idx] = fieldValues->getAsFloat(idx);
std::cout << "section 5" << std::endl;
}
}
std::cout << "AA = " << aircraftAlts[idx] << std::endl;
}

return std::make_shared<DataObject<float>>(aircraftAlts,
Expand Down
153 changes: 93 additions & 60 deletions src/compo/aeronet_aaod2ioda.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# -o: output IODA file

import numpy as np
import netCDF4 as nc
import inspect, sys, os, argparse
import pandas as pd
from datetime import datetime, timedelta
Expand Down Expand Up @@ -123,6 +124,8 @@ def add_data(infile):
print(aeronetinv_chan)
print(frequency)

long_missing_value = nc.default_fillvals['i8']

nlocs, columns = f3.shape
nchans = len(aeronetinv_chan)
if nlocs == 0:
Expand All @@ -134,93 +137,123 @@ def add_data(infile):
outdata = defaultdict(lambda: DefaultOrderedDict(OrderedDict))
varAttrs = DefaultOrderedDict(lambda: DefaultOrderedDict(dict))

obsvars = {'aerosol_optical_depth': ['aod_coincident_input[440nm]', 'aod_coincident_input[675nm]',
'aod_coincident_input[870nm]', 'aod_coincident_input[1020nm]'],
'absorption_aerosol_optical_depth': ['absorption_aod[440nm]', 'absorption_aod[675nm]',
'absorption_aod[870nm]', 'absorption_aod[1020nm]']}
obsvars = {'aerosolOpticalDepth': ['aod_coincident_input[440nm]', 'aod_coincident_input[675nm]',
'aod_coincident_input[870nm]', 'aod_coincident_input[1020nm]'],
'absorptionAerosolOpticalDepth': ['absorption_aod[440nm]', 'absorption_aod[675nm]',
'absorption_aod[870nm]', 'absorption_aod[1020nm]']}

AttrData = {
'converter': os.path.basename(__file__)
}
# A dictionary of global attributes. More filled in further down.
AttrData = {}
AttrData['ioda_object_type'] = 'absorptionAOD'
AttrData['sensor'] = 'aeronet'

DimDict = {
}
# A dictionary of variable dimensions.
DimDict = {}

# A dictionary of variable names and their dimensions.
VarDims = {
'aerosol_optical_depth': ['nlocs', 'nchans'],
'absorption_aerosol_optical_depth': ['nlocs', 'nchans'],
'frequency': ['nchans'],
'sensor_channel': ['nchans']
'aerosolOpticalDepth': ['Location', 'Channel'],
'absorptionAerosolOpticalDepth': ['Location', 'Channel'],
'sensorCentralFrequency': ['Channel'],
'sensorChannelNumber': ['Channel']
}

# Get the group names we use the most.
metaDataName = iconv.MetaDataName()
obsValName = iconv.OvalName()
obsErrName = iconv.OerrName()
qcName = iconv.OqcName()

# Define varDict variables
for key, value in obsvars.items():
varDict[key]['valKey'] = key, iconv.OvalName()
varAttrs[key, iconv.OvalName()]['_FillValue'] = -999.
varAttrs[key, iconv.OvalName()]['coordinates'] = 'longitude latitude station_elevation'
varAttrs[key, iconv.OvalName()]['units'] = '1'
varDict[key]['errKey'] = key, iconv.OerrName()
varAttrs[key, iconv.OerrName()]['_FillValue'] = -999.
varAttrs[key, iconv.OerrName()]['coordinates'] = 'longitude latitude station_elevation'
varAttrs[key, iconv.OerrName()]['units'] = '1'
varDict[key]['qcKey'] = key, iconv.OqcName()
varAttrs[key, iconv.OqcName()]['_FillValue'] = -999
varAttrs[key, iconv.OqcName()]['coordinates'] = 'longitude latitude station_elevation'
varAttrs[key, iconv.OqcName()]['units'] = 'unitless'
varDict[key]['valKey'] = key, obsValName
varDict[key]['errKey'] = key, obsErrName
varDict[key]['qcKey'] = key, qcName
varAttrs[key, obsValName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, obsErrName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, qcName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, obsValName]['_FillValue'] = -9999.
varAttrs[key, obsErrName]['_FillValue'] = -9999.
varAttrs[key, qcName]['_FillValue'] = -9999
varAttrs[key, obsValName]['units'] = '1'
varAttrs[key, obsErrName]['units'] = '1'

for key, value in obsvars.items():
outdata[varDict[key]['valKey']] = np.array(np.float32(f3[value].fillna(np.float32(-999.))))
outdata[varDict[key]['qcKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-999.),
outdata[varDict[key]['valKey']] = np.array(np.float32(f3[value].fillna(np.float32(-9999.))))
outdata[varDict[key]['qcKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-9999.),
1, 0)
if key in ["aerosol_optical_depth"]:
outdata[varDict[key]['errKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-999.),
np.float32(-999.), np.float32(0.02))
if key in ["aerosolOpticalDepth"]:
outdata[varDict[key]['errKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-9999.),
np.float32(-9999.), np.float32(0.02))
else:
outdata[varDict[key]['errKey']] = np.full((nlocs, nchans), np.float32(-999.))
outdata[varDict[key]['errKey']] = np.full((nlocs, nchans), np.float32(-9999.))

outdata[('latitude', 'MetaData')] = np.array(np.float32(f3['latitude']))
outdata[('longitude', 'MetaData')] = np.array(np.float32(f3['longitude']))
outdata[('station_elevation', 'MetaData')] = np.array(np.float32(f3['elevation']))
varAttrs[('station_elevation', 'MetaData')]['units'] = 'm'
outdata[('surface_type', 'MetaData')] = np.full((nlocs), 1)
varAttrs[('surface_type', 'MetaData')]['units'] = 'unitless'

# Whether aaod reaches Level 2.0 without the threshold of aod440 >= 0.4 (0: yes, 1: no)
outdata[('aaod_l2_qc_without_aod440_le_0.4_threshold', 'MetaData')] = np.where(f3['if_retrieval_is_l2(without_l2_0.4_aod_440_threshold)'] == 1, 0, 1)
varAttrs[('aaod_l2_qc_without_aod440_le_0.4_threshold', 'MetaData')]['units'] = 'unitless'
outdata[('latitude', metaDataName)] = np.array(np.float32(f3['latitude']))
outdata[('longitude', metaDataName)] = np.array(np.float32(f3['longitude']))
outdata[('stationElevation', metaDataName)] = np.array(np.float32(f3['elevation']))
varAttrs[('stationElevation', metaDataName)]['units'] = 'm'

# Whether Coincident_AOD440nm in aeronet_cad.txt reaches Level 2.0 (0: yes, 1: no)
outdata[('aod_l2_qc', 'MetaData')] = np.where(f3['if_aod_is_l2'] == 1, 0, 1)
varAttrs[('aod_l2_qc', 'MetaData')]['units'] = 'unitless'
qcL2Aod = np.where(f3['if_aod_is_l2'] == 1, 0, 1)

# aaod inversion type: 0 for ALM20 and 1 for ALM15
outdata[('aaod_l2_qc', 'MetaData')] = np.where(f3['inversion_data_quality_level'] == 'lev20', 0, 1)
varAttrs[('aaod_l2_qc', 'MetaData')]['units'] = 'unitless'
qcL2Aaod = np.where(f3['inversion_data_quality_level'] == 'lev20', 0, 1)

# Whether aaod reaches Level 2.0 without the threshold of aod440 >= 0.4 (0: yes, 1: no)
qcL2Aaod2 = np.where(f3['if_retrieval_is_l2(without_l2_0.4_aod_440_threshold)'] == 1, 0, 1)

qcAll = np.full(len(qcL2Aod), long_missing_value, dtype=np.int32)
for i in range(len(qcL2Aod)):
qc1 = qcL2Aod[i]
qc2 = qcL2Aaod[i]
qc3 = qcL2Aaod2[i]
if qc1 == 0 and qc2 == 0 and qc3 == 0:
# Both AOD and AAOD w/and w/o aod440>0.4 threshold reach L2.
qcAll[i] = 0
elif qc1 == 0 and qc2 == 0 and qc3 == 1:
# Both AOD and AAOD w/ aod440>0.4 threshold reaches L2,
# but AAOD w/o aod440>0.4 threshold does not.
qcAll[i] = 1
elif qc1 == 0 and qc2 == 1 and qc3 == 0:
# Both AOD and AAOD w/o aod440>0.4 threshold reaches L2,
# but AAOD w/ aod440>0.4 threshold does not.
qcAll[i] = 2
elif qc1 == 0 and qc2 == 1 and qc3 == 1:
# Only AOD reaches L2.
qcAll[i] = 3
elif qc1 == 1 and qc2 == 0 and qc3 == 0:
# AAOD w/ and w/o aod440>0.4 threshold reaches L2,
# but AOD does not.
qcAll[i] = 4
elif qc1 == 1 and qc2 == 0 and qc3 == 1:
# AAOD w/ aod440>0.4 threshold reaches L2,
# but AOD and AAOD w/o aod440>0.4 threshold do not.
qcAll[i] = 5
elif qc1 == 1 and qc2 == 1 and qc3 == 0:
# AAOD w/o aod440>0.4 threshold reaches L2,
# but AOD and AAOD w/ aod440>0.4 threshold do not.
qcAll[i] = 6
elif qc1 == 1 and qc2 == 1 and qc3 == 1:
# Neither AOD or AAOD w/ and w/o aod440>0.4 threshold reaches L2.
qcAll[i] = 7

outdata[('qualityFlags', metaDataName)] = qcAll
c = np.empty([nlocs], dtype=object)
c[:] = np.array(f3.siteid)
outdata[('station_id', 'MetaData')] = c
varAttrs[('station_id', 'MetaData')]['units'] = ''
outdata[('stationIdentification', metaDataName)] = c

d = np.empty([nlocs], dtype=object)
for i in range(nlocs):
d[i] = f3.time[i].strftime('%Y-%m-%dT%H:%M:%SZ')
outdata[('datetime', 'MetaData')] = d
varAttrs[('datetime', 'MetaData')]['units'] = ''
outdata[('dateTime', metaDataName)] = d

outdata[('frequency', 'MetaData')] = np.float32(frequency)
varAttrs[('frequency', 'MetaData')]['units'] = 'Hz'
outdata[('sensor_channel', 'MetaData')] = np.int32(aeronetinv_chan)
varAttrs[('sensor_channel', 'MetaData')]['units'] = 'unitless'
outdata[('sensorCentralFrequency', metaDataName)] = np.float32(frequency)
varAttrs[('sensorCentralFrequency', metaDataName)]['units'] = 'Hz'
outdata[('sensorChannelNumber', metaDataName)] = np.int32(aeronetinv_chan)

# Add global atrributes
DimDict['nlocs'] = nlocs
DimDict['nchans'] = aeronetinv_chan
AttrData['nlocs'] = np.int32(DimDict['nlocs'])
AttrData['nchans'] = np.int32(nchans)
AttrData['observation_type'] = 'AAOD'
AttrData['sensor'] = 'aeronet'
AttrData['surface_type'] = 'ocean=0,land=1,costal=2'
DimDict['Location'] = nlocs
DimDict['Channel'] = aeronetinv_chan

# Setup the IODA writer
writer = iconv.IodaWriter(outfile, locationKeyList, DimDict)
Expand Down
97 changes: 47 additions & 50 deletions src/compo/aeronet_aod2ioda.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,82 +103,79 @@ def add_data(infile):
print('Zero AERONET AOD is available in file: ' + infile + ' and exit.')
exit(0)

locationKeyList = [("latitude", "float"), ("longitude", "float"), ("datetime", "string")]
locationKeyList = [("latitude", "float"), ("longitude", "float"), ("dateTime", "string")]
varDict = defaultdict(lambda: defaultdict(dict))
outdata = defaultdict(lambda: DefaultOrderedDict(OrderedDict))
varAttrs = DefaultOrderedDict(lambda: DefaultOrderedDict(dict))

obsvars = {'aerosol_optical_depth': ['aod_340nm', 'aod_380nm',
'aod_440nm', 'aod_675nm',
'aod_500nm', 'aod_870nm',
'aod_1020nm', 'aod_1640nm']}
obsvars = {'aerosolOpticalDepth': ['aod_340nm', 'aod_380nm',
'aod_440nm', 'aod_675nm',
'aod_500nm', 'aod_870nm',
'aod_1020nm', 'aod_1640nm']}

AttrData = {
'converter': os.path.basename(__file__),
}
# A dictionary of global attributes. More filled in further down.
AttrData = {}
AttrData['ioda_object_type'] = 'AOD'
AttrData['sensor'] = 'aeronet'

DimDict = {
}
# A dictionary of variable dimensions.
DimDict = {}

# A dictionary of variable names and their dimensions.
VarDims = {
'aerosol_optical_depth': ['nlocs', 'nchans'],
'frequency': ['nchans'],
'sensor_channel': ['nchans']
'aerosolOpticalDepth': ["Location", "Channel"],
'sensorCentralFrequency': ['Channel'],
'sensorChannelNumber': ['Channel']
}

# Get the group names we use the most.
metaDataName = iconv.MetaDataName()
obsValName = iconv.OvalName()
obsErrName = iconv.OerrName()
qcName = iconv.OqcName()

for key, value in obsvars.items():
varDict[key]['valKey'] = key, iconv.OvalName()
varAttrs[key, iconv.OvalName()]['_FillValue'] = -999.
varAttrs[key, iconv.OvalName()]['coordinates'] = 'longitude latitude station_elevation'
varAttrs[key, iconv.OvalName()]['units'] = '1'
varDict[key]['errKey'] = key, iconv.OerrName()
varAttrs[key, iconv.OerrName()]['_FillValue'] = -999.
varAttrs[key, iconv.OerrName()]['units'] = '1'
varAttrs[key, iconv.OerrName()]['coordinates'] = 'longitude latitude station_elevation'
varDict[key]['qcKey'] = key, iconv.OqcName()
varAttrs[key, iconv.OqcName()]['_FillValue'] = -999
varAttrs[key, iconv.OqcName()]['coordinates'] = 'longitude latitude station_elevation'
varAttrs[key, iconv.OqcName()]['units'] = 'unitless'
varDict[key]['valKey'] = key, obsValName
varDict[key]['errKey'] = key, obsErrName
varDict[key]['qcKey'] = key, qcName
varAttrs[key, obsValName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, obsErrName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, qcName]['coordinates'] = 'longitude latitude stationElevation'
varAttrs[key, obsValName]['_FillValue'] = -9999.
varAttrs[key, obsErrName]['_FillValue'] = -9999.
varAttrs[key, qcName]['_FillValue'] = -9999
varAttrs[key, obsValName]['units'] = '1'
varAttrs[key, obsErrName]['units'] = '1'

for key, value in obsvars.items():
outdata[varDict[key]['valKey']] = np.array(np.float32(f3[value].fillna(np.float32(-999.))))
outdata[varDict[key]['qcKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-999.),
outdata[varDict[key]['valKey']] = np.array(np.float32(f3[value].fillna(np.float32(-9999.))))
outdata[varDict[key]['qcKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-9999.),
1, 0)
outdata[varDict[key]['errKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-999.),
np.float32(-999.), np.float32(0.02))
outdata[varDict[key]['errKey']] = np.where(outdata[varDict[key]['valKey']] == np.float32(-9999.),
np.float32(-9999.), np.float32(0.02))

# Add metadata variables
outdata[('latitude', 'MetaData')] = np.array(np.float32(f3['latitude']))
outdata[('longitude', 'MetaData')] = np.array(np.float32(f3['longitude']))
outdata[('station_elevation', 'MetaData')] = np.array(np.float32(f3['elevation']))
varAttrs[('station_elevation', 'MetaData')]['units'] = 'm'
outdata[('surface_type', 'MetaData')] = np.full((nlocs), 1)
varAttrs[('surface_type', 'MetaData')]['units'] = 'unitless'
outdata[('latitude', metaDataName)] = np.array(np.float32(f3['latitude']))
outdata[('longitude', metaDataName)] = np.array(np.float32(f3['longitude']))
outdata[('stationElevation', metaDataName)] = np.array(np.float32(f3['elevation']))
varAttrs[('stationElevation', metaDataName)]['units'] = 'm'

c = np.empty([nlocs], dtype=object)
c[:] = np.array(f3.siteid)
outdata[('station_id', 'MetaData')] = c
varAttrs[('station_id', 'MetaData')]['units'] = ''
outdata[('stationIdentification', metaDataName)] = c

d = np.empty([nlocs], dtype=object)
for i in range(nlocs):
d[i] = f3.time[i].strftime('%Y-%m-%dT%H:%M:%SZ')
outdata[('datetime', 'MetaData')] = d
varAttrs[('datetime', 'MetaData')]['units'] = ''
outdata[('dateTime', metaDataName)] = d

outdata[('frequency', 'MetaData')] = np.float32(frequency)
varAttrs[('frequency', 'MetaData')]['units'] = 'Hz'
outdata[('sensor_channel', 'MetaData')] = np.int32(aod_chan)
varAttrs[('sensor_channel', 'MetaData')]['units'] = 'unitless'
outdata[('sensorCentralFrequency', metaDataName)] = np.float32(frequency)
varAttrs[('sensorCentralFrequency', metaDataName)]['units'] = 'Hz'
outdata[('sensorChannelNumber', metaDataName)] = np.int32(aod_chan)

# Add global atrributes
DimDict['nlocs'] = nlocs
DimDict['nchans'] = aod_chan
AttrData['nlocs'] = np.int32(DimDict['nlocs'])
AttrData['nchans'] = np.int32(nchans)
AttrData['observation_type'] = 'AOD'
AttrData['sensor'] = 'aeronet'
AttrData['surface_type'] = 'ocean=0,land=1,costal=2'
DimDict['Location'] = nlocs
DimDict['Channel'] = aod_chan

# Setup the IODA writer
writer = iconv.IodaWriter(outfile, locationKeyList, DimDict)
Expand Down
Loading