1111from imap_processing .cdf .imap_cdf_manager import ImapCdfAttributes
1212from imap_processing .cdf .utils import load_cdf
1313from imap_processing .lo .l1b .lo_l1b import (
14+ DE_CLOCK_TICK_S ,
1415 calculate_de_rates ,
1516 calculate_histogram_rates ,
1617 calculate_star_sensor_profile_for_group ,
@@ -219,7 +220,9 @@ def l1a_hist():
219220 "imap_processing.lo.l1b.lo_l1b.cartesian_to_latitudinal" ,
220221 return_value = np .zeros ((2000 , 3 )),
221222)
223+ @patch ("imap_processing.lo.l1b.lo_l1b.interpolate_spin_data" )
222224def test_lo_l1b_de (
225+ mock_interpolate_spin_data ,
223226 mock_frame_transform ,
224227 mock_lo_instrument_pointing ,
225228 mocked_get_pointing_times ,
@@ -229,6 +232,15 @@ def test_lo_l1b_de(
229232 anc_dependencies ,
230233):
231234 # Arrange
235+ # Mock the spin data to provide spin start times
236+ # Create a DataFrame covering the time range of the test data
237+ num_events = 2000
238+ mock_spin_df = pd .DataFrame (
239+ {
240+ "spin_start_met" : np .ones (num_events ),
241+ }
242+ )
243+ mock_interpolate_spin_data .return_value = mock_spin_df
232244
233245 # Add l1b_nhk dependency with pivot angle information
234246 l1b_nhk = xr .Dataset (
@@ -490,94 +502,82 @@ def test_spin_cycle(mock_get_spin_number):
490502 np .testing .assert_array_equal (spin_cycle_data ["spin_cycle" ], spin_cycle_expected )
491503
492504
493- def test_get_spin_start_times ():
505+ @patch ("imap_processing.lo.l1b.lo_l1b.interpolate_spin_data" )
506+ def test_get_spin_start_times (mock_interpolate_spin_data ):
494507 # Arrange
495- l1b_de = xr .Dataset (
508+ # Mock the spin data to return specific spin start times
509+ mock_spin_df = pd .DataFrame (
496510 {
497- "spin_cycle" : ("epoch" , [0 , 1 , 2 , 3 , 4 ]),
498- },
499- coords = {
500- "epoch" : [
501- 0 ,
502- 1 ,
503- 2 ,
504- 3 ,
505- 4 ,
506- ]
507- },
511+ "spin_start_met" : [10.5 , 10.5 , 30.1 , 30.1 , 30.1 ],
512+ }
508513 )
514+ mock_interpolate_spin_data .return_value = mock_spin_df
515+
509516 l1a_de = xr .Dataset (
510517 {
511- "shcoarse" : ("epoch" , [0 , 1 ]),
518+ "shcoarse" : ("epoch" , [15 , 35 ]),
512519 "de_count" : ("epoch" , [2 , 3 ]),
513- "met" : ("epoch" , [0 , 1 ]), # MET per time epoch, not per direct event
514- "de_time" : ("direct_event" , [0000 , 1000 , 2000 , 3000 , 4000 ]),
520+ "de_time" : ("direct_event" , [0 , 1000 , 2000 , 3000 , 4000 ]),
515521 },
516522 coords = {"epoch" : [0 , 1 ], "direct_event" : [0 , 1 , 2 , 3 , 4 ]},
517523 )
518- spin = xr .Dataset (
519- {
520- "shcoarse" : ("epoch" , [0 , 1 ]),
521- "acq_start_sec" : (
522- "epoch" ,
523- [20 , 25 ],
524- ),
525- "acq_start_subsec" : (
526- "epoch" ,
527- [0 , 0 ],
528- ),
529- "acq_end_sec" : (
530- "epoch" ,
531- [25 , 30 ],
532- ),
533- "acq_end_subsec" : (
534- "epoch" ,
535- [0 , 0 ],
536- ),
537- "num_completed" : (
538- "epoch" ,
539- [28 , 14 ],
540- ),
541- }
542- )
543524
525+ # Expected: shcoarse 15 should match spin at index 0 (10 < 15 < 20)
526+ # shcoarse 35 should match spin at index 2 (30 < 35 < 40)
527+ # Repeated by de_count: [2, 3] -> [index0, index0, index2, index2, index2]
544528 spin_start_times_expected = np .array (
545- [20 , 20 + 5 / 28 , 25 + 5 * 2 / 14 , 25 + 5 * 3 / 14 , 25 + 5 * 4 / 14 ]
529+ [10.5 , 10.5 , 30.1 , 30.1 , 30.1 ] # 10 + 0.5e6*1e-6 # 30 + 0.1e6*1e-6
546530 )
547- spin_start_times = get_spin_start_times (l1a_de , l1b_de , spin )
548531
532+ # Act
533+ spin_start_times = get_spin_start_times (l1a_de )
534+
535+ # Assert
549536 np .testing .assert_allclose (
550537 spin_start_times ,
551538 spin_start_times_expected ,
552539 atol = 1e-4 ,
553540 )
554541
555542
556- def test_set_event_met ():
543+ @patch ("imap_processing.lo.l1b.lo_l1b.interpolate_spin_data" )
544+ def test_set_event_met (mock_interpolate_spin_data ):
557545 # Arrange
546+ # Mock the spin data
547+ mock_spin_df = pd .DataFrame (
548+ {
549+ "spin_start_met" : [10 , 10 , 30 , 30 , 30 ],
550+ }
551+ )
552+ mock_interpolate_spin_data .return_value = mock_spin_df
553+
558554 l1b_de = xr .Dataset ()
559555 l1a_de = xr .Dataset (
560556 {
557+ "shcoarse" : ("epoch" , [15 , 35 ]),
561558 "de_count" : ("epoch" , [2 , 3 ]),
562- "de_time" : ("direct_event" , [0000 , 1000 , 2000 , 3000 , 4000 ]),
559+ "de_time" : ("direct_event" , [0 , 1000 , 2000 , 3000 , 4000 ]),
563560 },
564561 coords = {
565562 "epoch" : [0 , 1 ],
566- "direct_event" : [
567- 0 ,
568- 1 ,
569- 2 ,
570- 3 ,
571- 4 ,
572- ],
563+ "direct_event" : [0 , 1 , 2 , 3 , 4 ],
573564 },
574565 )
575- avg_spin_durations = xr .DataArray ([5 , 10 ])
576- spin_start_times = xr .DataArray ([10 , 20 , 30 , 40 , 50 ])
577- expected_event_met = np .array ([10 , 21.2207 , 34.8828 , 47.3242 , 59.7656 ])
566+
567+ # shcoarse 15 -> spin_start 10, shcoarse 35 -> spin_start 30
568+ # event_met = spin_start + de_time * DE_CLOCK_TICK_S
569+ expected_event_met = np .array (
570+ [
571+ 10 + 0 * DE_CLOCK_TICK_S , # 10.0
572+ 10 + 1000 * DE_CLOCK_TICK_S , # 14.096
573+ 30 + 2000 * DE_CLOCK_TICK_S , # 38.192
574+ 30 + 3000 * DE_CLOCK_TICK_S , # 42.288
575+ 30 + 4000 * DE_CLOCK_TICK_S , # 46.384
576+ ]
577+ )
578578
579579 # Act
580- l1b_de = set_event_met (l1a_de , l1b_de , spin_start_times , avg_spin_durations )
580+ l1b_de = set_event_met (l1a_de , l1b_de )
581581
582582 # Assert
583583 np .testing .assert_allclose (
@@ -586,24 +586,25 @@ def test_set_event_met():
586586 atol = 1e-4 ,
587587 )
588588
589- def test_set_each_event_epoch ():
590- l1b_de = xr .Dataset (
591- {
592- "event_met" : ("epoch" , [10 , 20 , 30 , 40 , 50 ]),
593- },
594- coords = {
595- "epoch" : [0 , 1 , 2 , 3 , 4 ],
596- },
597- )
598- epoch_expected = met_to_ttj2000ns (np .array ([10 , 20 , 30 , 40 , 50 ]))
599589
600- l1b_de = set_each_event_epoch (l1b_de )
590+ def test_set_each_event_epoch ():
591+ l1b_de = xr .Dataset (
592+ {
593+ "event_met" : ("epoch" , [10 , 20 , 30 , 40 , 50 ]),
594+ },
595+ coords = {
596+ "epoch" : [0 , 1 , 2 , 3 , 4 ],
597+ },
598+ )
599+ epoch_expected = met_to_ttj2000ns (np .array ([10 , 20 , 30 , 40 , 50 ]))
601600
602- np .testing .assert_allclose (
603- l1b_de ["epoch" ].values ,
604- epoch_expected ,
605- atol = 1e-4 ,
606- )
601+ l1b_de = set_each_event_epoch (l1b_de )
602+
603+ np .testing .assert_allclose (
604+ l1b_de ["epoch" ].values ,
605+ epoch_expected ,
606+ atol = 1e-4 ,
607+ )
607608
608609
609610def test_set_avg_spin_durations_per_event ():
@@ -838,6 +839,8 @@ def test_set_direction(mock_lo_instrument_pointing, imap_ena_sim_metakernel):
838839)
839840@patch (
840841 "imap_processing.lo.l1b.lo_l1b.cartesian_to_latitudinal" ,
842+ # Longitudes: -180 -> 180, 0 -> 0, 90 -> 90, 180 -> 180
843+ # After shift to 0-360: 180, 0, 90, 180
841844 return_value = np .array ([[0 , - 180 , - 2 ], [0 , 0 , 0 ], [0 , 90 , 1 ], [0 , 180 , 2 ]]),
842845)
843846def test_pointing_bins (mock_cartesian_to_latitudinal , mock_frame_transform ):
@@ -859,7 +862,8 @@ def test_pointing_bins(mock_cartesian_to_latitudinal, mock_frame_transform):
859862 )
860863
861864 expected_pointing_lats = np .array ([0 , 20 , 30 , 40 ])
862- expected_pointing_lons = np .array ([0 , 1800 , 2700 , 3600 ])
865+ # Longitude bins are now in 0-360 range after the shift
866+ expected_pointing_lons = np .array ([1800 , 0 , 900 , 1800 ])
863867
864868 # Act
865869 l1b_de = set_pointing_bin (l1b_de )
0 commit comments