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
|
@@ -16,7 +16,7 @@ from imap_processing.ccsds.ccsds_data import CcsdsData
|
|
|
16
16
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
17
17
|
from imap_processing.mag.constants import DataMode
|
|
18
18
|
from imap_processing.mag.l0.mag_l0_data import MagL0, Mode
|
|
19
|
-
from imap_processing.spice.time import
|
|
19
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
20
20
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
@@ -109,7 +109,7 @@ def generate_dataset(
|
|
|
109
109
|
)
|
|
110
110
|
vector_data[index, :vector_len] = datapoint.VECTORS
|
|
111
111
|
|
|
112
|
-
shcoarse_data[index] =
|
|
112
|
+
shcoarse_data[index] = met_to_ttj2000ns(datapoint.SHCOARSE)
|
|
113
113
|
# Add remaining pieces to arrays
|
|
114
114
|
for key, value in dataclasses.asdict(datapoint).items():
|
|
115
115
|
if key not in ("ccsds_header", "VECTORS", "SHCOARSE"):
|
|
@@ -16,7 +16,10 @@ from imap_processing.mag.l1a.mag_l1a_data import (
|
|
|
16
16
|
MagL1aPacketProperties,
|
|
17
17
|
TimeTuple,
|
|
18
18
|
)
|
|
19
|
-
from imap_processing.spice.time import
|
|
19
|
+
from imap_processing.spice.time import (
|
|
20
|
+
et_to_utc,
|
|
21
|
+
ttj2000ns_to_et,
|
|
22
|
+
)
|
|
20
23
|
|
|
21
24
|
logger = logging.getLogger(__name__)
|
|
22
25
|
|
|
@@ -148,15 +151,12 @@ def process_packets(
|
|
|
148
151
|
mago_is_primary = mag_l0.PRI_SENS == PrimarySensor.MAGO.value
|
|
149
152
|
|
|
150
153
|
primary_day = (
|
|
151
|
-
|
|
152
|
-
+ met_to_j2000ns(primary_start_time.to_seconds()).astype("timedelta64[ns]")
|
|
154
|
+
et_to_utc(ttj2000ns_to_et([primary_start_time.to_j2000ns()]))[0]
|
|
153
155
|
).astype("datetime64[D]")
|
|
154
156
|
secondary_day = (
|
|
155
|
-
|
|
156
|
-
+ met_to_j2000ns(secondary_start_time.to_seconds()).astype(
|
|
157
|
-
"timedelta64[ns]"
|
|
158
|
-
)
|
|
157
|
+
et_to_utc(ttj2000ns_to_et([secondary_start_time.to_j2000ns()]))[0]
|
|
159
158
|
).astype("datetime64[D]")
|
|
159
|
+
|
|
160
160
|
primary_packet_properties = MagL1aPacketProperties(
|
|
161
161
|
mag_l0.SHCOARSE,
|
|
162
162
|
primary_start_time,
|
|
@@ -16,7 +16,7 @@ from imap_processing.mag.constants import (
|
|
|
16
16
|
MAX_FINE_TIME,
|
|
17
17
|
RANGE_BIT_WIDTH,
|
|
18
18
|
)
|
|
19
|
-
from imap_processing.spice.time import
|
|
19
|
+
from imap_processing.spice.time import met_to_ttj2000ns
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@dataclass
|
|
@@ -24,19 +24,20 @@ class TimeTuple:
|
|
|
24
24
|
"""
|
|
25
25
|
Class for storing fine time/coarse time for MAG data.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Coarse time is MET in seconds. Fine time is 16bit unsigned sub-second
|
|
28
28
|
counter.
|
|
29
29
|
|
|
30
30
|
Attributes
|
|
31
31
|
----------
|
|
32
32
|
coarse_time : int
|
|
33
|
-
Coarse time in seconds.
|
|
33
|
+
Coarse time in seconds (MET).
|
|
34
34
|
fine_time : int
|
|
35
|
-
Subsecond.
|
|
35
|
+
Subsecond counter, equal to fine_time/max_int16 seconds.
|
|
36
36
|
|
|
37
37
|
Methods
|
|
38
38
|
-------
|
|
39
39
|
to_seconds()
|
|
40
|
+
to_j2000ns()
|
|
40
41
|
"""
|
|
41
42
|
|
|
42
43
|
coarse_time: int
|
|
@@ -79,6 +80,19 @@ class TimeTuple:
|
|
|
79
80
|
"""
|
|
80
81
|
return float(self.coarse_time + self.fine_time / MAX_FINE_TIME)
|
|
81
82
|
|
|
83
|
+
def to_j2000ns(self) -> np.int64:
|
|
84
|
+
"""
|
|
85
|
+
Convert time tuple into J2000ns.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
j2000ns : numpy.int64
|
|
90
|
+
Time in nanoseconds since J2000 epoch.
|
|
91
|
+
"""
|
|
92
|
+
coarse_j2000ns = np.int64(met_to_ttj2000ns(self.coarse_time))
|
|
93
|
+
fine_ns = np.int64(self.fine_time / MAX_FINE_TIME * 1e9)
|
|
94
|
+
return coarse_j2000ns + fine_ns
|
|
95
|
+
|
|
82
96
|
|
|
83
97
|
@dataclass
|
|
84
98
|
class MagL1aPacketProperties:
|
|
@@ -204,7 +218,7 @@ class MagL1a:
|
|
|
204
218
|
Sequence number of the most recent packet added to the object
|
|
205
219
|
missing_sequences : list[int]
|
|
206
220
|
List of missing sequence numbers in the day
|
|
207
|
-
start_time : numpy.
|
|
221
|
+
start_time : numpy.int64
|
|
208
222
|
Start time of the day, in ns since J2000 epoch
|
|
209
223
|
compression_flags : np.ndarray
|
|
210
224
|
Array of flags to indication compression and width for all timestamps in the
|
|
@@ -233,10 +247,10 @@ class MagL1a:
|
|
|
233
247
|
shcoarse: int
|
|
234
248
|
vectors: np.ndarray
|
|
235
249
|
starting_packet: InitVar[MagL1aPacketProperties]
|
|
236
|
-
packet_definitions: dict[np.
|
|
250
|
+
packet_definitions: dict[np.int64, MagL1aPacketProperties] = field(init=False)
|
|
237
251
|
most_recent_sequence: int = field(init=False)
|
|
238
252
|
missing_sequences: list[int] = field(default_factory=list)
|
|
239
|
-
start_time: np.
|
|
253
|
+
start_time: np.int64 = field(init=False)
|
|
240
254
|
compression_flags: np.ndarray | None = field(init=False, default=None)
|
|
241
255
|
|
|
242
256
|
def __post_init__(self, starting_packet: MagL1aPacketProperties) -> None:
|
|
@@ -248,10 +262,7 @@ class MagL1a:
|
|
|
248
262
|
starting_packet : MagL1aPacketProperties
|
|
249
263
|
The packet properties for the first packet in the day, including start time.
|
|
250
264
|
"""
|
|
251
|
-
|
|
252
|
-
self.start_time = (J2000_EPOCH + met_to_j2000ns(self.shcoarse)).astype(
|
|
253
|
-
"datetime64[D]"
|
|
254
|
-
)
|
|
265
|
+
self.start_time = np.int64(met_to_ttj2000ns(starting_packet.shcoarse))
|
|
255
266
|
self.packet_definitions = {self.start_time: starting_packet}
|
|
256
267
|
# most_recent_sequence is the sequence number of the packet used to initialize
|
|
257
268
|
# the object
|
|
@@ -338,8 +349,8 @@ class MagL1a:
|
|
|
338
349
|
cdf.utils.met_to_j2000ns.
|
|
339
350
|
"""
|
|
340
351
|
timedelta = np.timedelta64(int(1 / vectors_per_sec * 1e9), "ns")
|
|
341
|
-
# TODO:
|
|
342
|
-
start_time_ns =
|
|
352
|
+
# TODO: From finetime and coarsetime, depends per packet
|
|
353
|
+
start_time_ns = start_time.to_j2000ns()
|
|
343
354
|
|
|
344
355
|
# Calculate time skips for each vector in ns
|
|
345
356
|
times = np.reshape(
|
|
@@ -616,7 +627,7 @@ class MagL1a:
|
|
|
616
627
|
(expected_range_data_length - end_padding) * has_range_data_section
|
|
617
628
|
)
|
|
618
629
|
|
|
619
|
-
# Cut off the first vector width and the
|
|
630
|
+
# Cut off the first vector width and the range data section.
|
|
620
631
|
vector_bits = bit_array[first_vector_width - 1 : end_vector]
|
|
621
632
|
|
|
622
633
|
# Shift the bit array over one to the left, then sum them up. This is used to
|
|
@@ -731,7 +742,7 @@ class MagL1a:
|
|
|
731
742
|
primary_count,
|
|
732
743
|
uncompressed_vector_size,
|
|
733
744
|
compression_width,
|
|
734
|
-
)
|
|
745
|
+
)[0]
|
|
735
746
|
|
|
736
747
|
# Secondary vector processing
|
|
737
748
|
first_secondary_vector = MagL1a.unpack_one_vector(
|
|
@@ -747,8 +758,7 @@ class MagL1a:
|
|
|
747
758
|
secondary_split_bits = np.split(
|
|
748
759
|
vector_bits[: secondary_boundaries[-1]], secondary_boundaries[:-1]
|
|
749
760
|
)[1:]
|
|
750
|
-
|
|
751
|
-
secondary_vectors = MagL1a._process_vector_section(
|
|
761
|
+
secondary_process_vectors = MagL1a._process_vector_section(
|
|
752
762
|
vector_bits,
|
|
753
763
|
secondary_split_bits,
|
|
754
764
|
secondary_boundaries[-1],
|
|
@@ -757,21 +767,28 @@ class MagL1a:
|
|
|
757
767
|
uncompressed_vector_size,
|
|
758
768
|
compression_width,
|
|
759
769
|
)
|
|
770
|
+
secondary_vectors = secondary_process_vectors[0]
|
|
771
|
+
|
|
772
|
+
# The range data length has 2 bits per vector, minus 2 for the uncompressed
|
|
773
|
+
# first vectors in the primary and secondary sensors.
|
|
774
|
+
# Then, the range data length is padded to the nearest 8 bits.
|
|
775
|
+
end_vector = ((secondary_process_vectors[1] + first_vector_width) + 7) // 8 * 8
|
|
760
776
|
|
|
761
777
|
# If there is a range data section, it describes all the data, compressed or
|
|
762
778
|
# uncompressed.
|
|
763
779
|
if has_range_data_section:
|
|
780
|
+
range_bits = bit_array[end_vector:]
|
|
764
781
|
primary_vectors = MagL1a.process_range_data_section(
|
|
765
|
-
|
|
782
|
+
range_bits[: (primary_count - 1) * 2],
|
|
766
783
|
primary_vectors,
|
|
767
784
|
)
|
|
768
785
|
secondary_vectors = MagL1a.process_range_data_section(
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
+ (primary_count + secondary_count - 2) * 2
|
|
786
|
+
range_bits[
|
|
787
|
+
(primary_count - 1) * 2 : (primary_count + secondary_count - 2) * 2
|
|
772
788
|
],
|
|
773
789
|
secondary_vectors,
|
|
774
790
|
)
|
|
791
|
+
|
|
775
792
|
return primary_vectors, secondary_vectors
|
|
776
793
|
|
|
777
794
|
@staticmethod
|
|
@@ -783,7 +800,7 @@ class MagL1a:
|
|
|
783
800
|
vector_count: int,
|
|
784
801
|
uncompressed_vector_size: int,
|
|
785
802
|
compression_width: int,
|
|
786
|
-
) -> np.ndarray:
|
|
803
|
+
) -> tuple[np.ndarray, int]:
|
|
787
804
|
"""
|
|
788
805
|
Generate a section of vector data, primary or secondary.
|
|
789
806
|
|
|
@@ -809,20 +826,33 @@ class MagL1a:
|
|
|
809
826
|
|
|
810
827
|
Returns
|
|
811
828
|
-------
|
|
812
|
-
numpy.ndarray
|
|
813
|
-
|
|
829
|
+
(numpy.ndarray, int)
|
|
830
|
+
A tuple consisting of: an array of processed vectors, and the index of the
|
|
831
|
+
end of the last vector. In a fully compressed case, this will be the same
|
|
832
|
+
as last_index.
|
|
814
833
|
"""
|
|
834
|
+
compressed_count = math.ceil(len(split_bits) / AXIS_COUNT) + 1
|
|
835
|
+
uncompressed_count = vector_count - compressed_count
|
|
836
|
+
|
|
837
|
+
# will have either 0 or 8 extra bits
|
|
838
|
+
# If we have more splits than vectors, we have included part of the range
|
|
839
|
+
# data section. Drop those values and update end_vector.
|
|
840
|
+
if len(split_bits) > (vector_count - 1) * AXIS_COUNT:
|
|
841
|
+
split_bits = split_bits[: (vector_count - 1) * AXIS_COUNT]
|
|
842
|
+
last_index -= 8
|
|
843
|
+
|
|
844
|
+
end = last_index + uncompressed_vector_size * uncompressed_count
|
|
845
|
+
|
|
815
846
|
vector_diffs = list(map(MagL1a.decode_fib_zig_zag, split_bits))
|
|
847
|
+
# if we got more than the expected length, we may have gotten some of the range
|
|
848
|
+
# data section.
|
|
849
|
+
|
|
816
850
|
vectors = MagL1a.convert_diffs_to_vectors(
|
|
817
851
|
first_vector, vector_diffs, vector_count
|
|
818
852
|
)
|
|
819
853
|
# If we are missing any vectors from primary_split_bits, we know we have
|
|
820
854
|
# uncompressed vectors to process.
|
|
821
|
-
compressed_count = math.ceil(len(split_bits) / AXIS_COUNT) + 1
|
|
822
|
-
uncompressed_count = vector_count - compressed_count
|
|
823
|
-
|
|
824
855
|
if uncompressed_count:
|
|
825
|
-
end = last_index + uncompressed_vector_size * uncompressed_count
|
|
826
856
|
uncompressed_vectors = vector_bits[last_index : end + 1]
|
|
827
857
|
|
|
828
858
|
for i in range(uncompressed_count):
|
|
@@ -836,8 +866,11 @@ class MagL1a:
|
|
|
836
866
|
)
|
|
837
867
|
vectors[i + compressed_count] = decoded_vector
|
|
838
868
|
vectors[i + compressed_count][3] = vectors[0][3]
|
|
869
|
+
# If there is an extra byte, this is from the range data section.
|
|
870
|
+
if len(vector_bits[last_index:]) - end == 8:
|
|
871
|
+
end -= 8
|
|
839
872
|
|
|
840
|
-
return vectors
|
|
873
|
+
return (vectors, end)
|
|
841
874
|
|
|
842
875
|
@staticmethod
|
|
843
876
|
def process_range_data_section(
|
|
@@ -870,7 +903,6 @@ class MagL1a:
|
|
|
870
903
|
"Incorrect length for range_data, there should be two bits per vector, "
|
|
871
904
|
"excluding the first."
|
|
872
905
|
)
|
|
873
|
-
|
|
874
906
|
updated_vectors: np.ndarray = np.copy(vectors)
|
|
875
907
|
range_str = "".join([str(i) for i in range_data])
|
|
876
908
|
for i in range(len(vectors) - 1):
|
|
@@ -4,12 +4,13 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import xarray as xr
|
|
7
|
+
from xarray import Dataset
|
|
7
8
|
|
|
8
9
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
9
10
|
from imap_processing.cdf.utils import load_cdf
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
def mag_l1b(input_dataset: xr.Dataset, version: str) ->
|
|
13
|
+
def mag_l1b(input_dataset: xr.Dataset, version: str) -> Dataset:
|
|
13
14
|
"""
|
|
14
15
|
Will process MAG L1B data from L1A data.
|
|
15
16
|
|
|
@@ -28,6 +29,9 @@ def mag_l1b(input_dataset: xr.Dataset, version: str) -> xr.Dataset:
|
|
|
28
29
|
# TODO:
|
|
29
30
|
# Read in calibration file
|
|
30
31
|
# multiply all vectors by calibration file
|
|
32
|
+
if "raw" in input_dataset.attrs["Logical_source"]:
|
|
33
|
+
# Raw files should not be processed in L1B.
|
|
34
|
+
raise ValueError("Raw L1A file passed into L1B. Unable to process.")
|
|
31
35
|
|
|
32
36
|
output_dataset = mag_l1b_processing(input_dataset)
|
|
33
37
|
attribute_manager = ImapCdfAttributes()
|
|
@@ -64,6 +68,7 @@ def mag_l1b_processing(input_dataset: xr.Dataset) -> xr.Dataset:
|
|
|
64
68
|
"""
|
|
65
69
|
# TODO: There is a time alignment step that will add a lot of complexity.
|
|
66
70
|
# This needs to be done once we have some SPICE time data.
|
|
71
|
+
|
|
67
72
|
mag_attributes = ImapCdfAttributes()
|
|
68
73
|
mag_attributes.add_instrument_variable_attrs("mag", "l1")
|
|
69
74
|
|
|
@@ -73,6 +78,7 @@ def mag_l1b_processing(input_dataset: xr.Dataset) -> xr.Dataset:
|
|
|
73
78
|
calibration_dataset = load_cdf(
|
|
74
79
|
Path(__file__).parent / "imap_calibration_mag_20240229_v01.cdf"
|
|
75
80
|
)
|
|
81
|
+
# TODO: add time shift
|
|
76
82
|
# TODO: Check validity of time range for calibration
|
|
77
83
|
if "mago" in input_dataset.attrs["Logical_source"][0]:
|
|
78
84
|
calibration_matrix = calibration_dataset["MFOTOURFO"]
|
|
@@ -137,8 +143,9 @@ def update_vector(
|
|
|
137
143
|
tuple[numpy.ndarray, numpy.ndarray]
|
|
138
144
|
Updated vector and the same compression flags.
|
|
139
145
|
"""
|
|
140
|
-
vector =
|
|
141
|
-
|
|
146
|
+
vector = rescale_vector(input_vector, input_compression)
|
|
147
|
+
cal_vector = calibrate_vector(vector, calibration_matrix)
|
|
148
|
+
return cal_vector, input_compression
|
|
142
149
|
|
|
143
150
|
|
|
144
151
|
def rescale_vector(
|
|
@@ -200,9 +207,7 @@ def calibrate_vector(
|
|
|
200
207
|
Calibrated vector.
|
|
201
208
|
"""
|
|
202
209
|
updated_vector = input_vector.copy()
|
|
203
|
-
|
|
204
|
-
updated_vector[:3] = np.matmul(
|
|
210
|
+
updated_vector[:3] = np.dot(
|
|
205
211
|
calibration_matrix.values[:, :, int(input_vector[3])], input_vector[:3]
|
|
206
212
|
)
|
|
207
|
-
|
|
208
213
|
return updated_vector
|
imap_processing/quality_flags.py
CHANGED
|
@@ -37,14 +37,29 @@ class ENAFlags(FlagNameMixin):
|
|
|
37
37
|
BADSPIN = 2**2 # bit 2, Bad spin
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
class
|
|
40
|
+
class ImapHkUltraFlags(FlagNameMixin):
|
|
41
41
|
"""IMAP Ultra flags."""
|
|
42
42
|
|
|
43
43
|
NONE = CommonFlags.NONE
|
|
44
44
|
INF = CommonFlags.INF # bit 0
|
|
45
45
|
NEG = CommonFlags.NEG # bit 1
|
|
46
46
|
BADSPIN = ENAFlags.BADSPIN # bit 2
|
|
47
|
-
FLAG1 = 2**3 # bit
|
|
47
|
+
FLAG1 = 2**3 # bit 3
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ImapAttitudeUltraFlags(FlagNameMixin):
|
|
51
|
+
"""IMAP Ultra flags."""
|
|
52
|
+
|
|
53
|
+
NONE = CommonFlags.NONE
|
|
54
|
+
SPINRATE = 2**0 # bit 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ImapRatesUltraFlags(FlagNameMixin):
|
|
58
|
+
"""IMAP Ultra Rates flags."""
|
|
59
|
+
|
|
60
|
+
NONE = CommonFlags.NONE
|
|
61
|
+
ZEROCOUNTS = 2**0 # bit 0
|
|
62
|
+
HIGHRATES = 2**1 # bit 1
|
|
48
63
|
|
|
49
64
|
|
|
50
65
|
class ImapLoFlags(FlagNameMixin):
|
|
@@ -54,7 +69,7 @@ class ImapLoFlags(FlagNameMixin):
|
|
|
54
69
|
INF = CommonFlags.INF # bit 0
|
|
55
70
|
NEG = CommonFlags.NEG # bit 1
|
|
56
71
|
BADSPIN = ENAFlags.BADSPIN # bit 2
|
|
57
|
-
FLAG2 = 2**3 # bit
|
|
72
|
+
FLAG2 = 2**3 # bit 3
|
|
58
73
|
|
|
59
74
|
|
|
60
75
|
class HitFlags(
|