Skip to content

Add pseudo-orbit BPM reading mode#28

Open
thellert wants to merge 5 commits intokparasch:developfrom
als-apg:feature/pseudo-orbit
Open

Add pseudo-orbit BPM reading mode#28
thellert wants to merge 5 commits intokparasch:developfrom
als-apg:feature/pseudo-orbit

Conversation

@thellert
Copy link
Copy Markdown

Summary

  • Adds BPMSystem.capture_pseudo_orbit() — injects, tracks N turns, averages per-BPM across turns via nanmean. Returns (n_bpms,) arrays matching orbit interface shape.
  • Adds pySCPseudoOrbitInterface that plugs directly into orbit_correction() using the orbit response matrix.
  • Extends Tuning.correct_orbit() with pseudo=True, n_turns=N — one-flag switch from closed-orbit to pseudo-orbit correction.
  • Fixes pre-existing np.concatnp.concatenate bug in fit_dispersive_orbit().
  • Removes the commented-out correct_pseudo_orbit_at_injection prototype.

Motivation

Pseudo-orbit is the natural reading mode between TBT (beam threading) and closed-orbit (stable operation). After stitching achieves multi-turn survival, pseudo-orbit averages out turn-by-turn jitter to give a smoother correction target. This is needed for ALSU accumulator ring commissioning.

@kparasch — I'm open to alternative implementations of this feature, but pseudo-orbit as a first-class reading mode is something we definitely need for ALSU commissioning. It would be nice to have a convenient high-level function for this in pySC. Happy to iterate on the API if you have preferences.

Usage

# Direct reading
x, y = SC.bpm_system.capture_pseudo_orbit(n_turns=20)

# Via interface (for custom correction loops)
from pySC.tuning.pySC_interface import pySCPseudoOrbitInterface
interface = pySCPseudoOrbitInterface(SC=SC, n_turns=20)
x, y = interface.get_orbit()

# One-flag switch on existing correction
SC.tuning.correct_orbit(pseudo=True, n_turns=20, n_reps=3)

Test plan

  • 3 new BPM system tests (shape, transmission, single-turn equivalence)
  • 1 new tuning smoke test (correct_orbit(pseudo=True))
  • All 29 existing tests pass, 0 regressions

- codes.py: Fix DispersionCode.DONE value collision with HORIZONTAL
- response.py: Replace np.concat with np.concatenate
- response_matrix.py: Fix disable_all_outputs_but copy-paste bug, fix MICADO UnboundLocalError
- bpm_system.py: Fix reconstruct_true_orbit gain inversion
- tune.py: Store tune_response_matrix on self
- tuning_core.py: Guard wiggle_last_corrector against UnboundLocalError
- bba.py: Fix reject_bpm_outlier np.abs usage, add total_rejections field
- bpm_system_conf.py: Fix config pattern matching
- general.py: Prevent scale_error_table from mutating input arrays
- rf_conf.py: Fix 'frequncy' typo
- injection.py: Fix injection tracking
- magnetsettings.py: Fix add_individually_powered indentation logic
- rdt.py: Fix fjklm phase wrapping
Tests cover all core modules (configuration, core, tuning, apps, utils)
with 53 test files providing structural and behavioral coverage.
Pseudo-orbit averages injection TBT data per-BPM across turns,
bridging the gap between raw TBT (beam threading) and closed-orbit
(stable operation) reading modes. Needed for ALSU commissioning
after stitching achieves multi-turn survival.

- BPMSystem.capture_pseudo_orbit(): delegates to capture_injection + nanmean
- pySCPseudoOrbitInterface: plugs into orbit_correction with orbit RM
- Tuning.correct_orbit(pseudo=True, n_turns=N): one-flag switch
- Fix pre-existing np.concat bug in fit_dispersive_orbit
- Remove commented-out correct_pseudo_orbit_at_injection prototype
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant