Skip to content

Commit

Permalink
A first draft fix of the viewing geometry per feed horn
Browse files Browse the repository at this point in the history
Signed-off-by: Adam.Dybbroe <[email protected]>
  • Loading branch information
Adam.Dybbroe committed Oct 10, 2024
1 parent 70bbc86 commit a84d874
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 30 deletions.
147 changes: 133 additions & 14 deletions satpy/etc/readers/aws_l1b_nc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -363,46 +363,165 @@ datasets:

# --- Navigation data ---

solar_azimuth:
name: solar_azimuth
solar_azimuth_horn1:
name: solar_azimuth_horn1
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_azimuth_angle
standard_name: solar_azimuth_angle
horn: ["1", "2", "3", "4"]
horn: "1"
coordinates:
- longitude
- latitude

solar_azimuth_horn2:
name: solar_azimuth_horn2
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_azimuth_angle
standard_name: solar_azimuth_angle
horn: "2"
coordinates:
- longitude
- latitude

solar_zenith:
name: solar_zenith
solar_azimuth_horn3:
name: solar_azimuth_horn3
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_azimuth_angle
standard_name: solar_azimuth_angle
horn: "3"
coordinates:
- longitude
- latitude

solar_azimuth_horn4:
name: solar_azimuth_horn4
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_azimuth_angle
standard_name: solar_azimuth_angle
horn: "4"
coordinates:
- longitude
- latitude

solar_zenith_horn1:
name: solar_zenith_horn1
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_zenith_angle
standard_name: solar_zenith_angle
horn: ["1", "2", "3", "4"]
horn: "1"
coordinates:
- longitude
- latitude

satellite_azimuth:
name: satellite_azimuth
solar_zenith_horn2:
name: solar_zenith_horn2
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_azimuth_angle
standard_name: satellite_azimuth_angle
horn: ["1", "2", "3", "4"]
file_key: data/navigation/aws_solar_zenith_angle
standard_name: solar_zenith_angle
horn: "2"
coordinates:
- longitude
- latitude

satellite_zenith:
name: satellite_zenith
solar_zenith_horn3:
name: solar_zenith_horn3
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_zenith_angle
standard_name: solar_zenith_angle
horn: "3"
coordinates:
- longitude
- latitude

solar_zenith_horn4:
name: solar_zenith_horn4
file_type: aws_l1b_nc
file_key: data/navigation/aws_solar_zenith_angle
standard_name: solar_zenith_angle
horn: "4"
coordinates:
- longitude
- latitude

satellite_zenith_horn1:
name: satellite_zenith_horn1
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_zenith_angle
standard_name: satellite_zenith_angle
horn: ["1", "2", "3", "4"]
horn: "1"
coordinates:
- longitude
- latitude

satellite_zenith_horn2:
name: satellite_zenith_horn2
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_zenith_angle
standard_name: satellite_zenith_angle
horn: "2"
coordinates:
- longitude
- latitude

satellite_zenith_horn3:
name: satellite_zenith_horn3
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_zenith_angle
standard_name: satellite_zenith_angle
horn: "3"
coordinates:
- longitude
- latitude

satellite_zenith_horn4:
name: satellite_zenith_horn4
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_zenith_angle
standard_name: satellite_zenith_angle
horn: "4"
coordinates:
- longitude
- latitude

satellite_azimuth_horn1:
name: satellite_azimuth_horn1
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_azimuth_angle
standard_name: satellite_azimuth_angle
horn: "1"
coordinates:
- longitude
- latitude

satellite_azimuth_horn2:
name: satellite_azimuth_horn2
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_azimuth_angle
standard_name: satellite_azimuth_angle
horn: "2"
coordinates:
- longitude
- latitude

satellite_azimuth_horn3:
name: satellite_azimuth_horn3
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_azimuth_angle
standard_name: satellite_azimuth_angle
horn: "3"
coordinates:
- longitude
- latitude

satellite_azimuth_horn4:
name: satellite_azimuth_horn4
file_type: aws_l1b_nc
file_key: data/navigation/aws_satellite_azimuth_angle
standard_name: satellite_azimuth_angle
horn: "4"
coordinates:
- longitude
- latitude

file_types:
aws_l1b_nc:
Expand Down
22 changes: 19 additions & 3 deletions satpy/readers/aws_l1b.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,25 @@ def get_dataset(self, dataset_id, dataset_info):
"""Get the data."""
if dataset_id["name"] in AWS_CHANNEL_NAMES:
data_array = self._get_channel_data(dataset_id, dataset_info)
elif (dataset_id["name"] in ["longitude", "latitude",
"solar_azimuth", "solar_zenith",
"satellite_zenith", "satellite_azimuth"]):
elif dataset_id["name"] in ["satellite_zenith_horn1",
"satellite_zenith_horn2",
"satellite_zenith_horn3",
"satellite_zenith_horn4",
"solar_azimuth_horn1",
"solar_azimuth_horn2",
"solar_azimuth_horn3",
"solar_azimuth_horn4",
"solar_zenith_horn1",
"solar_zenith_horn2",
"solar_zenith_horn3",
"solar_zenith_horn4",
"satellite_azimuth_horn1",
"satellite_azimuth_horn2",
"satellite_azimuth_horn3",
"satellite_azimuth_horn4"]:
data_array = self._get_navigation_data(dataset_id, dataset_info)

elif dataset_id["name"] in ["longitude", "latitude"]:
data_array = self._get_navigation_data(dataset_id, dataset_info)
else:
raise NotImplementedError

Check warning on line 125 in satpy/readers/aws_l1b.py

View check run for this annotation

Codecov / codecov/patch

satpy/readers/aws_l1b.py#L125

Added line #L125 was not covered by tests
Expand Down
53 changes: 40 additions & 13 deletions satpy/tests/reader_tests/test_aws_l1b.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,27 @@

platform_name = "AWS1"
file_pattern = "W_XX-OHB-Stockholm,SAT,{platform_name}-MWR-1B-RAD_C_OHB_{processing_time:%Y%m%d%H%M%S}_G_D_{start_time:%Y%m%d%H%M%S}_{end_time:%Y%m%d%H%M%S}_T_B____.nc" # noqa
fake_data_np = np.random.randint(0, 700000, size=19*5*5).reshape((19, 5, 5))

rng = np.random.default_rng()

fake_data_np = rng.integers(0, 700000, size=19*5*5).reshape((19, 5, 5))
fake_data_np[0, 0, 0] = -2147483648
fake_data_np[0, 0, 1] = 700000 + 10
fake_data_np[0, 0, 2] = -10

fake_data = xr.DataArray(fake_data_np,
dims=["n_channels", "n_fovs", "n_scans"])
fake_lon_data = xr.DataArray(np.random.randint(0, 3599999, size=25 * 4).reshape((4, 5, 5)),
fake_lon_data = xr.DataArray(rng.integers(0, 3599999, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])
fake_lat_data = xr.DataArray(np.random.randint(-900000, 900000, size=25 * 4).reshape((4, 5, 5)),
fake_lat_data = xr.DataArray(rng.integers(-900000, 900000, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])
fake_sun_azi_data = xr.DataArray(np.random.randint(0, 36000, size=25 * 4).reshape((4, 5, 5)),
fake_sun_azi_data = xr.DataArray(rng.integers(0, 36000, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])
fake_sun_zen_data = xr.DataArray(np.random.randint(0, 36000, size=25 * 4).reshape((4, 5, 5)),
fake_sun_zen_data = xr.DataArray(rng.integers(0, 36000, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])
fake_sat_azi_data = xr.DataArray(np.random.randint(0, 36000, size=25 * 4).reshape((4, 5, 5)),
fake_sat_azi_data = xr.DataArray(rng.integers(0, 36000, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])
fake_sat_zen_data = xr.DataArray(np.random.randint(0, 36000, size=25 * 4).reshape((4, 5, 5)),
fake_sat_zen_data = xr.DataArray(rng.integers(0, 36000, size=25 * 4).reshape((4, 5, 5)),
dims=["n_geo_groups", "n_fovs", "n_scans"])


Expand All @@ -56,6 +59,8 @@ def aws_file(tmp_path_factory):

instrument = "AWS"
ds.attrs["instrument"] = instrument
ds.attrs["orbit_start"] = 9991
ds.attrs["orbit_end"] = 9992
ds["data/calibration/aws_toa_brightness_temperature"] = fake_data
ds["data/calibration/aws_toa_brightness_temperature"].attrs["scale_factor"] = 0.001
ds["data/calibration/aws_toa_brightness_temperature"].attrs["add_offset"] = 0.0
Expand All @@ -76,6 +81,7 @@ def aws_file(tmp_path_factory):
ds["status/satellite/subsat_latitude_start"] = np.array(55.41)
ds["status/satellite/subsat_longitude_end"] = np.array(296.79)


tmp_dir = tmp_path_factory.mktemp("aws_l1b_tests")
filename = tmp_dir / compose(file_pattern, dict(start_time=start_time, end_time=end_time,
processing_time=processing_time, platform_name=platform_name))
Expand All @@ -84,7 +90,7 @@ def aws_file(tmp_path_factory):
return filename


@pytest.fixture()
@pytest.fixture
def aws_handler(aws_file):
"""Create an aws filehandler."""
filename_info = parse(file_pattern, os.path.basename(aws_file))
Expand Down Expand Up @@ -133,12 +139,9 @@ def test_get_channel_data(aws_handler):
@pytest.mark.parametrize(("id_name", "file_key", "fake_array"),
[("longitude", "data/navigation/aws_lon", fake_lon_data * 1e-4),
("latitude", "data/navigation/aws_lat", fake_lat_data),
("solar_azimuth", "data/navigation/aws_solar_azimuth_angle", fake_sun_azi_data),
("solar_zenith", "data/navigation/aws_solar_zenith_angle", fake_sun_zen_data),
("satellite_azimuth", "data/navigation/aws_satellite_azimuth_angle", fake_sat_azi_data),
("satellite_zenith", "data/navigation/aws_satellite_zenith_angle", fake_sat_zen_data)])
])
def test_get_navigation_data(aws_handler, id_name, file_key, fake_array):
"""Test retrieving the angles_data."""
"""Test retrieving the geolocation (lon-lat) data."""
Horn = Enum("Horn", ["1", "2", "3", "4"])
did = dict(name=id_name, horn=Horn["1"])
dataset_info = dict(file_key=file_key, standard_name=id_name)
Expand All @@ -155,3 +158,27 @@ def test_get_navigation_data(aws_handler, id_name, file_key, fake_array):
assert "n_geo_groups" not in res.coords
if id_name == "longitude":
assert res.max() <= 180


@pytest.mark.parametrize(("id_name", "file_key", "fake_array"),
[("solar_azimuth_horn1", "data/navigation/aws_solar_azimuth_angle", fake_sun_azi_data),
("solar_zenith_horn1", "data/navigation/aws_solar_zenith_angle", fake_sun_zen_data),
("satellite_azimuth_horn1", "data/navigation/aws_satellite_azimuth_angle", fake_sat_azi_data),
("satellite_zenith_horn1", "data/navigation/aws_satellite_zenith_angle", fake_sat_zen_data)])
def test_get_viewing_geometry_data(aws_handler, id_name, file_key, fake_array):
"""Test retrieving the angles_data."""
Horn = Enum("Horn", ["1", "2", "3", "4"])
did = dict(name=id_name, horn=Horn["1"])

dataset_info = dict(file_key=file_key, standard_name=id_name)
res = aws_handler.get_dataset(did, dataset_info)

np.testing.assert_allclose(res, fake_array.isel(n_geo_groups=0))
assert "x" in res.dims
assert "y" in res.dims
assert "orbital_parameters" in res.attrs
assert res.dims == ("x", "y")
assert "standard_name" in res.attrs
assert "n_geo_groups" not in res.coords
if id_name == "longitude":
assert res.max() <= 180

Check warning on line 184 in satpy/tests/reader_tests/test_aws_l1b.py

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Code Duplication

The module contains 2 functions with similar structure: test_get_navigation_data,test_get_viewing_geometry_data. Avoid duplicated, aka copy-pasted, code inside the module. More duplication lowers the code health.

Check warning on line 184 in satpy/tests/reader_tests/test_aws_l1b.py

View check run for this annotation

Codecov / codecov/patch

satpy/tests/reader_tests/test_aws_l1b.py#L184

Added line #L184 was not covered by tests

0 comments on commit a84d874

Please sign in to comment.