Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion imap_processing/tests/ultra/unit/test_lookup_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def test_get_angular_profiles():
def test_get_energy_efficiencies(ancillary_files):
"""Tests function get_get_energy_efficiencies."""

u45_efficiencies = get_energy_efficiencies(ancillary_files)
u45_efficiencies = get_energy_efficiencies(ancillary_files, "ultra45")

assert u45_efficiencies.shape == (58081, 157)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ def test_get_efficiency():
/ "imap_ultra_l1b-45sensor-logistic-interpolation_20250101_v000.csv"
}

efficiency = get_efficiency(energy, phi, theta, ancillary_files)
efficiency = get_efficiency(energy, phi, theta, ancillary_files, "ultra45")
expected_efficiency = np.array([0.0593281, 0.21803386, 0.0593281, 0.0628940])

np.testing.assert_allclose(efficiency, expected_efficiency, atol=1e-03, rtol=0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ def test_get_eff_and_gf(imap_ena_sim_metakernel, ancillary_files, spun_index_dat
mock_theta,
mock_phi,
npix=pix,
sensor_id=45,
ancillary_files=ancillary_files,
apply_bsf=False,
)
Expand Down
14 changes: 11 additions & 3 deletions imap_processing/ultra/l1b/lookup_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def get_angular_profiles(
return lookup_table


def get_energy_efficiencies(ancillary_files: dict) -> pd.DataFrame:
def get_energy_efficiencies(ancillary_files: dict, sensor: str) -> pd.DataFrame:
"""
Lookup table for efficiencies for theta and phi.

Expand All @@ -221,14 +221,22 @@ def get_energy_efficiencies(ancillary_files: dict) -> pd.DataFrame:
----------
ancillary_files : dict[Path]
Ancillary files.
sensor : str
Sensor name: "ultra45" or "ultra90".

Returns
-------
lookup_table : DataFrame
Efficiencies lookup table for a given sensor.
"""
# TODO: add sensor to input when new lookup tables are available.
lookup_table = pd.read_csv(ancillary_files["l1b-45sensor-logistic-interpolation"])
if sensor == "ultra45":
lookup_table = pd.read_csv(
ancillary_files["l1b-45sensor-logistic-interpolation"]
)
else:
lookup_table = pd.read_csv(
ancillary_files["l1b-90sensor-logistic-interpolation"]
)
Comment on lines +232 to +239
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduces a hard dependency on ancillary_files["l1b-90sensor-logistic-interpolation"] for ULTRA90. The current test ancillary fixture/config only includes the 45-sensor file, so ULTRA90 processing will KeyError unless the 90-sensor logistic interpolation CSV is also provisioned. Either (1) ensure the ancillary bundling/downloader + test fixtures include the new 90-sensor file, or (2) implement a temporary fallback to the 45-sensor efficiencies with a clear warning if the 90-sensor file is missing (to preserve the previous behavior).

Copilot uses AI. Check for mistakes.

return lookup_table

Expand Down
10 changes: 8 additions & 2 deletions imap_processing/ultra/l1b/ultra_l1b_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,7 @@ def get_fwhm(

def get_efficiency_interpolator(
ancillary_files: dict,
sensor: str,
) -> tuple[RegularGridInterpolator, tuple, tuple]:
"""
Return a callable function that interpolates efficiency values for each event.
Expand All @@ -1178,6 +1179,8 @@ def get_efficiency_interpolator(
----------
ancillary_files : dict
Ancillary files.
sensor : str
Sensor name: "ultra45" or "ultra90".

Returns
-------
Expand All @@ -1188,7 +1191,7 @@ def get_efficiency_interpolator(
phi_min_max : tuple
Minimum and maximum phi values in the lookup table.
"""
lookup_table = get_energy_efficiencies(ancillary_files)
lookup_table = get_energy_efficiencies(ancillary_files, sensor)

theta_vals = np.sort(lookup_table["theta (deg)"].unique())
phi_vals = np.sort(lookup_table["phi (deg)"].unique())
Expand Down Expand Up @@ -1218,6 +1221,7 @@ def get_efficiency(
phi_inst: NDArray,
theta_inst: NDArray,
ancillary_files: dict,
sensor: str,
interpolator: RegularGridInterpolator = None,
) -> np.ndarray:
"""
Expand All @@ -1233,6 +1237,8 @@ def get_efficiency(
Instrument-frame elevation angle for each event.
ancillary_files : dict
Ancillary files.
sensor : str
Sensor name: "ultra45" or "ultra90".
interpolator : RegularGridInterpolator, optional
Precomputed interpolator to use for efficiency lookup.
If None, a new interpolator will be created from the ancillary files.
Expand All @@ -1243,7 +1249,7 @@ def get_efficiency(
Interpolated efficiency values.
"""
if not interpolator:
interpolator, _, _ = get_efficiency_interpolator(ancillary_files)
interpolator, _, _ = get_efficiency_interpolator(ancillary_files, sensor)

return interpolator((theta_inst, phi_inst, energy))

Expand Down
1 change: 1 addition & 0 deletions imap_processing/ultra/l1c/helio_pset.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def calculate_helio_pset(
theta_vals.values,
phi_vals.values,
n_pix,
sensor_id,
ancillary_files,
apply_bsf,
)
Expand Down
1 change: 1 addition & 0 deletions imap_processing/ultra/l1c/spacecraft_pset.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def calculate_spacecraft_pset(
theta_vals,
phi_vals,
n_pix,
sensor_id,
ancillary_files,
apply_bsf,
)
Expand Down
7 changes: 6 additions & 1 deletion imap_processing/ultra/l1c/ultra_l1c_pset_bins.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ def get_efficiencies_and_geometric_function(
theta_vals: np.ndarray,
phi_vals: np.ndarray,
npix: int,
sensor_id: int,
ancillary_files: dict,
apply_bsf: bool = True,
) -> tuple[np.ndarray, np.ndarray]:
Expand Down Expand Up @@ -529,6 +530,8 @@ def get_efficiencies_and_geometric_function(
corresponding phi for each pixel (and energy, if present).
npix : int
Number of HEALPix pixels.
sensor_id : int
Sensor ID, either 45 or 90.
ancillary_files : dict
Dictionary containing ancillary files.
apply_bsf : bool, optional
Expand All @@ -543,9 +546,10 @@ def get_efficiencies_and_geometric_function(
Averaged efficiencies across all spin phases.
Shape = (n_energy_bins, npix).
"""
sensor_name = f"ultra{sensor_id}"
# Load callable efficiency interpolator function
eff_interpolator, theta_min_max, phi_min_max = get_efficiency_interpolator(
ancillary_files
ancillary_files, sensor_name
)
# load geometric factor lookup table
geometric_lookup_table = load_geometric_factor_tables(
Expand Down Expand Up @@ -622,6 +626,7 @@ def get_efficiencies_and_geometric_function(
phi_at_spin_clipped[pixel_inds],
theta_at_spin_clipped[pixel_inds],
ancillary_files,
sensor_name,
interpolator=eff_interpolator,
)

Expand Down
Loading