Skip to content

Commit

Permalink
feat: Enable to read for the Q4 coverage and the IQTI files for the f…
Browse files Browse the repository at this point in the history
…ci l1c data
  • Loading branch information
ClementLaplace committed Jun 28, 2024
1 parent df4a1ba commit da769ce
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 27 deletions.
42 changes: 25 additions & 17 deletions satpy/readers/fci_l1c_nc.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,16 +216,21 @@ def __init__(self, filename, filename_info, filetype_info):
logger.debug("Start: {}".format(self.start_time))
logger.debug("End: {}".format(self.end_time))

if self.filename_info["coverage"] == "Q4":
# change number of chunk so that padding gets activated correctly on missing chunks
self.filename_info["count_in_repeat_cycle"] += 28

if self.filename_info["facility_or_tool"] == "IQTI":
self.is_iqt = True
else :
self.is_iqt = False

self._cache = {}

@property
def rc_period_min(self):
"""Get nominal repeat cycle duration.
As RSS is not yet implemented an error will be raised if RSS are tried to be read.
"""
"""Get nominal repeat cycle duration."""
if self.filename_info["coverage"] not in ["FD","AF"]:
raise NotImplementedError(f"coverage for {self.filename_info['coverage']} not supported by this reader")
return 2.5
return 10

Expand Down Expand Up @@ -378,11 +383,12 @@ def _get_dataset_measurand(self, key, info=None):
self["attr/platform"], self["attr/platform"])

# remove unpacking parameters for calibrated data
if key["calibration"] in ["brightness_temperature", "reflectance"]:
if key["calibration"] in ["brightness_temperature", "reflectance","radiance"]:
res.attrs.pop("add_offset")
res.attrs.pop("warm_add_offset")
res.attrs.pop("scale_factor")
res.attrs.pop("warm_scale_factor")
res.attrs.pop("valid_range")

# remove attributes from original file which don't apply anymore
res.attrs.pop("long_name")
Expand All @@ -400,9 +406,18 @@ def _get_dataset_measurand(self, key, info=None):
@cached_property
def orbital_param(self):
"""Compute the orbital parameters for the current segment."""
actual_subsat_lon = float(np.nanmean(self._get_aux_data_lut_vector("subsatellite_longitude")))
actual_subsat_lat = float(np.nanmean(self._get_aux_data_lut_vector("subsatellite_latitude")))
actual_sat_alt = float(np.nanmean(self._get_aux_data_lut_vector("platform_altitude")))
if self.is_iqt:
actual_subsat_lon = -3.4
actual_subsat_lat = 0.0
actual_sat_alt = 35786400
logger.info("IQT data the following parameters are hardcoded "
f"satellite_actual_longitude = {actual_subsat_lon} ,"
f" satellite_actual_latitude = {actual_subsat_lat} ,"
f"satellite_sat_alt = {actual_sat_alt}")
else:
actual_subsat_lon = float(np.nanmean(self._get_aux_data_lut_vector("subsatellite_longitude")))
actual_subsat_lat = float(np.nanmean(self._get_aux_data_lut_vector("subsatellite_latitude")))
actual_sat_alt = float(np.nanmean(self._get_aux_data_lut_vector("platform_altitude")))
# The "try" is a temporary part of the code as long as the AF data are not modified
try :
nominal_and_proj_subsat_lon = float(
Expand Down Expand Up @@ -687,16 +702,9 @@ def calibrate_rad_to_refl(self, radiance, key):
"cannot produce reflectance for {:s}.".format(measured))
return radiance * np.float32(np.nan)

sun_earth_distance = np.mean(
sun_earth_distance = np.nanmean(
self.get_and_cache_npxr("state/celestial/earth_sun_distance")) / 149597870.7 # [AU]

# TODO remove this check when old versions of IDPF test data (<v5) are deprecated.
if sun_earth_distance < 0.9 or sun_earth_distance > 1.1:
logger.info("The variable state/celestial/earth_sun_distance contains unexpected values"
"(mean value is {} AU). Defaulting to 1 AU for reflectance calculation."
"".format(sun_earth_distance))
sun_earth_distance = 1

res = 100 * radiance * np.float32(np.pi) * np.float32(sun_earth_distance) ** np.float32(2) / cesi
return res

Expand Down
71 changes: 61 additions & 10 deletions satpy/tests/reader_tests/test_fci_l1c_nc.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-HRFI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc"
]
],
"fdhsi_q4": ["W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-Q4--"
"CHK-BODY--DIS-NC4E_C_EUMT_20230723025408_IDPFI_DEV_"
"20230722120000_20230722120027_N_JLS_C_0289_0001.nc"
],
"hrfi_q4": ["W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-HRFI-Q4--"
"CHK-BODY--DIS-NC4E_C_EUMT_20230723025408_IDPFI_DEV"
"_20230722120000_20230722120027_N_JLS_C_0289_0001.nc"]
}

def resolutions(channel):
Expand Down Expand Up @@ -558,6 +565,16 @@ def FakeFCIFileHandlerFDHSI_fixture():
}
yield param_dict

@pytest.fixture()
def FakeFCIFileHandlerFDHSIQ4_fixture():
"""Get a fixture for the fake FDHSI filehandler, including channel and file names."""
with mocked_basefilehandler(FakeFCIFileHandlerFDHSI):
param_dict = {
"filetype": "fci_l1c_fdhsi",
"channels": CHANS_FHDSI,
"filenames": TEST_FILENAMES["fdhsi_q4"]
}
yield param_dict

@pytest.fixture()
def FakeFCIFileHandlerHRFI_fixture():
Expand All @@ -570,6 +587,18 @@ def FakeFCIFileHandlerHRFI_fixture():
}
yield param_dict

@pytest.fixture()
def FakeFCIFileHandlerHRFIQ4_fixture():
"""Get a fixture for the fake HRFI filehandler, including channel and file names."""
with mocked_basefilehandler(FakeFCIFileHandlerHRFI):
param_dict = {
"filetype": "fci_l1c_hrfi",
"channels": CHANS_HRFI,
"filenames": TEST_FILENAMES["hrfi_q4"]
}
yield param_dict


@pytest.fixture()
def FakeFCIFileHandlerAF_fixture(channel,resolution):
"""Get a fixture for the fake AF filehandler, it contains only one channel and one resolution."""
Expand All @@ -595,7 +624,11 @@ class TestFCIL1cNCReader:
fh_param_for_filetype = {"hrfi": {"channels": CHANS_HRFI,
"filenames": TEST_FILENAMES["hrfi"]},
"fdhsi": {"channels": CHANS_FHDSI,
"filenames": TEST_FILENAMES["fdhsi"]}}
"filenames": TEST_FILENAMES["fdhsi"]},
"hrfi_q4": {"channels": CHANS_HRFI,
"filenames": TEST_FILENAMES["hrfi_q4"]},
"fdhsi_q4": {"channels": CHANS_FHDSI,
"filenames": TEST_FILENAMES["fdhsi_q4"]}}

def _get_type_ter_AF(self,channel):
"""Get the type_ter."""
Expand Down Expand Up @@ -642,7 +675,9 @@ def test_file_pattern(self, reader_configs, filenames):
assert len(files) == 1

@pytest.mark.parametrize("filenames", [TEST_FILENAMES["fdhsi"][0].replace("BODY", "TRAIL"),
TEST_FILENAMES["hrfi"][0].replace("BODY", "TRAIL")])
TEST_FILENAMES["hrfi"][0].replace("BODY", "TRAIL"),
TEST_FILENAMES["hrfi_q4"][0].replace("BODY", "TRAIL"),
TEST_FILENAMES["fdhsi_q4"][0].replace("BODY", "TRAIL")])
def test_file_pattern_for_TRAIL_file(self, reader_configs, filenames):
"""Test file pattern matching for TRAIL files, which should not be picked up."""
from satpy.readers import load_reader
Expand All @@ -653,7 +688,9 @@ def test_file_pattern_for_TRAIL_file(self, reader_configs, filenames):

@pytest.mark.parametrize("calibration", ["counts","radiance","brightness_temperature","reflectance"])
@pytest.mark.parametrize(("fh_param","res_type"), [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture"),"hdfi"),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"),"hrfi")])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"),"hrfi"),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture"),"hrfi"),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"),"hdfi")])
def test_load_calibration(self, reader_configs, fh_param,
caplog,calibration,res_type):
"""Test loading with counts,radiance,reflectance and bt."""
Expand Down Expand Up @@ -704,7 +741,9 @@ def test_load_calibration_af(self,FakeFCIFileHandlerAF_fixture,reader_configs,ch


@pytest.mark.parametrize("fh_param", [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"))])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture")),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"))])
def test_orbital_parameters_attr(self, reader_configs, fh_param):
"""Test the orbital parameter attribute."""
reader = _get_reader_with_filehandlers(fh_param["filenames"], reader_configs)
Expand All @@ -727,7 +766,9 @@ def test_orbital_parameters_attr(self, reader_configs, fh_param):

@pytest.mark.parametrize(("fh_param", "expected_pos_info"), [
(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture"), EXPECTED_POS_INFO_FOR_FILETYPE["fdhsi"]),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"), EXPECTED_POS_INFO_FOR_FILETYPE["hrfi"])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"), EXPECTED_POS_INFO_FOR_FILETYPE["hrfi"]),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture"),EXPECTED_POS_INFO_FOR_FILETYPE["hrfi"]),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"), EXPECTED_POS_INFO_FOR_FILETYPE["fdhsi"])
])
def test_get_segment_position_info(self, reader_configs, fh_param, expected_pos_info):
"""Test the segment position info method."""
Expand All @@ -748,7 +789,9 @@ def test_not_get_segment_info_called_af(self,FakeFCIFileHandlerAF_fixture,reader

@pytest.mark.parametrize("calibration", ["index_map","pixel_quality"])
@pytest.mark.parametrize(("fh_param", "expected_res_n"), [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture"), 16),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"), 4)])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"), 4),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture"),4),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"),16)])
def test_load_map_and_pixel(self, reader_configs, fh_param, expected_res_n,calibration):
"""Test loading of index_map and pixel_quality."""
reader = _get_reader_with_filehandlers(fh_param["filenames"], reader_configs)
Expand Down Expand Up @@ -793,7 +836,9 @@ def test_load_map_and_pixel_af(self,FakeFCIFileHandlerAF_fixture,reader_configs,


@pytest.mark.parametrize("fh_param", [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"))])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture")),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"))])
def test_load_aux_data(self, reader_configs, fh_param):
"""Test loading of auxiliary data."""
from satpy.readers.fci_l1c_nc import AUX_DATA
Expand All @@ -810,7 +855,9 @@ def test_load_aux_data(self, reader_configs, fh_param):
numpy.testing.assert_array_equal(res[aux][1, 1], 10)

@pytest.mark.parametrize("fh_param", [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"))])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture")),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"))])
def test_platform_name(self, reader_configs, fh_param):
"""Test that platform name is exposed.
Expand All @@ -824,6 +871,8 @@ def test_platform_name(self, reader_configs, fh_param):
@pytest.mark.parametrize(("fh_param", "expected_area"), [
(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture"), ["mtg_fci_fdss_1km", "mtg_fci_fdss_2km"]),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"), ["mtg_fci_fdss_500m", "mtg_fci_fdss_1km"]),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture"),["mtg_fci_fdss_500m", "mtg_fci_fdss_1km"]),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"),["mtg_fci_fdss_1km", "mtg_fci_fdss_2km"])
])
def test_area_definition_computation(self, reader_configs, fh_param, expected_area):
"""Test that the geolocation computation is correct."""
Expand All @@ -850,7 +899,9 @@ def test_area_definition_computation(self, reader_configs, fh_param, expected_ar
assert area_def.crs.ellipsoid.is_semi_minor_computed

@pytest.mark.parametrize("fh_param", [(lazy_fixture("FakeFCIFileHandlerFDHSI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture"))])
(lazy_fixture("FakeFCIFileHandlerHRFI_fixture")),
(lazy_fixture("FakeFCIFileHandlerHRFIQ4_fixture")),
(lazy_fixture("FakeFCIFileHandlerFDHSIQ4_fixture"))])
def test_excs(self, reader_configs, fh_param):
"""Test that exceptions are raised where expected."""
reader = _get_reader_with_filehandlers(fh_param["filenames"], reader_configs)
Expand Down

0 comments on commit da769ce

Please sign in to comment.