COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
widget_canapass.py
1 
37 """
38 Widget to simulate a closed loop using CANAPASS
39 
40 Usage:
41  widget_canapass.py [<parameters_filename>]
42 
43 with 'parameters_filename' the path to the parameters file
44 
45 Options:
46  -h --help Show this help message and exit
47  -i, --interactive keep the script interactive
48 """
49 
50 import os, sys
51 import numpy as np
52 
53 from rich.progress import track
54 
55 try:
56  from PyQt5 import QtWidgets
57 except ModuleNotFoundError as e:
58  try:
59  from PySide2 import QtWidgets
60  except ModuleNotFoundError as e:
61  raise ModuleNotFoundError("No module named 'PyQt5' or PySide2', please install one of them\nException raised: "+e.msg)
62 
63 from shesha.supervisor.canapassSupervisor import CanapassSupervisor
64 from typing import Any
65 from docopt import docopt
66 
67 from shesha.widgets.widget_base import WidgetBase
68 from shesha.widgets.widget_ao import widgetAOWindow, widgetAOWindow
69 
70 global server
71 server = None
72 
73 
75 
76  def __init__(self, config_file: Any = None, cacao: bool = False,
77  expert: bool = False) -> None:
78  widgetAOWindow.__init__(self, config_file, cacao, hide_histograms=True)
79  #Pyro.core.ObjBase.__init__(self)
80  self.CBCB = {}
81  self.wpyrwpyr = None
82  self.current_buffercurrent_buffer = 1
83 
89  self.uiAOuiAO.actionShow_Pyramid_Tools.toggled.connect(self.show_pyr_toolsshow_pyr_tools)
90  self.wpyrNbBufferwpyrNbBuffer = 1
91 
94  def init_config(self) -> None:
95  self.supervisorsupervisorsupervisor = CanapassSupervisor(self.configconfig)
96  WidgetBase.init_config(self)
97 
98  def init_configFinished(self) -> None:
99  widgetAOWindow.init_configFinished(self)
100  global server
101  server = self.start_pyro_serverstart_pyro_server()
102 
103  def loop_once(self) -> None:
104  widgetAOWindow.loop_once(self)
105  if (self.uiAOuiAO.actionShow_Pyramid_Tools.isChecked()): # PYR only
106  self.wpyrwpyr.Fe = 1 / self.configconfig.p_loop.ittime # needs Fe for PSD...
107  if (self.wpyrwpyr.CBNumber == 1):
108  self.aiai = self.compute_modal_residuals()
109  self.set_pyr_tools_paramsset_pyr_tools_params(self.aiai)
110  else:
111  if (self.current_buffercurrent_buffer == 1): # First iter of the CB
112  aiVect = self.compute_modal_residuals()
113  self.aiai = aiVect[np.newaxis, :]
114  self.current_buffercurrent_buffer += 1 # Keep going
115 
116  else: # Keep filling the CB
117  aiVect = self.compute_modal_residuals()
118  self.aiai = np.concatenate((self.aiai, aiVect[np.newaxis, :]))
119  if (self.current_buffercurrent_buffer < self.wpyrwpyr.CBNumber):
120  self.current_buffercurrent_buffer += 1 # Keep going
121  else:
122  self.current_buffercurrent_buffer = 1 # reset buffer
123  self.set_pyr_tools_paramsset_pyr_tools_params(self.aiai) # display
124 
125  def next(self, nbIters):
126  ''' Move atmos -> get_slopes -> applyControl ; One integrator step '''
127  for i in track(range(nbIters)):
128  self.supervisorsupervisorsupervisor.next()
129 
130  def initPyrTools(self):
131  ADOPTPATH = os.getenv("ADOPTPATH")
132  sys.path.append(ADOPTPATH + "/widgets")
133  from pyrStats import widget_pyrStats
134  print("OK Pyramid Tools Widget initialized")
135  self.wpyrwpyr = widget_pyrStats()
136  self.wpyrNbBufferwpyrNbBuffer = self.wpyrwpyr.CBNumber
137  self.wpyrwpyr.show()
138 
139  def set_pyr_tools_params(self, ai):
140  self.wpyrwpyr.pup = self.supervisorsupervisorsupervisor.config.p_geom._spupil
141  self.wpyrwpyr.phase = self.supervisorsupervisorsupervisor.target.get_tar_phase(0, pupil=True)
142  self.wpyrwpyr.updateResiduals(ai)
143  if (self.phase_to_modesphase_to_modes is None):
144  print('computing phase 2 Modes basis')
145  self.phase_to_modesphase_to_modes = self.supervisorsupervisorsupervisor.basis.compute_phase_to_modes(self.modal_basis)
146  self.wpyrwpyr.phase_to_modes = self.phase_to_modesphase_to_modes
147 
148  def show_pyr_tools(self):
149  if (self.wpyrwpyr is None):
150  try:
151  print("Lauching pyramid widget...")
152  self.initPyrToolsinitPyrTools()
153  print("Done")
154  except:
155  raise ValueError("ERROR: ADOPT not found. Cannot launch Pyramid tools")
156  else:
157  if (self.uiAOuiAO.actionShow_Pyramid_Tools.isChecked()):
158  self.wpyrwpyr.show()
159  else:
160  self.wpyrwpyr.hide()
161 
162  def getAi(self):
163  return self.wpyrwpyr.ai
164 
165  def start_pyro_server(self):
166  try:
167  from subprocess import Popen, PIPE
168  from hraa.server.pyroServer import PyroServer
169 
170  # Init looper
171  wao_loop = loopHandler(self)
172 
173  # Find username
174  p = Popen("whoami", shell=True, stdout=PIPE, stderr=PIPE)
175  out, err = p.communicate()
176  if (err != b''):
177  print(err)
178  raise Exception("ERROR CANNOT RECOGNIZE USER")
179  else:
180  user = out.split(b"\n")[0].decode("utf-8")
181  print("User is " + user)
182 
183  if(self.supervisorsupervisorsupervisor.corono == None):
184  from shesha.util.pyroEmptyClass import PyroEmptyClass
185  coro2pyro = PyroEmptyClass()
186  else:
187  coro2pyro = self.supervisorsupervisorsupervisor.corono
188  devices = [self.supervisorsupervisorsupervisor, self.supervisorsupervisorsupervisor.rtc, self.supervisorsupervisorsupervisor.wfs,
189  self.supervisorsupervisorsupervisor.target, self.supervisorsupervisorsupervisor.tel,self.supervisorsupervisorsupervisor.basis, self.supervisorsupervisorsupervisor.calibration,
190  self.supervisorsupervisorsupervisor.atmos, self.supervisorsupervisorsupervisor.dms, self.supervisorsupervisorsupervisor.config, self.supervisorsupervisorsupervisor.modalgains, coro2pyro, wao_loop]
191 
192  names = ["supervisor", "supervisor_rtc", "supervisor_wfs",
193  "supervisor_target", "supervisor_tel", "supervisor_basis", "supervisor_calibration",
194  "supervisor_atmos", "supervisor_dms", "supervisor_config", "supervisor_modalgains","supervisor_corono", "wao_loop"]
195  nname = [];
196  for name in names:
197  nname.append(name+"_"+user)
198  server = PyroServer(listDevices=devices, listNames=nname)
199  server.start()
200  except:
201  raise Exception("Error could not connect to Pyro server.\n It can be:\n - Missing dependencies? (check if Pyro4 is installed)\n - pyro server not running")
202  return server
203 
204 
206 
207  def __init__(self, wao):
208  self.waowao = wao
209 
210  def start(self):
211  self.waowao.aoLoopClicked(True)
212  self.waowao.uiAO.wao_run.setChecked(True)
213 
214  def stop(self):
215  self.waowao.aoLoopClicked(False)
216  self.waowao.uiAO.wao_run.setChecked(False)
217 
218  def alive(self):
219  return "alive"
220 
221 
222 if __name__ == '__main__':
223  arguments = docopt(__doc__)
224  app = QtWidgets.QApplication(sys.argv)
225  app.setStyle('cleanlooks')
226  wao = widgetCanapassWindowPyro(arguments["<parameters_filename>"], cacao=True)
227  wao.show()
228  # if arguments["--interactive"]:
229  # from shesha.util.ipython_embed import embed
230  # from os.path import basename
231  # embed(basename(__file__), locals())
def next(self, nbIters)
Move atmos -> get_slopes -> applyControl ; One integrator step.
None __init__(self, Any config_file=None, bool cacao=False, bool expert=False)
Initialization and execution of a CANAPASS supervisor.
Widget to simulate a closed loop.
Definition: widget_ao.py:1
Abstract Widget base.
Definition: widget_base.py:1