COMPASS  5.0.0
End-to-end AO simulation tool using GPU acceleration
guardians.roket.Roket Class Reference
Inheritance diagram for guardians.roket.Roket:
Collaboration diagram for guardians.roket.Roket:

Public Member Functions

def __init__ (self, str=None, N_preloop=1000, gamma=1.)
 Initializes an instance of Roket class. More...
 
def init_config (self)
 Initializes the COMPASS simulation and the ROKET buffers. More...
 
def next (self, **kwargs)
 
def loop (self, monitoring_freq=100, **kwargs)
 Performs the AO loop for n iterations. More...
 
def error_breakdown (self)
 
def save_in_hdf5 (self, savename)
 Saves all the ROKET buffers + simuation parameters in a HDF5 file. More...
 
def cov_cor (self)
 Computes covariance matrix and correlation matrix between all the contributors. More...
 
- Public Member Functions inherited from shesha.supervisor.compassSupervisor.CompassSupervisor
def __init__ (self, config, bool cacao=False)
 
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)
 Iterates the AO loop, with optional parameters. More...
 
def record_ao_circular_buffer (self, int cb_count, np.ndarray projection_matrix, int sub_sample=1, int controller_index=0, int tar_index=0, bool see_atmos=True, str cube_data_type=None, str cube_data_file_path="", int ncpa=0, np.ndarray ncpa_wfs=None, np.ndarray ref_slopes=None, bool ditch_strehl=True)
 Used to record a synchronized circular buffer AO loop data. More...
 
- Public Member Functions inherited from shesha.supervisor.genericSupervisor.GenericSupervisor
def __init__ (self, config)
 
def get_config (self)
 Returns the configuration in use, in a supervisor specific format ? More...
 
int get_frame_counter (self)
 Return the current iteration number of the loop. More...
 
None force_context (self)
 Active all the GPU devices specified in the parameters file. More...
 
def loop (self, int number_of_iter, *int monitoring_freq=100, bool compute_tar_psf=True, **kwargs)
 Perform the AO loop for <number_of_iter> iterations. More...
 
def reset (self)
 Reset the simulation to return to its original state. More...
 

Public Attributes

 N_preloop
 
 gamma
 
 iter_number
 
 n
 
 nfiltered
 
 nactus
 
 nslopes
 
 com
 
 noise_com
 
 alias_wfs_com
 
 alias_meas
 
 wf_com
 
 tomo_com
 
 trunc_com
 
 trunc_meas
 
 H_com
 
 mod_com
 
 bp_com
 
 fit
 
 psf_ortho
 
 centroid_gain
 
 centroid_gain2
 
 slopes
 
 IFpzt
 
 TT
 
 P
 
 cmat
 
 D
 
 RD
 
 gRD
 
 Nact
 
 SR2
 
 SR
 
 cov
 
 cor
 
- Public Attributes inherited from shesha.supervisor.compassSupervisor.CompassSupervisor
 cacao
 Instantiates a CompassSupervisor object. More...
 
 basis
 
 calibration
 
 tel
 
 atmos
 
 dms
 
 target
 
 wfs
 
 rtc
 
- Public Attributes inherited from shesha.supervisor.genericSupervisor.GenericSupervisor
 context
 
 config
 
 telescope
 
 atmos
 
 target
 
 wfs
 
 dms
 
 rtc
 
 is_init
 
 iter
 Init the a supervisor. More...
 

Detailed Description

Definition at line 33 of file roket.py.

Constructor & Destructor Documentation

◆ __init__()

def guardians.roket.Roket.__init__ (   self,
  str = None,
  N_preloop = 1000,
  gamma = 1. 
)

Initializes an instance of Roket class.

   :parameters:

str (str): (optional) path to a parameter file N_preloop (int): (optional) number of iterations before starting error breakdown estimation gamma (float): (optional) centroid gain

Definition at line 43 of file roket.py.

43  """
44  super().__init__(str)
45  self.N_preloop = N_preloop
46  self.gamma = gamma
47 

Member Function Documentation

◆ cov_cor()

def guardians.roket.Roket.cov_cor (   self)

Computes covariance matrix and correlation matrix between all the contributors.

Definition at line 396 of file roket.py.

396  """
397  self.cov = np.zeros((6, 6))
398  self.cor = np.zeros((6, 6))
399  bufdict = {
400  "0": self.noise_com.T,
401  "1": self.trunc_com.T,
402  "2": self.alias_wfs_com.T,
403  "3": self.H_com.T,
404  "4": self.bp_com.T,
405  "5": self.tomo_com.T
406  }
407  for i in range(self.cov.shape[0]):
408  for j in range(self.cov.shape[1]):
409  if (j >= i):
410  tmpi = self.P.dot(bufdict[str(i)])
411  tmpj = self.P.dot(bufdict[str(j)])
412  self.cov[i, j] = np.sum(
413  np.mean(tmpi * tmpj, axis=1) -
414  np.mean(tmpi, axis=1) * np.mean(tmpj, axis=1))
415  else:
416  self.cov[i, j] = self.cov[j, i]
417 
418  s = np.reshape(np.diag(self.cov), (self.cov.shape[0], 1))
419  sst = np.dot(s, s.T)
420  ok = np.where(sst)
421  self.cor[ok] = self.cov[ok] / np.sqrt(sst[ok])
422 
423 
Here is the caller graph for this function:

◆ error_breakdown()

def guardians.roket.Roket.error_breakdown (   self)

Definition at line 165 of file roket.py.

165  """
166  g = self.config.p_controllers[0].gain
167  Dcom = self.get_command(0)
168  Derr = self.get_err(0)
169  self.com[self.iter_number, :] = Dcom
170  tarphase = self.get_tar_phase(0)
171  self.slopes[self.iter_number, :] = self.get_slopes(0)
172 
173  ###########################################################################
174  ## Noise contribution
175  ###########################################################################
176  if (self.config.p_wfss[0].type == scons.WFSType.SH):
177  ideal_img = np.array(self._sim.wfs.d_wfs[0].d_binimg_notnoisy)
178  binimg = np.array(self._sim.wfs.d_wfs[0].d_binimg)
179  if (self.config.p_centroiders[0].type == scons.CentroiderType.TCOG
180  ): # Select the same pixels with or without noise
181  invalidpix = np.where(binimg <= self.config.p_centroiders[0].thresh)
182  ideal_img[invalidpix] = 0
183  self.set_centroider_threshold(0, -1e16)
184  self._sim.wfs.d_wfs[0].set_binimg(ideal_img, ideal_img.size)
185  elif (self.config.p_wfss[0].type == scons.centroiderType.PYRHR):
186  ideal_pyrimg = np.array(self._sim.wfs.d_wfs[0].d_binimg_notnoisy)
187  self._sim.wfs.d_wfs[0].set_binimg(ideal_pyrimg, ideal_pyrimg.size)
188 
189  self._sim.doCentroids(0)
190  if (self.config.p_centroiders[0].type == scons.CentroiderType.TCOG):
191  self.set_centroider_threshold(0, config.p_centroiders[0].thresh)
192 
193  self._sim.do_control(0)
194  E = self.get_err(0)
195  E_meas = self.get_slopes(0)
196  # Apply loop filter to get contribution of noise on commands
197  if (self.iter_number + 1 < self.config.p_loop.niter):
198  self.noise_com[self.iter_number + 1, :] = self.gRD.dot(
199  self.noise_com[self.iter_number, :]) + g * (Derr - E)
200  ###########################################################################
201  ## Sampling/truncature contribution
202  ###########################################################################
203  self._sim.doCentroidsGeom(0)
204  self._sim.do_control(0)
205  F = self.get_err(0)
206  F_meas = self.get_slopes(0)
207  self.trunc_meas[self.iter_number, :] = E_meas - F_meas
208  # Apply loop filter to get contribution of sampling/truncature on commands
209  if (self.iter_number + 1 < self.config.p_loop.niter):
210  self.trunc_com[self.iter_number + 1, :] = self.gRD.dot(
211  self.trunc_com[self.iter_number, :]) + g * (E - self.gamma * F)
212  self.centroid_gain += centroid_gain(E, F)
213  self.centroid_gain2 += centroid_gain(Derr, F)
214  ###########################################################################
215  ## Aliasing contribution on WFS direction
216  ###########################################################################
217  self._sim.do_control(1, 0, wfs_direction=True)
218  self._sim.applyControl(1)
219  for w in range(len(self.config.p_wfss)):
220  self._sim.raytrace_wfs(w, "dm", rst=False)
221  """
222  wfs.sensors_compimg(0)
223  if(config.p_wfss[0].type == scons.WFSType.SH):
224  ideal_img = wfs.get_binimgNotNoisy(0)
225  binimg = wfs.get_binimg(0)
226  if(config.p_centroiders[0].type == scons.CentroiderType.TCOG): # Select the same pixels with or without noise
227  invalidpix = np.where(binimg <= config.p_centroiders[0].thresh)
228  ideal_img[self.iter_numbernvalidpix] = 0
229  rtc.setthresh(0,-1e16)
230  wfs.set_binimg(0,ideal_img)
231  elif(config.p_wfss[0].type == scons.centroiderType.PYRHR):
232  ideal_pyrimg = wfs.get_binimg_notnoisy(0)
233  wfs.set_pyrimg(0,ideal_pyrimg)
234  """
235  self._sim.doCentroidsGeom(0)
236  self._sim.do_control(0)
237  Ageom = self.get_err(0)
238  self.alias_meas[self.iter_number, :] = self.get_slopes(0)
239  if (self.iter_number + 1 < self.config.p_loop.niter):
240  self.alias_wfs_com[self.iter_number + 1, :] = self.gRD.dot(
241  self.alias_wfs_com[self.iter_number, :]) + self.gamma * g * (
242  Ageom) # - (E-F))
243 
244  ###########################################################################
245  ## Wavefront + filtered modes reconstruction
246  ###########################################################################
247  self._sim.raytraceTar(0, "atmos")
248  self._sim.do_control(1, 0, wfs_direction=False)
249  B = self.get_command(1)
250 
251  ###########################################################################
252  ## Fitting
253  ###########################################################################
254  self._sim.applyControl(1)
255  self._sim.raytraceTar(0, "dm", rst=False)
256 
257  self._sim.comp_tar_image(0, compLE=False)
258  self._sim.compStrehl(0)
259  self.fit[self.iter_number] = self.get_strehl(0)[2]
260  if (self.iter_number >= self.N_preloop):
261  self.psf_ortho += self.get_tar_image(0, 'se')
262 
263  ###########################################################################
264  ## Filtered modes error & Commanded modes
265  ###########################################################################
266  modes = self.P.dot(B)
267  modes_filt = modes.copy() * 0.
268  modes_filt[-self.nfiltered - 2:-2] = modes[-self.nfiltered - 2:-2]
269  self.H_com[self.iter_number, :] = self.Btt.dot(modes_filt)
270  modes[-self.nfiltered - 2:-2] = 0
271  self.mod_com[self.iter_number, :] = self.Btt.dot(modes)
272 
273  ###########################################################################
274  ## Bandwidth error
275  ###########################################################################
276  C = self.mod_com[self.iter_number, :] - self.mod_com[self.iter_number - 1, :]
277 
278  self.bp_com[self.iter_number, :] = self.gRD.dot(
279  self.bp_com[self.iter_number - 1, :]) - C
280 
281  ###########################################################################
282  ## Tomographic error
283  ###########################################################################
284  #G = F - (mod_com[self.iter_number,:] + Ageom - np.dot(RDgeom,com[self.iter_number-1,:]))
285  for w in range(len(self.config.p_wfss)):
286  self._sim.raytrace_wfs(w, "atmos")
287 
288  self._sim.do_control(1, 0, wfs_direction=True)
289  G = self.get_command(1)
290  modes = self.P.dot(G)
291  modes[-self.nfiltered - 2:-2] = 0
292  self.wf_com[self.iter_number, :] = self.Btt.dot(modes)
293 
294  G = self.mod_com[self.iter_number, :] - self.wf_com[self.iter_number, :]
295  if (self.iter_number + 1 < self.config.p_loop.niter):
296  self.tomo_com[self.iter_number + 1, :] = self.gRD.dot(
297  self.tomo_com[self.iter_number, :]) - g * self.gamma * self.RD.dot(G)
298 
299  # Without anyone noticing...
300  self._sim.tar.d_targets[0].set_phase(tarphase)
301  self._sim.rtc.d_control[0].set_com(Dcom, Dcom.size)
302 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_config()

def guardians.roket.Roket.init_config (   self)

Initializes the COMPASS simulation and the ROKET buffers.

Definition at line 51 of file roket.py.

51  """
52  super().init_config()
53  self.iter_number = 0
54  self.n = self.config.p_loop.niter + self.N_preloop
55  self.nfiltered = int(self.config.p_controllers[0].maxcond)
56  self.nactus = self.get_command(0).size
57  self.nslopes = self.get_slopes(0).size
58  self.com = np.zeros((self.n, self.nactus), dtype=np.float32)
59  self.noise_com = np.zeros((self.n, self.nactus), dtype=np.float32)
60  self.alias_wfs_com = np.copy(self.noise_com)
61  self.alias_meas = np.zeros((self.n, self.nslopes), dtype=np.float32)
62  self.wf_com = np.copy(self.noise_com)
63  self.tomo_com = np.copy(self.noise_com)
64  self.trunc_com = np.copy(self.noise_com)
65  self.trunc_meas = np.copy(self.alias_meas)
66  self.H_com = np.copy(self.noise_com)
67  self.mod_com = np.copy(self.noise_com)
68  self.bp_com = np.copy(self.noise_com)
69  self.fit = np.zeros(self.n)
70  self.psf_ortho = self.get_tar_image(0) * 0
71  self.centroid_gain = 0
72  self.centroid_gain2 = 0
73  self.slopes = np.zeros((self.n, self.nslopes), dtype=np.float32)
74  #gamma = 1.0
75  self.config.p_loop.set_niter(self.n)
76  self.IFpzt = self.get_influ_basis_sparse(1)
77  self.TT = self.get_tt_influ_basis(1)
78 
79  self.Btt, self.P = compute_btt(self.IFpzt.T, self.TT)
80  tmp = self.Btt.dot(self.Btt.T)
81  self._sim.rtc.d_control[1].load_Btt(tmp[:-2, :-2], tmp[-2:, -2:])
82  compute_cmat_with_Btt(self._sim.rtc, self.Btt, self.nfiltered)
83  self.cmat = self.get_command_matrix(0)
84  self.D = self.get_interaction_matrix(0)
85  self.RD = np.dot(self.cmat, self.D)
86  self.gRD = np.identity(
87  self.RD.
88  shape[0]) - self.config.p_controllers[0].gain * self.gamma * self.RD
89 
90  self.Nact = create_nact_geom(self.config.p_dms[0])
91 

◆ loop()

def guardians.roket.Roket.loop (   self,
  monitoring_freq = 100,
**  kwargs 
)

Performs the AO loop for n iterations.

   :parameters:

monitoring_freq (int): (optional) Loop monitoring frequency [frames] in the terminal

Definition at line 114 of file roket.py.

114  """
115  print("-----------------------------------------------------------------")
116  print("iter# | SE SR | LE SR | FIT SR | PH SR | ETR (s) | Framerate (Hz)")
117  print("-----------------------------------------------------------------")
118  t0 = time.time()
119  for i in range(self.n):
120  self.next(**kwargs)
121  if ((i + 1) % monitoring_freq == 0):
122  framerate = (i + 1) / (time.time() - t0)
123  self._sim.comp_tar_image(0)
124  self._sim.compStrehl(0)
125  strehltmp = self.get_strehl(0)
126  etr = (self.n - i) / framerate
127  print("%d \t %.2f \t %.2f\t %.2f \t %.2f \t %.1f \t %.1f" %
128  (i + 1, strehltmp[0], strehltmp[1], np.exp(-strehltmp[2]),
129  np.exp(-strehltmp[3]), etr, framerate))
130  t1 = time.time()
131 
132  print(" loop execution time:", t1 - t0, " (", self.n, "iterations), ",
133  (t1 - t0) / self.n, "(mean) ", self.n / (t1 - t0), "Hz")
134 
135  #self.tar.comp_image(0)
136  SRs = self.get_strehl(0)
137  self.SR2 = np.exp(SRs[3])
138  self.SR = SRs[1]
139 
Here is the call graph for this function:

◆ next()

def guardians.roket.Roket.next (   self,
**  kwargs 
)

Definition at line 102 of file roket.py.

102  """
103  self._sim.next(apply_control=False)
104  self.error_breakdown()
105  self._sim.applyControl(0)
106  self.iter_number += 1
107 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_in_hdf5()

def guardians.roket.Roket.save_in_hdf5 (   self,
  savename 
)

Saves all the ROKET buffers + simuation parameters in a HDF5 file.

   :parameters:

savename (str): name of the output file

Definition at line 309 of file roket.py.

309  """
310  tmp = (self.config.p_geom._ipupil.shape[0] -
311  (self.config.p_dms[0]._n2 - self.config.p_dms[0]._n1 + 1)) // 2
312  tmp_e0 = self.config.p_geom._ipupil.shape[0] - tmp
313  tmp_e1 = self.config.p_geom._ipupil.shape[1] - tmp
314  pup = self.config.p_geom._ipupil[tmp:tmp_e0, tmp:tmp_e1]
315  indx_pup = np.where(pup.flatten() > 0)[0].astype(np.int32)
316  dm_dim = self.config.p_dms[0]._n2 - self.config.p_dms[0]._n1 + 1
317  self.cov_cor()
318  psf = self.get_tar_image(0, "le")
319 
320  fname = os.getenv("DATA_GUARDIAN") + savename
321  pdict = {
322  "noise":
323  self.noise_com[self.N_preloop:, :].T,
324  "aliasing":
325  self.alias_wfs_com[self.N_preloop:, :].T,
326  "tomography":
327  self.tomo_com[self.N_preloop:, :].T,
328  "filtered modes":
329  self.H_com[self.N_preloop:, :].T,
330  "non linearity":
331  self.trunc_com[self.N_preloop:, :].T,
332  "bandwidth":
333  self.bp_com[self.N_preloop:, :].T,
334  "wf_com":
335  self.wf_com[self.N_preloop:, :].T,
336  "P":
337  self.P,
338  "Btt":
339  self.Btt,
340  "IF.data":
341  self.IFpzt.data,
342  "IF.indices":
343  self.IFpzt.indices,
344  "IF.indptr":
345  self.IFpzt.indptr,
346  "TT":
347  self.TT,
348  "dm_dim":
349  dm_dim,
350  "indx_pup":
351  indx_pup,
352  "fitting":
353  np.mean(self.fit[self.N_preloop:]),
354  "SR":
355  self.SR,
356  "SR2":
357  self.SR2,
358  "cov":
359  self.cov,
360  "cor":
361  self.cor,
362  "psfortho":
363  np.fft.fftshift(self.psf_ortho) /
364  (self.config.p_loop.niter - self.N_preloop),
365  "centroid_gain":
366  self.centroid_gain / (self.config.p_loop.niter - self.N_preloop),
367  "centroid_gain2":
368  self.centroid_gain2 /
369  (self.config.p_loop.niter - self.N_preloop),
370  "dm.xpos":
371  self.config.p_dms[0]._xpos,
372  "dm.ypos":
373  self.config.p_dms[0]._ypos,
374  "R":
375  self.get_command_matrix(0),
376  "D":
377  self.get_interaction_matrix(0),
378  "Nact":
379  self.Nact,
380  "com":
381  self.com[self.N_preloop:, :].T,
382  "slopes":
383  self.slopes[self.N_preloop:, :].T,
384  "alias_meas":
385  self.alias_meas[self.N_preloop:, :].T,
386  "trunc_meas":
387  self.trunc_meas[self.N_preloop:, :].T
388  }
389  h5u.save_h5(fname, "psf", self.config, psf)
390  for k in list(pdict.keys()):
391  h5u.save_hdf5(fname, k, pdict[k])
392 
Here is the call graph for this function:

Member Data Documentation

◆ alias_meas

guardians.roket.Roket.alias_meas

Definition at line 61 of file roket.py.

◆ alias_wfs_com

guardians.roket.Roket.alias_wfs_com

Definition at line 60 of file roket.py.

◆ bp_com

guardians.roket.Roket.bp_com

Definition at line 68 of file roket.py.

◆ centroid_gain

guardians.roket.Roket.centroid_gain

Definition at line 71 of file roket.py.

◆ centroid_gain2

guardians.roket.Roket.centroid_gain2

Definition at line 72 of file roket.py.

◆ cmat

guardians.roket.Roket.cmat

Definition at line 83 of file roket.py.

◆ com

guardians.roket.Roket.com

Definition at line 58 of file roket.py.

◆ cor

guardians.roket.Roket.cor

Definition at line 398 of file roket.py.

◆ cov

guardians.roket.Roket.cov

Definition at line 397 of file roket.py.

◆ D

guardians.roket.Roket.D

Definition at line 84 of file roket.py.

◆ fit

guardians.roket.Roket.fit

Definition at line 69 of file roket.py.

◆ gamma

guardians.roket.Roket.gamma

Definition at line 46 of file roket.py.

◆ gRD

guardians.roket.Roket.gRD

Definition at line 86 of file roket.py.

◆ H_com

guardians.roket.Roket.H_com

Definition at line 66 of file roket.py.

◆ IFpzt

guardians.roket.Roket.IFpzt

Definition at line 76 of file roket.py.

◆ iter_number

guardians.roket.Roket.iter_number

Definition at line 53 of file roket.py.

◆ mod_com

guardians.roket.Roket.mod_com

Definition at line 67 of file roket.py.

◆ n

guardians.roket.Roket.n

Definition at line 54 of file roket.py.

◆ N_preloop

guardians.roket.Roket.N_preloop

Definition at line 45 of file roket.py.

◆ Nact

guardians.roket.Roket.Nact

Definition at line 90 of file roket.py.

◆ nactus

guardians.roket.Roket.nactus

Definition at line 56 of file roket.py.

◆ nfiltered

guardians.roket.Roket.nfiltered

Definition at line 55 of file roket.py.

◆ noise_com

guardians.roket.Roket.noise_com

Definition at line 59 of file roket.py.

◆ nslopes

guardians.roket.Roket.nslopes

Definition at line 57 of file roket.py.

◆ P

guardians.roket.Roket.P

Definition at line 79 of file roket.py.

◆ psf_ortho

guardians.roket.Roket.psf_ortho

Definition at line 70 of file roket.py.

◆ RD

guardians.roket.Roket.RD

Definition at line 85 of file roket.py.

◆ slopes

guardians.roket.Roket.slopes

Definition at line 73 of file roket.py.

◆ SR

guardians.roket.Roket.SR

Definition at line 138 of file roket.py.

◆ SR2

guardians.roket.Roket.SR2

Definition at line 137 of file roket.py.

◆ tomo_com

guardians.roket.Roket.tomo_com

Definition at line 63 of file roket.py.

◆ trunc_com

guardians.roket.Roket.trunc_com

Definition at line 64 of file roket.py.

◆ trunc_meas

guardians.roket.Roket.trunc_meas

Definition at line 65 of file roket.py.

◆ TT

guardians.roket.Roket.TT

Definition at line 77 of file roket.py.

◆ wf_com

guardians.roket.Roket.wf_com

Definition at line 62 of file roket.py.


The documentation for this class was generated from the following file: