From 3b206dce62b593d4fefb062d9bd32a88b72d372f Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 11:55:20 +0100 Subject: [PATCH 1/7] Fix bug in Himawari HSD reader that created error when observation_timeline was fill value. --- satpy/readers/ahi_hsd.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/satpy/readers/ahi_hsd.py b/satpy/readers/ahi_hsd.py index 116f5e7d5a..629b04c874 100644 --- a/satpy/readers/ahi_hsd.py +++ b/satpy/readers/ahi_hsd.py @@ -455,9 +455,13 @@ def _modify_observation_time_for_nominal(self, observation_time): else: observation_frequency_seconds = {'JP': 150, 'R3': 150, 'R4': 30, 'R5': 30}[self.observation_area[:2]] dt = observation_frequency_seconds * (int(self.observation_area[2:]) - 1) - return observation_time.replace( - hour=int(timeline[:2]), minute=int(timeline[2:4]) + dt//60, - second=dt % 60, microsecond=0) + if int(timeline[:2]) < 24: + return observation_time.replace( + hour=int(timeline[:2]), minute=int(timeline[2:4]) + dt//60, + second=dt % 60, microsecond=0) + else: + warnings.warn("Observation timeline is fill value, not rounding observation time.") + return observation_time def get_dataset(self, key, info): """Get the dataset.""" From 360785df3564d366f09b5b726e373820bca4e5fa Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 12:06:21 +0100 Subject: [PATCH 2/7] Remove unnecessary `else` from AHI HSD reader. --- satpy/readers/ahi_hsd.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/satpy/readers/ahi_hsd.py b/satpy/readers/ahi_hsd.py index 629b04c874..21563f120d 100644 --- a/satpy/readers/ahi_hsd.py +++ b/satpy/readers/ahi_hsd.py @@ -459,9 +459,8 @@ def _modify_observation_time_for_nominal(self, observation_time): return observation_time.replace( hour=int(timeline[:2]), minute=int(timeline[2:4]) + dt//60, second=dt % 60, microsecond=0) - else: - warnings.warn("Observation timeline is fill value, not rounding observation time.") - return observation_time + warnings.warn("Observation timeline is fill value, not rounding observation time.") + return observation_time def get_dataset(self, key, info): """Get the dataset.""" From 1965d09b5a62ef86ab2908657b923b35ef2c2ccd Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 14:05:20 +0100 Subject: [PATCH 3/7] Add function to check AHI HSD timeline is valid. --- satpy/readers/ahi_hsd.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/satpy/readers/ahi_hsd.py b/satpy/readers/ahi_hsd.py index 21563f120d..92b568d87a 100644 --- a/satpy/readers/ahi_hsd.py +++ b/satpy/readers/ahi_hsd.py @@ -436,6 +436,13 @@ def nominal_end_time(self): """Get the nominal end time.""" return self._modify_observation_time_for_nominal(self.observation_end_time) + @staticmethod + def _is_valid_timeline(timeline): + """Check that the `observation_timeline` value is not a fill value.""" + if int(timeline[:2]) > 23: + return False + return True + def _modify_observation_time_for_nominal(self, observation_time): """Round observation time to a nominal time based on known observation frequency. @@ -450,17 +457,19 @@ def _modify_observation_time_for_nominal(self, observation_time): """ timeline = "{:04d}".format(self.basic_info['observation_timeline'][0]) + if not self._is_valid_timeline(timeline): + warnings.warn("Observation timeline is fill value, not rounding observation time.") + return observation_time + if self.observation_area == 'FLDK': dt = 0 else: observation_frequency_seconds = {'JP': 150, 'R3': 150, 'R4': 30, 'R5': 30}[self.observation_area[:2]] dt = observation_frequency_seconds * (int(self.observation_area[2:]) - 1) - if int(timeline[:2]) < 24: - return observation_time.replace( - hour=int(timeline[:2]), minute=int(timeline[2:4]) + dt//60, - second=dt % 60, microsecond=0) - warnings.warn("Observation timeline is fill value, not rounding observation time.") - return observation_time + + return observation_time.replace( + hour=int(timeline[:2]), minute=int(timeline[2:4]) + dt//60, + second=dt % 60, microsecond=0) def get_dataset(self, key, info): """Get the dataset.""" From cab16be51443cfe681f17298db9d5cee38578efc Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 14:37:14 +0100 Subject: [PATCH 4/7] Add tests for time rounding. --- satpy/tests/reader_tests/test_ahi_hsd.py | 26 +++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/satpy/tests/reader_tests/test_ahi_hsd.py b/satpy/tests/reader_tests/test_ahi_hsd.py index 3a2495d5d0..4883bd2a74 100644 --- a/satpy/tests/reader_tests/test_ahi_hsd.py +++ b/satpy/tests/reader_tests/test_ahi_hsd.py @@ -37,11 +37,11 @@ FAKE_BASIC_INFO: InfoDict = { 'blocklength': 0, - 'satellite': np.array(['Himawari-8']), - 'observation_area': np.array(['FLDK']), - 'observation_start_time': np.array([58413.12523839]), - 'observation_end_time': np.array([58413.12562439]), - 'observation_timeline': np.array([300]), + 'satellite': 'Himawari-8', + 'observation_area': 'FLDK', + 'observation_start_time': 58413.12523839, + 'observation_end_time': 58413.12562439, + 'observation_timeline': '0300', } FAKE_DATA_INFO: InfoDict = { 'blocklength': 50, @@ -359,6 +359,22 @@ def test_blocklen_error(self, *mocks): fh._check_fpos(fp_, fpos, 0, 'header 1') assert len(w) > 0 + def test_time_rounding(self): + """Test rounding of the nominal time.""" + + assert AHIHSDFileHandler._is_valid_timeline(FAKE_BASIC_INFO['observation_timeline']) is True + assert AHIHSDFileHandler._is_valid_timeline('65526') is False + + mocker = mock.MagicMock() + in_date = datetime(2020, 1, 1, 12, 0, 0) + + with mock.patch('satpy.readers.ahi_hsd.AHIHSDFileHandler._is_valid_timeline', mocker): + with _fake_hsd_handler() as fh: + mocker.return_value = True + assert fh._modify_observation_time_for_nominal(in_date) == datetime(2020, 1, 1, 3, 0, 0) + mocker.return_value = False + assert fh._modify_observation_time_for_nominal(in_date) == datetime(2020, 1, 1, 12, 0, 0) + class TestAHICalibration(unittest.TestCase): """Test case for various AHI calibration types.""" From f19dfdc152a5cb59ecc72811a46f6c8cf96ac23a Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 14:38:40 +0100 Subject: [PATCH 5/7] Add tests for time rounding. --- satpy/tests/reader_tests/test_ahi_hsd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/satpy/tests/reader_tests/test_ahi_hsd.py b/satpy/tests/reader_tests/test_ahi_hsd.py index 4883bd2a74..7b318c5ecc 100644 --- a/satpy/tests/reader_tests/test_ahi_hsd.py +++ b/satpy/tests/reader_tests/test_ahi_hsd.py @@ -361,7 +361,6 @@ def test_blocklen_error(self, *mocks): def test_time_rounding(self): """Test rounding of the nominal time.""" - assert AHIHSDFileHandler._is_valid_timeline(FAKE_BASIC_INFO['observation_timeline']) is True assert AHIHSDFileHandler._is_valid_timeline('65526') is False From ee4aed5eb89d9c8c9b7189e8f7e1274fc2baece2 Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 19:53:40 +0100 Subject: [PATCH 6/7] Update AHI HSD tests. --- satpy/tests/reader_tests/test_ahi_hsd.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/satpy/tests/reader_tests/test_ahi_hsd.py b/satpy/tests/reader_tests/test_ahi_hsd.py index 7b318c5ecc..c2cc0d8aba 100644 --- a/satpy/tests/reader_tests/test_ahi_hsd.py +++ b/satpy/tests/reader_tests/test_ahi_hsd.py @@ -359,10 +359,14 @@ def test_blocklen_error(self, *mocks): fh._check_fpos(fp_, fpos, 0, 'header 1') assert len(w) > 0 + def test_is_valid_time(self): + """Test that valid times are correctly itentified""" + + assert AHIHSDFileHandler._is_valid_timeline(FAKE_BASIC_INFO['observation_timeline']) + assert not AHIHSDFileHandler._is_valid_timeline('65526') + def test_time_rounding(self): """Test rounding of the nominal time.""" - assert AHIHSDFileHandler._is_valid_timeline(FAKE_BASIC_INFO['observation_timeline']) is True - assert AHIHSDFileHandler._is_valid_timeline('65526') is False mocker = mock.MagicMock() in_date = datetime(2020, 1, 1, 12, 0, 0) From 03a62efa3e17d6a0ee00f08823c6c3b7777eb178 Mon Sep 17 00:00:00 2001 From: simonrp84 Date: Mon, 9 May 2022 19:55:06 +0100 Subject: [PATCH 7/7] Fix AHI test typo and docstring. --- satpy/tests/reader_tests/test_ahi_hsd.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/satpy/tests/reader_tests/test_ahi_hsd.py b/satpy/tests/reader_tests/test_ahi_hsd.py index c2cc0d8aba..1112ebe5a5 100644 --- a/satpy/tests/reader_tests/test_ahi_hsd.py +++ b/satpy/tests/reader_tests/test_ahi_hsd.py @@ -360,14 +360,12 @@ def test_blocklen_error(self, *mocks): assert len(w) > 0 def test_is_valid_time(self): - """Test that valid times are correctly itentified""" - + """Test that valid times are correctly identified.""" assert AHIHSDFileHandler._is_valid_timeline(FAKE_BASIC_INFO['observation_timeline']) assert not AHIHSDFileHandler._is_valid_timeline('65526') def test_time_rounding(self): """Test rounding of the nominal time.""" - mocker = mock.MagicMock() in_date = datetime(2020, 1, 1, 12, 0, 0)