COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
modalGains.py
1 import numpy as np
2 
3 class ModalGains(object):
4  """ This optimizer class handles the modal gain optimization related operations
5  using the CLOSE algorithm. Should be used with a modal integrator command law.
6 
7  Attributes:
8  _config : (config) : Configuration parameters module
9 
10  _rtc : (RtcCompass) : RtcCompass instance
11 
12  _ntotact : (int) : total number of actuators used in the simulation
13 
14  modal_basis : (np.ndarray) : KL2V modal basis
15 
16  cmat_modal : (np.ndarray) : modal command matrix
17 
18  _mask : (np.ndarray) : mask array (containig 0 or 1) filtering the modes
19 
20  _ac_idx : (int) : autocorrelation index
21 
22  _up_idx : (int) : update index (averaging length of AC estimator before modal gains update)
23 
24  _lf : (float) : learning factor of the autocorrelation computation
25 
26  _lfdownup : (float) : learning factors for modal gain update
27 
28  _trgt : (float) : target value for the autocorrelation optimization
29 
30  _initial_gain : (float) : initial value for the modal gains (same for all modes)
31 
32  _modal_meas : (list) : list containing previous modal measurements to
33  be used for CLOSE optimization
34 
35  _ac_est_0 : (np.ndarray) : autocorrelation estimation for no frames delay
36 
37  _ac_est_dt : (np.ndarray) : autocorrelation estimation for _ac_idx delay
38 
39  mgains : (np.ndarray) : modal gains that will be updated
40 
41  close_iter : (int) : number of iteration of CLOSE optimizations
42  """
43 
44  def __init__(self, config, rtc):
45  """ Instantiate a ModalGains optimizer object.
46 
47  Args:
48  config : (config module) : Parameters configuration structure module
49 
50  rtc : (sutraWrap.Rtc) : Sutra rtc instance
51  """
52  self._config_config = config
53  self._rtc_rtc = rtc
54  self._ntotact_ntotact = config.p_controllers[0].nactu
55  # parameters of the CLOSE optimization
56  self.modal_basismodal_basis = None # carrĂ©e !!
57  self.cmat_modalcmat_modal = None
58  self._mask_mask = np.ones(self._ntotact_ntotact)
59  self._ac_idx_ac_idx = int(config.p_controllers[0].delay * 2 + 1)
60  self._up_idx_up_idx = config.p_controllers[0].get_close_update_index()
61  self._lf_lf = config.p_controllers[0].get_close_learning_factor()
62  self._lfdownup_lfdownup = np.array(config.p_controllers[0].get_lfdownup())
63  self._trgt_trgt = config.p_controllers[0].get_close_target()
64  self._initial_gain_initial_gain = config.p_controllers[0].get_mgain_init()
65  # computation intermediaries
66  self._modal_meas_modal_meas = []
67  self._buffer_buffer = []
68  self._ac_est_0_ac_est_0 = np.zeros((self._ntotact_ntotact), dtype=np.float32)
69  self._ac_est_dt_ac_est_dt = np.zeros((self._ntotact_ntotact), dtype=np.float32)
70  # out variables
71  self.mgainsmgains = np.ones(self._ntotact_ntotact) * self._initial_gain_initial_gain
72  self.close_iterclose_iter = 0
73  if (self._config_config.p_controllers[0].close_opti):
74  self._rtc_rtc.set_modal_gains(0, self.mgainsmgains)
75  # print(f"total number of actuators {self._ntotact}")
76  # print(f"Autocorrelation index for CLOSE optimization is {self._ac_idx}")
77 
78  def update_modal_meas(self):
79  """Save the modal measurement of the current iter"""
80  if self.cmat_modalcmat_modal is None or self.modal_basismodal_basis is None :
81  raise Exception("Modal basis and cmat modal should be not None")
82  slp = self._rtc_rtc.get_slopes(0)
83  self._modal_meas_modal_meas.append(self.cmat_modalcmat_modal.dot(slp))
84  if len(self._modal_meas_modal_meas) == self._ac_idx_ac_idx + 1:
85  self._modal_meas_modal_meas.pop(0)
86 
87  def update_mgains(self):
88  """Compute a new modal gains
89  This function computes and updates the modal gains according to the
90  CLOSE algorithm.
91  """
92  #ctrl_modes = self._mask != 0 # where modes are controlled
93  ctrl_modes = np.where(self._mask_mask)[0] # where modes are controlled
94  if self.cmat_modalcmat_modal is None or self.modal_basismodal_basis is None :
95  raise Exception("Modal basis and cmat modal should be not None")
96  # get new measurement
97  slp = self._rtc_rtc.get_slopes(0)
98  temp_modal_meas = self.cmat_modalcmat_modal.dot(slp)
99  self._modal_meas_modal_meas.append(temp_modal_meas)
100  # estimate autocorrelation
101  if np.all(self._ac_est_0_ac_est_0 == 0):
102 
103  self._ac_est_0_ac_est_0[ctrl_modes] = self._modal_meas_modal_meas[-1][ctrl_modes] ** 2
104  else:
105  self._ac_est_0_ac_est_0[ctrl_modes] = self._ac_est_0_ac_est_0[ctrl_modes] * (1 - self._lf_lf) + self._modal_meas_modal_meas[-1][ctrl_modes] ** 2 * self._lf_lf
106  if len(self._modal_meas_modal_meas) == self._ac_idx_ac_idx + 1:
107  if np.all(self._ac_est_dt_ac_est_dt == 0):
108  self._ac_est_dt_ac_est_dt[ctrl_modes] = self._modal_meas_modal_meas[0][ctrl_modes] * self._modal_meas_modal_meas[-1][ctrl_modes]
109  else:
110  self._ac_est_dt_ac_est_dt[ctrl_modes] = self._ac_est_dt_ac_est_dt[ctrl_modes] * (1 - self._lf_lf) \
111  + self._modal_meas_modal_meas[0][ctrl_modes] * self._modal_meas_modal_meas[-1][ctrl_modes] * self._lf_lf
112  # compute new modal gains
113  x = self._ac_est_dt_ac_est_dt[ctrl_modes] / self._ac_est_0_ac_est_0[ctrl_modes] - self._trgt_trgt
114  self._buffer_buffer.append(x)
115  if len(self._buffer_buffer) >= self._up_idx_up_idx:
116  mean = np.mean(self._buffer_buffer, axis=0)
117  sign_ac = (mean > 0).astype(np.int8)
118  self.mgainsmgains[ctrl_modes] = self.mgainsmgains[ctrl_modes] * (1 + self._lfdownup_lfdownup[sign_ac] * x)
119  self._rtc_rtc.set_modal_gains(0, self.mgainsmgains)
120  self._buffer_buffer = []
121  self._modal_meas_modal_meas.pop(0)
122  self.close_iterclose_iter +=1
123 
124  def reset_close(self):
125  """Reset modal gain and computation variables"""
126  self.mgainsmgains = np.ones(self._ntotact_ntotact) * self._mask_mask * self._initial_gain_initial_gain
127  self._ac_est_0_ac_est_0 = np.zeros((self._ntotact_ntotact), dtype=np.float32)
128  self._ac_est_dt_ac_est_dt = np.zeros((self._ntotact_ntotact), dtype=np.float32)
129  self._modal_meas_modal_meas = []
130  self.close_iterclose_iter = 0
131  self._rtc_rtc.set_modal_gains(0, self.mgainsmgains)
132  self.adapt_modal_gainsadapt_modal_gains(False)
133 
134 
135  def reset_mgains(self):
136  """Reset the modal gains only"""
137  self.mgainsmgains = np.ones(self._ntotact_ntotact) * self._mask_mask * self._initial_gain_initial_gain
138 
139  def adapt_modal_gains(self, flag):
140  """Set the flag indicating to use CLOSE optimization.
141 
142  Args:
143  flag : (bool) : If true, update the modal gains value according to CLOSE algo
144  """
145  self._config_config.p_controllers[0].set_close_opti(flag)
146 
147  def set_modal_basis(self, modal_basis):
148  """Set the modal basis to be used in CLOSE calculation.
149 
150  Args:
151  modal_basis : (np.ndarray) : modal basis (KL2V) to be used (square)
152  """
153  if (modal_basis.shape[0] != modal_basis.shape[1]):
154  raise Exception("Modal basis should be square matrix")
155  self.modal_basismodal_basis = modal_basis
156  self._rtc_rtc.set_E_matrix(0, modal_basis)
157  print("Modal basis is set")
158 
159  def get_modal_basis(self):
160  """Get the modal basis
161 
162  Returns:
163  self.modal_basis : (np.ndarray) : modal basis (KL2V) used in the optimizer
164  """
165  return self.modal_basismodal_basis
166 
167  def set_cmat_modal(self, cmat_modal):
168  """Set cmat modal
169 
170  Args:
171  cmat_modal : (np.ndarray) : modal command matrix
172  """
173  self.cmat_modalcmat_modal = cmat_modal
174  self._rtc_rtc.set_command_matrix(0, cmat_modal)
175  print("cmat_modal is set")
176 
177  def get_modal_gains(self):
178  """Get the modal gains
179 
180  Returns:
181  self.mgains : (np.ndarray) : modal gains
182  """
183  return self._rtc_rtc.get_modal_gains(0)
184 
185  def set_modal_gains(self, mgains):
186  """Sets manually the modal gains
187 
188  Args:
189  mgains : (np.ndarray) : the modal gains array
190  """
191  self.mgainsmgains = mgains
192  self._rtc_rtc.set_modal_gains(0, mgains)
193 
194 
195  def set_mask(self, mask):
196  """Set the mode mask
197 
198  Args:
199  mask : (np.ndarray) : mask array (containig 0 or 1) filtering the modes
200  """
201  self._mask_mask = mask
202  self.mgainsmgains[mask == 0] = 0
203  self._rtc_rtc.set_modal_gains(0, self.mgainsmgains)
204 
205  def set_initial_gain(self, gain):
206  """Set the initial value for modal gains. This function reinitializes the modal gains.
207 
208  Args:
209  gain: (float) : initial value for modal gains
210  """
211  self._initial_gain_initial_gain = gain
212  self.mgainsmgains = np.ones(self._ntotact_ntotact) * self._initial_gain_initial_gain
213  self.mgainsmgains[self._mask_mask == 0] = 0
214  self._rtc_rtc.set_modal_gains(0, self.mgainsmgains)
215  self._config_config.p_controllers[0].set_mgain_init(gain)
216 
217  def set_config(self, p, qminus, qplus, target, up_idx):
218  """Set the 4 parameters for the CLOSE optimization loop
219 
220  Args:
221  p: (float) : learning factor for autocorrelation
222 
223  qminus: (float) : learning factor for mgain optimization when lower than target
224 
225  qplus: (float) : learning factor for mgain optimization when higher than target
226 
227  target: (float) : autocorrelation target for optimization
228 
229  up_idx: (int) : modal gains update rate [frame]
230  """
231  self._lf_lf = p
232  self._config_config.p_controllers[0].set_close_learning_factor(p)
233  self._lfdownup_lfdownup = np.array([qminus, qplus])
234  self._config_config.p_controllers[0].set_lfdownup(qminus, qplus)
235  self._trgt_trgt = target
236  self._config_config.p_controllers[0].set_close_target(target)
237  self._up_idx_up_idx = up_idx
238  self._config_config.p_controllers[0].set_close_update_index(up_idx)
This optimizer class handles the modal gain optimization related operations using the CLOSE algorithm...
Definition: modalGains.py:8
def set_mask(self, mask)
Set the mode mask.
Definition: modalGains.py:251
modal_basis
(np.ndarray) : KL2V modal basis
Definition: modalGains.py:107
def set_initial_gain(self, gain)
Set the initial value for modal gains.
Definition: modalGains.py:261
def set_modal_basis(self, modal_basis)
Set the modal basis to be used in CLOSE calculation.
Definition: modalGains.py:203
def set_config(self, p, qminus, qplus, target, up_idx)
Set the 4 parameters for the CLOSE optimization loop.
Definition: modalGains.py:281
def set_cmat_modal(self, cmat_modal)
Set cmat modal.
Definition: modalGains.py:223
close_iter
(int) : number of iteration of CLOSE optimizations
Definition: modalGains.py:123
def update_modal_meas(self)
Save the modal measurement of the current ite.
Definition: modalGains.py:130
def reset_close(self)
Reset modal gain and computation variables.
Definition: modalGains.py:176
def update_mgains(self)
Compute a new modal gains This function computes and updates the modal gains according to the CLOSE a...
Definition: modalGains.py:142
def __init__(self, config, rtc)
Instantiate a ModalGains optimizer object.
Definition: modalGains.py:102
mgains
(np.ndarray) : modal gains that will be updated
Definition: modalGains.py:122
def get_modal_basis(self)
Get the modal basis.
Definition: modalGains.py:215
def get_modal_gains(self)
Get the modal gains.
Definition: modalGains.py:233
def reset_mgains(self)
Reset the modal gains only.
Definition: modalGains.py:187
def set_modal_gains(self, mgains)
Sets manually the modal gains.
Definition: modalGains.py:241
def adapt_modal_gains(self, flag)
Set the flag indicating to use CLOSE optimization.
Definition: modalGains.py:195
cmat_modal
(np.ndarray) : modal command matrix
Definition: modalGains.py:108