COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
rtc_init.py
1 
37 
38 import shesha.config as conf
39 import shesha.constants as scons
40 from shesha.constants import CONST
41 
42 from shesha.ao import imats, cmats, tomo, basis, modopti
43 
44 from shesha.util import utilities, rtc_util
45 from shesha.init import dm_init
46 from typing import List
47 
48 import numpy as np
49 from shesha.sutra_wrap import (carmaWrap_context, Sensors, Dms, Target, Rtc_brahma,
50  Rtc_cacao_FFF, Atmos, Telescope)
51 from shesha.sutra_wrap import Rtc_FFF as Rtc
52 
53 
54 def rtc_init(context: carmaWrap_context, tel: Telescope, wfs: Sensors, dms: Dms,
55  atmos: Atmos, p_wfss: list, p_tel: conf.Param_tel, p_geom: conf.Param_geom,
56  p_atmos: conf.Param_atmos, ittime: float, p_centroiders=None,
57  p_controllers=None, p_dms=None, do_refslp=False, brahma=False, cacao=False,
58  tar=None, dataBase={}, use_DB=False):
59  """Initialize all the SutraRtc objects : centroiders and controllers
60 
61  Args:
62  context: (carmaWrap_context): context
63 
64  tel: (Telescope) : Telescope object
65 
66  wfs: (Sensors) : Sensors object
67 
68  dms: (Dms) : Dms object
69 
70  atmos: (Atmos) : Atmos object
71 
72  p_wfss: (list of Param_wfs) : wfs settings
73 
74  p_tel: (Param_tel) : telescope settings
75 
76  p_geom: (Param_geom) : geom settings
77 
78  p_atmos: (Param_atmos) : atmos settings
79 
80  ittime: (float) : iteration time [s]
81 
82  Kwargs:
83  p_centroiders : (list of Param_centroider): centroiders settings
84 
85  p_controllers : (list of Param_controller): controllers settings
86 
87  p_dms: (list of Param_dms) : dms settings
88 
89  do_refslp : (bool): do ref slopes flag, default=False
90 
91  brahma: (bool) : brahma flag
92 
93  cacao: (bool) : cacao flag
94 
95  tar: (Target) : Target object
96 
97  dataBase: (dict): dict containig paths to files to load
98 
99  use_DB: (bool): use dataBase flag
100 
101  Returns:
102  Rtc : (Rtc) : Rtc object
103  """
104  # initialisation var
105  # ________________________________________________
106  if brahma:
107  rtc = Rtc_brahma(context, wfs, tar, "rtc_brahma")
108  elif cacao:
109  rtc = Rtc_cacao_FFF(p_controllers[0].calpix_name, p_controllers[0].loopdata_name)
110  else:
111  rtc = Rtc()
112 
113  if p_wfss is None:
114  return rtc
115 
116  if p_centroiders:
117  ncentro = len(p_centroiders)
118  else:
119  ncentro = 0
120 
121  if p_controllers:
122  ncontrol = len(p_controllers)
123  else:
124  ncontrol = 0
125 
126  if p_centroiders is not None:
127  for i in range(ncentro):
128  nwfs = p_centroiders[i].nwfs
129  init_centroider(context, nwfs, p_wfss[nwfs], p_centroiders[i], p_tel,
130  p_atmos, wfs, rtc)
131 
132  if p_controllers is not None:
133  if (p_wfss is not None and p_dms is not None):
134  for i in range(ncontrol):
135  if not "dm" in dataBase:
136  imat = imats.imat_geom(wfs, dms, p_wfss, p_dms, p_controllers[i],
137  meth=0)
138  else:
139  imat = None
140 
141  if p_dms[0].type == scons.DmType.PZT:
142  dm_init.correct_dm(context, dms, p_dms, p_controllers[i], p_geom,
143  imat, dataBase=dataBase, use_DB=use_DB)
144 
145  init_controller(context, i, p_controllers[i], p_wfss, p_geom, p_dms,
146  p_atmos, ittime, p_tel, rtc, dms, wfs, tel, atmos,
147  p_centroiders, do_refslp, dataBase=dataBase,
148  use_DB=use_DB)
149 
150  # add a geometric controller for processing error breakdown
151  roket_flag = True in [w.roket for w in p_wfss]
152  if (roket_flag):
153  p_controller = p_controllers[0]
154  Nphi = np.where(p_geom._spupil)[0].size
155 
156  list_dmseen = [p_dms[j].type for j in p_controller.ndm]
157  nactu = np.sum([p_dms[j]._ntotact for j in p_controller.ndm])
158 
159  nmodes = 0
160  if(p_controller.nmodes is not None):
161  nmodes = p_controller.nmodes
162 
163  rtc.add_controller(context, scons.ControllerType.GEO, context.active_device,
164  0, p_controller.nslope, p_controller.nactu,
165  p_controller.nslope_buffer, p_controller.nstates, p_controller.nstate_buffer,
166  nmodes, p_controller.n_iir_in, p_controller.n_iir_out,
167  p_controller.polc, p_controller.modal, dms, p_controller.ndm,
168  p_controller.ndm.size, p_controller.nwfs, p_controller.nwfs.size, Nphi, True)
169  init_controller_geo(ncontrol, rtc, dms, p_geom, p_controller, p_dms,
170  roket=True)
171 
172  return rtc
173 
174 
175 def rtc_standalone(context: carmaWrap_context, nwfs: int, nvalid: list, nactu: int,
176  centroider_type: list, delay: list, offset: list, scale: list,
177  brahma: bool = False, fp16: bool = False, cacao: bool = False) -> Rtc:
178  """Initialize all the SutraRtc objects : centroiders and controllers
179 
180  Args:
181  context: (carmaWrap_context): context
182 
183  nwfs: (int): number of wavefront sensors
184 
185  nvalid: (int): number of valid measures as input
186 
187  nactu: (int): number of actuators as output
188 
189  centroider_type: (list): type of centroiders
190 
191  delay: (list): delay of each controller
192 
193  offset: (list): offset added in the cog computation of each WFS
194 
195  scale: (list): scale factor used in the cog computation of each WFS
196 
197  Kwargs:
198  brahma: (bool) : brahma flag (default=False)
199 
200  fp16: (bool) : fp16 flag (default=False)
201 
202  cacao: (bool) : cacao flag (default=False)
203 
204  Returns:
205  Rtc : (Rtc) : Rtc object
206  """
207  print("start rtc_standalone")
208  if brahma:
209  rtc = Rtc_brahma(context, None, None, "rtc_brahma")
210  elif cacao:
211  if fp16:
212  from shesha.sutra_wrap import Rtc_cacao_FHF
213  rtc = Rtc_cacao_FHF("compass_calPix", "compass_loopData")
214  else:
215  rtc = Rtc_cacao_FFF("compass_calPix", "compass_loopData")
216  else:
217  if fp16:
218  from shesha.sutra_wrap import Rtc_FHF
219  rtc = Rtc_FHF()
220  else:
221  rtc = Rtc()
222  for k in range(nwfs):
223  # print(context, nvalid[k], offset[k], scale[k], False,
224  # context.active_device, centroider_type[k])
225  rtc.add_centroider(context, nvalid[k], offset[k], scale[k], False,
226  context.active_device, centroider_type[k])
227 
228  nslopes = sum([c.nslopes for c in rtc.d_centro])
229 
230  rtc.add_controller(context, "generic", context.active_device,delay[0],
231  nslopes, nactu, idx_centro=np.arange(nwfs),
232  ncentro=nwfs)
233 
234  print("rtc_standalone set")
235  return rtc
236 
237 
238 def init_centroider(context, nwfs: int, p_wfs: conf.Param_wfs,
239  p_centroider: conf.Param_centroider, p_tel: conf.Param_tel,
240  p_atmos: conf.Param_atmos, wfs: Sensors, rtc: Rtc):
241  """ Initialize a centroider object in Rtc
242 
243  Args:
244  context: (carmaWrap_context): context
245 
246  nwfs : (int) : index of wfs
247 
248  p_wfs : (Param_wfs): wfs settings
249 
250  p_centroider : (Param_centroider) : centroider settings
251 
252  wfs: (Sensors): Sensor object
253 
254  rtc : (Rtc) : Rtc object
255  """
256  if (p_wfs.type == scons.WFSType.SH):
257  if (p_centroider.type != scons.CentroiderType.CORR):
258  s_offset = p_wfs.npix // 2. - 0.5
259  else:
260  if (p_centroider.type_fct == scons.CentroiderFctType.MODEL):
261  if (p_wfs.npix % 2 == 0):
262  s_offset = p_wfs.npix // 2 - 0.5
263  else:
264  s_offset = p_wfs.npix // 2
265  else:
266  s_offset = p_wfs.npix // 2 - 0.5
267  s_scale = p_wfs.pixsize
268 
269  elif (p_wfs.type == scons.WFSType.PYRHR or p_wfs.type == scons.WFSType.PYRLR):
270  s_offset = 0.
271  s_scale = (p_wfs.Lambda * 1e-6 / p_tel.diam) * \
272  p_wfs.pyr_ampl * CONST.RAD2ARCSEC
273 
274  rtc.add_centroider(context, p_wfs._nvalid, s_offset, s_scale, p_centroider.filter_TT,
275  context.active_device, p_centroider.type, wfs.d_wfs[nwfs])
276  rtc.d_centro[-1].load_validpos(p_wfs._validsubsx, p_wfs._validsubsy,
277  p_wfs._nvalid * p_wfs.nPupils)
278 
279  rtc.d_centro[-1].set_npix(p_wfs.npix)
280 
281  if (p_centroider.type != scons.CentroiderType.MASKEDPIX):
282  p_centroider._nslope = 2 * p_wfs._nvalid
283  else:
284  p_centroider._nslope = p_wfs._validsubsx.size
285 
286  if (p_centroider.type == scons.CentroiderType.PYR):
287  # FIXME SIGNATURE CHANGES
288  rtc.d_centro[nwfs].set_pyr_method(p_centroider.method)
289  rtc.d_centro[nwfs].set_pyr_thresh(p_centroider.thresh)
290 
291  elif (p_wfs.type == scons.WFSType.SH):
292  if (p_centroider.type == scons.CentroiderType.TCOG or
293  p_centroider.type == scons.CentroiderType.WCOG):
294  rtc.d_centro[nwfs].set_threshold(p_centroider.thresh)
295  if (p_centroider.type == scons.CentroiderType.BPCOG):
296  rtc.d_centro[nwfs].set_nmax(p_centroider.nmax)
297  if (p_centroider.type == scons.CentroiderType.WCOG or
298  p_centroider.type == scons.CentroiderType.CORR):
299  r0 = p_atmos.r0 * (p_wfs.Lambda / 0.5)**(6 / 5.)
300  seeing = CONST.RAD2ARCSEC * (p_wfs.Lambda * 1.e-6) / r0
301  npix = seeing // p_wfs.pixsize
302  comp_weights(p_centroider, p_wfs, npix)
303  if p_centroider.type == scons.CentroiderType.WCOG:
304  rtc.d_centro[nwfs].init_weights()
305  rtc.d_centro[nwfs].load_weights(p_centroider.weights,
306  p_centroider.weights.ndim)
307  else:
308  corrnorm = np.ones((2 * p_wfs.npix, 2 * p_wfs.npix), dtype=np.float32)
309  p_centroider.sizex = 3
310  p_centroider.sizey = 3
311  p_centroider.interpmat = rtc_util.create_interp_mat(
312  p_centroider.sizex, p_centroider.sizey).astype(np.float32)
313 
314  if (p_centroider.weights is None):
315  raise ValueError("p_centroider.weights is None")
316  rtc.d_centro[nwfs].init_corr(p_centroider.sizex, p_centroider.sizey,
317  p_centroider.interpmat)
318  rtc.d_centro[nwfs].load_corr(p_centroider.weights, corrnorm,
319  p_centroider.weights.ndim)
320 
321 
322 def comp_weights(p_centroider: conf.Param_centroider, p_wfs: conf.Param_wfs, npix: int):
323  """ Compute the weights used by centroider wcog and corr
324 
325  Args:
326  p_centroider : (Param_centroider) : centroider settings
327 
328  p_wfs : (Param_wfs) : wfs settings
329 
330  npix: (int):
331  """
332  if (p_centroider.type_fct == scons.CentroiderFctType.MODEL):
333 
334  if (p_wfs.gsalt > 0):
335  tmp = p_wfs._lgskern
336  tmp2 = utilities.makegaussian(tmp.shape[1],
337  npix * p_wfs._nrebin).astype(np.float32)
338  tmp3 = np.zeros((tmp.shape[1], tmp.shape[1], p_wfs._nvalid),
339  dtype=np.float32)
340 
341  for j in range(p_wfs._nvalid):
342  tmp3[:, :, j] = np.fft.ifft2(
343  np.fft.fft2(tmp[:, :, j]) * np.fft.fft2(tmp2.T)).real
344  tmp3[:, :, j] *= tmp3.shape[0] * tmp3.shape[1]
345  tmp3[:, :, j] = np.fft.fftshift(tmp3[:, :, j])
346 
347  offset = (p_wfs._Ntot - p_wfs._nrebin * p_wfs.npix) // 2
348  j = offset + p_wfs._nrebin * p_wfs.npix
349  tmp = np.zeros((j - offset + 1, j - offset + 1, tmp3.shape[2]),
350  dtype=np.float32)
351  tmp3 = np.cumsum(tmp3[offset:j, offset:j, :], axis=0)
352  tmp[1:, 1:, :] = np.cumsum(tmp3, axis=1)
353  tmp = np.diff(tmp[::p_wfs._nrebin, ::p_wfs._nrebin, :], axis=0)
354  tmp = np.diff(tmp, axis=1)
355 
356  p_centroider.weights = tmp
357  else:
358  p_centroider.type_fct = scons.CentroiderFctType.GAUSS
359  print("No LGS found, centroider weighting function becomes gaussian")
360 
361  if (p_centroider.type_fct == scons.CentroiderFctType.GAUSS):
362  if p_centroider.width is None:
363  p_centroider.width = npix
364  if (p_wfs.npix % 2 == 1):
365  p_centroider.weights = utilities.makegaussian(
366  p_wfs.npix, p_centroider.width, p_wfs.npix // 2,
367  p_wfs.npix // 2).astype(np.float32)
368  elif (p_centroider.type == scons.CentroiderType.CORR):
369  p_centroider.weights = utilities.makegaussian(
370  p_wfs.npix, p_centroider.width, p_wfs.npix // 2,
371  p_wfs.npix // 2).astype(np.float32)
372  else:
373  p_centroider.weights = utilities.makegaussian(
374  p_wfs.npix, p_centroider.width, p_wfs.npix // 2 - 0.5,
375  p_wfs.npix // 2 - 0.5).astype(np.float32)
376 
377 
378 def init_controller(context, i: int, p_controller: conf.Param_controller, p_wfss: list,
379  p_geom: conf.Param_geom, p_dms: list, p_atmos: conf.Param_atmos,
380  ittime: float, p_tel: conf.Param_tel, rtc: Rtc, dms: Dms,
381  wfs: Sensors, tel: Telescope, atmos: Atmos,
382  p_centroiders: List[conf.Param_centroider], do_refslp=False,
383  dataBase={}, use_DB=False):
384  """ Initialize the controller part of rtc
385 
386  Args:
387  context: (carmaWrap_context): context
388 
389  i : (int) : controller index
390 
391  p_controller: (Param_controller) : controller settings
392 
393  p_wfss: (list of Param_wfs) : wfs settings
394 
395  p_geom: (Param_geom) : geom settings
396 
397  p_dms: (list of Param_dms) : dms settings
398 
399  p_atmos: (Param_atmos) : atmos settings
400 
401  ittime: (float) : iteration time [s]
402 
403  p_tel: (Param_tel) : telescope settings
404 
405  rtc: (Rtc) : Rtc objet
406 
407  dms: (Dms) : Dms object
408 
409  wfs: (Sensors) : Sensors object
410 
411  tel: (Telescope) : Telescope object
412 
413  atmos: (Atmos) : Atmos object
414 
415  p_centroiders: (list of Param_centroider): centroiders settings
416 
417  Kwargs:
418  do_refslp: (bool): do the reference slopes at startup,
419 
420  dataBase: (dict): database used
421 
422  use_DB: (bool): use database or not
423  """
424  if (p_controller.type != scons.ControllerType.GEO):
425  nwfs = p_controller.nwfs
426  if (len(p_wfss) == 1):
427  nwfs = p_controller.nwfs
428  # TODO fixing a bug ... still not understood
429  p_controller.set_nvalid(int(np.sum([p_wfss[k]._nvalid for k in nwfs])))
430  tmp = 0
431  for c in p_centroiders:
432  if (c.nwfs in nwfs):
433  tmp = tmp + c._nslope
434  p_controller.set_nslope(int(tmp))
435  else:
436  nslope = np.sum([c._nslope for c in p_centroiders])
437  p_controller.set_nslope(int(nslope))
438 
439  # parameter for add_controller(_geo)
440  ndms = p_controller.ndm.tolist()
441  nactu = np.sum([p_dms[j]._ntotact for j in ndms])
442  p_controller.set_nactu(int(nactu))
443 
444  alt = np.array([p_dms[j].alt for j in p_controller.ndm], dtype=np.float32)
445 
446  list_dmseen = [p_dms[j].type for j in p_controller.ndm]
447  if (p_controller.type == scons.ControllerType.GEO):
448  Nphi = np.where(p_geom._spupil)[0].size
449  else:
450  Nphi = -1
451 
452  #nslope = np.sum([c._nslope for c in p_centroiders])
453  #p_controller.set_nslope(int(nslope))
454 
455  nmodes = 0
456  if(p_controller.nmodes is not None):
457  nmodes = p_controller.nmodes
458 
459  if (p_controller.type == scons.ControllerType.GENERIC_LINEAR):
460  configure_generic_linear(p_controller)
461  nmodes = p_controller.nmodes
462 
463  #TODO : find a proper way to set the number of slope (other than 2 times nvalid)
464  rtc.add_controller(context, p_controller.type, context.active_device,p_controller.delay,
465  p_controller.nslope, p_controller.nactu, p_controller.nslope_buffer,
466  p_controller.nstates, p_controller.nstate_buffer, nmodes,
467  p_controller.n_iir_in, p_controller.n_iir_out,
468  p_controller.polc, p_controller.modal, dms, p_controller.ndm,
469  p_controller.ndm.size, p_controller.nwfs, p_controller.nwfs.size, Nphi, False)
470 
471  print("CONTROLLER ADDED")
472  if (p_wfss is not None and do_refslp):
473  rtc.do_centroids_ref(i)
474 
475  if (p_controller.type == scons.ControllerType.GEO):
476  init_controller_geo(i, rtc, dms, p_geom, p_controller, p_dms)
477 
478  if (p_controller.type == scons.ControllerType.LS):
479  init_controller_ls(i, p_controller, p_wfss, p_geom, p_dms, p_atmos, ittime,
480  p_tel, rtc, dms, wfs, tel, atmos, dataBase=dataBase,
481  use_DB=use_DB)
482 
483  if (p_controller.type == scons.ControllerType.CURED):
484  init_controller_cured(i, rtc, p_controller, p_dms, p_wfss)
485 
486  if (p_controller.type == scons.ControllerType.MV):
487  init_controller_mv(i, p_controller, p_wfss, p_geom, p_dms, p_atmos, p_tel, rtc,
488  dms, wfs, atmos)
489 
490  elif (p_controller.type == scons.ControllerType.GENERIC):
491  init_controller_generic(i, p_controller, p_dms, rtc)
492  try:
493  p_controller._imat = imats.imat_geom(wfs, dms, p_wfss, p_dms, p_controller,
494  meth=0)
495  except:
496  print("p_controller._imat not set")
497 
498 
499 def init_controller_geo(i: int, rtc: Rtc, dms: Dms, p_geom: conf.Param_geom,
500  p_controller: conf.Param_controller, p_dms: list, roket=False):
501  """ Initialize geometric controller
502 
503  Args:
504  i: (int): controller index
505 
506  rtc: (Rtc): rtc object
507 
508  dms: (Dms): Dms object
509 
510  p_geom: (Param_geom): geometry settings
511 
512  p_controller: (Param_controller): controller settings
513 
514  p_dms: (list of Param_dms): dms settings
515 
516  Kwargs
517  roket: (bool): Flag to initialize ROKET
518  """
519  indx_pup = np.where(p_geom._spupil.flatten('F'))[0].astype(np.int32)
520  indx_mpup = np.where(p_geom._mpupil.flatten('F'))[0].astype(np.int32)
521  cpt = 0
522  indx_dm = np.zeros((p_controller.ndm.size * indx_pup.size), dtype=np.int32)
523  for dmn in range(p_controller.ndm.size):
524  tmp_s = (p_geom._ipupil.shape[0] - (p_dms[dmn]._n2 - p_dms[dmn]._n1 + 1)) // 2
525  tmp_e0 = p_geom._ipupil.shape[0] - tmp_s
526  tmp_e1 = p_geom._ipupil.shape[1] - tmp_s
527  pup_dm = p_geom._ipupil[tmp_s:tmp_e0, tmp_s:tmp_e1]
528  indx_dm[cpt:cpt + np.where(pup_dm)[0].size] = np.where(pup_dm.flatten('F'))[0]
529  cpt += np.where(pup_dm)[0].size
530  # convert unitpervolt list to a np.ndarray
531  unitpervolt = np.array([p_dms[j].unitpervolt
532  for j in range(len(p_dms))], dtype=np.float32)
533 
534  rtc.d_control[i].init_proj_sparse(dms, indx_dm, unitpervolt, indx_pup, indx_mpup,
535  roket=roket)
536 
537 
538 def init_controller_ls(i: int, p_controller: conf.Param_controller, p_wfss: list,
539  p_geom: conf.Param_geom, p_dms: list, p_atmos: conf.Param_atmos,
540  ittime: float, p_tel: conf.Param_tel, rtc: Rtc, dms: Dms,
541  wfs: Sensors, tel: Telescope, atmos: Atmos, dataBase: dict = {},
542  use_DB: bool = False):
543  """ Initialize the least square controller
544 
545  Args:
546  i : (int) : controller index
547 
548  p_controller: (Param_controller) : controller settings
549 
550  p_wfss: (list of Param_wfs) : wfs settings
551 
552  p_geom: (Param_geom) : geom settings
553 
554  p_dms: (list of Param_dms) : dms settings
555 
556  p_atmos: (Param_atmos) : atmos settings
557 
558  ittime: (float) : iteration time [s]
559 
560  p_tel: (Param_tel) : telescope settings
561 
562  rtc: (Rtc) : Rtc objet
563 
564  dms: (Dms) : Dms object
565 
566  wfs: (Sensors) : Sensors object
567 
568  tel: (Telescope) : Telescope object
569 
570  atmos: (Atmos) : Atmos object
571 
572  Kwargs:
573  dataBase: (dict): database used
574 
575  use_DB: (bool): use database or not
576  """
577  from shesha.ao import basis
578  M2V = None
579  if p_controller.do_kl_imat:
580  IF = basis.compute_IFsparse(dms, p_dms, p_geom).T
581  M2V, _ = basis.compute_btt(IF[:, :-2], IF[:, -2:].toarray())
582  print("Filtering ", p_controller.nModesFilt, " modes based on mode ordering")
583  M2V = M2V[:, list(range(M2V.shape[1] - 2 - p_controller.nModesFilt)) + [-2, -1]]
584 
585  if len(p_controller.klpush) == 1: # Scalar allowed, now we expand
586  p_controller.klpush = p_controller.klpush[0] * np.ones(M2V.shape[1])
587  imats.imat_init(i, rtc, dms, p_dms, wfs, p_wfss, p_tel, p_controller, M2V,
588  dataBase=dataBase, use_DB=use_DB)
589 
590  if p_controller.modopti:
591  print("Initializing Modal Optimization : ")
592  p_controller.nrec = int(2**np.ceil(np.log2(p_controller.nrec)))
593  if p_controller.nmodes is None:
594  p_controller.nmodes = sum([p_dms[j]._ntotact for j in range(len(p_dms))])
595 
596  IF = basis.compute_IFsparse(dms, p_dms, p_geom).T
597  M2V, _ = basis.compute_btt(IF[:, :-2], IF[:, -2:].toarray())
598  M2V = M2V[:, list(range(p_controller.nmodes - 2)) + [-2, -1]]
599 
600  rtc.d_control[i].init_modalOpti(p_controller.nmodes, p_controller.nrec, M2V,
601  p_controller.gmin, p_controller.gmax,
602  p_controller.ngain, 1. / ittime)
603  ol_slopes = modopti.open_loopSlp(tel, atmos, wfs, rtc, p_controller.nrec, i,
604  p_wfss)
605  rtc.d_control[i].loadopen_loopSlp(ol_slopes)
606  rtc.d_control[i].modalControlOptimization()
607  else:
608  cmats.cmat_init(i, rtc, p_controller, p_wfss, p_atmos, p_tel, p_dms,
609  nmodes=p_controller.nmodes)
610 
611  rtc.d_control[i].set_gain(p_controller.gain)
612  mgain = np.ones(
613  sum([p_dms[j]._ntotact for j in range(len(p_dms))]), dtype=np.float32)
614  cc = 0
615  for ndm in p_dms:
616  mgain[cc:cc + ndm._ntotact] = ndm.gain
617  cc += ndm._ntotact
618  rtc.d_control[i].set_modal_gains(mgain)
619 
620 
621 def init_controller_cured(i: int, rtc: Rtc, p_controller: conf.Param_controller,
622  p_dms: list, p_wfss: list):
623  """ Initialize the CURED controller
624 
625  Args:
626  i : (int) : controller index
627 
628  rtc: (Rtc) : Rtc objet
629 
630  p_controller: (Param_controller) : controller settings
631 
632  p_dms: (list of Param_dms) : dms settings
633 
634  p_wfss: (list of Param_wfs) : wfs settings
635  """
636 
637  print("initializing cured controller")
638  if (scons.DmType.TT in [p_dms[j].type for j in range(len(p_dms))]):
639  tt_flag = True
640  else:
641  tt_flag = False
642  rtc.d_control[i].init_cured(p_wfss[0].nxsub, p_wfss[0]._isvalid,
643  p_controller.cured_ndivs, tt_flag)
644  rtc.d_control[i].set_gain(p_controller.gain)
645 
646 
647 def init_controller_mv(i: int, p_controller: conf.Param_controller, p_wfss: list,
648  p_geom: conf.Param_geom, p_dms: list, p_atmos: conf.Param_atmos,
649  p_tel: conf.Param_tel, rtc: Rtc, dms: Dms, wfs: Sensors,
650  atmos: Atmos):
651  """ Initialize the MV controller
652 
653  Args:
654  i : (int) : controller index
655 
656  p_controller: (Param_controller) : controller settings
657 
658  p_wfss: (list of Param_wfs) : wfs settings
659 
660  p_geom: (Param_geom) : geom settings
661 
662  p_dms: (list of Param_dms) : dms settings
663 
664  p_atmos: (Param_atmos) : atmos settings
665 
666  p_tel: (Param_tel) : telescope settings
667 
668  rtc: (Rtc) : Rtc objet
669 
670  dms: (Dms) : Dms object
671 
672  wfs: (Sensors) : Sensors object
673 
674  atmos: (Atmos) : Atmos object
675  """
676  p_controller._imat = imats.imat_geom(wfs, dms, p_wfss, p_dms, p_controller)
677  # imat_init(i,rtc,p_rtc,dms,wfs,p_wfss,p_tel,clean=1,simul_name=simul_name)
678  rtc.d_control[i].set_imat(p_controller._imat)
679  rtc.d_control[i].set_gain(p_controller.gain)
680  size = sum([p_dms[j]._ntotact for j in range(len(p_dms))])
681  mgain = np.ones(size, dtype=np.float32)
682  rtc.d_control[i].set_modal_gains(mgain)
683  tomo.do_tomo_matrices(i, rtc, p_wfss, dms, atmos, wfs, p_controller, p_geom, p_dms,
684  p_tel, p_atmos)
685  cmats.cmat_init(i, rtc, p_controller, p_wfss, p_atmos, p_tel, p_dms)
686 
687 
688 def init_controller_generic(i: int, p_controller: conf.Param_controller, p_dms: list,
689  rtc: Rtc):
690  """ Initialize the generic controller
691 
692  Args:
693  i: (int): controller index
694 
695  p_controller: (Param_controller): controller settings
696 
697  p_dms: (list of Param_dm): dms settings
698 
699  rtc: (Rtc): Rtc object
700  """
701  size = sum([p_dms[j]._ntotact for j in range(len(p_dms))])
702  decayFactor = np.ones(size, dtype=np.float32)
703  mgain = np.ones(size, dtype=np.float32) * p_controller.gain
704  matE = np.identity(size, dtype=np.float32)
705  cmat = np.zeros((size, p_controller.nslope), dtype=np.float32)
706 
707  if p_controller.command_law is not None:
708  rtc.d_control[i].set_commandlaw(p_controller.command_law)
709 
710  rtc.d_control[i].set_decayFactor(decayFactor)
711  rtc.d_control[i].set_modal_gains(mgain)
712  rtc.d_control[i].set_cmat(cmat)
713  rtc.d_control[i].set_matE(matE)
714 
715 def configure_generic_linear(p_controller: conf.Param_controller):
716  """ Configures the generic controller based on set parameters.
717 
718  Args:
719  i: (int): controller index
720 
721  p_controller: (Param_controller): controller settings
722 
723  p_dms: (list of Param_dm): dms settings
724 
725  rtc: (Rtc): Rtc object
726  """
727  if not p_controller.get_modal() or p_controller.get_nmodes() is None:
728  p_controller.set_nmodes(p_controller.get_nactu())
729  if p_controller.get_nstate_buffer() == 0:
730  p_controller.set_nstates(p_controller.get_nmodes())
Python package for AO operations on COMPASS simulation.
Definition: ao/__init__.py:1
Parameter classes for COMPASS.
Numerical constants for shesha and config enumerations for safe-typing.
Definition: constants.py:1
def init_centroider(context, int nwfs, conf.Param_wfs p_wfs, conf.Param_centroider p_centroider, conf.Param_tel p_tel, conf.Param_atmos p_atmos, Sensors wfs, Rtc rtc)
Initialize a centroider object in Rtc.
Definition: rtc_init.py:255
def init_controller_generic(int i, conf.Param_controller p_controller, list p_dms, Rtc rtc)
Initialize the generic controller.
Definition: rtc_init.py:700
Rtc rtc_standalone(carmaWrap_context context, int nwfs, list nvalid, int nactu, list centroider_type, list delay, list offset, list scale, bool brahma=False, bool fp16=False, bool cacao=False)
Initialize all the SutraRtc objects : centroiders and controllers.
Definition: rtc_init.py:206
def configure_generic_linear(conf.Param_controller p_controller)
Configures the generic controller based on set parameters.
Definition: rtc_init.py:726
def init_controller(context, int i, conf.Param_controller p_controller, list p_wfss, conf.Param_geom p_geom, list p_dms, conf.Param_atmos p_atmos, float ittime, conf.Param_tel p_tel, Rtc rtc, Dms dms, Sensors wfs, Telescope tel, Atmos atmos, List[conf.Param_centroider] p_centroiders, do_refslp=False, dataBase={}, use_DB=False)
Initialize the controller part of rtc.
Definition: rtc_init.py:423
def init_controller_mv(int i, conf.Param_controller p_controller, list p_wfss, conf.Param_geom p_geom, list p_dms, conf.Param_atmos p_atmos, conf.Param_tel p_tel, Rtc rtc, Dms dms, Sensors wfs, Atmos atmos)
Initialize the MV controller.
Definition: rtc_init.py:675
def init_controller_cured(int i, Rtc rtc, conf.Param_controller p_controller, list p_dms, list p_wfss)
Initialize the CURED controller.
Definition: rtc_init.py:635
def init_controller_ls(int i, conf.Param_controller p_controller, list p_wfss, conf.Param_geom p_geom, list p_dms, conf.Param_atmos p_atmos, float ittime, conf.Param_tel p_tel, Rtc rtc, Dms dms, Sensors wfs, Telescope tel, Atmos atmos, dict dataBase={}, bool use_DB=False)
Initialize the least square controller.
Definition: rtc_init.py:576
def init_controller_geo(int i, Rtc rtc, Dms dms, conf.Param_geom p_geom, conf.Param_controller p_controller, list p_dms, roket=False)
Initialize geometric controller.
Definition: rtc_init.py:518
def rtc_init(carmaWrap_context context, Telescope tel, Sensors wfs, Dms dms, Atmos atmos, list p_wfss, conf.Param_tel p_tel, conf.Param_geom p_geom, conf.Param_atmos p_atmos, float ittime, p_centroiders=None, p_controllers=None, p_dms=None, do_refslp=False, brahma=False, cacao=False, tar=None, dataBase={}, use_DB=False)
Initialize all the SutraRtc objects : centroiders and controllers.
Definition: rtc_init.py:103
def comp_weights(conf.Param_centroider p_centroider, conf.Param_wfs p_wfs, int npix)
Compute the weights used by centroider wcog and corr.
Definition: rtc_init.py:331
Python package for COMPASS simulation initialization.
Definition: init/__init__.py:1
Utilities functions.
Definition: util/__init__.py:1