40 """ This optimizer class handles all the modal basis and DM Influence functions
44 config : (config) : Configuration parameters module
46 tel : (TelescopeCompass) : TelescopeCompass instance
48 atmos : (AtmosScompass) : AtmosCompass instance
50 dms : (DmCompass) : DmCompass instance
52 target : (TargetCompass) : TargetCompass instance
54 rtc : (RtcCompass) : RtcCompass instance
56 wfs : (WfsCompass) : WfsCompass instance
58 def __init__(self, config, tel, atmos, dms, target, rtc, wfs):
59 """ Instantiate a ModalBasis object
62 config : (config) : Configuration parameters module
64 tel : (TelescopeCompass) : TelescopeCompass instance
66 atmos : (AtmosScompass) : AtmosCompass instance
68 dms : (DmCompass) : DmCompass instance
70 target : (TargetCompass) : TargetCompass instance
72 rtc : (RtcCompass) : RtcCompass instance
74 wfs : (WfsCompass) : WfsCompass instance
85 turbu: bool =
False, reset: bool =
True):
86 """ Apply voltages, raytrace, compute WFS image, compute slopes and returns it
89 controller_index : (int) : Controller index
91 noise : (bool, optional) : Flag to enable noise for WFS image compuation. Default is False
93 turbu : (bool, optional) : Flag to enable atmosphere for WFS phase screen raytracing.
96 reset : (bool, optional) : Flag to reset previous phase screen before raytracing.
99 self.
rtc.apply_control(controller_index)
104 self.
wfs.raytrace(w, dms=self.
dms, reset=reset)
105 self.
wfs.compute_wfs_image(w, noise=noise)
106 return self.
rtc.compute_slopes(controller_index)
108 def do_imat_modal(self, controller_index : int, ampli : np.ndarray, modal_basis : np.ndarray,
109 *, noise : bool=
False, nmodes_max : int=0, with_turbu : bool=
False, push_pull : bool=
False) -> np.ndarray:
110 """ Computes an interaction matrix from provided modal basis
113 controller_index : (int) : Controller index
115 ampli : (np.ndarray) : amplitude to apply on each mode
117 modal_basis : (np.ndarray) : modal basis matrix
119 noise : (bool, optional) : Flag to enable noise for WFS image compuation. Default is False
121 nmodes_max : (int, optional) : Default is 0. TODO : description
123 with_turbu : (bool, optional) : Flag to enable atmosphere for WFS phase screen raytracing.
126 push_pull : (bool, optional) : If True, imat is computed as an average of push and pull ampli
130 modal_imat : (np.ndarray) : Modal interaction matrix
132 modal_imat = np.zeros((self.
config.p_controllers[controller_index].nslope, modal_basis.shape[1]))
134 if (nmodes_max == 0):
135 nmodes_max = modal_basis.shape[1]
136 v_old = self.
rtc.get_command(controller_index)
138 for m
in range(nmodes_max):
139 v = ampli[m] * modal_basis[:, m]
140 if ((push_pull
is True)
or
141 (with_turbu
is True)):
142 self.
rtc.set_perturbation_voltage(
143 controller_index,
"imat_modal",
146 turbu=with_turbu, noise=noise)
147 self.
rtc.set_perturbation_voltage(controller_index,
"imat_modal", v_old - v)
149 turbu=with_turbu, noise=noise)
150 modal_imat[:, m] = (devpos - devmin) / (2. * ampli[m])
153 self.
rtc.set_perturbation_voltage(controller_index,
"imat_modal", v)
155 self.
rtc.remove_perturbation_voltage(controller_index,
"imat_modal")
156 if ((push_pull
is True)
or (with_turbu
is True)):
157 self.
rtc.close_loop(controller_index)
160 def do_imat_phase(self, controller_index: int, cube_phase: np.ndarray, *, noise : bool=
False,
161 nmodes_max : int=0, with_turbu : bool=
False, push_pull : bool=
False, wfs_index : int=0) -> np.ndarray:
162 """ Computes an interaction matrix with the provided cube phase
165 controller_index : (int) : Controller index
167 cube_phase : (np.ndarray) : Cube of phase to insert as NCPA
169 noise : (bool, optional) : Flag to enable noise for WFS image compuation. Default is False
171 nmodes_max : (int, optional) : Default is 0. TODO : description
173 with_turbu : (bool, optional) : Flag to enable atmosphere for WFS phase screen raytracing.
176 push_pull : (bool, optional) : If True, imat is computed as an average of push and pull ampli
179 wfs_index : (int, optional) : WFS index. Default is 0
182 phase_imat : (np.ndarray) : Phase interaction matrix
184 imat_phase = np.zeros((cube_phase.shape[0], self.
config.p_controllers[controller_index].nslope))
185 for nphase
in range(cube_phase.shape[0]):
186 if ((push_pull
is True)
or (with_turbu
is True)
188 self.
wfs.set_ncpa_wfs(wfs_index, cube_phase[nphase, :, :])
190 turbu=with_turbu, noise=noise)
191 self.set_ncpa_wfs(wfs_index, -cube_phase[nphase, :, :])
193 turbu=with_turbu, noise=noise)
194 imat_phase[nphase, :] = (devpos - devmin) / 2
197 self.
wfs.set_ncpa_wfs(wfs_index, cube_phase[nphase, :, :])
199 controller_index, noise=noise)
200 self.
wfs.set_ncpa_wfs(wfs_index,
201 cube_phase[nphase, :, :] * 0.)
208 *, selected_actus : np.ndarray=
None) -> np.ndarray:
209 """ Computes the modal residual coefficients of the residual phase.
211 /!\ It supposed that roket is enabled, and the associated GEO controller is index 1.
213 Uses the projection matrix computed from compute_modes_to_volts_basis (modalBasis module)
216 projection_matrix : (np.ndarray) : Modal projection matrix
218 selected_actus : (np.ndarray) : TODO : description
221 ai : (np.ndarray) : Modal coefficients
224 self.
rtc.do_control(1, sources=self.
target.sources)
227 v = self.
rtc.get_command(1)
228 if (selected_actus
is None):
229 ai = projection_matrix.dot(v) * 1000.
234 ai = projection_matrix.dot(np.concatenate((v2, v3))) * 1000.