Loop
The Loop component is the control stage of the AO pipeline. It reads the processed wavefront signal, applies the configured control law, and writes the resulting correction vector to the wavefront-corrector stream.
In practical terms, Loop is where you:
load or compute interaction and control matrices
select an integration strategy
tune gain or leak parameters
apply dropped-mode and delay behavior
manage correction updates sent to the wavefront corrector
Soft-RTC Example
The following example shows the general pattern for starting a loop in soft-RTC mode. In this mode the control object lives in the same Python process as the rest of the AO chain.
import numpy as np
from pyRTC.Loop import Loop
from pyRTC.utils import read_yaml_file
conf = read_yaml_file("path/to/config.yaml")
loop = Loop(conf["loop"])
# A calibrated system usually loads or computes IM first, then derives CM.
loop.IM = np.eye(loop.signalSize, loop.numModes, dtype=np.float32)
loop.computeCM()
loop.setGain(0.1)
loop.start()
Hard-RTC Example
The hard-RTC path is appropriate when the loop needs to interact with hardware-facing processes through shared memory while keeping process boundaries explicit.
from pyRTC.Pipeline import hardwareLauncher
config = 'path/to/config.yaml'
port = 3004
loop = hardwareLauncher('path/to/pyRTC/Loop.py', config, port)
loop.launch()
# Once launched, controller methods and properties can be accessed remotely.
loop.run("computeCM")
loop.setProperty("gain", 0.1)
print(loop.getProperty("gain"))
Control Notes
The loop class supports several control-related concepts that matter operationally:
gain and leakyGain for integrator behavior
numDroppedModes for excluding poorly behaved modes
interaction-matrix and control-matrix workflows
optional GPU-assisted paths when PyTorch is available
delay and limit settings for controller tuning
In production use, the loop is usually one of the last components you tune after stream shapes, calibration files, and hardware-facing behavior are already stable.
Parameters
- class pyRTC.Loop.Loop(conf)[source]
Bases:
pyRTCComponentReal-time controller that closes the adaptive optics loop.
Loopreads the current residual signal from the slopes pipeline, combines that signal with the calibrated control model, and writes the next correction vector to the wavefront-corrector stream. It also owns the operator-facing calibration state used to load or build interaction and control matrices and to tune classical integrator settings.In day-to-day use, this is the component that embodies the chosen control law for the system.
Config
- numDroppedModesint, optional
Number of modes to drop. Default is 0.
- gainfloat, optional
Gain for the integrator. Default is 0.1.
- leakyGainfloat, optional
Leaky integrator gain. Default is 0.0.
- hardwareDelayfloat, optional
Delay for the hardware. Default is 0.0.
- pokeAmpfloat, optional
Amplitude for poking. Default is 0.01.
- numItersIMint, optional
Number of iterations for interaction matrix computation. Default is 100.
- delayint, optional
Delay for corrections. Default is 0.
- IMMethodstr, optional
Method for interaction matrix computation. Default is “push-pull”.
- IMFilestr, optional
File to save the interaction matrix. Default is “”.
- pGainfloat, optional
Proportional gain for PID integrator. Default is 0.1.
- iGainfloat, optional
Integral gain for PID integrator. Default is 0.0.
- dGainfloat, optional
Derivative gain for PID integrator. Default is 0.0.
- controlLimitslist, optional
Control limits for PID integrator. Default is [-inf, inf].
- integralLimitslist, optional
Integral limits for PID integrator. Default is [-inf, inf].
- absoluteLimitslist, optional
Absolute limits for corrections. Default is [-inf, inf].
- derivativeFilterfloat, optional
Filter for the derivative term. Default is 0.1.
Attributes
- confdict
Loop configuration.
- namestr
Name of the loop.
- signalDTypetype
Data type of the wavefront sensor signal.
- signalSizeint
Size of the wavefront sensor signal.
- signalShmImageSHM
Shared memory object for the wavefront sensor signal.
- nullSignalnumpy.ndarray
Null signal.
- signal2DDTypetype
Data type of the 2D wavefront sensor signal.
- signal2DSizeint
Size of the 2D wavefront sensor signal.
- signal2D_widthint
Width of the 2D wavefront sensor signal.
- signal2D_heightint
Height of the 2D wavefront sensor signal.
- wfcDTypetype
Data type of the wavefront corrector.
- numModesint
Number of modes in the wavefront corrector.
- wfcShmImageSHM
Shared memory object for the wavefront corrector.
- numDroppedModesint
Number of dropped modes.
- numActiveModesint
Number of active modes.
- flatnumpy.ndarray
Flat correction vector.
- IMnumpy.ndarray
Interaction matrix.
- CMnumpy.ndarray
Control matrix.
- gainfloat
Gain for the integrator.
- leakyGainfloat
Leaky integrator gain.
- perturbAmpfloat
Perturbation amplitude.
- hardwareDelayfloat
Delay for the hardware.
- pokeAmpfloat
Amplitude for poking.
- numItersIMint
Number of iterations for interaction matrix computation.
- delayint
Delay for corrections.
- IMMethodstr
Method for interaction matrix computation.
- IMFilestr
File to save the interaction matrix.
- pGainfloat
Proportional gain for PID integrator.
- iGainfloat
Integral gain for PID integrator.
- dGainfloat
Derivative gain for PID integrator.
- controlLimitslist
Control limits for PID integrator.
- integralLimitslist
Integral limits for PID integrator.
- absoluteLimitslist
Absolute limits for corrections.
- derivativeFilterfloat
Filter for the derivative term.
- integralnumpy.ndarray
Integral term for PID integrator.
- previousWfErrornumpy.ndarray
Previous wavefront error.
- previousDerivativenumpy.ndarray
Previous derivative term.
- controlOutputnumpy.ndarray
Control output.
- computeCM()[source]
Compute the control matrix from the interaction matrix.
- computeIM()[source]
Compute the interaction matrix using the specified method. Method specified using IMMethod, default is push-pull.
- docrimeIM()[source]
Compute the interaction matrix using the DOCRIME method.
- flatten()[source]
Send the flat correction to the wavefront corrector.
- leakyIntegrator()[source]
Leaky integrator.
- loadIM(filename='')[source]
Load the interaction matrix from a file.
Parameters
- filenamestr, optional
File to load the interaction matrix from. If not specified, uses the configured IMFile.
- pidIntegrator(slopes=None, correction=None)[source]
PID integrator.
Parameters
- slopesnumpy.ndarray, optional
Current slopes vector. If not provided, reads from shared memory.
- correctionnumpy.ndarray, optional
Current correction vector. If not provided, reads from shared memory.
- pidIntegratorPOL()[source]
PID integrator using the pseudo-open loop slopes.
- plotIM(row=None)[source]
- pushPullIM()[source]
Compute the interaction matrix using the push-pull method.
- saveIM(filename='')[source]
Save the interaction matrix to a file.
Parameters
- filenamestr, optional
File to save the interaction matrix to. If not specified, uses the configured IMFile.
- sendToWfc(correction, slopes=None)[source]
- setGain(gain)[source]
Set the integrator gain. Only needed for certain integrators.
Parameters
- gainfloat
Gain to set.
- solveDocrime()[source]
- standardIntegrator()[source]
Standard integrator.
- standardIntegratorPOL()[source]
Standard integrator using the pseudo open loop slopes.
- start()
Start the registered real-time functions.
- stop()
Stops the registered real-time functions.
- updateCorrectionPOL(correction=array([], dtype=float32), slopes=array([], dtype=float32))[source]
Update the correction using pseudo open loop slopes.
Parameters
- correctionnumpy.ndarray
Current correction vector.
- slopesnumpy.ndarray
Current slopes vector.
Returns
- numpy.ndarray
Updated correction vector.