COMPASS  5.0.0
End-to-end AO simulation tool using GPU acceleration
canapassSupervisor.py
1 
37 """
38 Initialization and execution of a CANAPASS supervisor
39 
40 Usage:
41  canapassSupervisor.py <parameters_filename> [options]
42 
43 with 'parameters_filename' the path to the parameters file
44 
45 Options:
46  -h, --help Show this help message and exit
47  -f, --freq freq change the frequency of the loop
48  -d, --delay delay change the delay of the loop
49 """
50 
51 import os, sys
52 import numpy as np
53 import time
54 from collections import OrderedDict
55 
56 from tqdm import tqdm
57 import astropy.io.fits as pfits
58 from threading import Thread
59 from subprocess import Popen, PIPE
60 
61 import shesha.ao as ao
62 import shesha.constants as scons
63 from shesha.constants import CentroiderType, WFSType
64 
65 from typing import Any, Dict, Tuple, Callable, List
66 from shesha.supervisor.compassSupervisor import CompassSupervisor
67 
68 # from carmaWrap.obj import obj_Double2D
69 # from carmaWrap.magma import syevd_Double, svd_host_Double
70 # from carmaWrap.context import context as carmaWrap_context
71 
72 # from carmaWrap.host_obj import host_obj_Double1D, host_obj_Double2D
73 
74 
76 
77  def __init__(self, config_file: str = None, cacao: bool = True) -> None:
78  CompassSupervisor.__init__(self, config_file=config_file, cacao=cacao)
79 
80  def get_config(self):
81  """ Returns the configuration in use, in a supervisor specific format """
82  return CompassSupervisor.get_config(self)
83 
84  def get_config_fab(self):
85  aodict = OrderedDict()
86  dataDict = {}
87  if (root is None):
88  root = self
89 
90  if (root.config.p_tel is not None):
91  aodict.update({"teldiam": root.config.p_tel.diam})
92  aodict.update({"telobs": root.config.p_tel.cobs})
93  aodict.update({"pixsize": root.config.p_geom._pixsize})
94  # TURBU
95  aodict.update({"r0": root.config.p_atmos.r0})
96  aodict.update({"Fe": 1 / root.config.p_loop.ittime})
97  aodict.update({"nbTargets": len(root.config.p_targets)})
98  else:
99  aodict.update({"nbTargets": 1})
100 
101  # WFS
102  aodict.update({"nbWfs": len(root.config.p_wfss)})
103  aodict.update({"nbCam": aodict["nbWfs"]})
104  aodict.update({"nbOffaxis": 0})
105  aodict.update({"nbNgsWFS": 1})
106  aodict.update({"nbLgsWFS": 0})
107  aodict.update({"nbFigSensor": 0})
108  aodict.update({"nbSkyWfs": aodict["nbWfs"]})
109  aodict.update({"nbOffNgs": 0})
110 
111  # DMS
112  aodict.update({"nbDms": len(root.config.p_dms)})
113  aodict.update({"Nactu": root.rtc.d_control[0].nactu})
114  # List of things
115  aodict.update({"list_NgsOffAxis": []})
116  aodict.update({"list_Fig": []})
117  aodict.update({"list_Cam": [0]})
118  aodict.update({"list_SkyWfs": [0]})
119  aodict.update({"list_ITS": []})
120  aodict.update({"list_Woofer": []})
121  aodict.update({"list_Tweeter": []})
122  aodict.update({"list_Steering": []})
123 
124  listOfNstatesPerController = []
125  listOfcontrolLawTypePerController = []
126  for control in self.config.p_controllers:
127  listOfNstatesPerController.append(control.nstates)
128  listOfcontrolLawTypePerController.append(control.type)
129  aodict.update({"list_nstatesPerController": listOfNstatesPerController})
130  aodict.update({"list_controllerType": listOfcontrolLawTypePerController})
131 
132  # fct of Nb of wfss
133  NslopesList = []
134  NsubapList = []
135  listWfsType = []
136  listCentroType = []
137 
138  pyrModulationList = []
139  pyr_npts = []
140  pyr_pupsep = []
141  pixsize = []
142  xPosList = []
143  yPosList = []
144  fstopsize = []
145  fstoptype = []
146  npixPerSub = []
147  nxsubList = []
148  nysubList = []
149  lambdaList = []
150  dms_seen = []
151  colTmpList = []
152  noise = []
153  #new_hduwfsl = pfits.HDUList()
154  #new_hduwfsSubapXY = pfits.HDUList()
155  for i in range(aodict["nbWfs"]):
156  #new_hduwfsl.append(pfits.ImageHDU(root.config.p_wfss[i]._isvalid)) # Valid subap array
157  #new_hduwfsl[i].header["DATATYPE"] = "valid_wfs%d" % i
158  dataDict["wfsValid_" + str(i)] = root.config.p_wfss[i]._isvalid
159 
160  xytab = np.zeros((2, root.config.p_wfss[i]._validsubsx.shape[0]))
161  xytab[0, :] = root.config.p_wfss[i]._validsubsx
162  xytab[1, :] = root.config.p_wfss[i]._validsubsy
163  dataDict["wfsValidXY_" + str(i)] = xytab
164 
165  #new_hduwfsSubapXY.append(pfits.ImageHDU(xytab)) # Valid subap array inXx Y on the detector
166  #new_hduwfsSubapXY[i].header["DATATYPE"] = "validXY_wfs%d" % i
167  pixsize.append(root.config.p_wfss[i].pixsize)
168  """
169  if (root.config.p_centroiders[i].type == "maskedpix"):
170  factor = 4
171  else:
172  factor = 2
173  NslopesList.append(
174  root.config.p_wfss[i]._nvalid * factor) # slopes per wfs
175  """
176  listCentroType.append(
177  root.config.p_centroiders[i].
178  type) # assumes that there is the same number of centroiders and wfs
179  NsubapList.append(root.config.p_wfss[i]._nvalid) # subap per wfs
180  listWfsType.append(root.config.p_wfss[i].type)
181  xPosList.append(root.config.p_wfss[i].xpos)
182  yPosList.append(root.config.p_wfss[i].ypos)
183  fstopsize.append(root.config.p_wfss[i].fssize)
184  fstoptype.append(root.config.p_wfss[i].fstop)
185  nxsubList.append(root.config.p_wfss[i].nxsub)
186  nysubList.append(root.config.p_wfss[i].nxsub)
187  lambdaList.append(root.config.p_wfss[i].Lambda)
188  if (root.config.p_wfss[i].dms_seen is not None):
189  dms_seen.append(list(root.config.p_wfss[i].dms_seen))
190  noise.append(root.config.p_wfss[i].noise)
191 
192  if (root.config.p_centroiders[i].type == CentroiderType.MASKEDPIX):
193  NslopesList.append(root.config.p_wfss[i]._nvalid * 4) # slopes per wfs
194  else:
195  NslopesList.append(root.config.p_wfss[i]._nvalid * 2) # slopes per wfs
196 
197  if (root.config.p_wfss[i].type == "pyrhr"):
198  pyrModulationList.append(root.config.p_wfss[i].pyr_ampl)
199  pyr_npts.append(root.config.p_wfss[i].pyr_npts)
200  pyr_pupsep.append(root.config.p_wfss[i].pyr_pup_sep)
201  npixPerSub.append(1)
202  else:
203  pyrModulationList.append(0)
204  pyr_npts.append(0)
205  pyr_pupsep.append(0)
206  npixPerSub.append(root.config.p_wfss[i].npix)
207  """
208  confname = filepath.split("/")[-1].split('.conf')[0]
209  print(filepath.split(".conf")[0] + '_wfsConfig.fits')
210  new_hduwfsl.writeto(
211  filepath.split(".conf")[0] + '_wfsConfig.fits', overwrite=True)
212  new_hduwfsSubapXY.writeto(
213  filepath.split(".conf")[0] + '_wfsValidXYConfig.fits', overwrite=True)
214  """
215  if (len(dms_seen) != 0):
216  aodict.update({"listWFS_dms_seen": dms_seen})
217 
218  aodict.update({"listWFS_NslopesList": NslopesList})
219  aodict.update({"listWFS_NsubapList": NsubapList})
220  aodict.update({"listWFS_CentroType": listCentroType})
221  aodict.update({"listWFS_WfsType": listWfsType})
222  aodict.update({"listWFS_pixarc": pixsize})
223  aodict.update({"listWFS_pyrModRadius": pyrModulationList})
224  aodict.update({"listWFS_pyrModNPts": pyr_npts})
225  aodict.update({"listWFS_pyrPupSep": pyr_pupsep})
226  aodict.update({"listWFS_fstopsize": fstopsize})
227  aodict.update({"listWFS_fstoptype": fstoptype})
228  aodict.update({"listWFS_NsubX": nxsubList})
229  aodict.update({"listWFS_NsubY": nysubList})
230  aodict.update({"listWFS_Nsub": nysubList})
231  aodict.update({"listWFS_NpixPerSub": npixPerSub})
232  aodict.update({"listWFS_Lambda": lambdaList})
233  if (len(noise) != 0):
234  aodict.update({"listWFS_noise": noise})
235 
236  listDmsType = []
237  NactuX = []
238  Nactu = []
239  unitPerVolt = []
240  push4imat = []
241  coupling = []
242  push4iMatArcSec = []
243  #new_hdudmsl = pfits.HDUList()
244 
245  for j in range(aodict["nbDms"]):
246  listDmsType.append(root.config.p_dms[j].type)
247  NactuX.append(
248  root.config.p_dms[j].nact) # nb of actuators across the diameter !!
249  Nactu.append(root.config.p_dms[j]._ntotact) # nb of actuators in total
250  unitPerVolt.append(root.config.p_dms[j].unitpervolt)
251  push4imat.append(root.config.p_dms[j].push4imat)
252  coupling.append(root.config.p_dms[j].coupling)
253  tmp = []
254  if (root.config.p_dms[j]._i1 is
255  not None): # Simu Case where i1 j1 is known (simulated)
256  if (root.config.p_dms[j].type != 'tt'):
257  tmpdata = np.zeros((4, len(root.config.p_dms[j]._i1)))
258  tmpdata[0, :] = root.config.p_dms[j]._j1
259  tmpdata[1, :] = root.config.p_dms[j]._i1
260  tmpdata[2, :] = root.config.p_dms[j]._xpos
261  tmpdata[3, :] = root.config.p_dms[j]._ypos
262  else:
263  tmpdata = np.zeros((4, 2))
264 
265  dataDict["dmData" + str(j)] = tmpdata
266  """
267  new_hdudmsl.append(pfits.ImageHDU(tmpdata)) # Valid subap array
268  new_hdudmsl[j].header["DATATYPE"] = "valid_dm%d" % j
269  """
270  #for k in range(aodict["nbWfs"]):
271  # tmp.append(root.computeDMrange(j, k))
272 
273  push4iMatArcSec.append(tmp)
274 
275  # new_hdudmsl.writeto(filepath.split(".conf")[0] + '_dmsConfig.fits', overwrite=True)
276  if (len(push4iMatArcSec) != 0):
277  aodict.update({"listDMS_push4iMat": push4imat})
278  aodict.update({"listDMS_unitPerVolt": unitPerVolt})
279  aodict.update({"listDMS_Nxactu": NactuX})
280  aodict.update({"listDMS_Nyactu": NactuX})
281  aodict.update({"listDMS_Nactu": Nactu})
282 
283  aodict.update({"listDMS_type": listDmsType})
284  aodict.update({"listDMS_coupling": coupling})
285 
286  if (root.config.p_targets is not None): # simu case
287  listTargetsLambda = []
288  listTargetsXpos = []
289  listTargetsYpos = []
290  listTargetsDmsSeen = []
291  listTargetsMag = []
292  listTARGETS_pixsize = []
293  for k in range(aodict["nbTargets"]):
294  listTargetsLambda.append(root.config.p_targets[k].Lambda)
295  listTargetsXpos.append(root.config.p_targets[k].xpos)
296  listTargetsYpos.append(root.config.p_targets[k].ypos)
297  listTargetsMag.append(root.config.p_targets[k].mag)
298  listTargetsDmsSeen.append(list(root.config.p_targets[k].dms_seen))
299  PSFPixsize = (root.config.p_targets[k].Lambda * 1e-6) / (
300  root.config.p_geom._pixsize *
301  root.config.p_geom.get_ipupil().shape[0]) * 206265.
302  listTARGETS_pixsize.append(PSFPixsize)
303 
304  aodict.update({"listTARGETS_Lambda": listTargetsLambda})
305  aodict.update({"listTARGETS_Xpos": listTargetsXpos})
306  aodict.update({"listTARGETS_Ypos": listTargetsYpos})
307  aodict.update({"listTARGETS_Mag": listTargetsMag})
308  aodict.update({"listTARGETS_DmsSeen": listTargetsDmsSeen})
309  aodict.update({"listTARGETS_pixsize": listTARGETS_pixsize})
310 
311  listDmsType = []
312  Nslopes = sum(NslopesList)
313  Nsubap = sum(NsubapList)
314  aodict.update({"Nslopes": Nslopes})
315  aodict.update({"Nsubap": Nsubap})
316  return aodict, dataDict
317 
318  def load_config(self, config_file: str) -> None:
319  """ Load the configuration for the compass supervisor
320  """
321  CompassSupervisor.load_config(self, config_file)
322  print("switching to a generic controller")
323  self.config.p_controllers[0].type = scons.ControllerType.GENERIC
324 
325 
326 
327 
328  # def initModalGain(self, gain, cmatModal, modal_basis, control=0, reset_gain=True):
329  # """
330  # Given a gain, cmat and btt2v initialise the modal gain mode
331  # """
332  # print("TODO: A RECODER !!!!")
333  # nmode_total = modal_basis.shape[1]
334  # nactu_total = modal_basis.shape[0]
335  # nfilt = nmode_total - cmatModal.shape[0]
336  # ctrl = self._sim.rtc.d_control[control]
337  # ctrl.set_commandlaw('modal_integrator')
338  # cmat = np.zeros((nactu_total, cmatModal.shape[1]))
339  # dec = cmat.shape[0] - cmatModal.shape[0]
340  # cmat[:-dec, :] += cmatModal # Fill the full Modal with all non-filtered modes
341  # modes2V = np.zeros((nactu_total, nactu_total))
342  # dec2 = modes2V.shape[1] - modal_basis.shape[1]
343  # modes2V[:, :-dec2] += modal_basis
344  # mgain = np.ones(len(modes2V)) * gain # Initialize the gain
345  # ctrl.set_matE(modes2V)
346  # ctrl.set_cmat(cmat)
347  # if reset_gain:
348  # ctrl.set_modal_gains(mgain)
349 
350  # def leaveModalGain(self, control=0):
351  # ctrl = self._sim.rtc.d_control[control]
352  # ctrl.set_commandlaw('integrator')
353 
354 if __name__ == '__main__':
355  from docopt import docopt
356  arguments = docopt(__doc__)
357  supervisor = CanapassSupervisor(arguments["<parameters_filename>"], cacao=True)
358  if (arguments["--freq"]):
359  print("Warning changed frequency loop to: ", arguments["--freq"])
360  supervisor.config.p_loop.set_ittime(1 / float(arguments["--freq"]))
361  if (arguments["--delay"]):
362  print("Warning changed delay loop to: ", arguments["--delay"])
363  supervisor.config.p_controllers[0].set_delay(float(arguments["--delay"]))
364  supervisor.init()
365 
366  try:
367  from subprocess import Popen, PIPE
368  from hraa.server.pyroServer import PyroServer
369 
370  p = Popen("whoami", shell=True, stdout=PIPE, stderr=PIPE)
371  out, err = p.communicate()
372  if (err != b''):
373  print(err)
374  raise ValueError("ERROR CANNOT RECOGNIZE USER")
375  else:
376  user = out.split(b"\n")[0].decode("utf-8")
377  print("User is " + user)
378  server = PyroServer()
379  server.add_device(supervisor, "waoconfig_" + user)
380  server.start()
381  except:
382  raise EnvironmentError(
383  "Missing dependencies (code HRAA or Pyro4 or Dill Serializer)")
shesha.supervisor.compassSupervisor
Initialization and execution of a COMPASS supervisor.
Definition: compassSupervisor.py:1
shesha.supervisor.canapassSupervisor.CanapassSupervisor
Definition: canapassSupervisor.py:75
shesha.ao
Python package for AO operations on COMPASS simulation.
Definition: shesha/shesha/ao/__init__.py:1
shesha.supervisor.genericSupervisor.GenericSupervisor.config
config
Definition: genericSupervisor.py:109
shesha.constants
Numerical constants for shesha and config enumerations for safe-typing.
Definition: constants.py:1
shesha.supervisor.canapassSupervisor.CanapassSupervisor.load_config
None load_config(self, str config_file)
Load the configuration for the compass supervisor.
Definition: canapassSupervisor.py:320
shesha.supervisor.compassSupervisor.CompassSupervisor
This class implements generic supervisor to handle compass simulation.
Definition: compassSupervisor.py:57
shesha.supervisor.canapassSupervisor.CanapassSupervisor.get_config
def get_config(self)
Returns the configuration in use, in a supervisor specific format.
Definition: canapassSupervisor.py:81
shesha.supervisor.canapassSupervisor.CanapassSupervisor.__init__
None __init__(self, str config_file=None, bool cacao=True)
Definition: canapassSupervisor.py:77
shesha.supervisor.canapassSupervisor.CanapassSupervisor.get_config_fab
def get_config_fab(self)
Definition: canapassSupervisor.py:84