COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
stageSupervisor.py
1 
37 
38 from shesha.supervisor.compassSupervisor import CompassSupervisor
39 from shesha.supervisor.components import AtmosCompass, DmCompass, RtcCompass, TargetCompass, TelescopeCompass, WfsCompass
40 from shesha.supervisor.optimizers import ModalBasis, Calibration, ModalGains
41 import numpy as np
42 import time
43 
44 import shesha.constants as scons
45 
46 from typing import Iterable
47 
48 
50  """ This class implements a single stage (e.g. first stage, second stage) supervisor
51  to handle compass simulations of cascaded AO. The main supervision will be handled by another
52  supervisor (manager).
53 
54  Attributes:
55  context : (CarmaContext) : a CarmaContext instance
56 
57  config : (config) : Parameters structure
58 
59  is_init : (bool) : Flag equals to True if the supervisor has already been initialized
60 
61  iter : (int) : Frame counter
62 
63  telescope : (TelescopeComponent) : a TelescopeComponent instance
64 
65  atmos : (AtmosComponent) : An AtmosComponent instance
66 
67  target : (targetComponent) : A TargetComponent instance
68 
69  wfs : (WfsComponent) : A WfsComponent instance
70 
71  dms : (DmComponent) : A DmComponent instance
72 
73  rtc : (RtcComponent) : A Rtc component instance
74 
75  cacao : (bool) : CACAO features enabled in the RTC
76 
77  basis : (ModalBasis) : a ModalBasis instance (optimizer)
78 
79  calibration : (Calibration) : a Calibration instance (optimizer)
80 
81  modalgains : (ModalGains) : a ModalGain instance (optimizer) using CLOSE algorithm
82 
83  close_modal_gains : (list of floats) : list of the previous values of the modal gains
84  """
85 
86  def next(self, *, move_atmos: bool = True, nControl: int = 0,
87  tar_trace: Iterable[int] = None, wfs_trace: Iterable[int] = None,
88  do_control: bool = True, apply_control: bool = True,
89  compute_tar_psf: bool = True, stack_wfs_image: bool = False,
90  do_centroids: bool = True, compute_corono: bool=True) -> None:
91  """Iterates the AO loop, with optional parameters, considering it is a single
92  stage and may be called in the middle of WFS frames.
93  Overload the CompassSupervisor next() method to arrange tasks orders and allow cascaded
94  simulation.
95 
96  Kwargs:
97  move_atmos: (bool): move the atmosphere for this iteration. Default is True
98 
99  nControl: (int): Controller number to use. Default is 0 (single control configuration)
100 
101  tar_trace: (List): list of targets to trace. None is equivalent to all (default)
102 
103  wfs_trace: (List): list of WFS to trace. None is equivalent to all (default)
104 
105  do_control : (bool) : Performs RTC operations if True (Default)
106 
107  apply_control: (bool): if True (default), apply control on DMs
108 
109  compute_tar_psf : (bool) : If True (default), computes the PSF at the end of the
110  iteration
111 
112  stack_wfs_image : (bool) : If False (default), the Wfs image is computed as
113  usual. Otherwise, a newly computed WFS image is accumulated
114  to the previous one.
115 
116  do_centroids : (bool) : If True (default), the last WFS image is stacked and
117  centroids computation is done. WFS image must be reset before
118  next loop (in the manager).
119 
120  compute_corono: (bool): If True (default), computes the coronagraphic image
121  """
122  try:
123  iter(nControl)
124  except TypeError:
125  # nControl is not an iterable creating a list
126  nControl = [nControl]
127 
128  #get the index of the first GEO controller (-1 if there is no GEO controller)
129  geo_index = next(( i for i,c in enumerate(self.configconfig.p_controllers)
130  if c.type== scons.ControllerType.GEO ), -1)
131 
132  if tar_trace is None and self.targettarget is not None:
133  tar_trace = range(len(self.configconfig.p_targets))
134  if wfs_trace is None and self.wfswfs is not None:
135  wfs_trace = range(len(self.configconfig.p_wfss))
136 
137  if move_atmos and self.atmosatmos is not None:
138  self.atmosatmos.move_atmos()
139  # in case there is at least 1 controller GEO in the controller list : use this one only
140  self.teltel.update_input_phase()
141 
142  if ( geo_index > -1):
143  nControl = geo_index
144 
145  if tar_trace is not None:
146  for t in tar_trace:
147 
148  if apply_control:
149  self.rtcrtc.apply_control(nControl)
150 
151  if self.atmosatmos.is_enable:
152  self.targettarget.raytrace(t, tel=self.teltel, atm=self.atmosatmos, ncpa=False)
153  else:
154  self.targettarget.raytrace(t, tel=self.teltel, ncpa=False)
155 
156  if do_control and self.rtcrtc is not None:
157  self.rtcrtc.do_control(nControl, sources=self.targettarget.sources)
158  self.targettarget.raytrace(t, dms=self.dmsdms, ncpa=True, reset=False)
159 
160  if self.cacaocacao:
161  self.rtcrtc.publish()
162 
163  else:
164  # start updating the DM shape
165  if apply_control:
166  for ncontrol in nControl :
167  # command buffer is updated and commands voltages update is applied
168  self.rtcrtc.apply_control(ncontrol)
169  # Note: clipping is always made by apply_control (CBE. 2023.01.27)
170 
171  # start the propagations
172  if tar_trace is not None: # already checked at line 213?
173  for t in tar_trace:
174  if self.atmosatmos.is_enable:
175  self.targettarget.raytrace(t, tel=self.teltel, atm=self.atmosatmos,
176  dms=self.dmsdms)
177  else:
178  self.targettarget.raytrace(t, tel=self.teltel, dms=self.dmsdms)
179 
180  if wfs_trace is not None: # already checked at line 215?
181  for w in wfs_trace:
182  if self.atmosatmos.is_enable:
183  self.wfswfs.raytrace(w, tel=self.teltel, atm=self.atmosatmos)
184  else:
185  self.wfswfs.raytrace(w, tel=self.teltel)
186 
187  if not self.configconfig.p_wfss[w].open_loop and self.dmsdms is not None:
188  self.wfswfs.raytrace(w, dms=self.dmsdms, ncpa=False, reset=False)
189 
190  if stack_wfs_image:
191  # accumulate image during sub-integration frames
192  wfs_image = self.wfswfs.get_wfs_image(w)
193  self.wfswfs.compute_wfs_image(w)
194  self.wfswfs.set_wfs_image(w, self.wfswfs.get_wfs_image(w) + wfs_image)
195  else:
196  self.wfswfs.compute_wfs_image(w)
197 
198  if self.rtcrtc is not None:
199  for ncontrol in nControl : # range(len(self.config.p_controllers)):
200  # modified to allow do_centroids when the WFS exposure is over.
201  # Also useful for calibration. (CBE 2023.01.30)
202  if do_centroids:
203  self.rtcrtc.do_centroids(ncontrol)
204 
205  if do_control:
206  self.rtcrtc.do_control(ncontrol)
207 
208  if self.cacaocacao:
209  self.rtcrtc.publish()
210 
211 
212  if compute_tar_psf:
213  for tar_index in tar_trace:
214  self.targettarget.comp_tar_image(tar_index)
215  self.targettarget.comp_strehl(tar_index)
216 
217  if self.coronocorono is not None and compute_corono:
218  for coro_index in range(len(self.configconfig.p_coronos)):
219  self.coronocorono.compute_image(coro_index)
220 
221  if self.configconfig.p_controllers[0].close_opti and (not self.rtcrtc._rtc.d_control[0].open_loop):
222  self.modalgainsmodalgains.update_mgains()
223  self.close_modal_gainsclose_modal_gains.append(self.modalgainsmodalgains.get_modal_gains())
224 
225  self.iteriter += 1
226 
227 
228  def reset(self):
229  """
230  Reset the simulation to return to its original state.
231  Overwrites the compassSupervisor reset function, reseting explicitely the WFS image,
232  to force a new integration of the frame.
233  """
234  self.atmosatmos.reset_turbu()
235  self.wfswfs.reset_noise()
236  self.wfswfs.reset_image()
237  for tar_index in range(len(self.configconfig.p_targets)):
238  self.targettarget.reset_strehl(tar_index)
239  self.dmsdms.reset_dm()
240  self.rtcrtc.open_loop()
241  self.rtcrtc.close_loop()
This class implements generic supervisor to handle compass simulation.
atmos
(AtmosComponent) : An AtmosComponent instance
rtc
(RtcComponent) : A Rtc component instance
target
(targetComponent) : A TargetComponent instance
cacao
(bool) : CACAO features enabled in the RTC
modalgains
(ModalGains) : a ModalGain instance (optimizer) using CLOSE algorithm
close_modal_gains
(list of floats) : list of the previous values of the modal gains
wfs
(WfsComponent) : A WfsComponent instance
This class implements a single stage (e.g.
None next(self, *bool move_atmos=True, int nControl=0, Iterable[int] tar_trace=None, Iterable[int] wfs_trace=None, bool do_control=True, bool apply_control=True, bool compute_tar_psf=True, bool stack_wfs_image=False, bool do_centroids=True, bool compute_corono=True)
Iterates the AO loop, with optional parameters, considering it is a single stage and may be called in...
def reset(self)
Reset the simulation to return to its original state.
Numerical constants for shesha and config enumerations for safe-typing.
Definition: constants.py:1
Initialization and execution of a COMPASS supervisor.
User layer for optimizing AO supervisor loop.