Skip to content

Commit 3530e8a

Browse files
authored
2341 hi l2 improve ram mask for spacecraft frame products (#2365)
* Add method to HiLoBasePointingSet for calculating the ram pixel mask * Update CG correction code to call update_ram_mask method * Move ram_mask calculation to corrections.py module * Add calculation of ram_mask to hi l2 s/c frame workflow * self review updates * remove no longer relavent test
1 parent 8e25334 commit 3530e8a

5 files changed

Lines changed: 302 additions & 38 deletions

File tree

imap_processing/ena_maps/ena_maps.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,13 @@ def update_az_el_points(self) -> None:
615615
"""
616616
Update the az_el_points instance variable with new az/el coordinates.
617617
618-
The values store in the "hae_longitude" and "hae_latitude" variables
618+
The values stored in the "hae_longitude" and "hae_latitude" variables
619619
are used to construct the azimuth and elevation coordinates.
620620
"""
621+
logger.info(
622+
"Updating az/el points based on data in hae_longitude and"
623+
"hae_latitude variables."
624+
)
621625
# Get lon/lat coordinates, squeeze the epoch dimension and stack along
622626
# the spatial dimensions. xarray.stack() takes possibly multiple spatial
623627
# dimensions and reshapes those into a single dimension.
@@ -654,15 +658,6 @@ def __init__(self, dataset: xr.Dataset | str | Path):
654658

655659
self.spatial_coords = ("spin_angle_bin",)
656660

657-
# Naively generate the ram_mask variable assuming spacecraft frame
658-
# binning. The ram_mask variable gets updated in the CG correction
659-
# code if the CG correction is applied.
660-
ram_mask = xr.zeros_like(self.data["spin_angle_bin"], dtype=bool)
661-
# ram only includes spin-phase interval [0, 0.5)
662-
# which is the first half of the spin_angle_bins
663-
ram_mask[slice(0, self.data["spin_angle_bin"].data.size // 2)] = True
664-
self.data["ram_mask"] = ram_mask
665-
666661
# Rename some PSET vars to match L2 variables
667662
self.data = self.data.rename(
668663
{

imap_processing/ena_maps/utils/corrections.py

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ class or child classes.
321321
return corrected_flux, corrected_flux_stat_unc
322322

323323

324-
def _add_spacecraft_velocity_to_pset(
324+
def add_spacecraft_velocity_to_pset(
325325
pset: LoHiBasePsetSubclass,
326326
) -> LoHiBasePsetSubclass:
327327
"""
@@ -344,10 +344,9 @@ def _add_spacecraft_velocity_to_pset(
344344
- "sc_direction_vector": Spacecraft velocity unit vector with dims ["x_y_z"]
345345
"""
346346
# Compute ephemeris time (J2000 seconds) of PSET midpoint time
347-
# TODO: Use the Pointing midpoint time. Epoch should be start time
348-
# but use it until we can make Lo and Hi PSETs have a consistent
349-
# variable to hold the midpoint time.
350-
et = ttj2000ns_to_et(pset.data["epoch"].values[0])
347+
et = ttj2000ns_to_et(
348+
pset.data["epoch"].values[0] + pset.data["epoch_delta"].values[0] / 2
349+
)
351350
# Get spacecraft state in HAE frame
352351
sc_state = geometry.imap_state(et, ref_frame=geometry.SpiceFrame.IMAP_HAE)
353352
sc_velocity_vector = sc_state[3:6]
@@ -532,18 +531,64 @@ def _calculate_compton_getting_transform(
532531
ena_source_direction_helio[..., 2],
533532
)
534533

534+
# Update the PSET ram mask.
535+
pset = calculate_ram_mask(pset)
536+
537+
return pset
538+
539+
540+
def calculate_ram_mask(pset: LoHiBasePsetSubclass) -> LoHiBasePsetSubclass:
541+
"""
542+
Calculate the RAM mask using the input spacecraft velocity vector.
543+
544+
The RAM mask is a boolean array with the same dimensions as what is stored
545+
in the "hae_longitude" and "hae_latitude" variables of the dataset.
546+
547+
Parameters
548+
----------
549+
pset : LoHiBasePointingSet
550+
Pointing set object. The pset dataset is assumed to have valid
551+
"hae_longitude", "hae_latitude", and "sc_direction_vector" variables.
552+
553+
Returns
554+
-------
555+
pset : LoHiBasePointingSet
556+
Pointing set object with ram_mask variable added.
557+
"""
558+
logger.debug(
559+
f"Calculating the RAM mask using input spacecraft direction"
560+
f"vector: {pset.data['sc_direction_vector']} and hae coordinates in the"
561+
f"dataset hae_longitude and hae_latitude variables."
562+
)
563+
longitude = pset.data["hae_longitude"]
564+
latitude = pset.data["hae_latitude"]
565+
spacecraft_direction_vec = pset.data["sc_direction_vector"].values
566+
spherical_coords = np.stack(
567+
[
568+
np.ones_like(longitude.values),
569+
longitude.values,
570+
latitude.values,
571+
],
572+
axis=-1,
573+
)
574+
cartesian_source_direction = xr.DataArray(
575+
geometry.spherical_to_cartesian(spherical_coords),
576+
dims=[*longitude.dims, CoordNames.CARTESIAN_VECTOR.value],
577+
)
535578
# For ram/anti-ram filtering we can use the sign of the scalar projection
536-
# of the ENA source direction onto the spacecraft velocity vector.
537-
# ram_mask = (v⃗_helio · û_sc) >= 0
579+
# of the ENA source direction vector (-v⃗_ena) onto the spacecraft velocity
580+
# vector.
581+
# ram_mask = (-v⃗_ena · û_sc) >= 0
582+
# Use Einstein summation for efficient vectorized dot product
538583
ram_mask = (
539584
np.einsum(
540-
"...i,...i->...", velocity_vector_helio, pset.data["sc_direction_vector"]
585+
"...i,...i->...", spacecraft_direction_vec, cartesian_source_direction
541586
)
542587
>= 0
543588
)
544589
pset.data["ram_mask"] = xr.DataArray(
545590
ram_mask,
546-
dims=velocity_vector_helio.dims[:-1],
591+
dims=longitude.dims,
547592
)
548593

549594
return pset
@@ -597,7 +642,7 @@ def apply_compton_getting_correction(
597642
which will be used for subsequent binning operations.
598643
"""
599644
# Step 1: Add spacecraft velocity and direction to pset
600-
pset = _add_spacecraft_velocity_to_pset(pset)
645+
pset = add_spacecraft_velocity_to_pset(pset)
601646

602647
# Step 2: Calculate and add look direction vectors to pset
603648
pset = _add_cartesian_look_direction(pset)

imap_processing/hi/hi_l2.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
)
1414
from imap_processing.ena_maps.utils.corrections import (
1515
PowerLawFluxCorrector,
16+
add_spacecraft_velocity_to_pset,
1617
apply_compton_getting_correction,
18+
calculate_ram_mask,
1719
interpolate_map_flux_to_helio_frame,
1820
)
1921
from imap_processing.ena_maps.utils.naming import MapDescriptor
@@ -145,6 +147,9 @@ def generate_hi_map(
145147
# convert esa nominal central energy from keV to eV
146148
esa_energy_ev = energy_kev * 1000
147149
pset = apply_compton_getting_correction(pset, esa_energy_ev)
150+
else:
151+
pset = add_spacecraft_velocity_to_pset(pset)
152+
pset = calculate_ram_mask(pset)
148153

149154
# Multiply variables that need to be exposure time weighted average by
150155
# exposure factor.

0 commit comments

Comments
 (0)