Skip to content

Commit 6a01d08

Browse files
committed
Addresses changes suggested on PR.
1 parent 34dfa4c commit 6a01d08

File tree

2 files changed

+52
-68
lines changed

2 files changed

+52
-68
lines changed

grib/src/main/resources/resources/grib2/mrms/MergedTableCode.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# created 2021-02-05T0637
2-
# using tables .\tables\UserTable_MRMS_v10.0.0.csv, .\tables\UserTable_MRMS_v10.0.1_updated20150407.csv, .\tables\UserTable_MRMS_v11.0.4.csv, .\tables\UserTable_MRMS_v11.5.5.csv, .\tables\UserTable_MRMS_v12.0.csv
1+
# created 2021-02-10T0300
2+
# using tables tables\UserTable_MRMS_v10.0.0.csv, tables\UserTable_MRMS_v10.0.1.csv, tables\UserTable_MRMS_v10.0.1_updated20150407.csv, tables\UserTable_MRMS_v11.0.4.csv, tables\UserTable_MRMS_v11.5.5.csv, tables\UserTable_MRMS_v12.0.csv
33
add(209, 2, 0, "NLDN_CG_001min_AvgDensity", "CG Average Lightning Density 1-min - NLDN", "flashes/km^2/min", -3, -1); // v12.0
44
add(209, 2, 1, "NLDN_CG_005min_AvgDensity", "CG Average Lightning Density 5-min - NLDN", "flashes/km^2/min", -3, -1); // v12.0
55
add(209, 2, 2, "NLDN_CG_015min_AvgDensity", "CG Average Lightning Density 15-min - NLDN", "flashes/km^2/min", -3, -1); // v12.0
@@ -144,7 +144,7 @@ add(209, 10, 4, "LayerCompositeReflectivity_Low", "Layer Composite Reflectivity
144144
add(209, 10, 5, "LayerCompositeReflectivity_High", "Layer Composite Reflectivity Mosaic 24-60 kft (highest altitude)", "dBZ", -999, -99); // v12.0
145145
add(209, 10, 6, "LayerCompositeReflectivity_Super", "Layer Composite Reflectivity Mosaic 33-60 kft (super high altitude)", "dBZ", -999, -99); // v12.0
146146
add(209, 10, 7, "CREF_1HR_MAX", "Composite Reflectivity Hourly Maximum", "dBZ", -999, -99); // v12.0
147-
add(209, 10, 8, "ReflectivityMaxAboveM10C", "Maximum Reflectivity at -10 deg C height and above", "dBZ", -999, -99); // v10.0.0
147+
add(209, 10, 8, "ReflectivityMaxAboveM10C", "Maximum Reflectivity at -10 deg C height and above", "dBZ", -999, -99); // v10.0.1
148148
add(209, 10, 9, "LayerCompositeReflectivity_ANC", "Layer Composite Reflectivity Mosaic (2-4.5km) (for ANC)", "dBZ", -999, -99); // v12.0
149149
add(209, 10, 10, "BREF_1HR_MAX", "Base Reflectivity Hourly Maximum", "dBZ", -999, -99); // v12.0
150150
add(209, 11, 0, "MergedBaseReflectivityQC", "Base Reflectivity Mosaic (optimal method)", "dBZ", -999, -99); // v12.0
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
#!/usr/bin/env python
22
import csv
3-
import datetime as dt
3+
from datetime import datetime
44
from collections import defaultdict, namedtuple
5-
from itertools import chain
6-
from os import listdir, remove
7-
from os.path import exists, join
85

96
debug = False
107

118
def parse_table_version(fname):
12-
# filenames need to look like UserTable_MRMS_v<version>.csv
9+
# Filenames need to look like path/blah/UserTable_MRMS_v<version>.csv
1310
return fname.split('S_v', 1)[1].replace('.csv', '')
1411

1512
def parse_file(fname):
@@ -56,40 +53,36 @@ def fix_item(item):
5653

5754
return item
5855

59-
# extract the important parameters needed by netCDF-Java
56+
# Extract the important parameters needed by netCDF-Java
6057
def important_table_info(param):
61-
important_info = '{0.Discipline}, {0.Category}, {0.Parameter}, "{0.Name}", ' + \
62-
'"{0.Description}", "{0.Unit}", {0.No_Coverage}, ' + \
63-
'{0.Missing}'
58+
return (f'{param.Discipline}, {param.Category}, {param.Parameter}, "{param.Name}", '
59+
f'"{param.Description}", "{param.Unit}", {param.No_Coverage}, '
60+
f'{param.Missing}')
6461

65-
return important_info.format(param)
66-
67-
# extract the critical parameters needed by netCDF-Java
62+
# Extract the critical parameters needed by netCDF-Java
6863
def critical_table_info(param):
69-
critical_info = '{0.Discipline}, {0.Category}, {0.Parameter}, "{0.Unit}", {0.No_Coverage}, ' + \
70-
'{0.Missing}'
71-
72-
return critical_info.format(param)
64+
return (f'{param.Discipline}, {param.Category}, {param.Parameter}, "{param.Unit}", '
65+
f'{param.No_Coverage}, {param.Missing}')
7366

7467
def sorter(item):
75-
# extract the discipline, category, and parameter as int values
68+
# Extract the discipline, category, and parameter as int values
7669
parts = important_table_info(item).split(',')
7770
return tuple(map(lambda x: int(x), parts[0:3]))
7871

7972
def make_java(info, tables):
80-
filename = 'MergedTableCode.txt'.format(dt.datetime.now())
81-
# sort by discipline, category, and parameter, in that order.
73+
filename = 'MergedTableCode.txt'
74+
# Sort by discipline, category, and parameter, in that order.
8275
info = sorted(info, key = lambda item: sorter(item))
8376
with open(filename, 'w') as f:
84-
f.write('# created {0:%Y}-{0:%m}-{0:%d}T{0:%I%M}\n'.format(dt.datetime.now()))
77+
f.write('# created {0:%Y}-{0:%m}-{0:%d}T{0:%I%M}\n'.format(datetime.now()))
8578
f.write('# using tables {}\n'.format(', '.join(tables)))
8679
for i in info:
8780
i = fix_item(i)
88-
# make sure the discipline value is numeric (skip the "Not GRIB2" items)
81+
# Make sure the discipline value is numeric (skip the "Not GRIB2" items)
8982
if i.Discipline.isnumeric():
9083
f.write('add({}); // v{}\n'.format(important_table_info(i), i.TableVersion))
9184

92-
# return true if the parameters needed by netcdf-java are the same.
85+
# Return true if the parameters needed by netcdf-java are the same.
9386
def parameter_comparison(param_a, param_b):
9487
critical = False
9588
if critical:
@@ -106,7 +99,9 @@ def parameter_comparison(param_a, param_b):
10699
return marker_a.lower() == marker_b.lower()
107100

108101
def process_tables(tables, interactive=False):
109-
102+
# Sort tables by name, lexicographically.
103+
# Should restuld in the tables being sorted by version (older to newer).
104+
tables.sort()
110105
params = defaultdict(list)
111106
for table in tables:
112107
info = parse_file(table)
@@ -118,32 +113,23 @@ def process_tables(tables, interactive=False):
118113
dupes = 0
119114
unique_params = []
120115
for param_key in params:
121-
# if there is only one entry for a given discipline-category-parameter combination, use it
122-
if len(params[param_key]) == 1:
123-
unique_params.append(params[param_key][0])
124-
else:
125-
# let's figure out if there are differences between the table entries with the same discipline-category-parameter combination
126-
has_diffs = False
116+
if len(params[param_key]) > 1:
117+
# There are multiple entries for a given discipline-category-parameter combination.
118+
# Let's figure out if there are differences between the table entries with the same discipline-category-parameter combination
127119
param_versions = params[param_key]
128120
first = param_versions[0]
121+
# By default, we will pick the latest version (for non-interactive cases)
122+
selection = -1
129123
for version in range(1, len(param_versions)):
130-
# compare the parameters from different tables to see if they are different
131-
has_diffs = not parameter_comparison(first, param_versions[version])
132-
if has_diffs:
133-
# ok, at least one entry is different, so let's stop checking here
134-
break
135-
# If they are all equal (except for the table version part)
136-
if not has_diffs:
137-
# all the same, so pick one (we'll go with the latest)
138-
unique_params.append(param_versions[-1])
139-
else:
140-
# So we have multiple table entries for a given discipline-category-parameter combination.
141-
# Need a human to sort this out. List the options and ask.
124+
if parameter_comparison(first, param_versions[version]):
125+
# Parameter definitions are the same, check next version
126+
continue
127+
128+
# If we make it here, we have multiple table entries for a given discipline-category-parameter
129+
# combination that are different. We might need a human to sort this out.
142130
dupes += 1
143131

144-
if not interactive:
145-
selection = -1
146-
else:
132+
if interactive:
147133
print('Which version of {} would you like to use?'.format(param_key))
148134
number_of_choices = len(param_versions)
149135
# figure out padding for pretty printing
@@ -159,27 +145,31 @@ def process_tables(tables, interactive=False):
159145
padding = ' '*(max_version_len - len(versioned_param[-1]))
160146
print(' {} ({}): {}{}'.format(version + 1, versioned_param[-1], padding, important_table_info(versioned_param)))
161147

162-
valid_selection = False
163-
while not valid_selection:
148+
while True:
149+
# default selection - empty string
150+
selection = ''
164151
if interactive:
165152
selection = input(' 1 - {} (default {}): '.format(number_of_choices, number_of_choices))
166-
else:
167-
selection = ''
168153

169154
if selection == '':
170155
# if default, select the last choice in the list
171156
selection = -1
172-
valid_selection = True
157+
break
173158
elif selection.isnumeric():
174159
selection = int(selection)
175160
if (selection > 0) and (selection <= number_of_choices):
176161
selection -= 1
177-
valid_selection = True
178-
179-
if not valid_selection:
162+
break
163+
else:
180164
print(' --> {} is invalid. Please choose between 1 and {}.'.format(selection, number_of_choices))
181-
182-
unique_params.append(param_versions[selection])
165+
break # break out of version loop since we resolved the multiple versions
166+
# The issue of multiple, possibly conflicting, versions of a parameter has been resolved - add that result
167+
# to the unique parameter list
168+
unique_params.append(param_versions[selection])
169+
else:
170+
# Only one entry for a given discipline-category-parameter combination exists across various versions of a
171+
# table, so add it to the unique parameter list.
172+
unique_params.append(params[param_key][0])
183173

184174
if debug or interactive:
185175
print('Selected {}'.format(param_versions[selection]))
@@ -191,23 +181,17 @@ def process_tables(tables, interactive=False):
191181

192182
if __name__ == '__main__':
193183
import argparse
184+
from pathlib import Path
194185

195186
parser = argparse.ArgumentParser(description="Convert MRMS GRIB 2 table to Java code")
196-
parser.add_argument('--table', type=str, required=False, action='append', nargs='+',
197-
help="One or more source table (multiple tables separated by spaces). If missing, will try to merge all source tables located in tables/")
187+
parser.add_argument('--table', type=str, required=False, action='append',
188+
help="Path to a GRIB table (can be used multiple times to provide multiple tables). If missing, will try to merge all GRIB tables located in tables/")
198189
parser.add_argument('--interactive', action='store_true',
199190
help="When merging tables, prompt user to select between conflicting parameter definitions.")
200191
args = parser.parse_args()
201192

202193
tables = args.table
203194
if tables is None:
204-
table_directory_name = 'tables/'
205-
tables = listdir(table_directory_name)
206-
tables = map(lambda x: join(table_directory_name, x), tables)
207-
else:
208-
if isinstance(tables, str):
209-
tables = [tables]
210-
else:
211-
tables = list(chain.from_iterable(tables))
195+
tables = list(map(str, Path('tables/').iterdir()))
212196

213-
process_tables(tables, interactive = args.interactive)
197+
process_tables(tables, interactive=args.interactive)

0 commit comments

Comments
 (0)