Maybe add an optional binary engage channel to the *.ini parser (see for example PIDLocker_beta.py). The default when no channel is given should be 'always on', otherwise it should activate the loop on a given list of soft channels. Running a bunch of scripts in tmux is fine for a while when testing but becomes a pain in the long term.
You can use the function,
def ANDChannels(chanList): # find boolean AND of a list of binary EPICs chans
return all([RCPID.read(ii, log=False) for ii in chanList])
to take a list of binary IOC channels and return true if all are state 1. You can then make rmsMonitor.py 's behavior dependent on the FSS and PMC lock state as well as a medm binary switch. We want our lockers and controls have a hierarchical structure so they have a sequence of behavior built into the logic of their rules of engagement. If the parts have a well defined mode of engage and failure the whole system will be much more predictable and stable. This also avoids the need for a central manager script of all the tasks. We can run all this stuff as daemons under services (in /etc/init) and let Linux do the heavy lifting of keeping it all alive.
On that note, the Marconi2023A_BeatnoteTrack.py script lost the PLL lock last night but failed to exit. Its inability to sense if its locked at zero PLL DC error signal or just way out of range is a problem. When it does this it fails to drop the North cavity PID loop. This morning the north cavity heater had railed at 0 watts which will take hours to recover back to stable ~100 MHz offset. We may need an out of loop frequency sensor to track wide variations of frequency.
Very often in our lab our FSS boxes "ring", i.e. the EOM and PZT actuators fight each other for control of the laser frequency, instead of working together. If the EOM actuator rails, the PZT comes stomping in trying to lock high frequency laser frequency noise, but the EOM comes back in and says, "no, it's my job", but the PZT is all like "obviously you can't do your job cause you're not strong enough", which really only makes the EOM angry, causing rail-to-rail actuation jumps and high, nonlinear noise in our FSS loops. This is bad for our PLL autolocker, as the high noise hurts the PLL control signal and eventually causes it to lose the beatnote, and obviously bad for the beatnote ASD itself, which we are monitoring at all times on our webpage.
So today I created rmsMonitor.py, a python script which monitors the RMS of the FSS Fastmon voltage, the PZT control signal. If the Fastmon RMS ever exceeds 250 mV, rmsMonitor.py will call awade's gaincycle.py on the offending FSS box, which brings both Common and Fast Gain values to their lowest setting, then steadily ramps them back up to where they were in a nice way such that ringing won't start up again. In this way we can automatically eliminate ringing whenever it starts.
rmsMonitor.py lives in ~/Git/cit_ctnlab/ctn_scripts/, and has two associated .ini files, RMSMonitor_North.ini and RMSMonitor_South.ini. Inside the .ini files is defined the Fastmon path channel name, i.e. C3:PSL-NCAV_FSS_FASTMON for the north path, and the max rms limit, which is currently 250 mV for both paths.
To run this script on our North path, call
$ python rmsMonitor.py RMSMonitor_North.ini &
Every two seconds, the script should print out something like
C3:PSL-NCAV_FSS_FASTMON rms = 0.0647327284305 V
which is the channel name and the rms calculated for that channel in that two seconds. Again, if rms is ever above 250 mV, it triggers gaincycle.py for that path and eliminates ringing.
These scripts are perpetually running in tmux sessions named RMSNorth and RMSSouth on acromag1. To access the north tmux session, log onto acromag1 and run $ tmux attach -t RMSNorth.
These scripts will need to be turned off when debugging persistent FSS ringing.