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
|
@@ -42,7 +42,12 @@ def swe_l1a(packet_file: str, data_version: str) -> xr.Dataset:
|
|
|
42
42
|
packet_file, xtce_document, use_derived_value=False
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
+
if SWEAPID.SWE_SCIENCE not in datasets_by_apid:
|
|
46
|
+
logger.info("No science data found in packet file.")
|
|
47
|
+
return []
|
|
45
48
|
# TODO: figure out how to handle non-science data
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
return [
|
|
50
|
+
swe_science(
|
|
51
|
+
l0_dataset=datasets_by_apid[SWEAPID.SWE_SCIENCE], data_version=data_version
|
|
52
|
+
)
|
|
53
|
+
]
|
|
@@ -141,45 +141,45 @@ def swe_science(l0_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
141
141
|
attrs=cdf_attrs.get_variable_attributes("epoch"),
|
|
142
142
|
)
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
spin_sector = xr.DataArray(
|
|
145
145
|
np.arange(180),
|
|
146
|
-
name="
|
|
147
|
-
dims=["
|
|
148
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
146
|
+
name="spin_sector",
|
|
147
|
+
dims=["spin_sector"],
|
|
148
|
+
attrs=cdf_attrs.get_variable_attributes("spin_sector"),
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
# NOTE: LABL_PTR_1 should be CDF_CHAR.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
name="
|
|
155
|
-
dims=["
|
|
156
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
152
|
+
spin_sector_label = xr.DataArray(
|
|
153
|
+
spin_sector.values.astype(str),
|
|
154
|
+
name="spin_sector_label",
|
|
155
|
+
dims=["spin_sector"],
|
|
156
|
+
attrs=cdf_attrs.get_variable_attributes("spin_sector_label"),
|
|
157
157
|
)
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
cem_id = xr.DataArray(
|
|
160
160
|
np.arange(7),
|
|
161
|
-
name="
|
|
162
|
-
dims=["
|
|
163
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
161
|
+
name="cem_id",
|
|
162
|
+
dims=["cem_id"],
|
|
163
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id"),
|
|
164
164
|
)
|
|
165
165
|
|
|
166
166
|
# NOTE: LABL_PTR_2 should be CDF_CHAR.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
name="
|
|
170
|
-
dims=["
|
|
171
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
167
|
+
cem_id_label = xr.DataArray(
|
|
168
|
+
cem_id.values.astype(str),
|
|
169
|
+
name="cem_id_label",
|
|
170
|
+
dims=["cem_id"],
|
|
171
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id_label"),
|
|
172
172
|
)
|
|
173
173
|
|
|
174
174
|
science_xarray = xr.DataArray(
|
|
175
175
|
science_array,
|
|
176
|
-
dims=["epoch", "
|
|
176
|
+
dims=["epoch", "spin_sector", "cem_id"],
|
|
177
177
|
attrs=cdf_attrs.get_variable_attributes("science_data"),
|
|
178
178
|
)
|
|
179
179
|
|
|
180
180
|
raw_science_xarray = xr.DataArray(
|
|
181
181
|
raw_science_array,
|
|
182
|
-
dims=["epoch", "
|
|
182
|
+
dims=["epoch", "spin_sector", "cem_id"],
|
|
183
183
|
attrs=cdf_attrs.get_variable_attributes("raw_counts"),
|
|
184
184
|
)
|
|
185
185
|
|
|
@@ -190,10 +190,10 @@ def swe_science(l0_dataset: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
190
190
|
dataset = xr.Dataset(
|
|
191
191
|
coords={
|
|
192
192
|
"epoch": epoch_time,
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
193
|
+
"spin_sector": spin_sector,
|
|
194
|
+
"cem_id": cem_id,
|
|
195
|
+
"spin_sector_label": spin_sector_label,
|
|
196
|
+
"cem_id_label": cem_id_label,
|
|
197
197
|
},
|
|
198
198
|
attrs=l1a_global_attrs,
|
|
199
199
|
)
|
|
@@ -8,38 +8,13 @@ import pandas as pd
|
|
|
8
8
|
import xarray as xr
|
|
9
9
|
|
|
10
10
|
from imap_processing.cdf.imap_cdf_manager import ImapCdfAttributes
|
|
11
|
-
from imap_processing.swe.utils.swe_utils import
|
|
11
|
+
from imap_processing.swe.utils.swe_utils import (
|
|
12
|
+
ESA_VOLTAGE_ROW_INDEX_DICT,
|
|
13
|
+
read_lookup_table,
|
|
14
|
+
)
|
|
12
15
|
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
15
|
-
# ESA voltage and index in the final data table
|
|
16
|
-
esa_voltage_row_index_dict = {
|
|
17
|
-
0.56: 0,
|
|
18
|
-
0.78: 1,
|
|
19
|
-
1.08: 2,
|
|
20
|
-
1.51: 3,
|
|
21
|
-
2.10: 4,
|
|
22
|
-
2.92: 5,
|
|
23
|
-
4.06: 6,
|
|
24
|
-
5.64: 7,
|
|
25
|
-
7.85: 8,
|
|
26
|
-
10.92: 9,
|
|
27
|
-
15.19: 10,
|
|
28
|
-
21.13: 11,
|
|
29
|
-
29.39: 12,
|
|
30
|
-
40.88: 13,
|
|
31
|
-
56.87: 14,
|
|
32
|
-
79.10: 15,
|
|
33
|
-
110.03: 16,
|
|
34
|
-
153.05: 17,
|
|
35
|
-
212.89: 18,
|
|
36
|
-
296.14: 19,
|
|
37
|
-
411.93: 20,
|
|
38
|
-
572.99: 21,
|
|
39
|
-
797.03: 22,
|
|
40
|
-
1108.66: 23,
|
|
41
|
-
}
|
|
42
|
-
|
|
43
18
|
|
|
44
19
|
def get_esa_dataframe(esa_table_number: int) -> pd.DataFrame:
|
|
45
20
|
"""
|
|
@@ -110,7 +85,7 @@ def deadtime_correction(counts: np.ndarray, acq_duration: int) -> npt.NDArray:
|
|
|
110
85
|
return corrected_count.astype(np.float64)
|
|
111
86
|
|
|
112
87
|
|
|
113
|
-
def convert_counts_to_rate(data: np.ndarray, acq_duration:
|
|
88
|
+
def convert_counts_to_rate(data: np.ndarray, acq_duration: np.ndarray) -> npt.NDArray:
|
|
114
89
|
"""
|
|
115
90
|
Convert counts to rate using sampling time.
|
|
116
91
|
|
|
@@ -120,7 +95,7 @@ def convert_counts_to_rate(data: np.ndarray, acq_duration: int) -> npt.NDArray:
|
|
|
120
95
|
----------
|
|
121
96
|
data : numpy.ndarray
|
|
122
97
|
Counts data.
|
|
123
|
-
acq_duration :
|
|
98
|
+
acq_duration : numpy.ndarray
|
|
124
99
|
Acquisition duration. acq_duration is in microseconds.
|
|
125
100
|
|
|
126
101
|
Returns
|
|
@@ -134,51 +109,107 @@ def convert_counts_to_rate(data: np.ndarray, acq_duration: int) -> npt.NDArray:
|
|
|
134
109
|
return count_rate.astype(np.float64)
|
|
135
110
|
|
|
136
111
|
|
|
137
|
-
def
|
|
112
|
+
def read_in_flight_cal_data() -> pd.DataFrame:
|
|
138
113
|
"""
|
|
139
|
-
|
|
114
|
+
Read in-flight calibration data.
|
|
140
115
|
|
|
141
|
-
|
|
116
|
+
In-flight calibration data file will contain rows where each line
|
|
117
|
+
has 8 numbers, with the first being a time stamp in MET, and the next
|
|
118
|
+
7 being the factors for the 7 detectors.
|
|
142
119
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
120
|
+
This file will be updated weekly with new calibration data. In other
|
|
121
|
+
words, one line of data will be added each week to the existing file.
|
|
122
|
+
File will be in CSV format. Processing won't be kicked off until there
|
|
123
|
+
is in-flight calibration data that covers science data.
|
|
146
124
|
|
|
147
|
-
|
|
125
|
+
TODO: decide filename convention given this information. This function
|
|
126
|
+
is a placeholder for reading in the calibration data until we decide on
|
|
127
|
+
how to read calibration data through dependencies list.
|
|
148
128
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
129
|
+
Returns
|
|
130
|
+
-------
|
|
131
|
+
in_flight_cal_df : pandas.DataFrame
|
|
132
|
+
DataFrame with in-flight calibration data.
|
|
133
|
+
"""
|
|
134
|
+
# TODO: Read in in-flight calibration file.
|
|
153
135
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
| these points represent calibration measurements taken at different times.
|
|
157
|
-
| The function figures out which two calibration points are closest in time
|
|
158
|
-
| to the specific measurement time you're interested in.
|
|
136
|
+
# Define the column headers
|
|
137
|
+
columns = ["met_time", "cem1", "cem2", "cem3", "cem4", "cem5", "cem6", "cem7"]
|
|
159
138
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
| to make it more accurate, considering how the instrument's sensitivity changed
|
|
164
|
-
| between those two calibration points.
|
|
139
|
+
# Create an empty DataFrame with the specified columns
|
|
140
|
+
empty_df = pd.DataFrame(columns=columns)
|
|
141
|
+
return empty_df
|
|
165
142
|
|
|
166
|
-
| 4. **Returning the Correction Factor**: Finally, the function returns this
|
|
167
|
-
| correction factor. You can then use this factor to adjust or calibrate your
|
|
168
|
-
| measurements at the specific time you're interested in. This ensures that
|
|
169
|
-
| your measurements are as accurate as possible, taking into account the
|
|
170
|
-
| instrument's changing sensitivity over time.
|
|
171
143
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
Input time.
|
|
144
|
+
def calculate_calibration_factor(
|
|
145
|
+
acquisition_times: np.ndarray, cal_times: np.ndarray, cal_data: np.ndarray
|
|
146
|
+
) -> npt.NDArray:
|
|
176
147
|
"""
|
|
177
|
-
|
|
178
|
-
|
|
148
|
+
Calculate calibration factor using linear interpolation.
|
|
149
|
+
|
|
150
|
+
Steps to calculate calibration factor:
|
|
151
|
+
1. Convert input time to match time format in the calibration data file.
|
|
152
|
+
Both times should be in S/C MET time.
|
|
153
|
+
2. Find the nearest in time calibration data point.
|
|
154
|
+
3. Linear interpolate between those two nearest time and get factor for
|
|
155
|
+
input time.
|
|
179
156
|
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
acquisition_times : numpy.ndarray
|
|
160
|
+
Data points to interpolate. Shape is (24, 30).
|
|
161
|
+
cal_times : numpy.ndarray
|
|
162
|
+
X-coordinates data points. Calibration times. Shape is (n,).
|
|
163
|
+
cal_data : numpy.ndarray
|
|
164
|
+
Y-coordinates data points. Calibration data of corresponding cal_times.
|
|
165
|
+
Shape is (n, 7).
|
|
180
166
|
|
|
181
|
-
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
calibration_factor : numpy.ndarray
|
|
170
|
+
Calibration factor for each CEM detector. Shape is (24, 30, 7)
|
|
171
|
+
where last 7 dimension contains calibration factor for each CEM detector.
|
|
172
|
+
"""
|
|
173
|
+
# Raise error if there is no pre or post time in cal_times. SWE does not
|
|
174
|
+
# want to extrapolate calibration data.
|
|
175
|
+
if (
|
|
176
|
+
acquisition_times.min() < cal_times.min()
|
|
177
|
+
or acquisition_times.max() > cal_times.max()
|
|
178
|
+
):
|
|
179
|
+
error_msg = (
|
|
180
|
+
f"Acquisition min/max times: {acquisition_times.min()} to "
|
|
181
|
+
f"{acquisition_times.max()}. "
|
|
182
|
+
f"Calibration min/max times: {cal_times.min()} to {cal_times.max()}. "
|
|
183
|
+
"Acquisition times should be within calibration time range."
|
|
184
|
+
)
|
|
185
|
+
raise ValueError(error_msg)
|
|
186
|
+
|
|
187
|
+
# This line of code finds the indices of acquisition_times in cal_times where
|
|
188
|
+
# acquisition_times should be inserted to maintain order. As a result, it finds
|
|
189
|
+
# its nearest pre and post time from cal_times.
|
|
190
|
+
input_time_indices = np.searchsorted(cal_times, acquisition_times)
|
|
191
|
+
|
|
192
|
+
# Assign to a variable for better readability
|
|
193
|
+
x = acquisition_times
|
|
194
|
+
xp = cal_times
|
|
195
|
+
fp = cal_data
|
|
196
|
+
|
|
197
|
+
# Given this situation which will be the case for SWE data
|
|
198
|
+
# where data will fall in between two calibration times and
|
|
199
|
+
# not be exactly equal to any calibration time,
|
|
200
|
+
# >>> a = [1, 2, 3]
|
|
201
|
+
# >>> np.searchsorted(a, [2.5])
|
|
202
|
+
# array([2])
|
|
203
|
+
# we need to use (j - 1) to get pre time indices. (j-1) is
|
|
204
|
+
# pre time indices and j is post time indices.
|
|
205
|
+
j = input_time_indices
|
|
206
|
+
w = (x - xp[j - 1]) / (xp[j] - xp[j - 1])
|
|
207
|
+
return fp[j - 1] + w[..., None] * (fp[j] - fp[j - 1])
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def apply_in_flight_calibration(
|
|
211
|
+
corrected_counts: np.ndarray, acquisition_time: np.ndarray
|
|
212
|
+
) -> npt.NDArray:
|
|
182
213
|
"""
|
|
183
214
|
Apply in flight calibration to full cycle data.
|
|
184
215
|
|
|
@@ -188,12 +219,29 @@ def apply_in_flight_calibration(data: np.ndarray) -> None:
|
|
|
188
219
|
|
|
189
220
|
Parameters
|
|
190
221
|
----------
|
|
191
|
-
|
|
192
|
-
|
|
222
|
+
corrected_counts : numpy.ndarray
|
|
223
|
+
Corrected count of full cycle data. Data shape is (24, 30, 7).
|
|
224
|
+
acquisition_time : numpy.ndarray
|
|
225
|
+
Acquisition time of full cycle data. Data shape is (24, 30).
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
corrected_counts : numpy.ndarray
|
|
230
|
+
Corrected count of full cycle data after applying in-flight calibration.
|
|
231
|
+
Array shape is (24, 30, 7).
|
|
193
232
|
"""
|
|
194
|
-
#
|
|
195
|
-
|
|
196
|
-
|
|
233
|
+
# Read in in-flight calibration data
|
|
234
|
+
in_flight_cal_df = read_in_flight_cal_data()
|
|
235
|
+
# calculate calibration factor.
|
|
236
|
+
# return shape of calculate_calibration_factor is (24, 30, 7) where
|
|
237
|
+
# last 7 dimension contains calibration factor for each CEM detector.
|
|
238
|
+
cal_factor = calculate_calibration_factor(
|
|
239
|
+
acquisition_time,
|
|
240
|
+
in_flight_cal_df["met_time"].values,
|
|
241
|
+
in_flight_cal_df.iloc[:, 1:].values,
|
|
242
|
+
)
|
|
243
|
+
# Apply to full cycle data
|
|
244
|
+
return corrected_counts.astype(np.float64) * cal_factor
|
|
197
245
|
|
|
198
246
|
|
|
199
247
|
def populate_full_cycle_data(
|
|
@@ -231,7 +279,10 @@ def populate_full_cycle_data(
|
|
|
231
279
|
# to use in level 2 processing to calculate
|
|
232
280
|
# spin phase. This is done below by using information from
|
|
233
281
|
# science packet.
|
|
234
|
-
acquisition_times = np.zeros((energy_steps, angle
|
|
282
|
+
acquisition_times = np.zeros((energy_steps, angle))
|
|
283
|
+
|
|
284
|
+
# Store acquisition duration for later calculation in this function
|
|
285
|
+
acq_duration_arr = np.zeros((energy_steps, angle))
|
|
235
286
|
|
|
236
287
|
# Initialize esa_step_number and column_index.
|
|
237
288
|
# esa_step_number goes from 0 to 719 range where
|
|
@@ -249,19 +300,12 @@ def populate_full_cycle_data(
|
|
|
249
300
|
acq_duration = l1a_data["acq_duration"].data[packet_index + index]
|
|
250
301
|
settle_duration = l1a_data["settle_duration"].data[packet_index + index]
|
|
251
302
|
corrected_counts = deadtime_correction(decompressed_counts, acq_duration)
|
|
252
|
-
# Convert counts to rate
|
|
253
|
-
counts_rate = convert_counts_to_rate(corrected_counts, acq_duration)
|
|
254
303
|
|
|
255
304
|
# Each quarter cycle data should have same acquisition start time coarse
|
|
256
305
|
# and fine value. We will use that as base time to calculate each
|
|
257
|
-
# acquisition time for each count data.
|
|
258
|
-
# data point will be calculated using this formula:
|
|
306
|
+
# acquisition time for each count data.
|
|
259
307
|
# base_quarter_cycle_acq_time = acq_start_coarse +
|
|
260
308
|
# acq_start_fine / 1000000
|
|
261
|
-
# each_count_acq_time = base_quarter_cycle_acq_time +
|
|
262
|
-
# (step * ( acq_duration + settle_duration) / 1000 )
|
|
263
|
-
# where step goes from 0 to 179, acq_start_coarse is in seconds and
|
|
264
|
-
# acq_start_fine is in microseconds and acq_duration is in milliseconds.
|
|
265
309
|
base_quarter_cycle_acq_time = (
|
|
266
310
|
l1a_data["acq_start_coarse"].data[packet_index + index]
|
|
267
311
|
+ l1a_data["acq_start_fine"].data[packet_index + index] / 1000000
|
|
@@ -273,18 +317,27 @@ def populate_full_cycle_data(
|
|
|
273
317
|
# Get esa voltage value from esa lookup table and
|
|
274
318
|
# use that to get row index in full data array
|
|
275
319
|
esa_voltage_value = esa_lookup_table.loc[esa_step_number]["esa_v"]
|
|
276
|
-
esa_voltage_row_index =
|
|
320
|
+
esa_voltage_row_index = ESA_VOLTAGE_ROW_INDEX_DICT[esa_voltage_value]
|
|
277
321
|
|
|
278
322
|
# every six steps, increment column index
|
|
279
323
|
if esa_step_number % 6 == 0:
|
|
280
324
|
column_index += 1
|
|
281
325
|
# Put counts rate in full cycle data array
|
|
282
|
-
full_cycle_data[esa_voltage_row_index][column_index] =
|
|
283
|
-
|
|
326
|
+
full_cycle_data[esa_voltage_row_index][column_index] = corrected_counts[
|
|
327
|
+
step
|
|
328
|
+
]
|
|
329
|
+
# Acquisition time (in seconds) of each count data point will be
|
|
330
|
+
# using this formula:
|
|
331
|
+
# each_count_acq_time = base_quarter_cycle_acq_time +
|
|
332
|
+
# (step * ( acq_duration + settle_duration) / 1000000 )
|
|
333
|
+
# where step goes from 0 to 179, acq_start_coarse is in seconds and
|
|
334
|
+
# acq_start_fine is in microseconds and acq_duration is in microseconds.
|
|
284
335
|
acquisition_times[esa_voltage_row_index][column_index] = (
|
|
285
336
|
base_quarter_cycle_acq_time
|
|
286
|
-
+ (step * (acq_duration + settle_duration) /
|
|
337
|
+
+ (step * (acq_duration + settle_duration) / 1000000)
|
|
287
338
|
)
|
|
339
|
+
# Store acquisition duration for later calculation
|
|
340
|
+
acq_duration_arr[esa_voltage_row_index][column_index] = acq_duration
|
|
288
341
|
esa_step_number += 1
|
|
289
342
|
|
|
290
343
|
# reset column index for next quarter cycle
|
|
@@ -295,11 +348,17 @@ def populate_full_cycle_data(
|
|
|
295
348
|
# data. But for now, we are advice to continue with current setup and can
|
|
296
349
|
# add/change it when we get real data.
|
|
297
350
|
|
|
351
|
+
# Apply calibration based on in-flight calibration.
|
|
352
|
+
calibrated_counts = apply_in_flight_calibration(full_cycle_data, acquisition_times)
|
|
353
|
+
|
|
354
|
+
# Convert counts to rate
|
|
355
|
+
counts_rate = convert_counts_to_rate(calibrated_counts, acq_duration)
|
|
356
|
+
|
|
298
357
|
# Store count data and acquisition times of full cycle data in xr.Dataset
|
|
299
358
|
full_cycle_ds = xr.Dataset(
|
|
300
359
|
{
|
|
301
|
-
"full_cycle_data": (["
|
|
302
|
-
"
|
|
360
|
+
"full_cycle_data": (["esa_step", "spin_sector", "cem_id"], counts_rate),
|
|
361
|
+
"acquisition_time": (["esa_step", "spin_sector"], acquisition_times),
|
|
303
362
|
}
|
|
304
363
|
)
|
|
305
364
|
|
|
@@ -464,7 +523,7 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
464
523
|
|
|
465
524
|
# save full data array to file
|
|
466
525
|
full_cycle_science_data.append(full_cycle_ds["full_cycle_data"].data)
|
|
467
|
-
full_cycle_acq_times.append(full_cycle_ds["
|
|
526
|
+
full_cycle_acq_times.append(full_cycle_ds["acquisition_time"].data)
|
|
468
527
|
|
|
469
528
|
# ------------------------------------------------------------------
|
|
470
529
|
# Save data to dataset.
|
|
@@ -486,34 +545,34 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
486
545
|
attrs=cdf_attrs.get_variable_attributes("epoch"),
|
|
487
546
|
)
|
|
488
547
|
|
|
489
|
-
|
|
548
|
+
esa_step = xr.DataArray(
|
|
490
549
|
np.arange(24),
|
|
491
|
-
name="
|
|
492
|
-
dims=["
|
|
493
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
550
|
+
name="esa_step",
|
|
551
|
+
dims=["esa_step"],
|
|
552
|
+
attrs=cdf_attrs.get_variable_attributes("esa_step"),
|
|
494
553
|
)
|
|
495
554
|
|
|
496
555
|
# NOTE: LABL_PTR_1 should be CDF_CHAR.
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
name="
|
|
500
|
-
dims=["
|
|
501
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
556
|
+
esa_step_label = xr.DataArray(
|
|
557
|
+
esa_step.values.astype(str),
|
|
558
|
+
name="esa_step_label",
|
|
559
|
+
dims=["esa_step"],
|
|
560
|
+
attrs=cdf_attrs.get_variable_attributes("esa_step_label"),
|
|
502
561
|
)
|
|
503
562
|
|
|
504
|
-
|
|
563
|
+
spin_sector = xr.DataArray(
|
|
505
564
|
np.arange(30),
|
|
506
|
-
name="
|
|
507
|
-
dims=["
|
|
508
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
565
|
+
name="spin_sector",
|
|
566
|
+
dims=["spin_sector"],
|
|
567
|
+
attrs=cdf_attrs.get_variable_attributes("spin_sector"),
|
|
509
568
|
)
|
|
510
569
|
|
|
511
570
|
# NOTE: LABL_PTR_2 should be CDF_CHAR.
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
name="
|
|
515
|
-
dims=["
|
|
516
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
571
|
+
spin_sector_label = xr.DataArray(
|
|
572
|
+
spin_sector.values.astype(str),
|
|
573
|
+
name="spin_sector_label",
|
|
574
|
+
dims=["spin_sector"],
|
|
575
|
+
attrs=cdf_attrs.get_variable_attributes("spin_sector_label"),
|
|
517
576
|
)
|
|
518
577
|
|
|
519
578
|
cycle = xr.DataArray(
|
|
@@ -523,19 +582,19 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
523
582
|
attrs=cdf_attrs.get_variable_attributes("cycle"),
|
|
524
583
|
)
|
|
525
584
|
|
|
526
|
-
|
|
585
|
+
cem_id = xr.DataArray(
|
|
527
586
|
np.arange(7, dtype=np.float64),
|
|
528
|
-
name="
|
|
529
|
-
dims=["
|
|
530
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
587
|
+
name="cem_id",
|
|
588
|
+
dims=["cem_id"],
|
|
589
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id"),
|
|
531
590
|
)
|
|
532
591
|
|
|
533
592
|
# NOTE: LABL_PTR_3 should be CDF_CHAR.
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
name="
|
|
537
|
-
dims=["
|
|
538
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
593
|
+
cem_id_label = xr.DataArray(
|
|
594
|
+
cem_id.values.astype(str),
|
|
595
|
+
name="cem_id_label",
|
|
596
|
+
dims=["cem_id"],
|
|
597
|
+
attrs=cdf_attrs.get_variable_attributes("cem_id_label"),
|
|
539
598
|
)
|
|
540
599
|
|
|
541
600
|
# Add science data and it's associated metadata into dataset.
|
|
@@ -556,26 +615,26 @@ def swe_l1b_science(l1a_data: xr.Dataset, data_version: str) -> xr.Dataset:
|
|
|
556
615
|
dataset = xr.Dataset(
|
|
557
616
|
coords={
|
|
558
617
|
"epoch": epoch_time,
|
|
559
|
-
"
|
|
560
|
-
"
|
|
561
|
-
"
|
|
618
|
+
"esa_step": esa_step,
|
|
619
|
+
"spin_sector": spin_sector,
|
|
620
|
+
"cem_id": cem_id,
|
|
562
621
|
"cycle": cycle,
|
|
563
|
-
"
|
|
564
|
-
"
|
|
565
|
-
"
|
|
622
|
+
"esa_step_label": esa_step_label,
|
|
623
|
+
"spin_sector_label": spin_sector_label,
|
|
624
|
+
"cem_id_label": cem_id_label,
|
|
566
625
|
},
|
|
567
626
|
attrs=cdf_attrs.get_global_attributes("imap_swe_l1b_sci"),
|
|
568
627
|
)
|
|
569
628
|
|
|
570
629
|
dataset["science_data"] = xr.DataArray(
|
|
571
630
|
full_cycle_science_data,
|
|
572
|
-
dims=["epoch", "
|
|
631
|
+
dims=["epoch", "esa_step", "spin_sector", "cem_id"],
|
|
573
632
|
attrs=cdf_attrs.get_variable_attributes("science_data"),
|
|
574
633
|
)
|
|
575
|
-
dataset["
|
|
634
|
+
dataset["acquisition_time"] = xr.DataArray(
|
|
576
635
|
full_cycle_acq_times,
|
|
577
|
-
dims=["epoch", "
|
|
578
|
-
attrs=cdf_attrs.get_variable_attributes("
|
|
636
|
+
dims=["epoch", "esa_step", "spin_sector"],
|
|
637
|
+
attrs=cdf_attrs.get_variable_attributes("acquisition_time"),
|
|
579
638
|
)
|
|
580
639
|
|
|
581
640
|
# create xarray dataset for each metadata field
|