added data saving feature
This commit is contained in:
@@ -167,6 +167,55 @@ class SweepProcessorTest(unittest.TestCase):
|
||||
self.assertTrue(np.all(np.isfinite(result.real)))
|
||||
self.assertTrue(np.all(np.isfinite(result.imag)))
|
||||
|
||||
# -- cross-sweep branch tracking ------------------------------------------
|
||||
|
||||
def test_align_phase_branch_anchors_first_sweep_to_calibration(self) -> None:
|
||||
# No previous anchor yet -> snap onto the branch nearest phase0 (=0 here).
|
||||
processor = self._processor()
|
||||
phase = np.array([0.05, 1.0, 2.0]) + 2.0 * np.pi # one turn above phase0
|
||||
aligned, anchor = processor._align_phase_branch(phase)
|
||||
np.testing.assert_allclose(aligned, np.array([0.05, 1.0, 2.0]), atol=1e-9)
|
||||
self.assertAlmostEqual(anchor, 0.05, places=6)
|
||||
|
||||
def test_align_phase_branch_snaps_to_previous_anchor(self) -> None:
|
||||
# A genuine sub-pi float is preserved; a full-turn anchor wrap is undone.
|
||||
processor = self._processor()
|
||||
processor._previous_anchor_rad = 0.05
|
||||
kept, kept_anchor = processor._align_phase_branch(np.array([0.40, 1.4, 2.4]))
|
||||
np.testing.assert_allclose(kept, np.array([0.40, 1.4, 2.4]), atol=1e-9) # <pi: untouched
|
||||
self.assertAlmostEqual(kept_anchor, 0.40, places=6)
|
||||
wrapped, wrapped_anchor = processor._align_phase_branch(np.array([0.05, 1.0, 2.0]) - 2.0 * np.pi)
|
||||
np.testing.assert_allclose(wrapped, np.array([0.05, 1.0, 2.0]), atol=1e-9) # turn undone
|
||||
self.assertAlmostEqual(wrapped_anchor, 0.05, places=6)
|
||||
|
||||
def test_rejected_sweep_does_not_update_branch_tracker(self) -> None:
|
||||
# The anchor is committed only on accepted sweeps, so a rejected sweep
|
||||
# cannot latch the tracker onto a wrong branch.
|
||||
processor = self._processor()
|
||||
covering = _reference(np.linspace(0.0, 100.0, 401))
|
||||
self.assertIsNotNone(processor.process(np.abs(covering).astype(np.complex128), covering))
|
||||
anchor_after_accept = processor._previous_anchor_rad
|
||||
self.assertIsNotNone(anchor_after_accept)
|
||||
short = _reference(np.linspace(0.0, 40.0, 201)) # does not span the band
|
||||
self.assertIsNone(processor.process(np.ones(201, dtype=np.complex128), short))
|
||||
self.assertEqual(processor._previous_anchor_rad, anchor_after_accept)
|
||||
|
||||
def test_cross_sweep_unwrap_recovers_continuous_anchor_across_a_wrap(self) -> None:
|
||||
# Two physically adjacent sweeps whose anchor straddles +pi: np.angle wraps
|
||||
# the second's anchor by ~2*pi, but the cross-sweep tracking must recover
|
||||
# the continuous value (~3.3), not the wrapped one (~-2.98).
|
||||
processor = self._processor()
|
||||
ramp_home = np.linspace(3.0, 80.0, 401) # anchor 3.0 (< pi), covers band
|
||||
ramp_drift = np.linspace(3.3, 80.3, 401) # anchor 3.3 (> pi) -> angle wraps
|
||||
ref_home = _reference(ramp_home)
|
||||
ref_drift = _reference(ramp_drift)
|
||||
self.assertIsNotNone(processor.process(np.abs(ref_home).astype(np.complex128), ref_home))
|
||||
self.assertAlmostEqual(processor._previous_anchor_rad, 3.0, places=2)
|
||||
self.assertIsNotNone(processor.process(np.abs(ref_drift).astype(np.complex128), ref_drift))
|
||||
# Without correction this would be ~-2.98 (one turn below); corrected it
|
||||
# continues smoothly from 3.0 to ~3.3.
|
||||
self.assertAlmostEqual(processor._previous_anchor_rad, 3.3, places=2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user