Skip to content

Commit 356e6c9

Browse files
Merge pull request #7 from dgarciabriseno/test-normalizer
Patch normalizer to use earth as center of SphericalScreen
2 parents 336cbda + 0030d05 commit 356e6c9

File tree

2 files changed

+83
-11
lines changed

2 files changed

+83
-11
lines changed

app/normalizer.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ def normalize_hpc(x: float, y: float, coord_time: Time, target: Time) -> SkyCoor
2929
Desired time for the new coordinates
3030
"""
3131
with transform_with_sun_center():
32-
real_coord = SkyCoord(
33-
x * u.arcsecond, y * u.arcsecond, frame=get_earth_frame(coord_time)
34-
)
32+
earth_frame = get_earth_frame(coord_time)
3533
hv_frame = get_helioviewer_frame(target)
36-
with SphericalScreen(hv_frame.observer, only_off_disk=True):
34+
with SphericalScreen(earth_frame.observer, only_off_disk=True):
35+
real_coord = SkyCoord(x * u.arcsecond, y * u.arcsecond, frame=earth_frame)
3736
return solar_rotate_coordinate(real_coord, hv_frame.observer)
3837

3938

@@ -62,13 +61,15 @@ def normalize_hpc_batch(coordinates: List[Dict], target: Time) -> List[Dict]:
6261
xs = [c["x"] for c in coordinates]
6362
ys = [c["y"] for c in coordinates]
6463
coord_times = [c["coord_time"] for c in coordinates]
65-
real_coord = SkyCoord(
66-
xs,
67-
ys,
68-
unit="arcsec,arcsec",
69-
frame=get_earth_frame(coord_times),
70-
)
71-
with SphericalScreen(hv_frame.observer, only_off_disk=True):
64+
65+
earth_frame = get_earth_frame(coord_times)
66+
with SphericalScreen(earth_frame.observer, only_off_disk=True):
67+
real_coord = SkyCoord(
68+
xs,
69+
ys,
70+
unit="arcsec,arcsec",
71+
frame=earth_frame,
72+
)
7273
result = solar_rotate_coordinate(real_coord, hv_frame.observer)
7374
return [{"x": c.Tx.value.item(), "y": c.Ty.value.item()} for c in result]
7475

app/test/test_api.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import pytest
2+
import random
3+
import math
24
from astropy import units as u
35
from fastapi.testclient import TestClient
46
from sunpy.coordinates import get_earth
@@ -147,6 +149,75 @@ def test_hpc_post(client: TestClient):
147149
assert pytest.approx(batch_coord["y"], abs=1e-10) == individual_coord["y"]
148150

149151

152+
def test_hpc_single_vs_batched(client: TestClient):
153+
"""
154+
Test that processing 100 random coordinates one-by-one gives the same
155+
results as processing them all at once with the batch endpoint.
156+
"""
157+
# Generate 100 random coordinates
158+
num_coords = 100
159+
random.seed(42) # For reproducibility
160+
161+
# Set a common target time
162+
target = "2020-01-01T00:00:00"
163+
164+
coordinates = []
165+
for _ in range(num_coords):
166+
x = random.uniform(-1000, 1000)
167+
y = random.uniform(-1000, 1000)
168+
# Use coord_time within 24 hours before target time
169+
hours_before = random.uniform(0, 24)
170+
from datetime import datetime, timedelta
171+
172+
target_dt = datetime.fromisoformat(target)
173+
coord_dt = target_dt - timedelta(hours=hours_before)
174+
coord_time = coord_dt.strftime("%Y-%m-%dT%H:%M:%S")
175+
176+
coordinates.append({"x": x, "y": y, "coord_time": coord_time})
177+
178+
# Process each coordinate individually using GET
179+
individual_results = []
180+
for i, coord in enumerate(coordinates):
181+
response = client.get(
182+
f"/hpc?x={coord['x']}&y={coord['y']}&coord_time={coord['coord_time']}&target={target}"
183+
)
184+
assert response.status_code == 200
185+
result = response.json()
186+
# Check for NaN values
187+
assert not math.isnan(
188+
result["x"]
189+
), f"Individual request {i} returned NaN for x (input: {coord})"
190+
assert not math.isnan(
191+
result["y"]
192+
), f"Individual request {i} returned NaN for y (input: {coord})"
193+
individual_results.append(result)
194+
195+
# Process all coordinates at once using POST
196+
batch_data = {"coordinates": coordinates, "target": target}
197+
batch_response = client.post("/hpc", json=batch_data)
198+
assert batch_response.status_code == 200
199+
batch_results = batch_response.json()["coordinates"]
200+
201+
# Compare results
202+
assert len(individual_results) == len(batch_results)
203+
for i, (individual, batched) in enumerate(zip(individual_results, batch_results)):
204+
# Check batch results for NaN
205+
assert not math.isnan(
206+
batched["x"]
207+
), f"Batch result {i} returned NaN for x (input: {coordinates[i]})"
208+
assert not math.isnan(
209+
batched["y"]
210+
), f"Batch result {i} returned NaN for y (input: {coordinates[i]})"
211+
212+
# Compare individual vs batch results
213+
assert (
214+
pytest.approx(individual["x"], abs=1e-10) == batched["x"]
215+
), f"Mismatch at index {i}: x values differ"
216+
assert (
217+
pytest.approx(individual["y"], abs=1e-10) == batched["y"]
218+
), f"Mismatch at index {i}: y values differ"
219+
220+
150221
def test_hgs2hpc(client: TestClient):
151222
# Missing lat
152223
response = client.get("/hgs2hpc?lon=0&coord_time=2012-01-01")

0 commit comments

Comments
 (0)