Skip to content

Commit 4d77e45

Browse files
authored
add components for surface snow data (#14)
This PR includes the following changes: 1. Add mapping and Python for surface snow data 2. Move test configuration from /spoc/dump/config to /spoc/ush/test 3. Remove an old test configuration file 4. Update README for test (/spoc/ush/test) 5. Change filename convention change from `bufr2ioda` to `bufr` (more general) 6. Fix Python coding norm errors (ctest is adding to obsForge - in progress [obsForge PR #4](NOAA-EMC/obsForge#4)
1 parent c52d014 commit 4d77e45

11 files changed

+393
-102
lines changed

dump/config/bufr2ioda_script_backend_satwnd_amv_goes.yaml

-58
This file was deleted.

dump/mapping/bufr_satwnd_amv_goes.py

+19-12
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,27 @@
55
import time
66
import numpy as np
77
import bufr
8-
from pyioda.ioda.Engines.Bufr import Encoder as iodaEncoder
9-
from bufr.encoders.netcdf import Encoder as netcdfEncoder
8+
from pyioda.ioda.Engines.Bufr import Encoder as iodaEncoder
9+
from bufr.encoders.netcdf import Encoder as netcdfEncoder
1010
from wxflow import Logger
1111

1212
# Initialize Logger
1313
# Get log level from the environment variable, default to 'INFO it not set
1414
log_level = os.getenv('LOG_LEVEL', 'INFO')
1515
logger = Logger('BUFR2IODA_satwnd_amv_goes.py', level=log_level, colored_log=False)
1616

17+
1718
def logging(comm, level, message):
1819
"""
1920
Logs a message to the console or log file, based on the specified logging level.
2021
21-
This function ensures that logging is only performed by the root process (`rank 0`)
22-
in a distributed computing environment. The function maps the logging level to
22+
This function ensures that logging is only performed by the root process (`rank 0`)
23+
in a distributed computing environment. The function maps the logging level to
2324
appropriate logger methods and defaults to the 'INFO' level if an invalid level is provided.
2425
2526
Parameters:
2627
comm: object
27-
The communicator object, typically from a distributed computing framework
28+
The communicator object, typically from a distributed computing framework
2829
(e.g., MPI). It must have a `rank()` method to determine the process rank.
2930
level: str
3031
The logging level as a string. Supported levels are:
@@ -33,7 +34,7 @@ def logging(comm, level, message):
3334
- 'WARNING'
3435
- 'ERROR'
3536
- 'CRITICAL'
36-
If an invalid level is provided, a warning will be logged, and the level
37+
If an invalid level is provided, a warning will be logged, and the level
3738
will default to 'INFO'.
3839
message: str
3940
The message to be logged.
@@ -73,6 +74,7 @@ def logging(comm, level, message):
7374
# Call the logging method
7475
log_method(message)
7576

77+
7678
def _make_description(mapping_path, update=False):
7779
description = bufr.encoders.Description(mapping_path)
7880

@@ -116,6 +118,7 @@ def _make_description(mapping_path, update=False):
116118

117119
return description
118120

121+
119122
def compute_wind_components(wdir, wspd):
120123
"""
121124
Compute the U and V wind components from wind direction and wind speed.
@@ -130,9 +133,10 @@ def compute_wind_components(wdir, wspd):
130133
wdir_rad = np.radians(wdir) # Convert degrees to radians
131134
u = -wspd * np.sin(wdir_rad)
132135
v = -wspd * np.cos(wdir_rad)
133-
136+
134137
return u.astype(np.float32), v.astype(np.float32)
135138

139+
136140
def _get_obs_type(swcm, chanfreq):
137141
"""
138142
Determine the observation type based on `swcm` and `chanfreq`.
@@ -164,6 +168,7 @@ def _get_obs_type(swcm, chanfreq):
164168

165169
return obstype
166170

171+
167172
def _make_obs(comm, input_path, mapping_path):
168173

169174
# Get container from mapping file first
@@ -175,7 +180,7 @@ def _make_obs(comm, input_path, mapping_path):
175180
logging(comm, 'DEBUG', f'category map = {container.get_category_map()}')
176181

177182
# Add new/derived data into container
178-
for cat in container.all_sub_categories():
183+
for cat in container.all_sub_categories():
179184

180185
logging(comm, 'DEBUG', f'category = {cat}')
181186

@@ -193,7 +198,7 @@ def _make_obs(comm, input_path, mapping_path):
193198
container.add('variables/windNorthward', wob, paths, cat)
194199

195200
else:
196-
# Add new variables: ObsType/windEastward & ObsType/windNorthward
201+
# Add new variables: ObsType/windEastward & ObsType/windNorthward
197202
swcm = container.get('variables/windComputationMethod', cat)
198203
chanfreq = container.get('variables/sensorCentralFrequency', cat)
199204

@@ -209,7 +214,7 @@ def _make_obs(comm, input_path, mapping_path):
209214
container.add('variables/obstype_uwind', obstype, paths, cat)
210215
container.add('variables/obstype_vwind', obstype, paths, cat)
211216

212-
# Add new variables: ObsValue/windEastward & ObsValue/windNorthward
217+
# Add new variables: ObsValue/windEastward & ObsValue/windNorthward
213218
wdir = container.get('variables/windDirection', cat)
214219
wspd = container.get('variables/windSpeed', cat)
215220

@@ -231,6 +236,7 @@ def _make_obs(comm, input_path, mapping_path):
231236

232237
return container
233238

239+
234240
def create_obs_group(input_path, mapping_path, category, env):
235241

236242
comm = bufr.mpi.Comm(env["comm_name"])
@@ -250,7 +256,7 @@ def create_obs_group(input_path, mapping_path, category, env):
250256

251257
container = _make_obs(comm, input_path, mapping_path)
252258

253-
# Gather data from all tasks into all tasks. Each task will have the complete record
259+
# Gather data from all tasks into all tasks. Each task will have the complete record
254260
logging(comm, 'INFO', f'Gather data from all tasks into all tasks')
255261
container.all_gather(comm)
256262

@@ -269,6 +275,7 @@ def create_obs_group(input_path, mapping_path, category, env):
269275
logging(comm, 'INFO', f'Return the encoded data for {category}')
270276
return data
271277

278+
272279
def create_obs_file(input_path, mapping_path, output_path):
273280

274281
comm = bufr.mpi.Comm("world")
@@ -279,7 +286,7 @@ def create_obs_file(input_path, mapping_path, output_path):
279286

280287
# Encode the data
281288
if comm.rank() == 0:
282-
netcdfEncoder(description).encode(container, output_path)
289+
netcdfEncoder(description).encode(container, output_path)
283290

284291
logging(comm, 'INFO', f'Return the encoded data')
285292

dump/mapping/bufr_satwnd_amv_goes_mapping.yaml

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ bufr:
1717
minute: "*/MINU"
1818
second: "*/SECO"
1919

20+
dataReceiptTime:
21+
datetime:
22+
year: "*/RCYR"
23+
month: "*/RCMO"
24+
day: "*/RCDY"
25+
hour: "*/RCHR"
26+
minute: "*/RCMI"
27+
2028
latitude:
2129
query: "*/CLATH"
2230

@@ -114,7 +122,12 @@ encoder:
114122
# MetaData
115123
- name: "MetaData/dateTime"
116124
source: variables/timestamp
117-
longName: "Datetime"
125+
longName: "Observation Time"
126+
units: "seconds since 1970-01-01T00:00:00Z"
127+
128+
- name: "MetaData/dataReceiptTime"
129+
source: variables/dataReceiptTime
130+
longName: "Observation Receipt Time"
118131
units: "seconds since 1970-01-01T00:00:00Z"
119132

120133
- name: "MetaData/latitude"

0 commit comments

Comments
 (0)