Skip to content

Changes to CoDICE I-ALiRT processing in prepration for I-ALiRT SIT#1832

Merged
bourque merged 8 commits intoIMAP-Science-Operations-Center:devfrom
bourque:codice-ialirt-mock-dataset-for-sit
Jun 23, 2025
Merged

Changes to CoDICE I-ALiRT processing in prepration for I-ALiRT SIT#1832
bourque merged 8 commits intoIMAP-Science-Operations-Center:devfrom
bourque:codice-ialirt-mock-dataset-for-sit

Conversation

@bourque
Copy link
Copy Markdown
Collaborator

@bourque bourque commented Jun 17, 2025

This PR makes various changes to the CoDICE I-ALiRT processing so that the code works on I-ALiRT SIT input test data and creates a mock CoDICE I-ALiRT dataset.

@bourque bourque self-assigned this Jun 17, 2025
@bourque bourque added Ins: CoDICE Related to the CoDICE instrument Level: L1 Level 1 processing Level: L2 Level 2 processing I-ALiRT labels Jun 17, 2025
@bourque bourque marked this pull request as draft June 17, 2025 18:28
@bourque bourque marked this pull request as ready for review June 17, 2025 19:41
@bourque bourque changed the title [WIP] Changes to CoDICE I-ALiRT processing in prepration for I-ALiRT SIT Changes to CoDICE I-ALiRT processing in prepration for I-ALiRT SIT Jun 17, 2025
Copy link
Copy Markdown
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 adapts the CoDICE I-ALiRT processing to work with SIT input data by mocking output products and updating tests to use the new packet parsing utility.

  • Tests now load packets via packet_file_to_datasets and expect two lists of dicts instead of an xarray.Dataset.
  • process_codice has been rewritten to generate mock CoDICE-Lo and CoDICE-Hi data with fill values.
  • New constants for I-ALiRT data fields were introduced, and packet grouping now accepts a prefix parameter.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
imap_processing/tests/ialirt/unit/test_process_codice.py Switched from decom_packets to packet_file_to_datasets, updated fixtures and assertions for tuple output
imap_processing/ialirt/l0/process_codice.py Replaced real processing with mock loops producing two lists of dicts using fill values
imap_processing/codice/constants.py Added CODICE_LO_IAL_DATA_FIELDS and CODICE_HI_IAL_DATA_FIELDS
imap_processing/codice/codice_l1a.py Extended group_ialirt_data to take a prefix and handle empty data in create_ialirt_dataset
Comments suppressed due to low confidence (2)

imap_processing/tests/ialirt/unit/test_process_codice.py:53

  • [nitpick] These assertions only verify types; consider adding checks for expected list lengths or sample field values to improve coverage of the new mock data logic.
    assert all(isinstance(item, dict) for item in cod_lo_data)

imap_processing/ialirt/l0/process_codice.py:17

  • Docstring should be updated to describe that this function now returns two lists (cod_lo_data, cod_hi_data) instead of a single dataset.
) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:

Comment thread imap_processing/tests/ialirt/unit/test_process_codice.py
Comment thread imap_processing/ialirt/l0/process_codice.py Outdated

else:
logger.warning("No I-ALiRT data found")
return None
Copy link

Copilot AI Jun 17, 2025

Choose a reason for hiding this comment

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

Returning None when no I-ALiRT data is found may lead to downstream NoneType errors; consider returning an empty xarray.Dataset or raising a specific exception.

Suggested change
return None
return xr.Dataset()

Copilot uses AI. Check for mistakes.
Comment on lines -1010 to +1063
grouped_data = group_ialirt_data(packets, data_field_range)

# Process each group to get the science data and corresponding metadata
science_values, metadata_values = process_ialirt_data_streams(grouped_data)

# How data are processed is different for lo-iarlirt and hi-ialirt
if apid == CODICEAPID.COD_HI_IAL:
# Set some necessary values and process as a binned dataset similar to
# a hi-omni data product
metadata_for_processing = [
"table_id",
"plan_id",
"plan_step",
"view_id",
"spin_period",
"suspect",
]
for var in metadata_for_processing:
packets[var] = metadata_values[var.upper()]
dataset = create_binned_dataset(apid, packets, science_values)

elif apid == CODICEAPID.COD_LO_IAL:
# Create a nominal instance of the pipeline and process similar to a
# lo-sw-species data product
pipeline = CoDICEL1aPipeline(
metadata_values["TABLE_ID"][0],
metadata_values["PLAN_ID"][0],
metadata_values["PLAN_STEP"][0],
metadata_values["VIEW_ID"][0],
)
pipeline.set_data_product_config(apid, packets)
pipeline.decompress_data(science_values)
pipeline.reshape_data()

# The calculate_epoch_values method needs acq_start_seconds and
# acq_start_subseconds attributes on the dataset
pipeline.dataset["acq_start_seconds"] = (
"_",
metadata_values["ACQ_START_SECONDS"],
)
pipeline.dataset["acq_start_subseconds"] = (
"_",
metadata_values["ACQ_START_SUBSECONDS"],
)
grouped_data = group_ialirt_data(packets, data_field_range, prefix)

if grouped_data:
# Process each group to get the science data and corresponding metadata
science_values, metadata_values = process_ialirt_data_streams(grouped_data)

# How data are processed is different for lo-iarlirt and hi-ialirt
if apid == CODICEAPID.COD_HI_IAL:
# Set some necessary values and process as a binned dataset similar to
# a hi-omni data product
metadata_for_processing = [
"table_id",
"plan_id",
"plan_step",
"view_id",
"spin_period",
"suspect",
]
for var in metadata_for_processing:
packets[var] = metadata_values[var.upper()]
dataset = create_binned_dataset(apid, packets, science_values)

elif apid == CODICEAPID.COD_LO_IAL:
# Create a nominal instance of the pipeline and process similar to a
# lo-sw-species data product
pipeline = CoDICEL1aPipeline(
metadata_values["TABLE_ID"][0],
metadata_values["PLAN_ID"][0],
metadata_values["PLAN_STEP"][0],
metadata_values["VIEW_ID"][0],
)
pipeline.set_data_product_config(apid, packets)
pipeline.decompress_data(science_values)
pipeline.reshape_data()
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Nothing much is changing here, I just put this all in an if/else statement to check if there are grouped datasets, and if there are none, throw a warning.

Copy link
Copy Markdown
Contributor

@laspsandoval laspsandoval left a comment

Choose a reason for hiding this comment

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

Approving. I think once you have addressed the comments it is good to start testing.

VALIDMAX: 1.7976931348623157e+308
dtype: float64

codicehi_h:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Keep in mind that each of these variables will be a single column in the database. So there will not be dimensions here. For SWE, for example, I have a separate variable for each energy level. Does this need to be broken down further?

Copy link
Copy Markdown
Collaborator Author

@bourque bourque Jun 18, 2025

Choose a reason for hiding this comment

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

Good question/good point -- For this particular data variable, there are 4 dimensions: epoch, energy (there are 15 levels), ssd_index (there are 4 of these), and spin_sector (there are 4 of these). So the dimensions of the data are (<# epochs>, 15, 4, 4).

I am not sure how to break this down. Would this mean I need to make (15*4*4=) 240 separate variables?

Comment thread imap_processing/ialirt/l0/process_codice.py Outdated
# TODO: Once I-ALiRT test data is acquired that actually has data in it,
# this can be turned back on
# codicelo_data = create_ialirt_dataset(CODICEAPID.COD_LO_IAL, dataset)
# codicehi_data = create_ialirt_dataset(CODICEAPID.COD_HI_IAL, dataset)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right after launch we will immediately begin to receive I-ALiRT packets that are empty. So we might have this scenario in real-life. Something to consider maybe in another PR, though, if it is too complicated to change now.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Is there a preferred way to handle empty packets? i.e. in that case, should the code return a completely empty list? Or a list with dicts that have all the expected fields but are empty?

Comment thread imap_processing/ialirt/l0/process_codice.py Outdated
Copy link
Copy Markdown
Contributor

@laspsandoval laspsandoval left a comment

Choose a reason for hiding this comment

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

One more thing to add based on recent changes to db.

epoch_data = {
"apid": int(dataset.pkt_apid[epoch].data),
"met": met,
"utc": utc,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"utc": utc,
"met_to_utc": utc,

@bourque bourque merged commit 4782c6a into IMAP-Science-Operations-Center:dev Jun 23, 2025
14 checks passed
@bourque bourque deleted the codice-ialirt-mock-dataset-for-sit branch June 23, 2025 17:02
@bourque bourque added this to IMAP Jun 30, 2025
@bourque bourque added this to the June 2025 milestone Jun 30, 2025
@bourque bourque moved this to Done in IMAP Jun 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I-ALiRT Ins: CoDICE Related to the CoDICE instrument Level: L1 Level 1 processing Level: L2 Level 2 processing

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants