imap-processing 0.9.0__py3-none-any.whl → 0.11.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/_version.py +2 -2
- imap_processing/cdf/config/imap_codice_l1a_variable_attrs.yaml +749 -442
- imap_processing/cdf/config/imap_glows_global_cdf_attrs.yaml +7 -0
- imap_processing/cdf/config/imap_glows_l1a_variable_attrs.yaml +8 -2
- imap_processing/cdf/config/imap_glows_l1b_variable_attrs.yaml +0 -1
- imap_processing/cdf/config/imap_glows_l2_variable_attrs.yaml +358 -0
- imap_processing/cdf/config/imap_hi_variable_attrs.yaml +59 -25
- imap_processing/cdf/config/imap_hit_global_cdf_attrs.yaml +22 -0
- imap_processing/cdf/config/imap_idex_l1a_variable_attrs.yaml +32 -8
- imap_processing/cdf/config/imap_idex_l1b_variable_attrs.yaml +94 -5
- imap_processing/cdf/config/imap_lo_l1a_variable_attrs.yaml +65 -37
- imap_processing/cdf/config/imap_swapi_variable_attrs.yaml +16 -1
- imap_processing/cdf/config/imap_swe_global_cdf_attrs.yaml +7 -0
- imap_processing/cdf/config/imap_swe_l1a_variable_attrs.yaml +14 -14
- imap_processing/cdf/config/imap_swe_l1b_variable_attrs.yaml +25 -24
- imap_processing/cdf/config/imap_swe_l2_variable_attrs.yaml +238 -0
- imap_processing/cdf/config/imap_ultra_l1b_variable_attrs.yaml +100 -92
- imap_processing/cdf/utils.py +2 -2
- imap_processing/cli.py +45 -9
- imap_processing/codice/codice_l1a.py +104 -58
- imap_processing/codice/constants.py +111 -155
- imap_processing/codice/data/esa_sweep_values.csv +256 -256
- imap_processing/codice/data/lo_stepping_values.csv +128 -128
- imap_processing/ena_maps/ena_maps.py +519 -0
- imap_processing/ena_maps/utils/map_utils.py +145 -0
- imap_processing/ena_maps/utils/spatial_utils.py +226 -0
- imap_processing/glows/__init__.py +3 -0
- imap_processing/glows/ancillary/imap_glows_pipeline_settings_v001.json +52 -0
- imap_processing/glows/l1a/glows_l1a.py +72 -14
- imap_processing/glows/l1b/glows_l1b.py +2 -1
- imap_processing/glows/l1b/glows_l1b_data.py +25 -1
- imap_processing/glows/l2/glows_l2.py +324 -0
- imap_processing/glows/l2/glows_l2_data.py +156 -51
- imap_processing/hi/l1a/science_direct_event.py +57 -51
- imap_processing/hi/l1b/hi_l1b.py +43 -28
- imap_processing/hi/l1c/hi_l1c.py +225 -42
- imap_processing/hi/utils.py +20 -3
- imap_processing/hit/l0/constants.py +2 -2
- imap_processing/hit/l0/decom_hit.py +1 -1
- imap_processing/hit/l1a/hit_l1a.py +94 -13
- imap_processing/hit/l1b/hit_l1b.py +158 -9
- imap_processing/ialirt/l0/process_codicehi.py +156 -0
- imap_processing/ialirt/l0/process_codicelo.py +5 -2
- imap_processing/ialirt/packet_definitions/ialirt.xml +28 -20
- imap_processing/ialirt/packet_definitions/ialirt_codicehi.xml +241 -0
- imap_processing/ialirt/packet_definitions/ialirt_swapi.xml +170 -0
- imap_processing/ialirt/packet_definitions/ialirt_swe.xml +258 -0
- imap_processing/ialirt/process_ephemeris.py +72 -40
- imap_processing/idex/decode.py +241 -0
- imap_processing/idex/idex_l1a.py +143 -81
- imap_processing/idex/idex_l1b.py +244 -10
- imap_processing/lo/l0/lo_science.py +61 -0
- imap_processing/lo/l1a/lo_l1a.py +98 -10
- imap_processing/lo/l1b/lo_l1b.py +2 -2
- imap_processing/lo/l1c/lo_l1c.py +2 -2
- imap_processing/lo/packet_definitions/lo_xtce.xml +1082 -9178
- imap_processing/mag/l0/decom_mag.py +2 -2
- imap_processing/mag/l1a/mag_l1a.py +7 -7
- imap_processing/mag/l1a/mag_l1a_data.py +62 -30
- imap_processing/mag/l1b/mag_l1b.py +11 -6
- imap_processing/quality_flags.py +18 -3
- imap_processing/spice/geometry.py +149 -177
- imap_processing/spice/kernels.py +26 -26
- imap_processing/spice/spin.py +233 -0
- imap_processing/spice/time.py +96 -31
- imap_processing/swapi/l1/swapi_l1.py +60 -31
- imap_processing/swapi/packet_definitions/swapi_packet_definition.xml +363 -384
- imap_processing/swe/l1a/swe_l1a.py +8 -3
- imap_processing/swe/l1a/swe_science.py +24 -24
- imap_processing/swe/l1b/swe_l1b.py +2 -1
- imap_processing/swe/l1b/swe_l1b_science.py +181 -122
- imap_processing/swe/l2/swe_l2.py +337 -70
- imap_processing/swe/utils/swe_utils.py +28 -0
- imap_processing/tests/cdf/test_utils.py +2 -2
- imap_processing/tests/codice/conftest.py +20 -17
- imap_processing/tests/codice/data/validation/imap_codice_l1a_hskp_20241110193622_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-aggregated_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-counters-singles_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-angular_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-priority_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-nsw-species_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-angular_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-priority_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/data/validation/imap_codice_l1a_lo-sw-species_20241110193700_v0.0.0.cdf +0 -0
- imap_processing/tests/codice/test_codice_l0.py +55 -121
- imap_processing/tests/codice/test_codice_l1a.py +147 -59
- imap_processing/tests/conftest.py +81 -22
- imap_processing/tests/ena_maps/test_ena_maps.py +309 -0
- imap_processing/tests/ena_maps/test_map_utils.py +286 -0
- imap_processing/tests/ena_maps/test_spatial_utils.py +161 -0
- imap_processing/tests/glows/conftest.py +7 -1
- imap_processing/tests/glows/test_glows_l1a_cdf.py +3 -7
- imap_processing/tests/glows/test_glows_l1a_data.py +34 -6
- imap_processing/tests/glows/test_glows_l1b_data.py +29 -17
- imap_processing/tests/glows/test_glows_l2.py +101 -0
- imap_processing/tests/hi/conftest.py +3 -3
- imap_processing/tests/hi/data/l1/imap_hi_l1b_45sensor-de_20250415_v999.cdf +0 -0
- imap_processing/tests/hi/data/l1/imap_his_pset-calibration-prod-config_20240101_v001.csv +31 -0
- imap_processing/tests/hi/test_hi_l1b.py +14 -9
- imap_processing/tests/hi/test_hi_l1c.py +136 -36
- imap_processing/tests/hi/test_l1a.py +0 -2
- imap_processing/tests/hi/test_science_direct_event.py +18 -14
- imap_processing/tests/hi/test_utils.py +16 -11
- imap_processing/tests/hit/helpers/__init__.py +0 -0
- imap_processing/tests/hit/helpers/l1_validation.py +405 -0
- imap_processing/tests/hit/test_data/sci_sample.ccsds +0 -0
- imap_processing/tests/hit/test_decom_hit.py +8 -10
- imap_processing/tests/hit/test_hit_l1a.py +117 -180
- imap_processing/tests/hit/test_hit_l1b.py +149 -55
- imap_processing/tests/hit/validation_data/hit_l1b_standard_sample2_nsrl_v4_3decimals.csv +62 -0
- imap_processing/tests/hit/validation_data/sci_sample_raw.csv +62 -0
- imap_processing/tests/ialirt/test_data/l0/20240827095047_SWE_IALIRT_packet.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/BinLog CCSDS_FRAG_TLM_20240826_152323Z_IALIRT_data_for_SDC.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/eu_SWP_IAL_20240826_152033.csv +644 -0
- imap_processing/tests/ialirt/test_data/l0/hi_fsw_view_1_ccsds.bin +0 -0
- imap_processing/tests/ialirt/test_data/l0/idle_export_eu.SWE_IALIRT_20240827_093852.csv +914 -0
- imap_processing/tests/ialirt/test_data/l0/imap_codice_l1a_hi-ialirt_20240523200000_v0.0.0.cdf +0 -0
- imap_processing/tests/ialirt/unit/test_process_codicehi.py +106 -0
- imap_processing/tests/ialirt/unit/test_process_ephemeris.py +33 -5
- imap_processing/tests/ialirt/unit/test_process_swapi.py +85 -0
- imap_processing/tests/ialirt/unit/test_process_swe.py +106 -0
- imap_processing/tests/idex/conftest.py +29 -1
- imap_processing/tests/idex/test_data/compressed_2023_102_14_24_55.pkts +0 -0
- imap_processing/tests/idex/test_data/non_compressed_2023_102_14_22_26.pkts +0 -0
- imap_processing/tests/idex/test_idex_l0.py +6 -3
- imap_processing/tests/idex/test_idex_l1a.py +151 -1
- imap_processing/tests/idex/test_idex_l1b.py +124 -2
- imap_processing/tests/lo/test_lo_l1a.py +62 -2
- imap_processing/tests/lo/test_lo_science.py +85 -0
- imap_processing/tests/lo/validation_data/Instrument_FM1_T104_R129_20240803_ILO_SPIN_EU.csv +2 -0
- imap_processing/tests/mag/conftest.py +16 -0
- imap_processing/tests/mag/test_mag_decom.py +6 -4
- imap_processing/tests/mag/test_mag_l1a.py +36 -7
- imap_processing/tests/mag/test_mag_l1b.py +55 -4
- imap_processing/tests/mag/test_mag_validation.py +148 -0
- imap_processing/tests/mag/validation/L1a/T001/all_p_ones.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T001/mag-l0-l1a-t001-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T002/all_n_ones.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T002/mag-l0-l1a-t002-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T003/field_like.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T003/mag-l0-l1a-t003-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T004/field_like.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T004/mag-l0-l1a-t004-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T005/field_like_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T005/mag-l0-l1a-t005-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T006/hdr_field.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T006/mag-l0-l1a-t006-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T007/hdr_field_and_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T007/mag-l0-l1a-t007-out.csv +17 -0
- imap_processing/tests/mag/validation/L1a/T008/field_like_range_change.txt +19200 -0
- imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-in.bin +0 -0
- imap_processing/tests/mag/validation/L1a/T008/mag-l0-l1a-t008-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T009/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T009/mag-l1a-l1b-t009-mago-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T010/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T010/mag-l1a-l1b-t010-mago-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/data.bin +0 -0
- imap_processing/tests/mag/validation/L1b/T011/field_like_all_ranges.txt +19200 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-in.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-magi-out.csv +17 -0
- imap_processing/tests/mag/validation/L1b/T011/mag-l1a-l1b-t011-mago-out.csv +17 -0
- imap_processing/tests/spice/test_geometry.py +128 -133
- imap_processing/tests/spice/test_kernels.py +37 -37
- imap_processing/tests/spice/test_spin.py +184 -0
- imap_processing/tests/spice/test_time.py +43 -20
- imap_processing/tests/swapi/test_swapi_l1.py +11 -10
- imap_processing/tests/swapi/test_swapi_l2.py +13 -3
- imap_processing/tests/swe/test_swe_l1a.py +1 -1
- imap_processing/tests/swe/test_swe_l1b.py +20 -3
- imap_processing/tests/swe/test_swe_l1b_science.py +54 -35
- imap_processing/tests/swe/test_swe_l2.py +148 -5
- imap_processing/tests/test_cli.py +39 -7
- imap_processing/tests/test_quality_flags.py +19 -19
- imap_processing/tests/test_utils.py +3 -2
- imap_processing/tests/ultra/test_data/l0/ultra45_raw_sc_ultrarawimg_withFSWcalcs_FM45_40P_Phi28p5_BeamCal_LinearScan_phi2850_theta-000_20240207T102740.csv +3314 -3314
- imap_processing/tests/ultra/test_data/mock_data.py +161 -0
- imap_processing/tests/ultra/unit/conftest.py +73 -0
- imap_processing/tests/ultra/unit/test_badtimes.py +58 -0
- imap_processing/tests/ultra/unit/test_cullingmask.py +87 -0
- imap_processing/tests/ultra/unit/test_de.py +61 -60
- imap_processing/tests/ultra/unit/test_ultra_l1a.py +3 -3
- imap_processing/tests/ultra/unit/test_ultra_l1b.py +51 -77
- imap_processing/tests/ultra/unit/test_ultra_l1b_annotated.py +5 -5
- imap_processing/tests/ultra/unit/test_ultra_l1b_culling.py +114 -0
- imap_processing/tests/ultra/unit/test_ultra_l1b_extended.py +86 -26
- imap_processing/tests/ultra/unit/test_ultra_l1c.py +1 -1
- imap_processing/tests/ultra/unit/test_ultra_l1c_pset_bins.py +3 -3
- imap_processing/ultra/constants.py +11 -1
- imap_processing/ultra/l1a/ultra_l1a.py +2 -2
- imap_processing/ultra/l1b/badtimes.py +22 -5
- imap_processing/ultra/l1b/cullingmask.py +31 -5
- imap_processing/ultra/l1b/de.py +32 -37
- imap_processing/ultra/l1b/extendedspin.py +44 -20
- imap_processing/ultra/l1b/ultra_l1b.py +21 -22
- imap_processing/ultra/l1b/ultra_l1b_culling.py +190 -0
- imap_processing/ultra/l1b/ultra_l1b_extended.py +81 -30
- imap_processing/ultra/l1c/histogram.py +6 -2
- imap_processing/ultra/l1c/pset.py +6 -2
- imap_processing/ultra/l1c/ultra_l1c.py +2 -3
- imap_processing/ultra/l1c/ultra_l1c_pset_bins.py +4 -3
- imap_processing/ultra/utils/ultra_l1_utils.py +70 -14
- imap_processing/utils.py +2 -2
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/METADATA +7 -2
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/RECORD +235 -152
- imap_processing/tests/codice/data/eu_unit_lookup_table.csv +0 -101
- imap_processing/tests/codice/data/idle_export_eu.COD_NHK_20230822_122700 2.csv +0 -100
- imap_processing/tests/codice/data/idle_export_raw.COD_NHK_20230822_122700.csv +0 -100
- imap_processing/tests/codice/data/imap_codice_l0_raw_20241110_v001.pkts +0 -0
- imap_processing/tests/hi/test_data/l1a/imap_hi_l1a_45sensor-de_20250415_v000.cdf +0 -0
- imap_processing/tests/hit/test_data/sci_sample1.ccsds +0 -0
- imap_processing/tests/ultra/unit/test_spatial_utils.py +0 -125
- imap_processing/ultra/utils/spatial_utils.py +0 -221
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_APP_NHK.csv +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_CNT.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/20231030_H45_SCI_DE.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_NHK_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_cnt_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/H90_sci_de_20241104.bin +0 -0
- /imap_processing/tests/hi/{test_data → data}/l0/README.txt +0 -0
- /imap_processing/tests/idex/{imap_idex_l0_raw_20231214_v001.pkts → test_data/imap_idex_l0_raw_20231214_v001.pkts} +0 -0
- /imap_processing/tests/idex/{impact_14_tof_high_data.txt → test_data/impact_14_tof_high_data.txt} +0 -0
- /imap_processing/tests/mag/{imap_mag_l1a_norm-magi_20251017_v001.cdf → validation/imap_mag_l1a_norm-magi_20251017_v001.cdf} +0 -0
- /imap_processing/tests/mag/{mag_l0_test_data.pkts → validation/mag_l0_test_data.pkts} +0 -0
- /imap_processing/tests/mag/{mag_l0_test_output.csv → validation/mag_l0_test_output.csv} +0 -0
- /imap_processing/tests/mag/{mag_l1_test_data.pkts → validation/mag_l1_test_data.pkts} +0 -0
- /imap_processing/tests/mag/{mag_l1a_test_output.csv → validation/mag_l1a_test_output.csv} +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/LICENSE +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/WHEEL +0 -0
- {imap_processing-0.9.0.dist-info → imap_processing-0.11.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Decompress IDEX raw wavelength data.
|
|
3
|
+
|
|
4
|
+
Originally written by Corinne Wuerthner.
|
|
5
|
+
A compressed data frame starts on a byte boundary, and begins with the 8-bit sequence
|
|
6
|
+
0xF5 to indicate the start of a frame.
|
|
7
|
+
A frame contains one or more subframes of compressed data. Subframes are packed as
|
|
8
|
+
tightly as possible, and are not aligned to any byte or word boundary. The compression
|
|
9
|
+
parameters are varied for each subframe to optimize the data compression. Within a
|
|
10
|
+
subframe the same predictor, and the same Rice parameter is used for all the
|
|
11
|
+
samples in that subframe. The predictor and rice parameter is allowed to vary
|
|
12
|
+
from subframe to subframe.
|
|
13
|
+
|
|
14
|
+
The start of each subframe consists of the following bits:
|
|
15
|
+
00: Constant value
|
|
16
|
+
The predictor assumes that every sample in the frame is equal to the
|
|
17
|
+
first sample in the frame. In this case, the first sample is stored as
|
|
18
|
+
the original NBIT binary value and no other samples are included in the
|
|
19
|
+
frame. The constant value predictor will only be selected for a
|
|
20
|
+
subframe where every sample is the same value.
|
|
21
|
+
|
|
22
|
+
01: Verbatim
|
|
23
|
+
The predictor assumes that the data is not well correlated, and simply
|
|
24
|
+
stores every sample in the frame using the original NBIT binary
|
|
25
|
+
representation. This predictor minimizes the impact of data expansion
|
|
26
|
+
for uncorrelated data samples where the golomb-rice coding would
|
|
27
|
+
actually make the encoded data significantly larger than the original
|
|
28
|
+
data set.
|
|
29
|
+
|
|
30
|
+
10: Linear predictor #1
|
|
31
|
+
This predictor assumes that each sample will have the same value as the
|
|
32
|
+
sample immediately before it (sample X(n) = sampleX(n-1)). The predicted
|
|
33
|
+
value is subtracted from the actual value of the sample and only the
|
|
34
|
+
error (residual) between the actual value, and the predicted value is
|
|
35
|
+
stored. This predictor requires a single uncompressed sample as a
|
|
36
|
+
“warmup sample” to be used in predicting the other samples in the
|
|
37
|
+
subframe.
|
|
38
|
+
|
|
39
|
+
11: Linear Predictor #2
|
|
40
|
+
This predictor assumes that sample X(n) = 2*X(n-1)-X(n-2). This
|
|
41
|
+
predictor calculates the slope of the signal based on the two previous
|
|
42
|
+
values (slope = X(n-1)-X(n-2)) and predicts the value of X(n) will
|
|
43
|
+
follow on a straight line drawn between the two previous points.
|
|
44
|
+
X(n) = X(n-1) + (X(n-1)-X(n-2)) = 2*X(n-1)-X(n-2).
|
|
45
|
+
|
|
46
|
+
M bits for the rice parameter k. The bit width of k is equal to ceiling(log2(NBITS)).
|
|
47
|
+
For 10 bits, the bit width of k is 4 because log2(10) = 3.32 and ceiling(3.32) = 4.
|
|
48
|
+
The rice parameter k is stored in the bit stream as an unsigned binary value. The rice
|
|
49
|
+
parameter is omitted from the bit stream if the predictor type is set to “00” or '01'.
|
|
50
|
+
The next NBITS contain the raw binary value of the first sample in the subframe.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
# sub_frame_size is the compression block size
|
|
54
|
+
SUB_FRAME_SIZE = 64
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _decode_sub_frame(
|
|
58
|
+
bits: str,
|
|
59
|
+
bp: int,
|
|
60
|
+
psel: int,
|
|
61
|
+
k: int,
|
|
62
|
+
n_bits: int,
|
|
63
|
+
) -> tuple[list[int], int]:
|
|
64
|
+
"""
|
|
65
|
+
Decode a subframe of compressed data.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
bits : str
|
|
70
|
+
Raw waveform binary string.
|
|
71
|
+
bp : int
|
|
72
|
+
Current position to start reading from bits.
|
|
73
|
+
psel : int
|
|
74
|
+
Predictor select value.
|
|
75
|
+
k : int
|
|
76
|
+
Rice parameter used to divide each re-mapped residual value into two parts.
|
|
77
|
+
n_bits : int
|
|
78
|
+
Expected number of bits per sample. Either 10 or 12.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
tuple[list, int]
|
|
83
|
+
Decompressed subframe as a list of integers and the bit position.
|
|
84
|
+
"""
|
|
85
|
+
sample_count = 0
|
|
86
|
+
sub_frame_data = []
|
|
87
|
+
|
|
88
|
+
while (sample_count < SUB_FRAME_SIZE) and bp < len(bits):
|
|
89
|
+
if sample_count == 0:
|
|
90
|
+
# For every subframe, the first sample is always uncompressed.
|
|
91
|
+
# Read warmup sample
|
|
92
|
+
d1, bp = read_bits(bits, bp, n_bits)
|
|
93
|
+
|
|
94
|
+
sub_frame_data.append(d1)
|
|
95
|
+
sample_count += 1
|
|
96
|
+
|
|
97
|
+
# A 'psel' value of zero assumes that every sample in the frame is equal
|
|
98
|
+
# to the first sample in the frame. In this case, the first sample is
|
|
99
|
+
# stored as the original NBIT binary value
|
|
100
|
+
if psel == 0:
|
|
101
|
+
sub_frame_data.extend([d1] * (SUB_FRAME_SIZE - 1))
|
|
102
|
+
sample_count = SUB_FRAME_SIZE
|
|
103
|
+
|
|
104
|
+
# A 'psel' value of 1 assumes that the data is not well correlated, and
|
|
105
|
+
# simply stores every sample in the frame using the original NBIT binary
|
|
106
|
+
# representation.
|
|
107
|
+
# A 'psel' value of 3 requires two uncompressed 'warm-up' samples.
|
|
108
|
+
elif (psel == 1) or ((sample_count == 1) and (psel == 3)):
|
|
109
|
+
d1, bp = read_bits(bits, bp, n_bits)
|
|
110
|
+
sub_frame_data.append(d1)
|
|
111
|
+
sample_count += 1
|
|
112
|
+
|
|
113
|
+
else:
|
|
114
|
+
# The rice parameter (k) is used to divide each re-mapped residual value
|
|
115
|
+
# into two parts. The least significant k bits of the value are called
|
|
116
|
+
# the remainder (r). The other part of the value (not included in the
|
|
117
|
+
# remainder) is called the quotient (q).
|
|
118
|
+
# The remapped quotient is unary encoded by including a number of 0 bits
|
|
119
|
+
# equal to the value of the quotient, followed by a single '1' bit.
|
|
120
|
+
q = bits[bp:].find("1")
|
|
121
|
+
bp += q + 1
|
|
122
|
+
# If the value of the quotient is equal to or larger than 47, then a
|
|
123
|
+
# special symbol is used to denote that this particular residual value
|
|
124
|
+
# is not rice encoded, but that this special symbol is followed by the
|
|
125
|
+
# raw binary representation of the residual value using a (N_BITS+2)
|
|
126
|
+
# bit binary number. This special symbol is simply 47 zeros followed
|
|
127
|
+
# by a one.
|
|
128
|
+
if q == 47:
|
|
129
|
+
d1, bp = read_bits(bits, bp, n_bits + 2, True)
|
|
130
|
+
else:
|
|
131
|
+
if q % 2 == 1:
|
|
132
|
+
q = int(-((q + 1) / 2))
|
|
133
|
+
else:
|
|
134
|
+
q = int(q / 2)
|
|
135
|
+
|
|
136
|
+
r, bp = read_bits(bits, bp, k + 1)
|
|
137
|
+
d1 = (q << (k + 1)) + r
|
|
138
|
+
|
|
139
|
+
if psel == 2:
|
|
140
|
+
d1 = d1 + sub_frame_data[sample_count - 1]
|
|
141
|
+
elif (sample_count > 1) and (psel == 3):
|
|
142
|
+
d1 = (
|
|
143
|
+
d1
|
|
144
|
+
+ 2 * sub_frame_data[(sample_count - 1)]
|
|
145
|
+
- sub_frame_data[(sample_count - 2)]
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if (d1 > 2**n_bits) or (d1 < -(2**n_bits)):
|
|
149
|
+
raise ValueError(
|
|
150
|
+
f"Overflow Error while decoding subframe "
|
|
151
|
+
f"{k=}, {q=}, {r=}, {d1=}\n"
|
|
152
|
+
f"DataOut = {sub_frame_data}"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
sub_frame_data.append(d1)
|
|
156
|
+
sample_count += 1
|
|
157
|
+
|
|
158
|
+
return sub_frame_data, bp
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def rice_decode(compressed_data: str, nbit10: bool, sample_count: int) -> list[int]:
|
|
162
|
+
"""
|
|
163
|
+
Decode compressed IDEX wavelength data using linear prediction and Golomb-RICE.
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
compressed_data : str
|
|
168
|
+
Binary string representation of the raw waveform.
|
|
169
|
+
nbit10 : bool
|
|
170
|
+
If nbit10 is true, then the samples are expected to be 10 bits each, and if
|
|
171
|
+
nbit10 is false, then the samples are expected to be 12 bits each.
|
|
172
|
+
sample_count : int
|
|
173
|
+
The total number of samples to be decompressed.
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
list
|
|
178
|
+
Decompressed data as a list of integers.
|
|
179
|
+
"""
|
|
180
|
+
# Constants:
|
|
181
|
+
k_bits = 4
|
|
182
|
+
n_bits = 10 if nbit10 else 12
|
|
183
|
+
|
|
184
|
+
# frame_size is the expected amount of data
|
|
185
|
+
frame_size = sample_count
|
|
186
|
+
sub_frame_per_frame = frame_size / SUB_FRAME_SIZE
|
|
187
|
+
|
|
188
|
+
bits = compressed_data
|
|
189
|
+
out_data = []
|
|
190
|
+
sub_frame_count = 0
|
|
191
|
+
bp = 0
|
|
192
|
+
# Decode all subframes
|
|
193
|
+
while bp < len(bits) and (sub_frame_count < sub_frame_per_frame):
|
|
194
|
+
# The next two bits are the predictor select bits
|
|
195
|
+
psel, bp = read_bits(bits, bp, 2)
|
|
196
|
+
if psel > 1:
|
|
197
|
+
k, bp = read_bits(bits, bp, k_bits)
|
|
198
|
+
else:
|
|
199
|
+
k = 0
|
|
200
|
+
|
|
201
|
+
sub_frame_data, bp = _decode_sub_frame(bits, bp, psel, k, n_bits)
|
|
202
|
+
|
|
203
|
+
out_data.extend(sub_frame_data)
|
|
204
|
+
sub_frame_count += 1
|
|
205
|
+
|
|
206
|
+
if bp < len(bits) and (len(out_data) < frame_size):
|
|
207
|
+
raise ValueError("End of file reached before", frame_size, "samples decoded")
|
|
208
|
+
|
|
209
|
+
return out_data
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def read_bits(
|
|
213
|
+
bits: str, bit_pointer: int, read_num: int, signed: bool = False
|
|
214
|
+
) -> tuple[int, int]:
|
|
215
|
+
"""
|
|
216
|
+
Read bits from a binary string and convert to an int.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
bits : str
|
|
221
|
+
Binary string to read from.
|
|
222
|
+
bit_pointer : int
|
|
223
|
+
Current position in binary string.
|
|
224
|
+
read_num : int
|
|
225
|
+
Number of bits to read.
|
|
226
|
+
signed : bool
|
|
227
|
+
If signed is True, convert bits to a signed int. Default is False.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
value : int
|
|
232
|
+
Value of bits read.
|
|
233
|
+
bit_pointer : int
|
|
234
|
+
Bit position after reading.
|
|
235
|
+
"""
|
|
236
|
+
value = int(bits[bit_pointer : bit_pointer + read_num], 2)
|
|
237
|
+
if signed and bits[bit_pointer] == "1":
|
|
238
|
+
# If signed and is negative convert value
|
|
239
|
+
value = value - 2**read_num
|
|
240
|
+
bit_pointer += read_num
|
|
241
|
+
return value, bit_pointer
|
imap_processing/idex/idex_l1a.py
CHANGED
|
@@ -25,8 +25,9 @@ import space_packet_parser
|
|
|
25
25
|
import xarray as xr
|
|
26
26
|
|
|
27
27
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
28
|
+
from imap_processing.idex.decode import rice_decode
|
|
28
29
|
from imap_processing.idex.idex_l0 import decom_packets
|
|
29
|
-
from imap_processing.spice.time import
|
|
30
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
30
31
|
from imap_processing.utils import convert_to_binary_string
|
|
31
32
|
|
|
32
33
|
logger = logging.getLogger(__name__)
|
|
@@ -76,7 +77,6 @@ class PacketParser:
|
|
|
76
77
|
Currently assumes one L0 file will generate exactly one L1a file.
|
|
77
78
|
"""
|
|
78
79
|
decom_packet_list = decom_packets(packet_file)
|
|
79
|
-
|
|
80
80
|
dust_events = {}
|
|
81
81
|
for packet in decom_packet_list:
|
|
82
82
|
if "IDX__SCI0TYPE" in packet:
|
|
@@ -105,24 +105,88 @@ class PacketParser:
|
|
|
105
105
|
idex_attrs = get_idex_attrs(data_version)
|
|
106
106
|
self.data.attrs = idex_attrs.get_global_attributes("imap_idex_l1a_sci")
|
|
107
107
|
|
|
108
|
+
# Add high and low sample rate coords
|
|
109
|
+
self.data["time_low_sample_rate_index"] = xr.DataArray(
|
|
110
|
+
np.arange(len(self.data["time_low_sample_rate"][0])),
|
|
111
|
+
name="time_low_sample_rate_index",
|
|
112
|
+
dims=["time_low_sample_rate_index"],
|
|
113
|
+
attrs=idex_attrs.get_variable_attributes("time_low_sample_rate_index"),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
self.data["time_high_sample_rate_index"] = xr.DataArray(
|
|
117
|
+
np.arange(len(self.data["time_high_sample_rate"][0])),
|
|
118
|
+
name="time_high_sample_rate_index",
|
|
119
|
+
dims=["time_high_sample_rate_index"],
|
|
120
|
+
attrs=idex_attrs.get_variable_attributes("time_high_sample_rate_index"),
|
|
121
|
+
)
|
|
108
122
|
# NOTE: LABL_PTR_1 should be CDF_CHAR.
|
|
109
|
-
self.data["
|
|
110
|
-
self.data.
|
|
111
|
-
name="
|
|
112
|
-
dims=["
|
|
113
|
-
attrs=idex_attrs.get_variable_attributes("
|
|
123
|
+
self.data["time_low_sample_rate_label"] = xr.DataArray(
|
|
124
|
+
self.data.time_low_sample_rate_index.values.astype(str),
|
|
125
|
+
name="time_low_sample_rate_label",
|
|
126
|
+
dims=["time_low_sample_rate_index"],
|
|
127
|
+
attrs=idex_attrs.get_variable_attributes("time_low_sample_rate_label"),
|
|
114
128
|
)
|
|
115
129
|
|
|
116
|
-
self.data["
|
|
117
|
-
self.data.
|
|
118
|
-
name="
|
|
119
|
-
dims=["
|
|
120
|
-
attrs=idex_attrs.get_variable_attributes("
|
|
130
|
+
self.data["time_high_sample_rate_label"] = xr.DataArray(
|
|
131
|
+
self.data.time_high_sample_rate_index.values.astype(str),
|
|
132
|
+
name="time_high_sample_rate_label",
|
|
133
|
+
dims=["time_high_sample_rate_index"],
|
|
134
|
+
attrs=idex_attrs.get_variable_attributes("time_high_sample_rate_label"),
|
|
121
135
|
)
|
|
122
136
|
|
|
123
137
|
logger.info("IDEX L1A science data processing completed.")
|
|
124
138
|
|
|
125
139
|
|
|
140
|
+
def _read_waveform_bits(waveform_raw: str, high_sample: bool = True) -> list[int]:
|
|
141
|
+
"""
|
|
142
|
+
Convert the raw waveform binary string to ints.
|
|
143
|
+
|
|
144
|
+
Parse a binary string representing a waveform.
|
|
145
|
+
If the data is a high sample waveform:
|
|
146
|
+
- Data arrives in 32-bit chunks, divided up into:
|
|
147
|
+
* 2 bits of padding
|
|
148
|
+
* 3x10 bits of integer data.
|
|
149
|
+
- The very last four numbers are usually bad, so remove those.
|
|
150
|
+
If the data is a low sample waveform:
|
|
151
|
+
- Data arrives in 32-bit chunks, divided up into:
|
|
152
|
+
* 8 bits of padding
|
|
153
|
+
* 2x12 bits of integer data.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
waveform_raw : str
|
|
158
|
+
The binary string representing the waveform.
|
|
159
|
+
high_sample : bool
|
|
160
|
+
If true, parse the waveform according to the high sample pattern,
|
|
161
|
+
otherwise use the low sample pattern.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
ints : list
|
|
166
|
+
List of the waveform.
|
|
167
|
+
"""
|
|
168
|
+
ints = []
|
|
169
|
+
if high_sample:
|
|
170
|
+
for i in range(0, len(waveform_raw), 32):
|
|
171
|
+
# 32-bit chunks, divided up into 2, 10, 10, 10
|
|
172
|
+
# skip first two bits
|
|
173
|
+
ints += [
|
|
174
|
+
int(waveform_raw[i + 2 : i + 12], 2),
|
|
175
|
+
int(waveform_raw[i + 12 : i + 22], 2),
|
|
176
|
+
int(waveform_raw[i + 22 : i + 32], 2),
|
|
177
|
+
]
|
|
178
|
+
ints = ints[:-4] # Remove last 4 numbers
|
|
179
|
+
else:
|
|
180
|
+
for i in range(0, len(waveform_raw), 32):
|
|
181
|
+
# 32-bit chunks, divided up into 8, 12, 12
|
|
182
|
+
# skip first eight bits
|
|
183
|
+
ints += [
|
|
184
|
+
int(waveform_raw[i + 8 : i + 20], 2),
|
|
185
|
+
int(waveform_raw[i + 20 : i + 32], 2),
|
|
186
|
+
]
|
|
187
|
+
return ints
|
|
188
|
+
|
|
189
|
+
|
|
126
190
|
class RawDustEvent:
|
|
127
191
|
"""
|
|
128
192
|
Encapsulate IDEX Raw Dust Event.
|
|
@@ -147,6 +211,10 @@ class RawDustEvent:
|
|
|
147
211
|
The number of samples in a "block" of low sample data.
|
|
148
212
|
NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK: int
|
|
149
213
|
The number of samples in a "block" of high sample data.
|
|
214
|
+
MAX_HIGH_BLOCKS: int
|
|
215
|
+
The maximum number of "blocks" for high sample data.
|
|
216
|
+
MAX_LOW_BLOCKS: int
|
|
217
|
+
The maximum number of "blocks" for low sample data.
|
|
150
218
|
|
|
151
219
|
Methods
|
|
152
220
|
-------
|
|
@@ -180,6 +248,9 @@ class RawDustEvent:
|
|
|
180
248
|
NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK = (
|
|
181
249
|
512 # The number of samples in a "block" of high sample data
|
|
182
250
|
)
|
|
251
|
+
# Maximum amount of data
|
|
252
|
+
MAX_HIGH_BLOCKS = 16
|
|
253
|
+
MAX_LOW_BLOCKS = 64
|
|
183
254
|
|
|
184
255
|
def __init__(
|
|
185
256
|
self, header_packet: space_packet_parser.packets.CCSDSPacket, data_version: str
|
|
@@ -229,6 +300,7 @@ class RawDustEvent:
|
|
|
229
300
|
self.Target_High_bits = ""
|
|
230
301
|
self.Ion_Grid_bits = ""
|
|
231
302
|
|
|
303
|
+
self.compressed = self.telemetry_items["idx__sci0comp"]
|
|
232
304
|
self.cdf_attrs = get_idex_attrs(data_version)
|
|
233
305
|
|
|
234
306
|
def _append_raw_data(self, scitype: Scitype, bits: str) -> None:
|
|
@@ -287,7 +359,7 @@ class RawDustEvent:
|
|
|
287
359
|
# Get the datetime of Jan 1 2012 as the start date
|
|
288
360
|
met = seconds_since_launch + microseconds_since_last_second * 1e-6
|
|
289
361
|
|
|
290
|
-
self.impact_time =
|
|
362
|
+
self.impact_time = met_to_ttj2000ns(met)
|
|
291
363
|
|
|
292
364
|
def _set_sample_trigger_times(
|
|
293
365
|
self, packet: space_packet_parser.packets.CCSDSPacket
|
|
@@ -361,11 +433,7 @@ class RawDustEvent:
|
|
|
361
433
|
Will process the high sample waveform.
|
|
362
434
|
|
|
363
435
|
Parse a binary string representing a high sample waveform.
|
|
364
|
-
|
|
365
|
-
* 2 bits of padding
|
|
366
|
-
* 3x10 bits of integer data.
|
|
367
|
-
|
|
368
|
-
The very last 4 numbers are bad usually, so remove those.
|
|
436
|
+
If the data has been compressed, decompress using the RICE Golomb algorithm.
|
|
369
437
|
|
|
370
438
|
Parameters
|
|
371
439
|
----------
|
|
@@ -377,25 +445,20 @@ class RawDustEvent:
|
|
|
377
445
|
ints : list
|
|
378
446
|
List of the high sample waveform.
|
|
379
447
|
"""
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
int(waveform_raw[i + 22 : i + 32], 2),
|
|
388
|
-
]
|
|
389
|
-
return ints[:-4] # Remove last 4 numbers
|
|
448
|
+
samples = self.MAX_HIGH_BLOCKS * self.NUMBER_SAMPLES_PER_HIGH_SAMPLE_BLOCK
|
|
449
|
+
if self.compressed.raw_value == 1:
|
|
450
|
+
ints = rice_decode(waveform_raw, nbit10=True, sample_count=samples)
|
|
451
|
+
ints = ints[:-3]
|
|
452
|
+
else:
|
|
453
|
+
ints = _read_waveform_bits(waveform_raw, high_sample=True)
|
|
454
|
+
return ints
|
|
390
455
|
|
|
391
456
|
def _parse_low_sample_waveform(self, waveform_raw: str) -> list[int]:
|
|
392
457
|
"""
|
|
393
458
|
Will process the low sample waveform.
|
|
394
459
|
|
|
395
460
|
Parse a binary string representing a low sample waveform
|
|
396
|
-
|
|
397
|
-
* 8 bits of padding
|
|
398
|
-
* 2x12 bits of integer data.
|
|
461
|
+
If the data has been compressed, decompress using the RICE Golomb algorithm.
|
|
399
462
|
|
|
400
463
|
Parameters
|
|
401
464
|
----------
|
|
@@ -407,12 +470,11 @@ class RawDustEvent:
|
|
|
407
470
|
ints : list
|
|
408
471
|
List of processed low sample waveform.
|
|
409
472
|
"""
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
ints
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
]
|
|
473
|
+
samples = self.MAX_LOW_BLOCKS * self.NUMBER_SAMPLES_PER_LOW_SAMPLE_BLOCK
|
|
474
|
+
if self.compressed.raw_value == 1:
|
|
475
|
+
ints = rice_decode(waveform_raw, nbit10=False, sample_count=samples)
|
|
476
|
+
else:
|
|
477
|
+
ints = _read_waveform_bits(waveform_raw, high_sample=False)
|
|
416
478
|
return ints
|
|
417
479
|
|
|
418
480
|
def _calc_low_sample_resolution(self, num_samples: int) -> npt.NDArray:
|
|
@@ -432,14 +494,15 @@ class RawDustEvent:
|
|
|
432
494
|
|
|
433
495
|
Returns
|
|
434
496
|
-------
|
|
435
|
-
|
|
497
|
+
time_low_sample_rate_data : numpy.ndarray
|
|
436
498
|
Low time sample data array.
|
|
437
499
|
"""
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
self.LOW_SAMPLE_RATE *
|
|
500
|
+
time_low_sample_rate_init = np.linspace(0, num_samples, num_samples)
|
|
501
|
+
time_low_sample_rate_data = (
|
|
502
|
+
self.LOW_SAMPLE_RATE * time_low_sample_rate_init
|
|
503
|
+
- self.low_sample_trigger_time
|
|
441
504
|
)
|
|
442
|
-
return
|
|
505
|
+
return time_low_sample_rate_data
|
|
443
506
|
|
|
444
507
|
def _calc_high_sample_resolution(self, num_samples: int) -> npt.NDArray:
|
|
445
508
|
"""
|
|
@@ -458,14 +521,15 @@ class RawDustEvent:
|
|
|
458
521
|
|
|
459
522
|
Returns
|
|
460
523
|
-------
|
|
461
|
-
|
|
524
|
+
time_high_sample_rate_data : numpy.ndarray
|
|
462
525
|
High sample time data array.
|
|
463
526
|
"""
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
self.HIGH_SAMPLE_RATE *
|
|
527
|
+
time_high_sample_rate_init = np.linspace(0, num_samples, num_samples)
|
|
528
|
+
time_high_sample_rate_data = (
|
|
529
|
+
self.HIGH_SAMPLE_RATE * time_high_sample_rate_init
|
|
530
|
+
- self.high_sample_trigger_time
|
|
467
531
|
)
|
|
468
|
-
return
|
|
532
|
+
return time_high_sample_rate_data
|
|
469
533
|
|
|
470
534
|
def _populate_bit_strings(
|
|
471
535
|
self, packet: space_packet_parser.packets.CCSDSPacket
|
|
@@ -510,81 +574,79 @@ class RawDustEvent:
|
|
|
510
574
|
)
|
|
511
575
|
|
|
512
576
|
# Process the 6 primary data variables
|
|
513
|
-
|
|
577
|
+
tof_high = xr.DataArray(
|
|
514
578
|
name="TOF_High",
|
|
515
579
|
data=[self._parse_high_sample_waveform(self.TOF_High_bits)],
|
|
516
|
-
dims=("epoch", "
|
|
580
|
+
dims=("epoch", "time_high_sample_rate_index"),
|
|
517
581
|
attrs=idex_attrs.get_variable_attributes("tof_high_attrs"),
|
|
518
582
|
)
|
|
519
|
-
|
|
583
|
+
tof_low = xr.DataArray(
|
|
520
584
|
name="TOF_Low",
|
|
521
585
|
data=[self._parse_high_sample_waveform(self.TOF_Low_bits)],
|
|
522
|
-
dims=("epoch", "
|
|
586
|
+
dims=("epoch", "time_high_sample_rate_index"),
|
|
523
587
|
attrs=idex_attrs.get_variable_attributes("tof_low_attrs"),
|
|
524
588
|
)
|
|
525
|
-
|
|
589
|
+
tof_mid = xr.DataArray(
|
|
526
590
|
name="TOF_Mid",
|
|
527
591
|
data=[self._parse_high_sample_waveform(self.TOF_Mid_bits)],
|
|
528
|
-
dims=("epoch", "
|
|
592
|
+
dims=("epoch", "time_high_sample_rate_index"),
|
|
529
593
|
attrs=idex_attrs.get_variable_attributes("tof_mid_attrs"),
|
|
530
594
|
)
|
|
531
|
-
|
|
595
|
+
target_high = xr.DataArray(
|
|
532
596
|
name="Target_High",
|
|
533
597
|
data=[self._parse_low_sample_waveform(self.Target_High_bits)],
|
|
534
|
-
dims=("epoch", "
|
|
598
|
+
dims=("epoch", "time_low_sample_rate_index"),
|
|
535
599
|
attrs=idex_attrs.get_variable_attributes("target_high_attrs"),
|
|
536
600
|
)
|
|
537
|
-
|
|
601
|
+
target_low = xr.DataArray(
|
|
538
602
|
name="Target_Low",
|
|
539
603
|
data=[self._parse_low_sample_waveform(self.Target_Low_bits)],
|
|
540
|
-
dims=("epoch", "
|
|
604
|
+
dims=("epoch", "time_low_sample_rate_index"),
|
|
541
605
|
attrs=idex_attrs.get_variable_attributes("target_low_attrs"),
|
|
542
606
|
)
|
|
543
|
-
|
|
607
|
+
ion_grid = xr.DataArray(
|
|
544
608
|
name="Ion_Grid",
|
|
545
609
|
data=[self._parse_low_sample_waveform(self.Ion_Grid_bits)],
|
|
546
|
-
dims=("epoch", "
|
|
610
|
+
dims=("epoch", "time_low_sample_rate_index"),
|
|
547
611
|
attrs=idex_attrs.get_variable_attributes("ion_grid_attrs"),
|
|
548
612
|
)
|
|
549
613
|
|
|
550
614
|
# Determine the 3 coordinate variables
|
|
551
|
-
|
|
615
|
+
epoch = xr.DataArray(
|
|
552
616
|
name="epoch",
|
|
553
617
|
data=[self.impact_time],
|
|
554
618
|
dims=("epoch"),
|
|
555
619
|
attrs=idex_attrs.get_variable_attributes("epoch"),
|
|
556
620
|
)
|
|
557
621
|
|
|
558
|
-
|
|
559
|
-
name="
|
|
560
|
-
data=[self._calc_low_sample_resolution(len(
|
|
561
|
-
dims=("epoch", "
|
|
562
|
-
attrs=idex_attrs.get_variable_attributes("
|
|
622
|
+
time_low_sample_rate = xr.DataArray(
|
|
623
|
+
name="time_low_sample_rate",
|
|
624
|
+
data=[self._calc_low_sample_resolution(len(target_low[0]))],
|
|
625
|
+
dims=("epoch", "time_low_sample_rate_index"),
|
|
626
|
+
attrs=idex_attrs.get_variable_attributes("low_sample_rate_attrs"),
|
|
563
627
|
)
|
|
564
628
|
|
|
565
|
-
|
|
566
|
-
name="
|
|
567
|
-
data=[self._calc_high_sample_resolution(len(
|
|
568
|
-
dims=("epoch", "
|
|
569
|
-
attrs=idex_attrs.get_variable_attributes("
|
|
629
|
+
time_high_sample_rate = xr.DataArray(
|
|
630
|
+
name="time_high_sample_rate",
|
|
631
|
+
data=[self._calc_high_sample_resolution(len(tof_low[0]))],
|
|
632
|
+
dims=("epoch", "time_high_sample_rate_index"),
|
|
633
|
+
attrs=idex_attrs.get_variable_attributes("high_sample_rate_attrs"),
|
|
570
634
|
)
|
|
571
635
|
|
|
572
636
|
# Combine to return a dataset object
|
|
573
637
|
dataset = xr.Dataset(
|
|
574
638
|
data_vars={
|
|
575
|
-
"TOF_Low":
|
|
576
|
-
"TOF_High":
|
|
577
|
-
"TOF_Mid":
|
|
578
|
-
"Target_High":
|
|
579
|
-
"Target_Low":
|
|
580
|
-
"Ion_Grid":
|
|
639
|
+
"TOF_Low": tof_low,
|
|
640
|
+
"TOF_High": tof_high,
|
|
641
|
+
"TOF_Mid": tof_mid,
|
|
642
|
+
"Target_High": target_high,
|
|
643
|
+
"Target_Low": target_low,
|
|
644
|
+
"Ion_Grid": ion_grid,
|
|
645
|
+
"time_low_sample_rate": time_low_sample_rate,
|
|
646
|
+
"time_high_sample_rate": time_high_sample_rate,
|
|
581
647
|
}
|
|
582
648
|
| trigger_vars,
|
|
583
|
-
coords={
|
|
584
|
-
"epoch": epoch_xr,
|
|
585
|
-
"time_low_sr": time_low_sr_xr,
|
|
586
|
-
"time_high_sr": time_high_sr_xr,
|
|
587
|
-
},
|
|
649
|
+
coords={"epoch": epoch},
|
|
588
650
|
)
|
|
589
651
|
|
|
590
652
|
return dataset
|