Skip to content

Conversation

@lacoak21
Copy link
Contributor

Change Summary

Overview

Fix spin start/ event time calculation for ULTRA l1b. Originally we were getting it from the universal spin table and the l1a spin_number variable. This value can overflow so we cant trust it. Instead calculate event times as explained below: This used the l1a aux dataset.
Screenshot 2025-12-12 at 4 08 28 PM

New Dependencies

l1a aux dataset

Updated Files

  • imap_processing/ultra/l1b/de.py
    • calculate new event times , spin starts, and spin numbers using aux packet
    • description of change 2 in file 2
  • imap_processing/ultra/l1b/lookup_utils.py
    • reverse theta and phi parameters
  • imap_processing/ultra/l1b/ultra_l1b_extended.py
    • remove old get_spin_number function (outdated)

Testing

Test for new event times function

@lacoak21 lacoak21 added this to the December 2025 milestone Dec 12, 2025
@lacoak21 lacoak21 requested review from greglucas and sdhoyt December 12, 2025 23:17
@lacoak21 lacoak21 self-assigned this Dec 12, 2025
@lacoak21 lacoak21 added this to IMAP Dec 12, 2025
@lacoak21 lacoak21 requested a review from Copilot December 12, 2025 23:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes the ULTRA L1b event time and spin number calculation by replacing the overflow-prone approach that relied on the universal spin table with a direct calculation using the L1a auxiliary dataset. The new implementation computes event times using the formula from section 3.3.1 of the ULTRA algorithm document, using spin start times, subsecond offsets, spin duration, and phase angles from the auxiliary data.

Key changes:

  • Replaces get_spin_number() function with direct aux dataset-based time calculation in get_eventtimes()
  • Corrects parameter order in is_inside_fov() function from (phi, theta) to (theta, phi) and enhances FOV boundary checking
  • Adds new FOV constants for improved field-of-view calculations

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
imap_processing/ultra/l1b/ultra_l1b_extended.py Removes old get_spin_number() function; rewrites get_eventtimes() to calculate event times directly from aux dataset using spin start times and durations
imap_processing/ultra/l1b/de.py Updates calculate_de() to accept aux_dataset parameter and pass it to get_eventtimes(); updates time handling to convert ET to MET for pointing checks
imap_processing/ultra/l1b/ultra_l1b.py Adds aux_dataset to calculate_de() call
imap_processing/ultra/l1b/lookup_utils.py Reverses is_inside_fov() parameter order from (phi, theta) to (theta, phi); adds phi limit check and theta offset to FOV calculations
imap_processing/ultra/constants.py Adds FOV_THETA_OFFSET_DEG and FOV_PHI_LIMIT_DEG constants for FOV boundary calculations
imap_processing/ultra/l1c/spacecraft_pset.py Clarifies comment to specify time bins are in ephemeris time
imap_processing/ultra/l1c/helio_pset.py Clarifies comment to specify time bins are in ephemeris time
imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py Updates test_get_eventtimes() to use new function signature with aux_dataset; removes old test_get_spin_number() test
imap_processing/tests/ultra/unit/test_ultra_l1b.py Adds aux_dataset fixture parameter to DE-related tests
imap_processing/tests/ultra/unit/test_de.py Updates test_calculate_events_in_pointing() to pass MET instead of ET

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +933 to 934
aux_dataset : numpy.ndarray
Spin number.
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The parameter documentation is incorrect. The parameter type for aux_dataset should be xarray.Dataset (or xr.Dataset), not numpy.ndarray. The description "Spin number" is also incorrect - it should describe the auxiliary dataset containing spin information.

Suggested change
aux_dataset : numpy.ndarray
Spin number.
aux_dataset : xarray.Dataset
Auxiliary dataset containing spin information.

Copilot uses AI. Check for mistakes.
Comment on lines +943 to +945
Event times in met.
spin_start_times: numpy.ndarray
Spin start times in met.
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The return value documentation is inconsistent with the actual return. The function returns event times in ephemeris time (ET), not MET. Line 975 shows the conversion: ttj2000ns_to_et(met_to_ttj2000ns(event_times)). The documentation should state "Event times in et" to match the actual behavior.

Suggested change
Event times in met.
spin_start_times: numpy.ndarray
Spin start times in met.
Event times in et.
spin_start_times: numpy.ndarray
Spin start times in et.

Copilot uses AI. Check for mistakes.
event_times : numpy.ndarray
Event times in met.
spin_start_times: numpy.ndarray
Spin start times in met.
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The return value documentation is inconsistent with the actual return. The function returns spin start times in ephemeris time (ET), not MET. Line 976 shows the conversion: ttj2000ns_to_et(met_to_ttj2000ns(spin_start_times)). The documentation should state "Spin start times in et" to match the actual behavior.

Suggested change
Spin start times in met.
Spin start times in et.

Copilot uses AI. Check for mistakes.
"non_proton": [20, 21, 22, 23, 24, 25, 26],
}

# For FOR calculations
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The comment says "For FOR calculations" but likely means "For FOV calculations" based on the variable names below (FOV_THETA_OFFSET_DEG and FOV_PHI_LIMIT_DEG). "FOR" appears to be a typo.

Suggested change
# For FOR calculations
# For FOV calculations

Copilot uses AI. Check for mistakes.
Comment on lines +956 to +958
start_inds = np.searchsorted(spin_start_sec, de_event_met, side="right") - 1
# Clip to valid range of indices
start_inds = np.clip(start_inds, 0, len(spin_start_sec) - 1)
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The searchsorted logic may incorrectly assign events that occur before the first spin or after the last spin. When de_event_met is less than spin_start_sec[0], searchsorted returns 0, and subtracting 1 gives -1, which is then clipped to 0. This causes events before the first spin to be incorrectly assigned to the first spin. Similarly, events after the last spin get assigned to the last spin. Consider validating that de_event_met values fall within the aux_dataset time range and handling out-of-range events appropriately (e.g., by setting quality flags or using fill values).

Copilot uses AI. Check for mistakes.

import numpy as np
import pandas
import xarray
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The xarray library is imported twice - once as xarray on line 10 and again as xr on line 11. Since the code uses xr.Dataset in the function signatures, the unaliased import on line 10 appears to be unused and should be removed to avoid redundancy.

Suggested change
import xarray

Copilot uses AI. Check for mistakes.
Use formula from section 3.3.1 of the ULTRA algorithm document.
t_e = t_spin_start + (t_start_sub / 1000) +
(t_spin_duration * theta_event) / (1000 * 720)
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The formula documentation uses theta_event but the actual code uses phase_angle. The variable theta_event doesn't exist in the function. The formula should use phase_angle instead to match the implementation and parameter names.

Suggested change
(t_spin_duration * theta_event) / (1000 * 720)
(t_spin_duration * phase_angle) / (1000 * 720)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant