From 470c4a22ff5b82ccc3ae907a34771d8413b882ef Mon Sep 17 00:00:00 2001 From: Benjamin Labrecque Date: Fri, 17 Jul 2026 11:41:26 +0200 Subject: [PATCH] feat: use PV external in scrubbing --- .../app/src/agebd_scrubbing/service.py | 127 +++++++++--------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/service.py b/services/scrubbing/current/app/src/agebd_scrubbing/service.py index 3be0bc5..e962a24 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/service.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/service.py @@ -4,36 +4,38 @@ from time import perf_counter, sleep import numpy as np from epics import PV -from agebd.pv import get_pv_class +from agebd.pv import get_pv_class, get_pv_external_class from agebd.service.pvs import BasePVs from agebd.utils import printgetversion __version__ = printgetversion(__file__) PV = get_pv_class() +PV_EXTERNAL = get_pv_external_class() class PVs(BasePVs): + # fmt: off cycles_BOIN_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-SP.VAL") cycles_BOIN_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOIN-RB.VAL") - cycles_BOIN_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL", auto_monitor=True) + cycles_BOIN_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-EVRCount-I.VAL", auto_monitor=True) cycles_BOMB_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-SP.VAL") cycles_BOMB_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOMB-RB.VAL") - cycles_BOMB_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL", auto_monitor=True) + cycles_BOMB_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-EVRCount-I.VAL", auto_monitor=True) cycles_BOME_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOME-SP.VAL") cycles_BOME_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOME-RB.VAL") - cycles_BOME_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL", auto_monitor=True) + cycles_BOME_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-EVRCount-I.VAL", auto_monitor=True) cycles_BOEX_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-SP.VAL") cycles_BOEX_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-BOEX-RB.VAL") - cycles_BOEX_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL", auto_monitor=True) + cycles_BOEX_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-Ext-EVRCount-I.VAL", auto_monitor=True) cycles_SRIN_sp = PV("AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-SP.VAL") cycles_SRIN_rb = PV("AGEBD-SCRUBBING:WARMUPCYCLES-SRIN-RB.VAL") - cycles_SRIN_cnt = PV("AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL", auto_monitor=True) - cycles_ALL_cnt = PV("AGETI-CVME-MASTER-TMA:Event-Seq-Cnt-I.VAL", auto_monitor=True) + cycles_SRIN_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-SR-Inj-EVRCount-I.VAL", auto_monitor=True) + cycles_ALL_cnt = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Event-Seq-Cnt-I.VAL", auto_monitor=True) ## Control PVs # top-up control mode - # topumod = PV('.VAL') + # topumod = PV_EXTERNAL('.VAL') # top-up mode vacuum limits vac_max = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-MAX.VAL") vac_min = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-MIN.VAL") @@ -46,111 +48,112 @@ class PVs(BasePVs): # mbfb gain setpoints for scrubbing mbfbx_gain_sp = PV("AGEBD-SCRUBBING:MBFBX-GAIN-SP.VAL") mbfby_gain_sp = PV("AGEBD-SCRUBBING:MBFBY-GAIN-SP.VAL") - mbfbx_gain = PV("ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN.VAL") - mbfby_gain = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN.VAL") + mbfbx_gain = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-X-DDS-GAIN.VAL") + mbfby_gain = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-GAIN.VAL") # RDP Scan # pause : set gain to 0 as normal, get current sweep freq, stop sweep, set initial freq of sweep to current freq # start : set gain to sp (i.e., 100) as normal, start sweep - mbfby_freq_sp = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ.VAL") - mbfby_sweep_onoff = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-EN.VAL") - mbfby_sweepfreq_start = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FREQ-START.VAL") - mbfby_sweepfreq_rb = PV("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FRQ-RB-REG.VAL") + mbfby_freq_sp = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-FRQ.VAL") + mbfby_sweep_onoff = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-EN.VAL") + mbfby_sweepfreq_start = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FREQ-START.VAL") + mbfby_sweepfreq_rb = PV_EXTERNAL("ARSGE-CECL-MBFB:MBFB-T-Y-DDS-SWEEP-FRQ-RB-REG.VAL") vac_dyn = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-DYN.VAL") vac_dyn_frac = PV("AGEBD-SCRUBBING:CONTROL-VACUUM-DYN-FRAC.VAL") - # grd_max = PV('AGEBD-SCRUBBING:CONTROL-GUNGRID-MAX.VAL') + # grd_max = PV_EXTERNAL('AGEBD-SCRUBBING:CONTROL-GUNGRID-MAX.VAL') grid_accum = PV("AGEBD-SCRUBBING:CONTROL-GUNGRID-ACCUM.VAL") grid_fpfb = PV("AGEBD-SCRUBBING:CONTROL-GUNGRID-FPFB.VAL") # current above which the feedback mode is started - current_threshold = PV("AGEBD-TIMING:CURRENT-THRESHOLD.VAL") + current_threshold = PV_EXTERNAL("AGEBD-TIMING:CURRENT-THRESHOLD.VAL") scrubbing = PV("AGEBD-SCRUBBING:CONTROL-SCRUB.VAL") # Input PVs vacs = [ - # PV('ARIVA-VMAVE:PRESS-MAX.VAL'), # VCS gauges in the Arcs + Straights - # PV('ARIVA-VMAVE-FE:PRESS-MAX.VAL'), # VCS gauges in the ring to always the first one after the FE-Valve - # PV('ARIVA-VMAVE-ALL:PRESS-MAX.VAL'), # Max of the two above - # PV('ARIVA-VMAVE-PSH:PRESS-MAX.VAL'), # VCS gauges in the Photon Shutters/Beam Stoppers of the existing beamlines - PV("ARIVA-VMAVE-ALL:PRESS-MAX.VAL"), # Max of three signals: Ring/FE/PSH - PV("ARS07-VMCC-0120:PRESSURE.VAL"), + # PV_EXTERNAL('ARIVA-VMAVE:PRESS-MAX.VAL'), # VCS gauges in the Arcs + Straights + # PV_EXTERNAL('ARIVA-VMAVE-FE:PRESS-MAX.VAL'), # VCS gauges in the ring to always the first one after the FE-Valve + # PV_EXTERNAL('ARIVA-VMAVE-ALL:PRESS-MAX.VAL'), # Max of the two above + # PV_EXTERNAL('ARIVA-VMAVE-PSH:PRESS-MAX.VAL'), # VCS gauges in the Photon Shutters/Beam Stoppers of the existing beamlines + PV_EXTERNAL("ARIVA-VMAVE-ALL:PRESS-MAX.VAL"), # Max of three signals: Ring/FE/PSH + PV_EXTERNAL("ARS07-VMCC-0120:PRESSURE.VAL"), ] - vac_all = PV("ARIVA-VMAVE-ALL:PRESS-MAX.VAL") + vac_all = PV_EXTERNAL("ARIVA-VMAVE-ALL:PRESS-MAX.VAL") vac_acc = [ - PV("ARIVA-VMAVE:PRESS-MAX.VAL"), - PV("ARS07-VMCC-0120:PRESSURE.VAL"), + PV_EXTERNAL("ARIVA-VMAVE:PRESS-MAX.VAL"), + PV_EXTERNAL("ARS07-VMCC-0120:PRESSURE.VAL"), ] - # vac_fe = PV('ARIVA-VMAVE-FE:PRESS-MAX.VAL') - # cur = PV('AGEBD-DBPM3CURR:CURRENT-AVG.VAL') - cur = PV("ARS07-DPCT-0000:CURR.VAL") - # cur1 = PV('ARS07-CECL-DPCT:BDC-DPCT100-SCALED') - # cur2 = PV('ARS07-CECL-DPCT2:BDC-DPCT200-SCALED') - # curuse = PV('ARS07-DPCT-0000:CHOICE-RB') + # vac_fe = PV_EXTERNAL('ARIVA-VMAVE-FE:PRESS-MAX.VAL') + # cur = PV_EXTERNAL('AGEBD-DBPM3CURR:CURRENT-AVG.VAL') + cur = PV_EXTERNAL("ARS07-DPCT-0000:CURR.VAL") + # cur1 = PV_EXTERNAL('ARS07-CECL-DPCT:BDC-DPCT100-SCALED') + # cur2 = PV_EXTERNAL('ARS07-CECL-DPCT2:BDC-DPCT200-SCALED') + # curuse = PV_EXTERNAL('ARS07-DPCT-0000:CHOICE-RB') - injguard = PV("AGEBD-INJECTIONGUARD:CHECK-SUM.VAL") + injguard = PV_EXTERNAL("AGEBD-INJECTIONGUARD:CHECK-SUM.VAL") - injactive = PV("AGEBD-PARAMS:INJECTION-ACTIVE") + injactive = PV_EXTERNAL("AGEBD-PARAMS:INJECTION-ACTIVE") - tau = PV("AGEBD-PARAMS:LIFETIME.VAL") + tau = PV_EXTERNAL("AGEBD-PARAMS:LIFETIME.VAL") # Regulated PVs - trig_firego = PV("AGEBD-TIMING:GO.VAL") - trig_master = PV("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") - master_mode = PV("AGETI-CVME-MASTER-TMA:FP-Mode-Sel.VAL") - trig_secret = PV("AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER.VAL") - # trig_guntxb = PV('ALIRF-VME-A-GUN:CH1-MODE.VAL') + trig_firego = PV_EXTERNAL("AGEBD-TIMING:GO.VAL") + trig_master = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:SR-Inj-Status-Sel.VAL") + master_mode = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:FP-Mode-Sel.VAL") + trig_secret = PV_EXTERNAL("AGEBD-INJECTIONGUARD:STATUS-SECRET-MASTER.VAL") + # trig_guntxb = PV_EXTERNAL('ALIRF-VME-A-GUN:CH1-MODE.VAL') # AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel - # trig_gunevt = PV('AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel.VAL') + # trig_gunevt = PV_EXTERNAL('AGETI-CVME-MASTER-TMA:Evt-LI-Gun-Ena-Sel.VAL') # AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel - trig_booinj = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel.VAL") + trig_booinj = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-Inj-Ena-Sel.VAL") # AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel - # trig_boormp = PV('AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel.VAL') - trig_bormp1 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel.VAL") + # trig_boormp = PV_EXTERNAL('AGETI-CVME-MASTER-TMA:Evt-Old-BO-HW-Ena-Sel.VAL') + trig_bormp1 = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-MA-B-Ena-Sel.VAL") # AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel - trig_bormp2 = PV("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel.VAL") - trig_booext = PV( + trig_bormp2 = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-BO-Ramp-Ena-Sel.VAL") + trig_booext = PV_EXTERNAL( "AGETI-CVME-MASTER-TMA:Evt-BO-Ext-Ena-Sel.VAL" ) # Alias AGETI-CVME-MASTER-TMA:Evt-10 - trig_rininj = PV( + trig_rininj = PV_EXTERNAL( "AGETI-CVME-MASTER-TMA:Evt-SR-Inj-Ena-Sel.VAL" ) # Alias AGETI-CVME-MASTER-TMA:Evt-26 - trig_pinger_h = PV( + trig_pinger_h = PV_EXTERNAL( "AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-H-Ena-Sel.VAL" ) # Alias AGETI-CVME-MASTER-TMA:Evt-14-Ena-Sel - trig_pinger_v = PV( + trig_pinger_v = PV_EXTERNAL( "AGETI-CVME-MASTER-TMA:Evt-SR-Pinger-V-Ena-Sel.VAL" ) # Alias AGETI-CVME-MASTER-TMA:Evt-14-Ena-Sel # # injection follow bucket workaround for linac (https://elog-gfa.psi.ch/SLS/64299) # # Before making injection, disable the LLRF phase feedback ... - # linac_llrf_phaseFB1 = PV('ALIRF-A1-LLE-DSP:PHASE-FB-SWITCH.VAL') - # linac_llrf_phaseFB2 = PV('ALIRF-A2-LLE-DSP:PHASE-FB-SWITCH.VAL') + # linac_llrf_phaseFB1 = PV_EXTERNAL('ALIRF-A1-LLE-DSP:PHASE-FB-SWITCH.VAL') + # linac_llrf_phaseFB2 = PV_EXTERNAL('ALIRF-A2-LLE-DSP:PHASE-FB-SWITCH.VAL') # # ... and disable the phase alarm by setting the phase limits - # linac_llrf_phaseFB_PBU_HIHI = PV('ALIRF-PBU:Ph-COMP.HIHI') - # linac_llrf_phaseFB_FBU_HIHI = PV('ALIRF-FBU:Ph-COMP.HIHI') - # linac_llrf_phaseFB_MOD1_HIHI = PV('ALIRF-AS-1:Ph-COMP.HIHI') - # linac_llrf_phaseFB_MOD2_HIHI = PV('ALIRF-AS-2:Ph-COMP.HIHI') - # linac_llrf_phaseFB_PBU_LOLO = PV('ALIRF-PBU:Ph-COMP.LOLO') - # linac_llrf_phaseFB_FBU_LOLO = PV('ALIRF-FBU:Ph-COMP.LOLO') - # linac_llrf_phaseFB_MOD1_LOLO = PV('ALIRF-AS-1:Ph-COMP.LOLO') - # linac_llrf_phaseFB_MOD2_LOLO = PV('ALIRF-AS-2:Ph-COMP.LOLO') + # linac_llrf_phaseFB_PBU_HIHI = PV_EXTERNAL('ALIRF-PBU:Ph-COMP.HIHI') + # linac_llrf_phaseFB_FBU_HIHI = PV_EXTERNAL('ALIRF-FBU:Ph-COMP.HIHI') + # linac_llrf_phaseFB_MOD1_HIHI = PV_EXTERNAL('ALIRF-AS-1:Ph-COMP.HIHI') + # linac_llrf_phaseFB_MOD2_HIHI = PV_EXTERNAL('ALIRF-AS-2:Ph-COMP.HIHI') + # linac_llrf_phaseFB_PBU_LOLO = PV_EXTERNAL('ALIRF-PBU:Ph-COMP.LOLO') + # linac_llrf_phaseFB_FBU_LOLO = PV_EXTERNAL('ALIRF-FBU:Ph-COMP.LOLO') + # linac_llrf_phaseFB_MOD1_LOLO = PV_EXTERNAL('ALIRF-AS-1:Ph-COMP.LOLO') + # linac_llrf_phaseFB_MOD2_LOLO = PV_EXTERNAL('ALIRF-AS-2:Ph-COMP.LOLO') - gun_grid = PV("ALIRF-GUN-GRID:V-SET.VAL") - # pinger_v = PV('ARS01-MKIK-0320:CTRL-ON-OFF.VAL') - # pinger_h = PV('ARS01-MKIK-0290:CTRL-ON-OFF.VAL') + gun_grid = PV_EXTERNAL("ALIRF-GUN-GRID:V-SET.VAL") + # pinger_v = PV_EXTERNAL('ARS01-MKIK-0320:CTRL-ON-OFF.VAL') + # pinger_h = PV_EXTERNAL('ARS01-MKIK-0290:CTRL-ON-OFF.VAL') topup_dt = PV("AGEBD-SCRUBBING:TOPUP-DELTAT.VAL") topup_dI = PV("AGEBD-SCRUBBING:TOPUP-DELTAI.VAL") topup_tau = PV("AGEBD-SCRUBBING:TOPUP-TAU.VAL") + # fmt: off def __init__(self, service_name: str, pv_factory=PV): super().__init__(service_name, pv_factory) PV = pv_factory # Service Callback PVs - self.CallbackPV = PV("AGETI-CVME-MASTER-TMA:Evt-Old-BO-SYN.VALA", auto_monitor=True) + self.CallbackPV = PV_EXTERNAL("AGETI-CVME-MASTER-TMA:Evt-Old-BO-SYN.VALA", auto_monitor=True) class Service: