From 3c3a931760bf1d7c9739966fd08275783096031b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:20:09 +0000 Subject: [PATCH 1/3] Initial plan From 1c3d46ec00696a239abbbfcbe593edbb375c8aac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:26:12 +0000 Subject: [PATCH 2/3] Use public SolarPosition API in preprocessing model --- nsrdb/preprocessing/base_data_model.py | 12 ++++-- tests/preproc/test_base_data_model.py | 55 ++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/nsrdb/preprocessing/base_data_model.py b/nsrdb/preprocessing/base_data_model.py index b64d9780..092342cf 100644 --- a/nsrdb/preprocessing/base_data_model.py +++ b/nsrdb/preprocessing/base_data_model.py @@ -182,17 +182,21 @@ def get_solar_zenith(self, ds): """Derive the solar zenith angle for the dataset.""" lats = ds['latitude'].values lons = ds['longitude'].values - return SolarPosition._zenith( - self.time_index, lats, lons + solar_pos = SolarPosition( + self.time_index, + np.column_stack((lats.ravel(), lons.ravel())), ) + return np.asarray(solar_pos.zenith).reshape(lats.shape) def get_solar_azimuth(self, ds): """Derive the solar azimuth angle for the dataset.""" lats = ds['latitude'].values lons = ds['longitude'].values - return SolarPosition._azimuth( - self.time_index, lats, lons + solar_pos = SolarPosition( + self.time_index, + np.column_stack((lats.ravel(), lons.ravel())), ) + return np.asarray(solar_pos.azimuth).reshape(lats.shape) @classmethod def rename_vars(cls, ds): diff --git a/tests/preproc/test_base_data_model.py b/tests/preproc/test_base_data_model.py index c6f8e018..5f3868c5 100644 --- a/tests/preproc/test_base_data_model.py +++ b/tests/preproc/test_base_data_model.py @@ -100,3 +100,58 @@ def test_run_data_model_jobs_accepts_multiple_glob_patterns( (file_1, '/tmp/out/{year}/{doy}/file_{timestamp}.nc'), (file_2, '/tmp/out/{year}/{doy}/file_{timestamp}.nc'), ] + + +def test_solar_angles_use_public_solar_position_api(monkeypatch): + """Solar angle helpers should use public SolarPosition properties.""" + + class FakeSolarPosition: + """Test double for rex SolarPosition.""" + + call_args = None + + def __init__(self, time_index, lat_lon): + self.time_index = time_index + self.lat_lon = lat_lon + self.__class__.call_args = (time_index, lat_lon) + + @property + def zenith(self): + return np.arange(self.lat_lon.shape[0])[None, :] + + @property + def azimuth(self): + return (100 + np.arange(self.lat_lon.shape[0]))[None, :] + + monkeypatch.setattr( + 'nsrdb.preprocessing.base_data_model.SolarPosition', + FakeSolarPosition, + ) + + model = DummyDataModel( + '/tmp/input_2025.001.12.nc', + '/tmp/out/{year}/{doy}/{timestamp}.nc', + ) + ds = xr.Dataset({ + 'latitude': ( + ('south_north', 'west_east'), + np.array([[10.0, 11.0], [12.0, 13.0]]), + ), + 'longitude': ( + ('south_north', 'west_east'), + np.array([[30.0, 31.0], [32.0, 33.0]]), + ), + }) + + zenith = model.get_solar_zenith(ds) + assert np.array_equal(zenith, np.array([[0, 1], [2, 3]])) + + time_index, lat_lon = FakeSolarPosition.call_args + assert time_index.equals(model.time_index) + assert np.array_equal( + lat_lon, + np.array([[10.0, 30.0], [11.0, 31.0], [12.0, 32.0], [13.0, 33.0]]), + ) + + azimuth = model.get_solar_azimuth(ds) + assert np.array_equal(azimuth, np.array([[100, 101], [102, 103]])) From 1e901903eb964e61aff23457427c4663cb58d2e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:27:17 +0000 Subject: [PATCH 3/3] Stabilize solar position API test assertions --- tests/preproc/test_base_data_model.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/preproc/test_base_data_model.py b/tests/preproc/test_base_data_model.py index 5f3868c5..f9dfd0eb 100644 --- a/tests/preproc/test_base_data_model.py +++ b/tests/preproc/test_base_data_model.py @@ -104,16 +104,15 @@ def test_run_data_model_jobs_accepts_multiple_glob_patterns( def test_solar_angles_use_public_solar_position_api(monkeypatch): """Solar angle helpers should use public SolarPosition properties.""" + call_args = [] class FakeSolarPosition: """Test double for rex SolarPosition.""" - call_args = None - def __init__(self, time_index, lat_lon): self.time_index = time_index self.lat_lon = lat_lon - self.__class__.call_args = (time_index, lat_lon) + call_args.append((time_index, lat_lon)) @property def zenith(self): @@ -146,7 +145,7 @@ def azimuth(self): zenith = model.get_solar_zenith(ds) assert np.array_equal(zenith, np.array([[0, 1], [2, 3]])) - time_index, lat_lon = FakeSolarPosition.call_args + time_index, lat_lon = call_args[-1] assert time_index.equals(model.time_index) assert np.array_equal( lat_lon,