From 06e909094772bcd614f1e703bb226b75976f34ed Mon Sep 17 00:00:00 2001 From: Gavin Evans Date: Wed, 14 Aug 2024 09:43:50 +0100 Subject: [PATCH] Edit to the interface to remove the ignore_intensity argument and use the presence of the intensity_categories dictionary instead. Also a few minor edits. --- improver/cli/weather_symbol_modes.py | 15 +++--- improver/wxcode/modal_code.py | 22 ++++----- improver_tests/acceptance/SHA256SUMS | 8 ++-- .../wxcode/wxcode/test_ModalFromGroupings.py | 47 ++++++++++--------- 4 files changed, 43 insertions(+), 49 deletions(-) diff --git a/improver/cli/weather_symbol_modes.py b/improver/cli/weather_symbol_modes.py index 78b8ff1efa..f6c0e774e1 100644 --- a/improver/cli/weather_symbol_modes.py +++ b/improver/cli/weather_symbol_modes.py @@ -44,7 +44,6 @@ def process( day_start: int = 6, day_end: int = 18, wet_bias: int = 1, - ignore_intensity: bool = False, model_id_attr: str = None, record_run_attr: str = None, ): @@ -62,9 +61,14 @@ def process( A JSON file containing a definition for a broad category grouping. The expected categories are wet and dry. wet_categories (dict): - A JSON file containing a definition for a wet category grouping. + A JSON file containing a definition for a wet category grouping. No specific + names for the keys are required. Key and values within the dictionary + should both be ordered in terms of descending priority. intensity_categories (dict): A JSON file containing a definition for an intensity category grouping. + Values should be ordered in terms of descending priority. The most common + weather code from the options available representing different intensities + will be used as the representative weather code. day_weighting: Weighting to provide day time weather codes. A weighting of 1 indicates the default weighting. A weighting of 2 indicates that the weather codes @@ -81,12 +85,6 @@ def process( only a quarter of codes are required to be wet, in order to generate a wet symbol. To generate a wet symbol, the fraction of wet symbols therefore need to be greater than or equal to 1 / (1 + wet_bias). - ignore_intensity: - Boolean indicating whether weather codes of different intensities - should be grouped together when establishing the most representative - weather code. The most common weather code from the options available - representing different intensities will be used as the representative - weather code. model_id_attr (str): Name of attribute recording source models that should be inherited by the output cube. The source models are expected as @@ -112,7 +110,6 @@ def process( day_start, day_end, wet_bias, - ignore_intensity, model_id_attr=model_id_attr, record_run_attr=record_run_attr, )(cubes) diff --git a/improver/wxcode/modal_code.py b/improver/wxcode/modal_code.py index 8c70ad23b6..ec29c43e0b 100644 --- a/improver/wxcode/modal_code.py +++ b/improver/wxcode/modal_code.py @@ -361,12 +361,11 @@ def __init__( self, broad_categories: Dict[str, int], wet_categories: Dict[str, int], - intensity_categories: Dict[str, int], + intensity_categories: Optional[Dict[str, int]] = None, day_weighting: int = 1, day_start: int = 6, day_end: int = 18, wet_bias: int = 1, - ignore_intensity: bool = False, model_id_attr: Optional[str] = None, record_run_attr: Optional[str] = None, ): @@ -383,7 +382,9 @@ def __init__( should both be ordered in terms of descending priority. intensity_categories: Dictionary defining intensity groupings. Values should be ordered in - terms of descending priority. + terms of descending priority. The most common weather code from the + options available representing different intensities will be used as the + representative weather code. day_weighting: Weighting to provide day time weather codes. A weighting of 1 indicates the default weighting. A weighting of 2 indicates that the weather codes @@ -400,12 +401,6 @@ def __init__( only a quarter of codes are required to be wet, in order to generate a wet symbol. To generate a wet symbol, the fraction of wet symbols therefore need to be greater than or equal to 1 / (1 + wet_bias). - ignore_intensity: - Boolean indicating whether weather codes of different intensities - should be grouped together when establishing the most representative - weather code. The most common weather code from the options available - representing different intensities will be used as the representative - weather code. model_id_attr: Name of attribute recording source models that should be inherited by the output cube. The source models are expected as @@ -421,7 +416,6 @@ def __init__( self.day_start = day_start self.day_end = day_end self.wet_bias = wet_bias - self.ignore_intensity = ignore_intensity self.model_id_attr = model_id_attr self.record_run_attr = record_run_attr @@ -433,10 +427,10 @@ def _consolidate_intensity_categories(self, cube: Cube) -> Cube: cube: Weather codes cube. Returns: - Weather codes cube with intensity categories consolidated, if the - ignore_intensity option is enabled. + Weather codes cube with intensity categories consolidated, + if intensity categories are provided. """ - if self.ignore_intensity: + if self.intensity_categories: # Ignore intensities, so that weather codes representing different # intensities can be grouped. for values in self.intensity_categories.values(): @@ -781,7 +775,7 @@ def process(self, cubes: CubeList) -> Cube: categorise_using_modal=False, ) - if self.ignore_intensity: + if self.intensity_categories: intensity_indices = self._find_intensity_indices(result) result = self._get_most_likely_following_grouping( original_cube, diff --git a/improver_tests/acceptance/SHA256SUMS b/improver_tests/acceptance/SHA256SUMS index 6aa08c5565..3c2d73c180 100644 --- a/improver_tests/acceptance/SHA256SUMS +++ b/improver_tests/acceptance/SHA256SUMS @@ -753,7 +753,7 @@ c44a00d49912f13fb17256fa0e01d9425977b5c94f2d41c602c657d39deb74cc ./weather-symb a981f6238828b63d7a9f7c597dd234dcc86dd35e2e3c4ba6c3b6feb491ec872e ./weather-symbol-modes/blend_mismatch_inputs/20201209T1700Z-weather_symbols-PT01H.nc de4a49bca4cd930328942cf6bb9a1bc1bdd2589120a57a2335ee4ef2449dbd5d ./weather-symbol-modes/blend_mismatch_inputs/20201209T1800Z-weather_symbols-PT01H.nc 9ee56eeaf451b360120a1e52b95435bc5fa1089f6447d92244afcb0ca84aa781 ./weather-symbol-modes/blend_mismatch_inputs/kgo.nc -bfefb60f52d72e81ddcf6d775c83762cf0894355601a3519d286571525eed813 ./weather-symbol-modes/broad_categories.json +bdaffce463e5d9e30ea6cfae58d4decfa266600cbb51480161d4170f46bb6ba3 ./weather-symbol-modes/broad_categories.json deb7f4effb821b2808b647e02ac955c91adae4baa33765b16378cff40e3ec5e8 ./weather-symbol-modes/gridded_input/20201209T0700Z-weather_symbols-PT01H.nc a61a70b0ce9e70577ba177462b9f1bfbda2457cc3975f0e9a562e1311e86e671 ./weather-symbol-modes/gridded_input/20201209T0800Z-weather_symbols-PT01H.nc 64fc223da6c516a1eef11a61119547fb33e899ce86eb570a2917be27a119b517 ./weather-symbol-modes/gridded_input/20201209T0900Z-weather_symbols-PT01H.nc @@ -766,7 +766,7 @@ bcd90ab1d28fd736d4a3d9e481374348438d7716b543f9c7d435b003ba10c344 ./weather-symb 973c60900aa526818e7119ed016997170055017ee1bbda279b9e640750f96f61 ./weather-symbol-modes/gridded_input/20201209T1600Z-weather_symbols-PT01H.nc 571bff58be29197e5f946745ed565889ec81499521c38d8f7286488079afb46d ./weather-symbol-modes/gridded_input/20201209T1700Z-weather_symbols-PT01H.nc 2af4455b0ba7c4124e49eb1ff004e770b6239a9e2e1513f60ba4db3f0beb02cf ./weather-symbol-modes/gridded_input/20201209T1800Z-weather_symbols-PT01H.nc -16d5a73082db5212d4f0039dd216edc9b3ecd948c00e828212a998a5d7b21e4c ./weather-symbol-modes/gridded_input/kgo.nc +c00571c03d331d661066607cbf51cb53e9a3e9c573c9c782361e41e9a643275f ./weather-symbol-modes/gridded_input/kgo.nc 96a8462af571f06dbd8b91a7a90aaef403eefd2b73929a5c6d8a3fbb01159aca ./weather-symbol-modes/gridded_ties/20201209T0700Z-weather_symbols-PT01H.nc 9f64c7a8aa7cf0e87799f96ebffe1e449e1f5174fb583d44f2479e085672dc84 ./weather-symbol-modes/gridded_ties/20201209T0800Z-weather_symbols-PT01H.nc c698b9599219fe89374a2565e55a374d9236904c9dd99a2ae61b5416506e98d3 ./weather-symbol-modes/gridded_ties/20201209T0900Z-weather_symbols-PT01H.nc @@ -780,7 +780,7 @@ c39ea98f6fe64788c4ea7ea242111a5c8bbeacfaf52b2ead0cf0aed0007d46ab ./weather-symb 6a5b04644ab11d077809f615bac2829656127a0eeee3843940f8d33673bd70c8 ./weather-symbol-modes/gridded_ties/20201209T1700Z-weather_symbols-PT01H.nc 39d0fa291798366a00ecae79a65de0b0692d5b4db17ac98a97d48e54b75e5dd4 ./weather-symbol-modes/gridded_ties/20201209T1800Z-weather_symbols-PT01H.nc fc922ede9e118dea3e7e3ba354664151f09407b32450688ed5c9870de5307c14 ./weather-symbol-modes/gridded_ties/kgo.nc -e50db92fb58503b6a7f7fa88cd96124bf005cf8df3924fefb007b41274dd2d74 ./weather-symbol-modes/intensity_categories.json +a534bf31735a0b4a00755447b35d9531da01eb5feb1a09d1e2cc68cdd93e5d09 ./weather-symbol-modes/intensity_categories.json 89ba47a99c53d23b5490254366211a7cc0a5c8633c9faee97c091ee48a366b87 ./weather-symbol-modes/single_input/20201210T0000Z-weather_symbols-PT01H.nc d64efaa75b03aa4ba1fb16caa31891492e9fc5f967a584de42a4a59dc2f54237 ./weather-symbol-modes/single_input/kgo.nc f4e13dec400ec945ba5bd03a286780b183665c22d707c038c0990ef3491e888e ./weather-symbol-modes/spot_input/20201209T0700Z-weather_symbols-PT01H.nc @@ -809,7 +809,7 @@ ea67ae7a7f5363ae3692b29c93fb9989449d96e49dc613a1297d98ddb12c578a ./weather-symb 51f636314a6d1fa894ab98cf750493503b191a779c67d6a15081aab2a3612a31 ./weather-symbol-modes/spot_ties/20201209T1700Z-weather_symbols-PT01H.nc 134fb1750cf47e868ee67801b1ea5b1f17120e6f58a787a69e54638d7d88ff82 ./weather-symbol-modes/spot_ties/20201209T1800Z-weather_symbols-PT01H.nc 391a9bd50824318fb8f147db3b14bcd56f5b0f0e0d5479b3579e08d70ef6ba77 ./weather-symbol-modes/spot_ties/kgo.nc -681fa8df3ee66828499311b94c47dba5bfff43c9e4c6ea2d2f81ed49f86edad6 ./weather-symbol-modes/wet_categories.json +2d66678569a1af9b3357cd1c9d6b75dfedd912a99c3ed77135b2a2169b12687e ./weather-symbol-modes/wet_categories.json 2ec32b8654824a633fcc9d7405d4d3a8b487514bddb9e8ec6aae66c9a96c2565 ./weather-symbol-modes/wx_decision_tree.json bd51a8596838e355c78509b8b3b1215a3f1e3b798d5b300d4aff8032a26507b7 ./weighted_blending/accum_cycle_blend/kgo.nc c465dc56d83e9e866c1140033c65f07a02db154792b505d4a704d2773c3744e4 ./weighted_blending/accum_cycle_blend/ukv_prob_accum_PT3H.nc diff --git a/improver_tests/wxcode/wxcode/test_ModalFromGroupings.py b/improver_tests/wxcode/wxcode/test_ModalFromGroupings.py index 90af61cce7..12c49aec30 100644 --- a/improver_tests/wxcode/wxcode/test_ModalFromGroupings.py +++ b/improver_tests/wxcode/wxcode/test_ModalFromGroupings.py @@ -46,14 +46,14 @@ RECORD_RUN_ATTR = "mosg__model_run" TARGET_TIME = dt(2020, 6, 15, 18) BROAD_CATEGORIES = { - "wet": np.arange(9, 31), - "dry": np.arange(0, 9), + "wet": [10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 24, 26, 27, 29, 30], + "dry": [1, 3, 4, 5, 6, 7, 8], } # Priority ordered categories (keys) in case of ties WET_CATEGORIES = { - "extreme_convection": [30, 29, 28, 21, 20, 19], - "frozen": [27, 26, 25, 24, 23, 22, 18, 17, 16], - "liquid": [15, 14, 13, 12, 11, 10, 9], + "extreme_convection": [30, 29, 21, 20], + "frozen": [27, 26, 24, 23, 18, 17], + "liquid": [15, 14, 12, 11, 10], } INTENSITY_CATEGORIES = { "rain_shower": [14, 10], @@ -140,9 +140,7 @@ def test_expected_values(wxcode_series, expected): """Test that the expected period representative symbol is returned.""" _, _, _, _, wxcode_cubes = wxcode_series - result = ModalFromGroupings(BROAD_CATEGORIES, WET_CATEGORIES, INTENSITY_CATEGORIES)( - wxcode_cubes - ) + result = ModalFromGroupings(BROAD_CATEGORIES, WET_CATEGORIES)(wxcode_cubes) expected = [expected] if not isinstance(expected, list) else expected for index in range(len(expected)): assert result.data.flatten()[index] == expected[index] @@ -212,9 +210,9 @@ def test_expected_values_wet_bias( if reverse_wet_keys: wet_categories = dict(reversed(list(wet_categories.items()))) - result = ModalFromGroupings( - BROAD_CATEGORIES, wet_categories, INTENSITY_CATEGORIES, wet_bias=wet_bias, - )(wxcode_cubes) + result = ModalFromGroupings(BROAD_CATEGORIES, wet_categories, wet_bias=wet_bias,)( + wxcode_cubes + ) expected = [expected] if not isinstance(expected, list) else expected for index in range(len(expected)): assert result.data.flatten()[index] == expected[index] @@ -278,7 +276,6 @@ def test_expected_values_day_weighting( result = ModalFromGroupings( BROAD_CATEGORIES, WET_CATEGORIES, - INTENSITY_CATEGORIES, day_weighting=day_weighting, day_start=day_start, day_end=day_end, @@ -332,11 +329,10 @@ def test_expected_values_ignore_intensity( intensity_categories = {} for key in INTENSITY_CATEGORIES.keys(): intensity_categories[key] = [i for i in reversed(INTENSITY_CATEGORIES[key])] + if not ignore_intensity: + intensity_categories = None result = ModalFromGroupings( - BROAD_CATEGORIES, - WET_CATEGORIES, - intensity_categories, - ignore_intensity=ignore_intensity, + BROAD_CATEGORIES, WET_CATEGORIES, intensity_categories=intensity_categories, )(wxcode_cubes) expected = [expected] if not isinstance(expected, list) else expected for index in range(len(expected)): @@ -398,15 +394,19 @@ def test_expected_values_interactions( _, _, _, _, wxcode_cubes = wxcode_series class_instance = ModalFromGroupings class_instance.DAY_LENGTH = day_length + if ignore_intensity: + intensity_categories = INTENSITY_CATEGORIES.copy() + else: + intensity_categories = None + result = class_instance( BROAD_CATEGORIES, WET_CATEGORIES, - INTENSITY_CATEGORIES, + intensity_categories=intensity_categories, wet_bias=wet_bias, day_weighting=day_weighting, day_start=day_start, day_end=day_end, - ignore_intensity=ignore_intensity, )(wxcode_cubes) expected = [expected] if not isinstance(expected, list) else expected for index in range(len(expected)): @@ -448,7 +448,10 @@ def as_utc_timestamp(time): kwargs.update({"record_run_attr": RECORD_RUN_ATTR}) result = ModalFromGroupings( - BROAD_CATEGORIES, WET_CATEGORIES, INTENSITY_CATEGORIES, **kwargs, + BROAD_CATEGORIES, + WET_CATEGORIES, + intensity_categories=INTENSITY_CATEGORIES, + **kwargs, )(wxcode_cubes) n_times = len(wxcode_cubes) @@ -513,6 +516,6 @@ def test_unmatching_bounds_exception(wxcode_series): with pytest.raises( ValueError, match="Input diagnostics do not have consistent periods." ): - ModalFromGroupings(BROAD_CATEGORIES, WET_CATEGORIES, INTENSITY_CATEGORIES,)( - wxcode_cubes - ) + ModalFromGroupings( + BROAD_CATEGORIES, WET_CATEGORIES, intensity_categories=INTENSITY_CATEGORIES, + )(wxcode_cubes)