diff --git a/pyspedas/elfin/epd/calibration.py b/pyspedas/elfin/epd/calibration_l1.py similarity index 100% rename from pyspedas/elfin/epd/calibration.py rename to pyspedas/elfin/epd/calibration_l1.py diff --git a/pyspedas/elfin/epd/epd.py b/pyspedas/elfin/epd/epd.py index 26c0af33..58a0bd64 100644 --- a/pyspedas/elfin/epd/epd.py +++ b/pyspedas/elfin/epd/epd.py @@ -18,7 +18,6 @@ def elfin_load_epd(trange=['2020-11-01', '2020-11-02'], no_update=False, time_clip=True, nspinsinsum=None, - no_spec=False, fullspin=False, PAspec_energies=None, PAspec_energybins=None, @@ -88,6 +87,34 @@ def elfin_load_epd(trange=['2020-11-01', '2020-11-02'], If true, generate full spin with l2 epd instead of half spin Default is False + PAspec_energybins: list of tuple of int, optional + Specified the energy bins used for generating l2 pitch angle spectra. + Default is [(0,2),(3,5), (6,8), (9,15)]. If both 'PAspec_energybins' and 'PAspec_energies' + are set, 'energybins' takes precedence + + PAspec_energies: list of tuple of float, optional + Specifies the energy range for each bin in the l2 pitch angle spectra. + Example: energies=[(50.,160.),(160.,345.),(345.,900.),(900.,7000.)] + If both 'energybins' and 'energies' are set, 'energybins' takes precedence. + Energy and energybin table: + channel energy_range energy_midbin + 0 50-80 63.2 + 1 80-120 97.9 + 2 120-160 138.5 + 3 160-210 183.3 + 4 210-270 238.1 + 5 270-345 305.2 + 6 345-430 385.1 + 7 430-630 520.4 + 8 630-900 752.9 + 9 900-1300 1081.6 + 10 1300-1800 1529.7 + 11 1800-2500 2121.3 + 12 2500-3350 2893.9 + 13 3350-4150 3728.6 + 14 4150-5800 4906.1 + 15 5800+ 6500.0 + Returns ---------- List of tplot variables created. @@ -113,7 +140,7 @@ def elfin_load_epd(trange=['2020-11-01', '2020-11-02'], if level == "l1": return epd_l1_postprocessing(tvars, trange=trange, type_=type_, nspinsinsum=nspinsinsum, - unit=CALIBRATED_TYPE_UNITS[type_], no_spec=no_spec) + unit=CALIBRATED_TYPE_UNITS[type_]) elif level == "l2": logging.info("ELFIN EPD L2: START PROCESSING.") # check whether input type is allowed diff --git a/pyspedas/elfin/epd/postprocessing.py b/pyspedas/elfin/epd/postprocessing.py index 086b1f21..c0bd7e61 100644 --- a/pyspedas/elfin/epd/postprocessing.py +++ b/pyspedas/elfin/epd/postprocessing.py @@ -4,7 +4,7 @@ from pyspedas.analysis.time_clip import time_clip as tclip from pyspedas.elfin.epd.calibration_l2 import epd_l2_Espectra, epd_l2_PAspectra -from pyspedas.elfin.epd.calibration import calibrate_epd +from pyspedas.elfin.epd.calibration_l1 import calibrate_epd def epd_l1_postprocessing( tplotnames, @@ -12,7 +12,6 @@ def epd_l1_postprocessing( type_=None, nspinsinsum=None, unit=None, - no_spec=False, ): """ Calibrates data from the Energetic Particle Detector (EPD) and sets dlimits. @@ -36,9 +35,6 @@ def epd_l1_postprocessing( unit : str, optional Units of the data. - no_spec : bool - Flag to set tplot options to linear rather than the default of spec. - Default is False. Returns ---------- @@ -132,6 +128,33 @@ def epd_l2_postprocessing( Options: 'e' for electron data, 'i' for ion data Default is 'e'. + PAspec_energybins: list of tuple of int, optional + Specified the energy bins used for generating l2 pitch angle spectra. + Default is [(0,2),(3,5), (6,8), (9,15)]. If both 'PAspec_energybins' and 'PAspec_energies' + are set, 'energybins' takes precedence + + PAspec_energies: list of tuple of float, optional + Specifies the energy range for each bin in the l2 pitch angle spectra. + Example: energies=[(50.,160.),(160.,345.),(345.,900.),(900.,7000.)] + If both 'energybins' and 'energies' are set, 'energybins' takes precedence. + Energy and energybin table: + channel energy_range energy_midbin + 0 50-80 63.2 + 1 80-120 97.9 + 2 120-160 138.5 + 3 160-210 183.3 + 4 210-270 238.1 + 5 270-345 305.2 + 6 345-430 385.1 + 7 430-630 520.4 + 8 630-900 752.9 + 9 900-1300 1081.6 + 10 1300-1800 1529.7 + 11 1800-2500 2121.3 + 12 2500-3350 2893.9 + 13 3350-4150 3728.6 + 14 4150-5800 4906.1 + 15 5800+ 6500.0 Returns ---------- diff --git a/pyspedas/elfin/tests/test_epd_calibration.py b/pyspedas/elfin/tests/test_epd_calibration.py index e440139a..32121caf 100644 --- a/pyspedas/elfin/tests/test_epd_calibration.py +++ b/pyspedas/elfin/tests/test_epd_calibration.py @@ -1,7 +1,7 @@ import unittest import importlib.resources -from pyspedas.elfin.epd.calibration import read_epde_calibration_data +from pyspedas.elfin.epd.calibration_l1 import read_epde_calibration_data EXPECTED_EPDE_CAL_DATA = [ {'ch_efficiencies': [0.74, 0.8, 0.85, 0.86, 0.87, 0.87, 0.87, 0.87, 0.82, 0.8, 0.75, 0.6, 0.5, 0.45, 0.25, 0.05], diff --git a/pyspedas/elfin/tests/test_epd_l2_spectrogram.py b/pyspedas/elfin/tests/test_epd_l2_spectrogram.py index fe84fc2e..57cdfa84 100644 --- a/pyspedas/elfin/tests/test_epd_l2_spectrogram.py +++ b/pyspedas/elfin/tests/test_epd_l2_spectrogram.py @@ -24,13 +24,15 @@ def setUpClass(cls): # 3. add download file from server # Testing time range - cls.t = ['2022-08-03/08:30:00','2022-08-03/09:00:00'] + #cls.t = ['2022-08-03/08:30:00','2022-08-03/09:00:00'] #cls.probe = 'a' - #cls.t = ['2021-04-26/00:34:18','2021-04-26/00:40:18'] - #cls.probe = 'b' + #cls.t = ['2022-04-12/19:00:00','2022-04-12/19:15:00'] + cls.t = ['2022-04-13/01:28:00','2022-04-13/01:35:00'] + cls.probe = 'b' #cls.t = ['2022-08-28/15:54','2022-08-28/16:15'] - cls.probe = 'a' + #cls.probe = 'a' # Load state validation variables from the test file + filename = f"elfin_data/validation_el{cls.probe}_state_{cls.t[0][0:4]+cls.t[0][5:7]+cls.t[0][8:10]}.tplot" tplot_restore(filename) cls.elf_pos_gei = pytplot.get_data(f"el{cls.probe}_pos_gei") @@ -80,8 +82,6 @@ def setUpClass(cls): tplot_restore(filename) cls.elf_pef_fs_nflux_ch0 = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_ch0") cls.elf_pef_fs_nflux_ch1 = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_ch1") - cls.elf_pef_fs_nflux_ch2 = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_ch2") - cls.elf_pef_fs_nflux_ch3 = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_ch3") cls.elf_pef_fs_nflux_omni = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_omni") cls.elf_pef_fs_nflux_para = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_para") cls.elf_pef_fs_nflux_anti = pytplot.get_data(f"el{cls.probe}_pef_fs_nflux_anti") @@ -120,7 +120,7 @@ def test_state(self): elf_att_spinper = pytplot.get_data(f"el{self.probe}_att_spinper") elf_spin_orbnorm = pytplot.get_data(f"el{self.probe}_spin_orbnorm_angle") elf_spin_sun = pytplot.get_data(f"el{self.probe}_spin_sun_angle") - + assert_array_almost_equal(elf_pos_gei.y, self.elf_pos_gei.y, decimal=4) assert_array_almost_equal(elf_vel_gei.y, self.elf_vel_gei.y, decimal=4) assert_array_almost_equal(elf_att_gei.y, self.elf_att_gei.y, decimal=2) @@ -149,14 +149,14 @@ def test_epd_l2_hs_nflux(self): elf_pef_hs_Epat_nflux = pytplot.get_data(f"el{self.probe}_pef_hs_Epat_nflux") elf_pef_Et_nflux = pytplot.get_data(f"el{self.probe}_pef_Et_nflux") elf_pef_pa = pytplot.get_data(f"el{self.probe}_pef_pa") - - assert_array_almost_equal(elf_pef_hs_Epat_nflux.v1, self.elf_pef_hs_Epat_nflux_ch1.v, decimal=1) - assert_array_almost_equal(elf_pef_hs_Epat_nflux.y[:,:,0], self.elf_pef_hs_Epat_nflux_ch0.y, decimal=1) - assert_array_almost_equal(elf_pef_hs_Epat_nflux.y[:,:,1], self.elf_pef_hs_Epat_nflux_ch1.y, decimal=1) - assert_array_almost_equal(elf_pef_hs_LCdeg.y, self.elf_pef_hs_LCdeg.y, decimal=1) - assert_array_almost_equal(elf_pef_hs_antiLCdeg.y, self.elf_pef_hs_antiLCdeg.y, decimal=1) - assert_array_almost_equal(elf_pef_pa.y, self.elf_pef_pa.y, decimal=1) - assert_allclose(elf_pef_Et_nflux.y, self.elf_pef_Et_nflux.y, rtol=1e-03) + + assert_allclose(elf_pef_hs_Epat_nflux.v1, self.elf_pef_hs_Epat_nflux_ch1.v[0:251,:], rtol=1e-02) + assert_allclose(elf_pef_hs_Epat_nflux.y[:,:,0], self.elf_pef_hs_Epat_nflux_ch0.y, rtol=1e-02) + assert_allclose(elf_pef_hs_Epat_nflux.y[:,:,1], self.elf_pef_hs_Epat_nflux_ch1.y, rtol=1e-02) + assert_allclose(elf_pef_hs_LCdeg.y, self.elf_pef_hs_LCdeg.y, rtol=1e-02) + assert_allclose(elf_pef_hs_antiLCdeg.y, self.elf_pef_hs_antiLCdeg.y, rtol=1e-02) + assert_allclose(elf_pef_pa.y, self.elf_pef_pa.y, rtol=1e-02) + assert_allclose(elf_pef_Et_nflux.y, self.elf_pef_Et_nflux.y, rtol=1e-02) assert_allclose(elf_pef_hs_nflux_omni.y, self.elf_pef_hs_nflux_omni.y, rtol=1e-02) assert_allclose(elf_pef_hs_nflux_para.y, self.elf_pef_hs_nflux_para.y, rtol=1e-02) assert_allclose(elf_pef_hs_nflux_anti.y, self.elf_pef_hs_nflux_anti.y, rtol=1e-02) @@ -191,14 +191,14 @@ def test_epd_l2_hs_eflux(self): elf_pef_hs_Epat_eflux = pytplot.get_data(f"el{self.probe}_pef_hs_Epat_eflux") elf_pef_Et_eflux = pytplot.get_data(f"el{self.probe}_pef_Et_eflux") - assert_array_almost_equal(elf_pef_hs_Epat_eflux.v1, self.elf_pef_hs_Epat_eflux_ch1.v, decimal=1) - assert_array_almost_equal(elf_pef_hs_Epat_eflux.y[:,:,0], self.elf_pef_hs_Epat_eflux_ch0.y, decimal=1) - assert_array_almost_equal(elf_pef_hs_Epat_eflux.y[:,:,1], self.elf_pef_hs_Epat_eflux_ch1.y, decimal=1) - assert_allclose(elf_pef_Et_eflux.y, self.elf_pef_Et_eflux.y, rtol=1e-03) - assert_allclose(elf_pef_hs_eflux_omni.y, self.elf_pef_hs_eflux_omni.y, rtol=1e-02) - assert_allclose(elf_pef_hs_eflux_para.y, self.elf_pef_hs_eflux_para.y, rtol=1e-02) - assert_allclose(elf_pef_hs_eflux_anti.y, self.elf_pef_hs_eflux_anti.y, rtol=1e-02) - assert_allclose(elf_pef_hs_eflux_perp.y, self.elf_pef_hs_eflux_perp.y, rtol=1e-02) + assert_allclose(elf_pef_hs_Epat_eflux.v1, self.elf_pef_hs_Epat_eflux_ch1.v, rtol=1e-02) + assert_allclose(elf_pef_hs_Epat_eflux.y[:,:,0], self.elf_pef_hs_Epat_eflux_ch0.y, rtol=1e-02) + assert_allclose(elf_pef_hs_Epat_eflux.y[:,:,1], self.elf_pef_hs_Epat_eflux_ch1.y, rtol=1e-02) + assert_allclose(elf_pef_Et_eflux.y, self.elf_pef_Et_eflux.y, rtol=1e-02) + assert_allclose(elf_pef_hs_eflux_omni.y, self.elf_pef_hs_eflux_omni.y, rtol=2e-02) + assert_allclose(elf_pef_hs_eflux_para.y, self.elf_pef_hs_eflux_para.y, rtol=2e-02) + assert_allclose(elf_pef_hs_eflux_anti.y, self.elf_pef_hs_eflux_anti.y, rtol=2e-02) + assert_allclose(elf_pef_hs_eflux_perp.y, self.elf_pef_hs_eflux_perp.y, rtol=2e-02) # test pa spectogram ch0 spec2plot, pas2plot = spec_pa_sort(self.elf_pef_hs_eflux_ch0.y, self.elf_pef_hs_eflux_ch0.v) # idl variable use aceding and decending pa assert_allclose(elf_pef_hs_eflux_ch0.y, spec2plot, rtol=1e-02) @@ -227,8 +227,6 @@ def test_epd_l2_fs_nflux(self): ) elf_pef_fs_nflux_ch0 = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_ch0") elf_pef_fs_nflux_ch1 = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_ch1") - elf_pef_fs_nflux_ch2 = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_ch2") - elf_pef_fs_nflux_ch3 = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_ch3") elf_pef_fs_nflux_perp = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_perp") elf_pef_fs_nflux_anti = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_anti") elf_pef_fs_nflux_para = pytplot.get_data(f"el{self.probe}_pef_fs_nflux_para") @@ -237,11 +235,11 @@ def test_epd_l2_fs_nflux(self): elf_pef_fs_LCdeg = pytplot.get_data(f"el{self.probe}_pef_fs_LCdeg") elf_pef_fs_Epat_nflux = pytplot.get_data(f"el{self.probe}_pef_fs_Epat_nflux") - assert_array_almost_equal(elf_pef_fs_Epat_nflux.v1, self.elf_pef_fs_Epat_nflux_ch1.v, decimal=1) - assert_array_almost_equal(elf_pef_fs_Epat_nflux.y[:,:,0], self.elf_pef_fs_Epat_nflux_ch0.y, decimal=1) - assert_array_almost_equal(elf_pef_fs_Epat_nflux.y[:,:,1], self.elf_pef_fs_Epat_nflux_ch1.y, decimal=1) - assert_array_almost_equal(elf_pef_fs_LCdeg.y, self.elf_pef_fs_LCdeg.y, decimal=1) - assert_array_almost_equal(elf_pef_fs_antiLCdeg.y, self.elf_pef_fs_antiLCdeg.y, decimal=1) + assert_allclose(elf_pef_fs_Epat_nflux.v1, self.elf_pef_fs_Epat_nflux_ch1.v, rtol=1e-02) + assert_allclose(elf_pef_fs_Epat_nflux.y[:,:,0], self.elf_pef_fs_Epat_nflux_ch0.y, rtol=1e-02) + assert_allclose(elf_pef_fs_Epat_nflux.y[:,:,1], self.elf_pef_fs_Epat_nflux_ch1.y, rtol=1e-02) + assert_allclose(elf_pef_fs_LCdeg.y, self.elf_pef_fs_LCdeg.y, rtol=1e-02) + assert_allclose(elf_pef_fs_antiLCdeg.y, self.elf_pef_fs_antiLCdeg.y, rtol=1e-02) assert_allclose(elf_pef_fs_nflux_omni.y, self.elf_pef_fs_nflux_omni.y, rtol=1e-02) assert_allclose(elf_pef_fs_nflux_para.y, self.elf_pef_fs_nflux_para.y, rtol=1e-02) assert_allclose(elf_pef_fs_nflux_anti.y, self.elf_pef_fs_nflux_anti.y, rtol=1e-02) @@ -274,10 +272,10 @@ def test_epd_l2_fs_eflux(self): elf_pef_fs_eflux_para = pytplot.get_data(f"el{self.probe}_pef_fs_eflux_para") elf_pef_fs_eflux_omni = pytplot.get_data(f"el{self.probe}_pef_fs_eflux_omni") elf_pef_fs_Epat_eflux = pytplot.get_data(f"el{self.probe}_pef_fs_Epat_eflux") - - assert_array_almost_equal(elf_pef_fs_Epat_eflux.v1, self.elf_pef_fs_Epat_eflux_ch1.v, decimal=1) - assert_array_almost_equal(elf_pef_fs_Epat_eflux.y[:,:,0], self.elf_pef_fs_Epat_eflux_ch0.y, decimal=1) - assert_array_almost_equal(elf_pef_fs_Epat_eflux.y[:,:,1], self.elf_pef_fs_Epat_eflux_ch1.y, decimal=1) + + assert_allclose(elf_pef_fs_Epat_eflux.v1, self.elf_pef_fs_Epat_eflux_ch1.v, rtol=1e-02) + assert_allclose(elf_pef_fs_Epat_eflux.y[:,:,0], self.elf_pef_fs_Epat_eflux_ch0.y, rtol=1e-02) + assert_allclose(elf_pef_fs_Epat_eflux.y[:,:,1], self.elf_pef_fs_Epat_eflux_ch1.y, rtol=1e-02) assert_allclose(elf_pef_fs_eflux_omni.y, self.elf_pef_fs_eflux_omni.y, rtol=1e-02) assert_allclose(elf_pef_fs_eflux_para.y, self.elf_pef_fs_eflux_para.y, rtol=1e-02) assert_allclose(elf_pef_fs_eflux_anti.y, self.elf_pef_fs_eflux_anti.y, rtol=1e-02)