3939
4040logger = logging .getLogger (__name__ )
4141
42+ DE_CLOCK_TICK_S = 4.096e-3 # seconds per DE clock tick
43+
4244
4345def lo_l1b (
4446 sci_dependencies : dict , anc_dependencies : list , descriptor : str
@@ -149,13 +151,9 @@ def l1b_de(
149151 avg_spin_durations_per_cycle = get_avg_spin_durations_per_cycle (spin_data )
150152 # set the spin cycle for each direct event
151153 l1b_de = set_spin_cycle (pointing_start_met , l1a_de , l1b_de )
152- # get spin start times for each event
153- spin_start_time = get_spin_start_times (l1a_de , l1b_de , spin_data )
154154
155155 # get the absolute met for each event
156- l1b_de = set_event_met (
157- l1a_de , l1b_de , spin_start_time , avg_spin_durations_per_cycle
158- )
156+ l1b_de = set_event_met (l1a_de , l1b_de )
159157 # set the epoch for each event
160158 l1b_de = set_each_event_epoch (l1b_de )
161159 # Set the ESA mode for each direct event
@@ -662,7 +660,7 @@ def _check_sufficient_spins(spin_data: xr.Dataset) -> np.ndarray:
662660
663661
664662def get_spin_start_times (
665- l1a_de : xr .Dataset , l1b_de : xr . Dataset , spin_data : xr . Dataset
663+ l1a_de : xr .Dataset ,
666664) -> xr .DataArray :
667665 """
668666 Get the start time for the spin that each direct event is in.
@@ -675,59 +673,51 @@ def get_spin_start_times(
675673 ----------
676674 l1a_de : xr.Dataset
677675 The L1A DE dataset.
678- l1b_de : xr.Dataset
679- The L1B DE dataset.
680- spin_data : xr.Dataset
681- The L1A Spin dataset.
682676
683677 Returns
684678 -------
685679 spin_start_time : xr.DataArray
686680 The start time for the spin that each direct event is in.
687681 """
688- # align l1a_de packets with spin_data packets
689- de_to_spin_indices = match_science_to_spin_asc (
690- l1a_de ["epoch" ].values , spin_data ["epoch" ].values
682+ # Get the actual spin start times from the spin data
683+ # Use the individual spin start times rather than calculating from ASC averages
684+ spin_df = get_spin_data ()
685+
686+ # For each direct event, find the closest spin start time
687+ # based on the DE's shcoarse time
688+ de_shcoarse = l1a_de ["shcoarse" ].values
689+ spin_start_sec = spin_df ["spin_start_sec_sclk" ].values
690+
691+ # Find the index of the closest spin start for each direct event
692+ # We want the closest prior spin (spin that has already started)
693+ closest_spin_indices = (
694+ np .searchsorted (spin_start_sec , de_shcoarse , side = "right" ) - 1
691695 )
692- # Repeat this for each direct event based on the de_count
693- de_to_spin_indices = np .repeat (de_to_spin_indices , l1a_de ["de_count" ])
694696
695- # There are 28 spins per epoch (1 aggregated science cycle)
696- # Set the spin_cycle_num to the spin number relative to the
697- # start of the ASC
698- spin_cycle_num = l1b_de ["spin_cycle" ] % 28
699- asc_starts = spin_data ["acq_start_sec" ] + spin_data ["acq_start_subsec" ] * 1e-6
700- avg_spin_durations = get_avg_spin_durations_per_cycle (spin_data )
697+ # Clip to valid range to handle edge cases
698+ closest_spin_indices = np .clip (closest_spin_indices , 0 , len (spin_df ) - 1 )
701699
702- # Calculate the time based off of the start of the acquisition period
703- # then using an average spin duration to calculate the offset within the ASC
704- # NOTE: We don't want to use the spin start times directly from the ASC spin packet
705- # because we are using an average spin_cycle for the ASC and there are
706- # times when only half the spins were completed in an ASC. This allows us
707- # to still get a valid spin_cycle start time for each direct event, even
708- # if the average spin_cycle was after the end of the acquisition period.
709- # TODO: Can we do even better by knowing how many esa_steps and spins were complete?
710- # i.e. change the spin_cycle calculation
711- spin_start_time = (
712- asc_starts [de_to_spin_indices ]
713- + spin_cycle_num * avg_spin_durations [de_to_spin_indices ]
700+ spin_start_times = (
701+ spin_df ["spin_start_sec_sclk" ].values [closest_spin_indices ]
702+ + spin_df ["spin_start_subsec_sclk" ].values [closest_spin_indices ] * 1e-6
714703 )
715- return spin_start_time
704+
705+ # repeat out to number of direct events
706+ spin_start_times = np .repeat (spin_start_times , l1a_de ["de_count" ].values )
707+
708+ return spin_start_times
716709
717710
718711def set_event_met (
719712 l1a_de : xr .Dataset ,
720713 l1b_de : xr .Dataset ,
721- spin_start_time : xr .DataArray ,
722- avg_spin_durations : xr .DataArray ,
723714) -> xr .Dataset :
724715 """
725716 Get the event MET for each direct event.
726717
727718 Each direct event is converted from a data number to engineering unit in seconds.
728- de_eu_time de_dn_time / 4096 * avg_spin_duration
729- where de_time is the direct event time Data Number (DN) and avg_spin_duration
730- is the average spin duration for the ASC that the event was measured in.
719+ time_from_start_of_spin = de_time * DE_CLOCK_TICK_S
720+ where de_time is the direct event time Data Number (DN).
731721
732722 The direct event time is the time of direct event relative to the start of the spin.
733723 The event MET is the sum of the start time of the spin and the
@@ -739,26 +729,18 @@ def set_event_met(
739729 The L1A DE dataset.
740730 l1b_de : xr.Dataset
741731 The L1B DE dataset.
742- spin_start_time : np.ndarray
743- The start time for the spin that each direct event is in.
744- avg_spin_durations : xr.DataArray
745- The average spin duration for each epoch.
746732
747733 Returns
748734 -------
749735 l1b_de : xr.Dataset
750736 The L1B DE dataset with the event MET.
751737 """
752- counts = l1a_de ["de_count" ].values
753- de_time_asc_groups = np .split (l1a_de ["de_time" ].values , np .cumsum (counts )[:- 1 ])
754- de_times_eu = []
755- for i , de_time_asc in enumerate (de_time_asc_groups ):
756- # DE Time is 12 bit DN. The max possible value is 4095
757- # divide by 4096 to get fraction of a spin duration
758- de_times_eu .extend (de_time_asc / 4096 * avg_spin_durations [i ].values )
738+ # get spin start times for each event
739+ spin_start_times = get_spin_start_times (l1a_de )
759740
741+ # spin start + offset based on de_time ticks
760742 l1b_de ["event_met" ] = xr .DataArray (
761- spin_start_time + de_times_eu ,
743+ spin_start_times + l1a_de [ "de_time" ]. values * DE_CLOCK_TICK_S ,
762744 dims = ["epoch" ],
763745 # attrs=attr_mgr.get_variable_attributes("epoch")
764746 )
@@ -1212,12 +1194,14 @@ def set_pointing_bin(l1b_de: xr.Dataset) -> xr.Dataset:
12121194 # first column: radius (Not needed)
12131195 # second column: longitude
12141196 lons = direction [:, 1 ]
1197+ # shift to 0-360 range (spin-phase 0 should be in bin 0)
1198+ lons = (lons + 360 ) % 360
12151199 # third column: latitude
12161200 lats = direction [:, 2 ]
12171201
12181202 # Define bin edges
12191203 # 3600 bins, 0.1° each
1220- lon_bins = np .linspace (- 180 , 180 , 3601 )
1204+ lon_bins = np .linspace (0 , 360 , 3601 )
12211205 # 40 bins, 0.1° each
12221206 lat_bins = np .linspace (- 2 , 2 , 41 )
12231207
0 commit comments