From 654e4144b0f3f7b39d8a584a61b688e9be676a5c Mon Sep 17 00:00:00 2001 From: Henry Wright Date: Fri, 24 Oct 2025 16:19:24 +0100 Subject: [PATCH] add table 1 --- lib/iris/fileformats/nimrod.py | 45 +++++++++++++++++++-- lib/iris/fileformats/nimrod_load_rules.py | 49 ++++++++++++++++++++--- 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/lib/iris/fileformats/nimrod.py b/lib/iris/fileformats/nimrod.py index d318c94882..7f57cc5b9a 100644 --- a/lib/iris/fileformats/nimrod.py +++ b/lib/iris/fileformats/nimrod.py @@ -101,7 +101,33 @@ # data specific header (int16) elements 108-159 (Fortran bytes 411-512) -data_header_int16s = ( +table_1_data_header_int16s = ( + "radar_number" + "radar_sites" + "additional_radar_sites" + "clutter_map_number" + "calibration_type" + "bright_band_height" + "bright_band_intensity" + "bright_band_test_param_1" + "bright_band_test_param_2" + "infill_flag" + "stop_elevation" + "" + "sensor_identifier" + "meteosat_identifier" + "" + "software_identifier" + "software_major_version" + "software_minor_version" + "software_micro_version" + "" + "period_seconds" +) + + +# data specific header (int16) elements 108-159 (Fortran bytes 411-512) +table_2_data_header_int16s = ( "threshold_type", "probability_method", "recursive_filter_iterations", @@ -215,7 +241,8 @@ def _read_header(self, infile): self._read_header_subset(infile, general_header_float32s, np.float32) # skip unnamed floats infile.seek(4 * (28 - len(general_header_float32s)), os.SEEK_CUR) - + threshold_set = True if self.threshold_value != -32767 else False + print(threshold_set) # data specific header (float32) elements 60-104 (bytes 175-354) self._read_header_subset(infile, data_header_float32s, np.float32) # skip unnamed floats @@ -226,6 +253,14 @@ def _read_header(self, infile): self.source = _read_chars(infile, 24) self.title = _read_chars(infile, 24) + # determine which of Table 1 or Table 2 is being used + if threshold_set: + table = "Table_2" + data_header_int16s = table_2_data_header_int16s + else: + table = "Table_1" + data_header_int16s = table_1_data_header_int16s + # data specific header (int16) elements 108- (bytes 411-512) self._read_header_subset(infile, data_header_int16s, np.int16) # skip unnamed int16s @@ -239,6 +274,8 @@ def _read_header(self, infile): ) ) + return table + def _read_data(self, infile): """Read the data array: int8, int16, int32 or float32. @@ -289,7 +326,7 @@ def _read_data(self, infile): self.data = self.data.reshape(self.num_rows, self.num_cols) -def load_cubes(filenames, callback=None): +def load_cubes(filenames, table, callback=None): """Load cubes from a list of NIMROD filenames. Parameters @@ -317,7 +354,7 @@ def load_cubes(filenames, callback=None): # End of file. Move on to the next file. break - cube = iris.fileformats.nimrod_load_rules.run(field) + cube = iris.fileformats.nimrod_load_rules.run(field, table) # Were we given a callback? if callback is not None: diff --git a/lib/iris/fileformats/nimrod_load_rules.py b/lib/iris/fileformats/nimrod_load_rules.py index 4b3987003a..a333f632cb 100644 --- a/lib/iris/fileformats/nimrod_load_rules.py +++ b/lib/iris/fileformats/nimrod_load_rules.py @@ -660,6 +660,38 @@ def add_attr(item): cube.attributes["institution"] = "Met Office" +def table_1_attributes(cube, field): + """Add attributes to the cube.""" + + def add_attr(item): + """Add an attribute to the cube.""" + if hasattr(field, item): + value = getattr(field, item) + if is_missing(field, value): + return + if "radius" in item: + value = f"{value} km" + cube.attributes[item] = value + + add_attr("radar_number") + add_attr("radar_sites") + add_attr("additional_radar_sites") + add_attr("clutter_map_number") + add_attr("calibration_type") + add_attr("bright_band_height") + add_attr("bright_band_intensity") + add_attr("bright_band_test_param_1") + add_attr("bright_band_test_param_2") + add_attr("infill_flag") + add_attr("stop_elevation") + add_attr("sensor_identifier") + add_attr("meteosat_identifier") + add_attr("software_identifier") + add_attr("software_major_version") + add_attr("software_minor_version") + add_attr("software_micro_version") + + def known_threshold_coord(field): """Supply known threshold coord meta-data for known use cases. @@ -894,7 +926,7 @@ def time_averaging(cube, field): cube.attributes["processing"] = averaging_attributes -def run(field, handle_metadata_errors=True): +def run(field, table, handle_metadata_errors=True): """Convert a NIMROD field to an Iris cube. Parameters @@ -930,10 +962,17 @@ def run(field, handle_metadata_errors=True): # vertical vertical_coord(cube, field) - # add other stuff, if present - soil_type_coord(cube, field) - probability_coord(cube, field, handle_metadata_errors) - ensemble_member(cube, field) + # add Table 1 specific stuff + if table == "Table_1": + table_1_attributes(cube, field) + + # add Table 2 specific stuff + if table == "Table_2": + soil_type_coord(cube, field) + probability_coord(cube, field, handle_metadata_errors) + ensemble_member(cube, field) + + # add other generic stuff, if present time_averaging(cube, field) attributes(cube, field)