imap-processing 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of imap-processing might be problematic. Click here for more details.
- imap_processing/__init__.py +1 -0
- imap_processing/_version.py +2 -2
- imap_processing/ccsds/ccsds_data.py +1 -2
- imap_processing/ccsds/excel_to_xtce.py +1 -2
- imap_processing/cdf/config/imap_codice_global_cdf_attrs.yaml +18 -12
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +569 -0
- imap_processing/cdf/config/imap_codice_l1b_variable_attrs.yaml +1846 -128
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +5 -5
- imap_processing/cdf/config/imap_idex_global_cdf_attrs.yaml +20 -1
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +6 -4
- imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +3 -3
- imap_processing/cdf/config/imap_mag_global_cdf_attrs.yaml +15 -0
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +22 -0
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +16 -0
- imap_processing/cdf/config/imap_ultra_global_cdf_attrs.yaml +178 -5
- imap_processing/cdf/config/imap_ultra_l1a_variable_attrs.yaml +5045 -41
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +33 -19
- imap_processing/cdf/config/imap_ultra_l1c_variable_attrs.yaml +8 -48
- imap_processing/cdf/utils.py +41 -33
- imap_processing/cli.py +463 -234
- imap_processing/codice/codice_l1a.py +260 -47
- imap_processing/codice/codice_l1b.py +51 -152
- imap_processing/codice/constants.py +38 -1
- imap_processing/ena_maps/ena_maps.py +658 -65
- imap_processing/ena_maps/utils/coordinates.py +1 -1
- imap_processing/ena_maps/utils/spatial_utils.py +10 -5
- imap_processing/glows/l1a/glows_l1a.py +28 -99
- imap_processing/glows/l1a/glows_l1a_data.py +2 -2
- imap_processing/glows/l1b/glows_l1b.py +1 -4
- imap_processing/glows/l1b/glows_l1b_data.py +1 -3
- imap_processing/glows/l2/glows_l2.py +2 -5
- imap_processing/hi/l1a/hi_l1a.py +31 -12
- imap_processing/hi/l1b/hi_l1b.py +80 -43
- imap_processing/hi/l1c/hi_l1c.py +12 -16
- imap_processing/hit/ancillary/imap_hit_l1b-to-l2-sector-dt0-factors_20250219_v002.csv +81 -0
- imap_processing/hit/hit_utils.py +93 -35
- imap_processing/hit/l0/decom_hit.py +3 -1
- imap_processing/hit/l1a/hit_l1a.py +30 -25
- imap_processing/hit/l1b/constants.py +6 -2
- imap_processing/hit/l1b/hit_l1b.py +279 -318
- imap_processing/hit/l2/constants.py +37 -0
- imap_processing/hit/l2/hit_l2.py +373 -264
- imap_processing/ialirt/l0/parse_mag.py +138 -10
- imap_processing/ialirt/l0/process_swapi.py +69 -0
- imap_processing/ialirt/l0/process_swe.py +318 -22
- imap_processing/ialirt/packet_definitions/ialirt.xml +216 -212
- imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +1 -1
- imap_processing/ialirt/packet_definitions/ialirt_codicelo.xml +1 -1
- imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +14 -14
- imap_processing/ialirt/utils/grouping.py +1 -1
- imap_processing/idex/idex_constants.py +9 -1
- imap_processing/idex/idex_l0.py +22 -8
- imap_processing/idex/idex_l1a.py +75 -44
- imap_processing/idex/idex_l1b.py +9 -8
- imap_processing/idex/idex_l2a.py +79 -45
- imap_processing/idex/idex_l2b.py +120 -0
- imap_processing/idex/idex_variable_unpacking_and_eu_conversion.csv +33 -39
- imap_processing/idex/packet_definitions/idex_housekeeping_packet_definition.xml +9130 -0
- imap_processing/lo/l0/lo_science.py +1 -2
- imap_processing/lo/l1a/lo_l1a.py +1 -4
- imap_processing/lo/l1b/lo_l1b.py +527 -6
- imap_processing/lo/l1b/tof_conversions.py +11 -0
- imap_processing/lo/l1c/lo_l1c.py +1 -4
- imap_processing/mag/constants.py +43 -0
- imap_processing/mag/imap_mag_sdc_configuration_v001.py +8 -0
- imap_processing/mag/l1a/mag_l1a.py +2 -9
- imap_processing/mag/l1a/mag_l1a_data.py +10 -10
- imap_processing/mag/l1b/mag_l1b.py +84 -17
- imap_processing/mag/l1c/interpolation_methods.py +180 -3
- imap_processing/mag/l1c/mag_l1c.py +236 -70
- imap_processing/mag/l2/mag_l2.py +140 -0
- imap_processing/mag/l2/mag_l2_data.py +288 -0
- imap_processing/spacecraft/quaternions.py +1 -3
- imap_processing/spice/geometry.py +3 -3
- imap_processing/spice/kernels.py +0 -276
- imap_processing/spice/pointing_frame.py +257 -0
- imap_processing/spice/repoint.py +48 -19
- imap_processing/spice/spin.py +38 -33
- imap_processing/spice/time.py +24 -0
- imap_processing/swapi/l1/swapi_l1.py +16 -12
- imap_processing/swapi/l2/swapi_l2.py +116 -4
- imap_processing/swapi/swapi_utils.py +32 -0
- imap_processing/swe/l1a/swe_l1a.py +2 -9
- imap_processing/swe/l1a/swe_science.py +8 -11
- imap_processing/swe/l1b/swe_l1b.py +898 -23
- imap_processing/swe/l2/swe_l2.py +21 -77
- imap_processing/swe/utils/swe_constants.py +1 -0
- imap_processing/tests/ccsds/test_excel_to_xtce.py +1 -1
- imap_processing/tests/cdf/test_utils.py +14 -16
- imap_processing/tests/codice/conftest.py +44 -33
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hi-pha_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-pha_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/test_codice_l1a.py +20 -11
- imap_processing/tests/codice/test_codice_l1b.py +6 -7
- imap_processing/tests/conftest.py +78 -22
- imap_processing/tests/ena_maps/test_ena_maps.py +462 -33
- imap_processing/tests/ena_maps/test_spatial_utils.py +1 -1
- imap_processing/tests/glows/conftest.py +10 -14
- imap_processing/tests/glows/test_glows_decom.py +4 -4
- imap_processing/tests/glows/test_glows_l1a_cdf.py +6 -27
- imap_processing/tests/glows/test_glows_l1a_data.py +6 -8
- imap_processing/tests/glows/test_glows_l1b.py +11 -11
- imap_processing/tests/glows/test_glows_l1b_data.py +5 -5
- imap_processing/tests/glows/test_glows_l2.py +2 -8
- imap_processing/tests/hi/conftest.py +1 -1
- imap_processing/tests/hi/test_hi_l1b.py +10 -12
- imap_processing/tests/hi/test_hi_l1c.py +27 -24
- imap_processing/tests/hi/test_l1a.py +7 -9
- imap_processing/tests/hi/test_science_direct_event.py +2 -2
- imap_processing/tests/hit/helpers/l1_validation.py +44 -43
- imap_processing/tests/hit/test_decom_hit.py +1 -1
- imap_processing/tests/hit/test_hit_l1a.py +9 -9
- imap_processing/tests/hit/test_hit_l1b.py +172 -217
- imap_processing/tests/hit/test_hit_l2.py +380 -118
- imap_processing/tests/hit/test_hit_utils.py +122 -55
- imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -62
- imap_processing/tests/hit/validation_data/sci_sample_raw.csv +1 -1
- imap_processing/tests/ialirt/unit/test_decom_ialirt.py +16 -81
- imap_processing/tests/ialirt/unit/test_grouping.py +2 -2
- imap_processing/tests/ialirt/unit/test_parse_mag.py +71 -16
- imap_processing/tests/ialirt/unit/test_process_codicehi.py +3 -3
- imap_processing/tests/ialirt/unit/test_process_codicelo.py +3 -10
- imap_processing/tests/ialirt/unit/test_process_ephemeris.py +4 -4
- imap_processing/tests/ialirt/unit/test_process_hit.py +3 -3
- imap_processing/tests/ialirt/unit/test_process_swapi.py +24 -16
- imap_processing/tests/ialirt/unit/test_process_swe.py +115 -7
- imap_processing/tests/idex/conftest.py +72 -7
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20241206_v001.pkts +0 -0
- imap_processing/tests/idex/test_data/imap_idex_l0_raw_20250108_v001.pkts +0 -0
- imap_processing/tests/idex/test_idex_l0.py +33 -11
- imap_processing/tests/idex/test_idex_l1a.py +50 -23
- imap_processing/tests/idex/test_idex_l1b.py +104 -25
- imap_processing/tests/idex/test_idex_l2a.py +48 -32
- imap_processing/tests/idex/test_idex_l2b.py +93 -0
- imap_processing/tests/lo/test_lo_l1a.py +3 -3
- imap_processing/tests/lo/test_lo_l1b.py +371 -6
- imap_processing/tests/lo/test_lo_l1c.py +1 -1
- imap_processing/tests/lo/test_lo_science.py +6 -7
- imap_processing/tests/lo/test_star_sensor.py +1 -1
- imap_processing/tests/mag/conftest.py +58 -9
- imap_processing/tests/mag/test_mag_decom.py +4 -3
- imap_processing/tests/mag/test_mag_l1a.py +13 -7
- imap_processing/tests/mag/test_mag_l1b.py +9 -9
- imap_processing/tests/mag/test_mag_l1c.py +151 -47
- imap_processing/tests/mag/test_mag_l2.py +130 -0
- imap_processing/tests/mag/test_mag_validation.py +144 -7
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-magi-normal-out.csv +1857 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T013/mag-l1b-l1c-t013-mago-normal-out.csv +1857 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-magi-normal-out.csv +1793 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-in.csv +1217 -0
- imap_processing/tests/mag/validation/L1c/T014/mag-l1b-l1c-t014-mago-normal-out.csv +1793 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-burst-in.csv +2561 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-in.csv +961 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-magi-normal-out.csv +1539 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-in.csv +1921 -0
- imap_processing/tests/mag/validation/L1c/T015/mag-l1b-l1c-t015-mago-normal-out.csv +2499 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-in.csv +865 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-magi-normal-out.csv +1196 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-in.csv +1729 -0
- imap_processing/tests/mag/validation/L1c/T016/mag-l1b-l1c-t016-mago-normal-out.csv +3053 -0
- imap_processing/tests/mag/validation/L2/imap_mag_l1b_norm-mago_20251017_v002.cdf +0 -0
- imap_processing/tests/mag/validation/calibration/imap_mag_l2-calibration-matrices_20251017_v004.cdf +0 -0
- imap_processing/tests/mag/validation/calibration/imap_mag_l2-offsets-norm_20251017_20251017_v001.cdf +0 -0
- imap_processing/tests/spacecraft/test_quaternions.py +1 -1
- imap_processing/tests/spice/test_data/fake_repoint_data.csv +4 -4
- imap_processing/tests/spice/test_data/fake_spin_data.csv +11 -11
- imap_processing/tests/spice/test_geometry.py +3 -3
- imap_processing/tests/spice/test_kernels.py +1 -200
- imap_processing/tests/spice/test_pointing_frame.py +185 -0
- imap_processing/tests/spice/test_repoint.py +20 -10
- imap_processing/tests/spice/test_spin.py +50 -9
- imap_processing/tests/spice/test_time.py +14 -0
- imap_processing/tests/swapi/lut/imap_swapi_esa-unit-conversion_20250211_v000.csv +73 -0
- imap_processing/tests/swapi/lut/imap_swapi_lut-notes_20250211_v000.csv +1025 -0
- imap_processing/tests/swapi/test_swapi_l1.py +7 -9
- imap_processing/tests/swapi/test_swapi_l2.py +180 -8
- imap_processing/tests/swe/lut/checker-board-indices.csv +24 -0
- imap_processing/tests/swe/lut/imap_swe_esa-lut_20250301_v000.csv +385 -0
- imap_processing/tests/swe/lut/imap_swe_l1b-in-flight-cal_20240510_20260716_v000.csv +3 -0
- imap_processing/tests/swe/test_swe_l1a.py +6 -6
- imap_processing/tests/swe/test_swe_l1a_science.py +3 -3
- imap_processing/tests/swe/test_swe_l1b.py +162 -24
- imap_processing/tests/swe/test_swe_l2.py +82 -102
- imap_processing/tests/test_cli.py +171 -88
- imap_processing/tests/test_utils.py +2 -1
- imap_processing/tests/ultra/data/mock_data.py +49 -21
- imap_processing/tests/ultra/unit/conftest.py +53 -70
- imap_processing/tests/ultra/unit/test_badtimes.py +2 -4
- imap_processing/tests/ultra/unit/test_cullingmask.py +4 -6
- imap_processing/tests/ultra/unit/test_de.py +3 -10
- imap_processing/tests/ultra/unit/test_decom_apid_880.py +27 -76
- imap_processing/tests/ultra/unit/test_decom_apid_881.py +15 -16
- imap_processing/tests/ultra/unit/test_decom_apid_883.py +12 -10
- imap_processing/tests/ultra/unit/test_decom_apid_896.py +202 -55
- imap_processing/tests/ultra/unit/test_lookup_utils.py +23 -1
- imap_processing/tests/ultra/unit/test_spacecraft_pset.py +3 -4
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +84 -307
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +30 -12
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +2 -2
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +4 -1
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +163 -29
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +5 -5
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +32 -43
- imap_processing/tests/ultra/unit/test_ultra_l2.py +230 -0
- imap_processing/ultra/constants.py +1 -1
- imap_processing/ultra/l0/decom_tools.py +21 -34
- imap_processing/ultra/l0/decom_ultra.py +168 -204
- imap_processing/ultra/l0/ultra_utils.py +152 -136
- imap_processing/ultra/l1a/ultra_l1a.py +55 -243
- imap_processing/ultra/l1b/badtimes.py +1 -4
- imap_processing/ultra/l1b/cullingmask.py +2 -6
- imap_processing/ultra/l1b/de.py +62 -47
- imap_processing/ultra/l1b/extendedspin.py +8 -4
- imap_processing/ultra/l1b/lookup_utils.py +72 -9
- imap_processing/ultra/l1b/ultra_l1b.py +3 -8
- imap_processing/ultra/l1b/ultra_l1b_culling.py +4 -4
- imap_processing/ultra/l1b/ultra_l1b_extended.py +236 -78
- imap_processing/ultra/l1c/histogram.py +2 -6
- imap_processing/ultra/l1c/spacecraft_pset.py +2 -4
- imap_processing/ultra/l1c/ultra_l1c.py +1 -5
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +107 -60
- imap_processing/ultra/l2/ultra_l2.py +299 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_LeftSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM45_RightSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_LeftSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/Angular_Profiles_FM90_RightSlit.csv +526 -0
- imap_processing/ultra/lookup_tables/FM45_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -2
- imap_processing/ultra/lookup_tables/FM90_Startup1_ULTRA_IMGPARAMS_20240719.csv +2 -0
- imap_processing/ultra/packet_definitions/README.md +38 -0
- imap_processing/ultra/packet_definitions/ULTRA_SCI_COMBINED.xml +15302 -482
- imap_processing/ultra/utils/ultra_l1_utils.py +13 -12
- imap_processing/utils.py +1 -1
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/METADATA +3 -2
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/RECORD +264 -225
- imap_processing/hi/l1b/hi_eng_unit_convert_table.csv +0 -154
- imap_processing/mag/imap_mag_sdc-configuration_v001.yaml +0 -6
- imap_processing/mag/l1b/__init__.py +0 -0
- imap_processing/swe/l1b/swe_esa_lookup_table.csv +0 -1441
- imap_processing/swe/l1b/swe_l1b_science.py +0 -699
- imap_processing/tests/swe/test_swe_l1b_science.py +0 -103
- imap_processing/ultra/lookup_tables/dps_sensitivity45.cdf +0 -0
- imap_processing/ultra/lookup_tables/ultra_90_dps_exposure_compressed.cdf +0 -0
- /imap_processing/idex/packet_definitions/{idex_packet_definition.xml → idex_science_packet_definition.xml} +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971383-404.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971384-405.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971385-406.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971386-407.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971387-408.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971388-409.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971389-410.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971390-411.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/461971391-412.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/IALiRT Raw Packet Telemetry.txt +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/apid01152.tlm +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/eu_SWP_IAL_20240826_152033.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hi_fsw_view_1_ccsds.bin +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.ccsds +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/hit_ialirt_sample.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/imap_codice_l1a_lo-ialirt_20241110193700_v0.0.0.cdf +0 -0
- /imap_processing/tests/ialirt/{test_data → data}/l0/sample_decoded_i-alirt_data.csv +0 -0
- /imap_processing/tests/mag/validation/{imap_calibration_mag_20240229_v01.cdf → calibration/imap_mag_l1b-calibration_20240229_v001.cdf} +0 -0
- /imap_processing/{swe/l1b/engineering_unit_convert_table.csv → tests/swe/lut/imap_swe_eu-conversion_20240510_v000.csv} +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.12.0.dist-info → imap_processing-0.13.0.dist-info}/entry_points.txt +0 -0
imap_processing/hi/l1c/hi_l1c.py
CHANGED
|
@@ -42,7 +42,7 @@ SPIN_PHASE_BIN_CENTERS = (SPIN_PHASE_BIN_EDGES[:-1] + SPIN_PHASE_BIN_EDGES[1:])
|
|
|
42
42
|
logger = logging.getLogger(__name__)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def hi_l1c(dependencies: list
|
|
45
|
+
def hi_l1c(dependencies: list) -> list[xr.Dataset]:
|
|
46
46
|
"""
|
|
47
47
|
High level IMAP-Hi l1c processing function.
|
|
48
48
|
|
|
@@ -56,10 +56,6 @@ def hi_l1c(dependencies: list, data_version: str) -> xr.Dataset:
|
|
|
56
56
|
dependencies : list
|
|
57
57
|
Input dependencies needed for l1c processing.
|
|
58
58
|
|
|
59
|
-
data_version : str
|
|
60
|
-
Data version to write to CDF files and the Data_version CDF attribute.
|
|
61
|
-
Should be in the format Vxxx.
|
|
62
|
-
|
|
63
59
|
Returns
|
|
64
60
|
-------
|
|
65
61
|
l1c_dataset : xarray.Dataset
|
|
@@ -76,9 +72,7 @@ def hi_l1c(dependencies: list, data_version: str) -> xr.Dataset:
|
|
|
76
72
|
"Input dependencies not recognized for l1c pset processing."
|
|
77
73
|
)
|
|
78
74
|
|
|
79
|
-
|
|
80
|
-
l1c_dataset.attrs["Data_version"] = data_version
|
|
81
|
-
return l1c_dataset
|
|
75
|
+
return [l1c_dataset]
|
|
82
76
|
|
|
83
77
|
|
|
84
78
|
def generate_pset_dataset(
|
|
@@ -108,14 +102,11 @@ def generate_pset_dataset(
|
|
|
108
102
|
config_df = CalibrationProductConfig.from_csv(calibration_prod_config_path)
|
|
109
103
|
|
|
110
104
|
pset_dataset = empty_pset_dataset(
|
|
105
|
+
de_dataset.epoch.data[0],
|
|
111
106
|
de_dataset.esa_energy_step.data,
|
|
112
107
|
config_df.cal_prod_config.number_of_products,
|
|
113
108
|
logical_source_parts["sensor"],
|
|
114
109
|
)
|
|
115
|
-
# For ISTP, epoch should be the center of the time bin.
|
|
116
|
-
pset_dataset.epoch.data[0] = np.mean(de_dataset.epoch.data[[0, -1]]).astype(
|
|
117
|
-
np.int64
|
|
118
|
-
)
|
|
119
110
|
pset_et = ttj2000ns_to_et(pset_dataset.epoch.data[0])
|
|
120
111
|
# Calculate and add despun_z, hae_latitude, and hae_longitude variables to
|
|
121
112
|
# the pset_dataset
|
|
@@ -144,13 +135,15 @@ def generate_pset_dataset(
|
|
|
144
135
|
|
|
145
136
|
|
|
146
137
|
def empty_pset_dataset(
|
|
147
|
-
l1b_energy_steps: np.ndarray, n_cal_prods: int, sensor_str: str
|
|
138
|
+
epoch_val: int, l1b_energy_steps: np.ndarray, n_cal_prods: int, sensor_str: str
|
|
148
139
|
) -> xr.Dataset:
|
|
149
140
|
"""
|
|
150
141
|
Allocate an empty xarray.Dataset with appropriate pset coordinates.
|
|
151
142
|
|
|
152
143
|
Parameters
|
|
153
144
|
----------
|
|
145
|
+
epoch_val : int
|
|
146
|
+
The starting epoch in J2000 TT nanoseconds for data in the PSET.
|
|
154
147
|
l1b_energy_steps : np.ndarray
|
|
155
148
|
The array of esa_energy_step data from the L1B DE product.
|
|
156
149
|
n_cal_prods : int
|
|
@@ -170,12 +163,12 @@ def empty_pset_dataset(
|
|
|
170
163
|
# preallocate coordinates xr.DataArrays
|
|
171
164
|
coords = dict()
|
|
172
165
|
# epoch coordinate has only 1 entry for pointing set
|
|
173
|
-
epoch_attrs = attr_mgr.get_variable_attributes("epoch")
|
|
166
|
+
epoch_attrs = attr_mgr.get_variable_attributes("epoch", check_schema=False)
|
|
174
167
|
epoch_attrs.update(
|
|
175
168
|
attr_mgr.get_variable_attributes("hi_pset_epoch", check_schema=False)
|
|
176
169
|
)
|
|
177
170
|
coords["epoch"] = xr.DataArray(
|
|
178
|
-
np.
|
|
171
|
+
np.array([epoch_val], dtype=np.int64), # TODO: get dtype from cdf attrs?
|
|
179
172
|
name="epoch",
|
|
180
173
|
dims=["epoch"],
|
|
181
174
|
attrs=epoch_attrs,
|
|
@@ -526,6 +519,9 @@ def pset_exposure(
|
|
|
526
519
|
)[0]
|
|
527
520
|
exposure_var["exposure_times"].values[:, i_esa] += new_exposure_times
|
|
528
521
|
|
|
522
|
+
# Convert exposure clock ticks to seconds
|
|
523
|
+
exposure_var["exposure_times"].values *= DE_CLOCK_TICK_S
|
|
524
|
+
|
|
529
525
|
return exposure_var
|
|
530
526
|
|
|
531
527
|
|
|
@@ -604,7 +600,7 @@ def get_de_clock_ticks_for_esa_step(
|
|
|
604
600
|
# The CCSDS packet gets created just AFTER the final spin in the 8-spin
|
|
605
601
|
# ESA step group so this match is the end time. The start time is
|
|
606
602
|
# 8-spins earlier.
|
|
607
|
-
spin_start_mets = spin_df.
|
|
603
|
+
spin_start_mets = spin_df.spin_start_met.to_numpy()
|
|
608
604
|
# CCSDS MET has one second resolution, add one to it to make sure it is
|
|
609
605
|
# greater than the spin start time it ended on.
|
|
610
606
|
end_time_ind = np.flatnonzero(ccsds_met + 1 >= spin_start_mets).max()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Species, Sector, Lower Energy (MeV), Upper Energy (MeV), Delta E (MeV), Geometry Factor (cm2 sr), Efficiency, b
|
|
2
|
+
H ,0,1.8,4,2.2,0.41686,1,0
|
|
3
|
+
H ,1,1.8,4,2.2,0.49253,1,0
|
|
4
|
+
H ,2,1.8,4,2.2,0.45156,1,0
|
|
5
|
+
H ,3,1.8,4,2.2,0.35599,1,0
|
|
6
|
+
H ,4,1.8,4,2.2,0.33312,1,0
|
|
7
|
+
H ,5,1.8,4,2.2,0.47444,1,0
|
|
8
|
+
H ,6,1.8,4,2.2,0.49253,1,0
|
|
9
|
+
H ,7,1.8,4,2.2,0.41686,1,0
|
|
10
|
+
H ,0,4,6,2,0.42008,1,0
|
|
11
|
+
H ,1,4,6,2,0.49746,1,0
|
|
12
|
+
H ,2,4,6,2,0.45515,1,0
|
|
13
|
+
H ,3,4,6,2,0.35921,1,0
|
|
14
|
+
H ,4,4,6,2,0.33619,1,0
|
|
15
|
+
H ,5,4,6,2,0.47817,1,0
|
|
16
|
+
H ,6,4,6,2,0.49746,1,0
|
|
17
|
+
H ,7,4,6,2,0.42008,1,0
|
|
18
|
+
H ,0,6,10,4,0.39177,1,0
|
|
19
|
+
H ,1,6,10,4,0.47095,1,0
|
|
20
|
+
H ,2,6,10,4,0.42764,1,0
|
|
21
|
+
H ,3,6,10,4,0.33171,1,0
|
|
22
|
+
H ,4,6,10,4,0.31091,1,0
|
|
23
|
+
H ,5,6,10,4,0.44844,1,0
|
|
24
|
+
H ,6,6,10,4,0.47095,1,0
|
|
25
|
+
H ,7,6,10,4,0.39177,1,0
|
|
26
|
+
He4 ,0,4,6,2,0.41995,1,0
|
|
27
|
+
He4 ,1,4,6,2,0.49964,1,0
|
|
28
|
+
He4 ,2,4,6,2,0.45649,1,0
|
|
29
|
+
He4 ,3,4,6,2,0.3584,1,0
|
|
30
|
+
He4 ,4,4,6,2,0.33563,1,0
|
|
31
|
+
He4 ,5,4,6,2,0.47925,1,0
|
|
32
|
+
He4 ,6,4,6,2,0.49964,1,0
|
|
33
|
+
He4 ,7,4,6,2,0.41995,1,0
|
|
34
|
+
He4 ,0,6,12,6,0.42404,1,0
|
|
35
|
+
He4 ,1,6,12,6,0.5045,1,0
|
|
36
|
+
He4 ,2,6,12,6,0.45897,1,0
|
|
37
|
+
He4 ,3,6,12,6,0.36098,1,0
|
|
38
|
+
He4 ,4,6,12,6,0.33793,1,0
|
|
39
|
+
He4 ,5,6,12,6,0.48202,1,0
|
|
40
|
+
He4 ,6,6,12,6,0.5045,1,0
|
|
41
|
+
He4 ,7,6,12,6,0.42404,1,0
|
|
42
|
+
CNO ,0,4,6,2,0.41976,1,0
|
|
43
|
+
CNO ,1,4,6,2,0.49594,1,0
|
|
44
|
+
CNO ,2,4,6,2,0.45356,1,0
|
|
45
|
+
CNO ,3,4,6,2,0.35698,1,0
|
|
46
|
+
CNO ,4,4,6,2,0.33409,1,0
|
|
47
|
+
CNO ,5,4,6,2,0.47645,1,0
|
|
48
|
+
CNO ,6,4,6,2,0.49594,1,0
|
|
49
|
+
CNO ,7,4,6,2,0.41976,1,0
|
|
50
|
+
CNO ,0,6,12,6,0.42026,1,0
|
|
51
|
+
CNO ,1,6,12,6,0.49871,1,0
|
|
52
|
+
CNO ,2,6,12,6,0.45567,1,0
|
|
53
|
+
CNO ,3,6,12,6,0.35809,1,0
|
|
54
|
+
CNO ,4,6,12,6,0.3351,1,0
|
|
55
|
+
CNO ,5,6,12,6,0.47866,1,0
|
|
56
|
+
CNO ,6,6,12,6,0.49871,1,0
|
|
57
|
+
CNO ,7,6,12,6,0.42026,1,0
|
|
58
|
+
NeMgSi ,0,4,6,2,0.37544,1,0
|
|
59
|
+
NeMgSi ,1,4,6,2,0.43535,1,0
|
|
60
|
+
NeMgSi ,2,4,6,2,0.40251,1,0
|
|
61
|
+
NeMgSi ,3,4,6,2,0.32308,1,0
|
|
62
|
+
NeMgSi ,4,4,6,2,0.30221,1,0
|
|
63
|
+
NeMgSi ,5,4,6,2,0.42339,1,0
|
|
64
|
+
NeMgSi ,6,4,6,2,0.43535,1,0
|
|
65
|
+
NeMgSi ,7,4,6,2,0.37544,1,0
|
|
66
|
+
NeMgSi ,0,6,12,6,0.42046,1,0
|
|
67
|
+
NeMgSi ,1,6,12,6,0.49714,1,0
|
|
68
|
+
NeMgSi ,2,6,12,6,0.45432,1,0
|
|
69
|
+
NeMgSi ,3,6,12,6,0.35764,1,0
|
|
70
|
+
NeMgSi ,4,6,12,6,0.33475,1,0
|
|
71
|
+
NeMgSi ,5,6,12,6,0.47721,1,0
|
|
72
|
+
NeMgSi ,6,6,12,6,0.49714,1,0
|
|
73
|
+
NeMgSi ,7,6,12,6,0.42046,1,0
|
|
74
|
+
Fe ,0,4,12,8,0.2752,1,0
|
|
75
|
+
Fe ,1,4,12,8,0.31996,1,0
|
|
76
|
+
Fe ,2,4,12,8,0.29577,1,0
|
|
77
|
+
Fe ,3,4,12,8,0.23669,1,0
|
|
78
|
+
Fe ,4,4,12,8,0.2213,1,0
|
|
79
|
+
Fe ,5,4,12,8,0.31118,1,0
|
|
80
|
+
Fe ,6,4,12,8,0.31996,1,0
|
|
81
|
+
Fe ,7,4,12,8,0.2752,1,0
|
imap_processing/hit/hit_utils.py
CHANGED
|
@@ -66,14 +66,12 @@ def get_datasets_by_apid(
|
|
|
66
66
|
return datasets_by_apid
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
def get_attribute_manager(
|
|
69
|
+
def get_attribute_manager(level: str) -> ImapCdfAttributes:
|
|
70
70
|
"""
|
|
71
71
|
Create an attribute manager for the HIT data products.
|
|
72
72
|
|
|
73
73
|
Parameters
|
|
74
74
|
----------
|
|
75
|
-
data_version : str
|
|
76
|
-
Version of the data product being created.
|
|
77
75
|
level : str
|
|
78
76
|
Data level of the product being created.
|
|
79
77
|
|
|
@@ -86,7 +84,6 @@ def get_attribute_manager(data_version: str, level: str) -> ImapCdfAttributes:
|
|
|
86
84
|
attr_mgr = ImapCdfAttributes()
|
|
87
85
|
attr_mgr.add_instrument_global_attrs(instrument="hit")
|
|
88
86
|
attr_mgr.add_instrument_variable_attrs(instrument="hit", level=level)
|
|
89
|
-
attr_mgr.add_global_attribute("Data_version", data_version)
|
|
90
87
|
return attr_mgr
|
|
91
88
|
|
|
92
89
|
|
|
@@ -227,7 +224,7 @@ def initialize_particle_data_arrays(
|
|
|
227
224
|
epoch_size: int,
|
|
228
225
|
) -> xr.Dataset:
|
|
229
226
|
"""
|
|
230
|
-
|
|
227
|
+
Add empty data arrays for a given particle.
|
|
231
228
|
|
|
232
229
|
Valid particle names:
|
|
233
230
|
h
|
|
@@ -252,44 +249,43 @@ def initialize_particle_data_arrays(
|
|
|
252
249
|
----------
|
|
253
250
|
dataset : xr.Dataset
|
|
254
251
|
The dataset to add the data arrays to.
|
|
255
|
-
|
|
256
252
|
particle : str
|
|
257
253
|
The abbreviated particle name.
|
|
258
|
-
|
|
259
254
|
num_energy_ranges : int
|
|
260
255
|
Number of energy ranges for the particle.
|
|
261
256
|
Used to define the shape of the data arrays.
|
|
262
|
-
|
|
263
257
|
epoch_size : int
|
|
264
258
|
Used to define the shape of the data arrays.
|
|
265
259
|
|
|
266
260
|
Returns
|
|
267
261
|
-------
|
|
268
|
-
|
|
269
|
-
The dataset with the
|
|
262
|
+
updated_ds : xr.Dataset
|
|
263
|
+
The updated dataset with the particle data arrays added.
|
|
270
264
|
"""
|
|
271
|
-
|
|
265
|
+
updated_ds = dataset.copy()
|
|
266
|
+
|
|
267
|
+
updated_ds[f"{particle}"] = xr.DataArray(
|
|
272
268
|
data=np.zeros((epoch_size, num_energy_ranges), dtype=np.float32),
|
|
273
269
|
dims=["epoch", f"{particle}_energy_mean"],
|
|
274
270
|
name=f"{particle}",
|
|
275
271
|
)
|
|
276
|
-
|
|
272
|
+
updated_ds[f"{particle}_stat_uncert_minus"] = xr.DataArray(
|
|
277
273
|
data=np.zeros((epoch_size, num_energy_ranges), dtype=np.float32),
|
|
278
274
|
dims=["epoch", f"{particle}_energy_mean"],
|
|
279
|
-
name=f"{particle}
|
|
275
|
+
name=f"{particle}_stat_uncert_minus",
|
|
280
276
|
)
|
|
281
|
-
|
|
277
|
+
updated_ds[f"{particle}_stat_uncert_plus"] = xr.DataArray(
|
|
282
278
|
data=np.zeros((epoch_size, num_energy_ranges), dtype=np.float32),
|
|
283
279
|
dims=["epoch", f"{particle}_energy_mean"],
|
|
284
|
-
name=f"{particle}
|
|
280
|
+
name=f"{particle}_stat_uncert_plus",
|
|
285
281
|
)
|
|
286
|
-
|
|
287
|
-
dataset.coords[f"{particle}_energy_mean"] = xr.DataArray(
|
|
282
|
+
updated_ds.coords[f"{particle}_energy_mean"] = xr.DataArray(
|
|
288
283
|
np.zeros(num_energy_ranges, dtype=np.int8),
|
|
289
284
|
dims=[f"{particle}_energy_mean"],
|
|
290
285
|
name=f"{particle}_energy_mean",
|
|
291
286
|
)
|
|
292
|
-
|
|
287
|
+
|
|
288
|
+
return updated_ds
|
|
293
289
|
|
|
294
290
|
|
|
295
291
|
def sum_particle_data(
|
|
@@ -318,10 +314,10 @@ def sum_particle_data(
|
|
|
318
314
|
summed_data : xr.DataArray
|
|
319
315
|
The summed data for the given energy range.
|
|
320
316
|
|
|
321
|
-
|
|
317
|
+
summed_uncertainty_minus : xr.DataArray
|
|
322
318
|
The summed data for delta minus statistical uncertainty.
|
|
323
319
|
|
|
324
|
-
|
|
320
|
+
summed_uncertainty_plus : xr.DataArray
|
|
325
321
|
The summed data for delta plus statistical uncertainty.
|
|
326
322
|
"""
|
|
327
323
|
summed_data = (
|
|
@@ -330,19 +326,19 @@ def sum_particle_data(
|
|
|
330
326
|
+ dataset["penfgrates"][:, indices["R4"]].sum(axis=1)
|
|
331
327
|
)
|
|
332
328
|
|
|
333
|
-
|
|
334
|
-
dataset["
|
|
335
|
-
+ dataset["
|
|
336
|
-
+ dataset["
|
|
329
|
+
summed_uncertainty_minus = (
|
|
330
|
+
dataset["l2fgrates_stat_uncert_minus"][:, indices["R2"]].sum(axis=1)
|
|
331
|
+
+ dataset["l3fgrates_stat_uncert_minus"][:, indices["R3"]].sum(axis=1)
|
|
332
|
+
+ dataset["penfgrates_stat_uncert_minus"][:, indices["R4"]].sum(axis=1)
|
|
337
333
|
)
|
|
338
334
|
|
|
339
|
-
|
|
340
|
-
dataset["
|
|
341
|
-
+ dataset["
|
|
342
|
-
+ dataset["
|
|
335
|
+
summed_uncertainty_plus = (
|
|
336
|
+
dataset["l2fgrates_stat_uncert_plus"][:, indices["R2"]].sum(axis=1)
|
|
337
|
+
+ dataset["l3fgrates_stat_uncert_plus"][:, indices["R3"]].sum(axis=1)
|
|
338
|
+
+ dataset["penfgrates_stat_uncert_plus"][:, indices["R4"]].sum(axis=1)
|
|
343
339
|
)
|
|
344
340
|
|
|
345
|
-
return summed_data,
|
|
341
|
+
return summed_data, summed_uncertainty_minus, summed_uncertainty_plus
|
|
346
342
|
|
|
347
343
|
|
|
348
344
|
def add_energy_variables(
|
|
@@ -367,27 +363,89 @@ def add_energy_variables(
|
|
|
367
363
|
|
|
368
364
|
Returns
|
|
369
365
|
-------
|
|
370
|
-
xr.Dataset
|
|
371
|
-
The dataset with the
|
|
366
|
+
updated_ds : xr.Dataset
|
|
367
|
+
The updated dataset with the energy variables added.
|
|
372
368
|
"""
|
|
369
|
+
updated_ds = dataset.copy()
|
|
370
|
+
|
|
373
371
|
energy_mean = np.mean(
|
|
374
372
|
np.array([energy_min_values, energy_max_values]), axis=0
|
|
375
373
|
).astype(np.float32)
|
|
376
374
|
|
|
377
|
-
|
|
375
|
+
updated_ds[f"{particle}_energy_mean"] = xr.DataArray(
|
|
378
376
|
data=energy_mean,
|
|
379
377
|
dims=[f"{particle}_energy_mean"],
|
|
380
378
|
name=f"{particle}_energy_mean",
|
|
381
379
|
)
|
|
382
|
-
|
|
380
|
+
updated_ds[f"{particle}_energy_delta_minus"] = xr.DataArray(
|
|
383
381
|
data=np.array(energy_mean - np.array(energy_min_values), dtype=np.float32),
|
|
384
382
|
dims=[f"{particle}_energy_mean"],
|
|
385
383
|
name=f"{particle}_energy_delta_minus",
|
|
386
384
|
)
|
|
387
|
-
|
|
385
|
+
updated_ds[f"{particle}_energy_delta_plus"] = xr.DataArray(
|
|
388
386
|
data=np.array(energy_max_values - energy_mean, dtype=np.float32),
|
|
389
387
|
dims=[f"{particle}_energy_mean"],
|
|
390
388
|
name=f"{particle}_energy_delta_plus",
|
|
391
389
|
)
|
|
390
|
+
return updated_ds
|
|
392
391
|
|
|
393
|
-
|
|
392
|
+
|
|
393
|
+
def add_summed_particle_data_to_dataset(
|
|
394
|
+
dataset: xr.Dataset,
|
|
395
|
+
source_dataset: xr.Dataset,
|
|
396
|
+
particle: str,
|
|
397
|
+
energy_ranges: list,
|
|
398
|
+
) -> xr.Dataset:
|
|
399
|
+
"""
|
|
400
|
+
Add summed particle data to the dataset.
|
|
401
|
+
|
|
402
|
+
Parameters
|
|
403
|
+
----------
|
|
404
|
+
dataset : xr.Dataset
|
|
405
|
+
The dataset to add the rates to (not modified in-place).
|
|
406
|
+
source_dataset : xr.Dataset
|
|
407
|
+
The dataset containing data to sum (counts or rates).
|
|
408
|
+
particle : str
|
|
409
|
+
The particle name.
|
|
410
|
+
energy_ranges : list
|
|
411
|
+
A list of energy range dictionaries for the particle.
|
|
412
|
+
|
|
413
|
+
Returns
|
|
414
|
+
-------
|
|
415
|
+
xr.Dataset
|
|
416
|
+
A new dataset with summed particle data added.
|
|
417
|
+
"""
|
|
418
|
+
# Make a copy of the dataset to update
|
|
419
|
+
ds = dataset.copy()
|
|
420
|
+
|
|
421
|
+
# Initialize particle data arrays
|
|
422
|
+
ds = initialize_particle_data_arrays(
|
|
423
|
+
ds, particle, len(energy_ranges), source_dataset.sizes["epoch"]
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
# Initialize arrays for energy values
|
|
427
|
+
energy_min = np.zeros(len(energy_ranges), dtype=np.float32)
|
|
428
|
+
energy_max = np.zeros(len(energy_ranges), dtype=np.float32)
|
|
429
|
+
|
|
430
|
+
# Compute summed data and update the dataset
|
|
431
|
+
for i, energy_range_dict in enumerate(energy_ranges):
|
|
432
|
+
summed_data, summed_data_uncert_minus, summed_data_uncert_plus = (
|
|
433
|
+
sum_particle_data(source_dataset, energy_range_dict)
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
ds[f"{particle}"][:, i] = summed_data.astype(np.float32)
|
|
437
|
+
ds[f"{particle}_stat_uncert_minus"][:, i] = summed_data_uncert_minus.astype(
|
|
438
|
+
np.float32
|
|
439
|
+
)
|
|
440
|
+
ds[f"{particle}_stat_uncert_plus"][:, i] = summed_data_uncert_plus.astype(
|
|
441
|
+
np.float32
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
# Store energy range values
|
|
445
|
+
energy_min[i] = energy_range_dict["energy_min"]
|
|
446
|
+
energy_max[i] = energy_range_dict["energy_max"]
|
|
447
|
+
|
|
448
|
+
# Add energy variables
|
|
449
|
+
ds = add_energy_variables(ds, particle, energy_min, energy_max)
|
|
450
|
+
|
|
451
|
+
return ds
|
|
@@ -113,7 +113,9 @@ def parse_count_rates(sci_dataset: xr.Dataset) -> None:
|
|
|
113
113
|
else:
|
|
114
114
|
dims = ["epoch"]
|
|
115
115
|
|
|
116
|
-
sci_dataset[field] = xr.DataArray(
|
|
116
|
+
sci_dataset[field] = xr.DataArray(
|
|
117
|
+
np.array(parsed_data, dtype=np.int64), dims=dims, name=field
|
|
118
|
+
)
|
|
117
119
|
# Add dimensions to coordinates
|
|
118
120
|
for dim in dims:
|
|
119
121
|
if dim not in sci_dataset.coords:
|
|
@@ -24,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|
|
24
24
|
fillval = -9223372036854775808
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def hit_l1a(packet_file: str
|
|
27
|
+
def hit_l1a(packet_file: str) -> list[xr.Dataset]:
|
|
28
28
|
"""
|
|
29
29
|
Will process HIT L0 data into L1A data products.
|
|
30
30
|
|
|
@@ -32,8 +32,6 @@ def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
|
32
32
|
----------
|
|
33
33
|
packet_file : str
|
|
34
34
|
Path to the CCSDS data packet file.
|
|
35
|
-
data_version : str
|
|
36
|
-
Version of the data product being created.
|
|
37
35
|
|
|
38
36
|
Returns
|
|
39
37
|
-------
|
|
@@ -44,7 +42,7 @@ def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
|
44
42
|
datasets_by_apid = get_datasets_by_apid(packet_file)
|
|
45
43
|
|
|
46
44
|
# Create the attribute manager for this data level
|
|
47
|
-
attr_mgr = get_attribute_manager(
|
|
45
|
+
attr_mgr = get_attribute_manager("l1a")
|
|
48
46
|
|
|
49
47
|
l1a_datasets = []
|
|
50
48
|
|
|
@@ -63,7 +61,7 @@ def hit_l1a(packet_file: str, data_version: str) -> list[xr.Dataset]:
|
|
|
63
61
|
return l1a_datasets
|
|
64
62
|
|
|
65
63
|
|
|
66
|
-
def subcom_sectorates(sci_dataset: xr.Dataset) ->
|
|
64
|
+
def subcom_sectorates(sci_dataset: xr.Dataset) -> xr.Dataset:
|
|
67
65
|
"""
|
|
68
66
|
Subcommutate sectorates data.
|
|
69
67
|
|
|
@@ -94,9 +92,16 @@ def subcom_sectorates(sci_dataset: xr.Dataset) -> None:
|
|
|
94
92
|
----------
|
|
95
93
|
sci_dataset : xarray.Dataset
|
|
96
94
|
Xarray dataset containing parsed HIT science data.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
sci_dataset : xarray.Dataset
|
|
99
|
+
Xarray dataset with sectored rates data organized by species.
|
|
97
100
|
"""
|
|
101
|
+
updated_dataset = sci_dataset.copy()
|
|
102
|
+
|
|
98
103
|
# Calculate mod 10 values
|
|
99
|
-
hdr_min_count_mod_10 =
|
|
104
|
+
hdr_min_count_mod_10 = updated_dataset.hdr_minute_cnt.values % 10
|
|
100
105
|
|
|
101
106
|
# Reference mod 10 mapping to initialize data structure for species and
|
|
102
107
|
# energy ranges and add 15x8 arrays with fill values for each science frame.
|
|
@@ -111,7 +116,7 @@ def subcom_sectorates(sci_dataset: xr.Dataset) -> None:
|
|
|
111
116
|
|
|
112
117
|
# Update counts for science frames where data is available
|
|
113
118
|
for i, mod_10 in enumerate(hdr_min_count_mod_10):
|
|
114
|
-
data_by_species_and_energy_range[mod_10]["counts"][i] =
|
|
119
|
+
data_by_species_and_energy_range[mod_10]["counts"][i] = updated_dataset[
|
|
115
120
|
"sectorates"
|
|
116
121
|
].values[i]
|
|
117
122
|
|
|
@@ -136,24 +141,26 @@ def subcom_sectorates(sci_dataset: xr.Dataset) -> None:
|
|
|
136
141
|
# shape: epoch, energy_mean, azimuth, declination
|
|
137
142
|
rates_data = np.transpose(np.array(data["counts"]), axes=(1, 0, 2, 3))
|
|
138
143
|
|
|
139
|
-
|
|
144
|
+
updated_dataset[f"{species}_sectored_counts"] = xr.DataArray(
|
|
140
145
|
data=rates_data,
|
|
141
146
|
dims=["epoch", f"{species}_energy_mean", "azimuth", "declination"],
|
|
142
147
|
name=f"{species}_counts_sectored",
|
|
143
148
|
)
|
|
144
149
|
|
|
145
150
|
# Add energy mean and deltas for each species
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
updated_dataset = add_energy_variables(
|
|
152
|
+
updated_dataset,
|
|
148
153
|
species,
|
|
149
154
|
np.array(data["energy_min"]),
|
|
150
155
|
np.array(data["energy_max"]),
|
|
151
156
|
)
|
|
152
157
|
|
|
158
|
+
return updated_dataset
|
|
159
|
+
|
|
153
160
|
|
|
154
161
|
def calculate_uncertainties(dataset: xr.Dataset) -> xr.Dataset:
|
|
155
162
|
"""
|
|
156
|
-
Calculate uncertainties
|
|
163
|
+
Calculate statistical uncertainties.
|
|
157
164
|
|
|
158
165
|
Calculate the upper and lower uncertainties. The uncertainty for
|
|
159
166
|
the raw Lev1A HIT data will be calculated as asymmetric Poisson
|
|
@@ -161,10 +168,10 @@ def calculate_uncertainties(dataset: xr.Dataset) -> xr.Dataset:
|
|
|
161
168
|
See section 5.5 in the algorithm document for details.
|
|
162
169
|
|
|
163
170
|
The upper uncertainty will be calculated as
|
|
164
|
-
|
|
171
|
+
uncert_plus = sqrt(counts + 1) + 1
|
|
165
172
|
|
|
166
173
|
The lower uncertainty will be calculated as
|
|
167
|
-
|
|
174
|
+
uncert_minus = sqrt(counts)
|
|
168
175
|
|
|
169
176
|
Parameters
|
|
170
177
|
----------
|
|
@@ -217,13 +224,13 @@ def calculate_uncertainties(dataset: xr.Dataset) -> xr.Dataset:
|
|
|
217
224
|
safe_values_plus = np.maximum(dataset[var] + 1, 0).astype(np.float32)
|
|
218
225
|
safe_values_minus = np.maximum(dataset[var], 0).astype(np.float32)
|
|
219
226
|
|
|
220
|
-
dataset[f"{var}
|
|
227
|
+
dataset[f"{var}_stat_uncert_plus"] = xr.DataArray(
|
|
221
228
|
np.where(
|
|
222
229
|
mask, np.sqrt(safe_values_plus) + 1, dataset[var].astype(np.float32)
|
|
223
230
|
),
|
|
224
231
|
dims=dataset[var].dims,
|
|
225
232
|
)
|
|
226
|
-
dataset[f"{var}
|
|
233
|
+
dataset[f"{var}_stat_uncert_minus"] = xr.DataArray(
|
|
227
234
|
np.where(mask, np.sqrt(safe_values_minus), dataset[var].astype(np.float32)),
|
|
228
235
|
dims=dataset[var].dims,
|
|
229
236
|
)
|
|
@@ -261,7 +268,7 @@ def process_science(
|
|
|
261
268
|
sci_dataset = decom_hit(dataset)
|
|
262
269
|
|
|
263
270
|
# Organize sectored rates by species type
|
|
264
|
-
subcom_sectorates(sci_dataset)
|
|
271
|
+
sci_dataset = subcom_sectorates(sci_dataset)
|
|
265
272
|
|
|
266
273
|
# Split the science data into count rates and event datasets
|
|
267
274
|
pha_raw_dataset = xr.Dataset(
|
|
@@ -277,14 +284,14 @@ def process_science(
|
|
|
277
284
|
|
|
278
285
|
datasets = []
|
|
279
286
|
# Update attributes and dimensions
|
|
280
|
-
for
|
|
287
|
+
for ds, logical_source in zip(
|
|
281
288
|
[count_rates_dataset, pha_raw_dataset], logical_sources
|
|
282
289
|
):
|
|
283
|
-
|
|
290
|
+
ds.attrs = attr_mgr.get_global_attributes(logical_source)
|
|
284
291
|
|
|
285
292
|
# TODO: Add CDF attributes to yaml once they're defined for L1A science data
|
|
286
293
|
# Assign attributes and dimensions to each data array in the Dataset
|
|
287
|
-
for field in
|
|
294
|
+
for field in ds.data_vars.keys():
|
|
288
295
|
try:
|
|
289
296
|
# Create a dict of dimensions using the DEPEND_I keys in the
|
|
290
297
|
# attributes
|
|
@@ -293,19 +300,17 @@ def process_science(
|
|
|
293
300
|
for key, value in attr_mgr.get_variable_attributes(field).items()
|
|
294
301
|
if "DEPEND" in key
|
|
295
302
|
}
|
|
296
|
-
|
|
297
|
-
|
|
303
|
+
ds[field].attrs = attr_mgr.get_variable_attributes(field)
|
|
304
|
+
ds[field].assign_coords(dims)
|
|
298
305
|
except KeyError:
|
|
299
306
|
print(f"Field {field} not found in attribute manager.")
|
|
300
307
|
logger.warning(f"Field {field} not found in attribute manager.")
|
|
301
308
|
|
|
302
309
|
# Skip schema check for epoch to prevent attr_mgr from adding the
|
|
303
310
|
# DEPEND_0 attribute which isn't required for epoch
|
|
304
|
-
|
|
305
|
-
"epoch", check_schema=False
|
|
306
|
-
)
|
|
311
|
+
ds.epoch.attrs = attr_mgr.get_variable_attributes("epoch", check_schema=False)
|
|
307
312
|
|
|
308
|
-
datasets.append(
|
|
313
|
+
datasets.append(ds)
|
|
309
314
|
|
|
310
315
|
logger.info(f"HIT L1A dataset created for {logical_source}")
|
|
311
316
|
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# Expected number of livestim pulses per integration time.
|
|
4
4
|
# This is used to calculate the fractional livetime
|
|
5
|
-
|
|
5
|
+
LIVESTIM_PULSES = 270
|
|
6
|
+
|
|
7
|
+
# Fill values for missing data
|
|
8
|
+
FILLVAL_FLOAT32 = -1.00e31
|
|
9
|
+
FILLVAL_INT64 = -9223372036854775808
|
|
6
10
|
|
|
7
11
|
# For the L1B summed rates product, counts are summed by particle type,
|
|
8
12
|
# energy range, and detector penetration range (Range 2, Range 3, and Range 4).
|
|
@@ -20,7 +24,7 @@ livestim_pulses = 270
|
|
|
20
24
|
# R4 = Indices for Range 4 (PENFGRATES)
|
|
21
25
|
# energy_units: MeV/n
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
SUMMED_PARTICLE_ENERGY_RANGE_MAPPING = {
|
|
24
28
|
"h": [
|
|
25
29
|
{
|
|
26
30
|
"energy_min": 1.8,
|