COMPASS  5.0.0
End-to-end AO simulation tool using GPU acceleration
widget_ao_expert.py
1 
37 
38 import os, sys
39 import numpy as np
40 
41 from PyQt5.uic import loadUiType
42 
43 import shesha.ao as ao
44 import shesha.constants as scons
45 from shesha.constants import CONST
46 from shesha.ao.wfs import comp_new_pyr_ampl
47 
48 from shesha.widgets.widget_base import uiLoader
49 ExpertWidgetTemplate, ExpertClassTemplate = uiLoader('widget_ao_expert')
50 
51 
53 
54  def __init__(self) -> None:
55  ExpertClassTemplate.__init__(self)
56  self.sim = None
57 
59  self.uiExpert.setupUi(self)
60 
61 
64 
65 
68 
69 
73  self.uiExpert.wao_setAtmos.clicked.connect(self.setAtmosParams)
74  self.uiExpert.wao_setWfs.clicked.connect(self.setWfsParams)
75  self.uiExpert.wao_setDM.clicked.connect(self.setDmParams)
76  self.uiExpert.wao_setControl.clicked.connect(self.setRtcParams)
77  self.uiExpert.wao_setCentro.clicked.connect(self.setRtcParams)
78  self.uiExpert.wao_setTelescope.clicked.connect(self.setTelescopeParams)
79  self.uiExpert.wao_reset_dm.clicked.connect(self.reset_dm)
80  self.uiExpert.wao_update_gain.clicked.connect(self.updateGain)
81  self.uiExpert.wao_update_pyr_ampl.clicked.connect(self.updatePyrAmpl)
82  self.uiExpert.wao_selectRtcMatrix.currentIndexChanged.connect(
83  self.displayRtcMatrix)
84  self.uiExpert.wao_commandBtt.clicked.connect(self.BttCommand)
85  self.uiExpert.wao_commandKL.clicked.connect(self.KLCommand)
86 
87  self.uiExpert.wao_dmUnitPerVolt.valueChanged.connect(self.updateDMrangeGUI)
88  self.uiExpert.wao_dmpush4iMat.valueChanged.connect(self.updateDMrangeGUI)
89  self.uiExpert.wao_pyr_ampl.valueChanged.connect(self.updateAmpliCompGUI)
90  self.uiExpert.wao_dmActuPushArcSecNumWFS.currentIndexChanged.connect(
91  self.updateDMrange)
92 
93 
96 
97  def setSim(self, sim) -> None:
98  self.sim = sim
99 
100  def updateGain(self) -> None:
101  if (self.sim.rtc):
102  self.sim.rtc.set_gain(0, float(self.uiExpert.wao_controlGain.value()))
103  print("Loop gain updated on GPU")
104 
105  def updateAmpliCompGUI(self) -> None:
106  diffract = self.sim.config.p_wfss[0].Lambda * \
107  1e-6 / self.sim.config.p_tel.diam * CONST.RAD2ARCSEC
108  self.uiExpert.wao_pyr_ampl_arcsec.setValue(
109  self.uiExpert.wao_pyr_ampl.value() * diffract)
110 
111  def updateAmpliComp(self) -> None:
112  diffract = self.sim.config.p_wfss[0].Lambda * \
113  1e-6 / self.sim.config.p_tel.diam * CONST.RAD2ARCSEC
114  self.uiExpert.wao_pyr_ampl_arcsec.setValue(
115  self.sim.config.p_wfss[0].pyr_ampl * diffract)
116 
117  def updatePyrAmpl(self) -> None:
118  if (self.sim.rtc):
119  comp_new_pyr_ampl(0, self.uiExpert.wao_pyr_ampl.value(), self.sim.config.p_wfss,
120  self.sim.config.p_tel)
121  self.sim.config.p_wfss[0].set_pyr_ampl(self.uiExpert.wao_pyr_ampl.value())
122  print("Pyramid modulation updated on GPU")
123  self.updatePlotWfs()
124 
125  def updateDMrangeGUI(self) -> None:
126  push4imat = self.uiExpert.wao_dmpush4iMat.value()
127  unitpervolt = self.uiExpert.wao_dmUnitPerVolt.value()
128  self.updateDMrange(push4imat=push4imat, unitpervolt=unitpervolt)
129 
130  def updateDMrange(self, push4imat: float = None, unitpervolt: float = None) -> None:
131  numdm = str(self.uiExpert.wao_selectDM.currentText())
132  numwfs = str(self.uiExpert.wao_dmActuPushArcSecNumWFS.currentText())
133  if ((numdm is not "") and (numwfs is not "") and (push4imat != 0) and
134  (unitpervolt != 0)):
135  arcsecDMrange = self.computeDMrange(
136  int(numdm), int(numwfs), push4imat=push4imat,
137  unitpervolt=unitpervolt)
138  self.uiExpert.wao_dmActPushArcsec.setValue(arcsecDMrange)
139 
140  def updateTelescopePanel(self) -> None:
141  self.uiExpert.wao_zenithAngle.setValue(self.sim.config.p_geom.zenithangle)
142  self.uiExpert.wao_diamTel.setValue(self.sim.config.p_tel.diam)
143  self.uiExpert.wao_cobs.setValue(self.sim.config.p_tel.cobs)
144 
145  def updateDmPanel(self) -> None:
146  ndm = self.uiExpert.wao_selectDM.currentIndex()
147  if (ndm < 0):
148  ndm = 0
149  self.uiExpert.wao_dmActuPushArcSecNumWFS.clear()
150  self.uiExpert.wao_dmActuPushArcSecNumWFS.addItems([
151  str(i) for i in range(len(self.sim.config.p_dms))
152  ])
153  self.uiExpert.wao_numberofDMs.setText(str(len(self.sim.config.p_dms)))
154  self.uiExpert.wao_dmTypeSelector.setCurrentIndex(
155  self.uiExpert.wao_dmTypeSelector.findText(
156  str(self.sim.config.p_dms[ndm].type)))
157  self.uiExpert.wao_dmAlt.setValue(self.sim.config.p_dms[ndm].alt)
158  if (self.sim.config.p_dms[ndm].type == scons.DmType.KL):
159  self.uiExpert.wao_dmNactu.setValue(self.sim.config.p_dms[ndm].nkl)
160  else:
161  self.uiExpert.wao_dmNactu.setValue(self.sim.config.p_dms[ndm].nact)
162  self.uiExpert.wao_dmUnitPerVolt.setValue(self.sim.config.p_dms[ndm].unitpervolt)
163  self.uiExpert.wao_dmpush4iMat.setValue(self.sim.config.p_dms[ndm].push4imat)
164  self.uiExpert.wao_dmCoupling.setValue(self.sim.config.p_dms[ndm].coupling)
165  self.uiExpert.wao_dmThresh.setValue(self.sim.config.p_dms[ndm].thresh)
166  self.updateDMrange()
167 
168  def updateWfsPanel(self) -> None:
169  nwfs = self.uiExpert.wao_selectWfs.currentIndex()
170  if (nwfs < 0):
171  nwfs = 0
172  self.uiExpert.wao_numberofWfs.setText(str(len(self.sim.config.p_dms)))
173  self.uiExpert.wao_wfsType.setText(str(self.sim.config.p_wfss[nwfs].type))
174  self.uiExpert.wao_wfsNxsub.setValue(self.sim.config.p_wfss[nwfs].nxsub)
175  self.uiExpert.wao_wfsNpix.setValue(self.sim.config.p_wfss[nwfs].npix)
176  self.uiExpert.wao_wfsPixSize.setValue(self.sim.config.p_wfss[nwfs].pixsize)
177  self.uiExpert.wao_wfsXpos.setValue(self.sim.config.p_wfss[nwfs].xpos)
178  self.uiExpert.wao_wfsYpos.setValue(self.sim.config.p_wfss[nwfs].ypos)
179  self.uiExpert.wao_wfsFracsub.setValue(self.sim.config.p_wfss[nwfs].fracsub)
180  self.uiExpert.wao_wfsLambda.setValue(self.sim.config.p_wfss[nwfs].Lambda)
181  self.uiExpert.wao_wfsMagnitude.setValue(self.sim.config.p_wfss[nwfs].gsmag)
182  self.uiExpert.wao_wfsZp.setValue(np.log10(self.sim.config.p_wfss[nwfs].zerop))
183  self.uiExpert.wao_wfsThrough.setValue(self.sim.config.p_wfss[nwfs].optthroughput)
184  self.uiExpert.wao_wfsNoise.setValue(self.sim.config.p_wfss[nwfs].noise)
185  self.uiExpert.wao_pyr_ampl.setValue(self.sim.config.p_wfss[nwfs].pyr_ampl)
186 
187  # LGS panel
188  if (self.sim.config.p_wfss[nwfs].gsalt > 0):
189  self.uiExpert.wao_wfsIsLGS.setChecked(True)
190  self.uiExpert.wao_wfsGsAlt.setValue(self.sim.config.p_wfss[nwfs].gsalt)
191  self.uiExpert.wao_wfsLLTx.setValue(self.sim.config.p_wfss[nwfs].lltx)
192  self.uiExpert.wao_wfsLLTy.setValue(self.sim.config.p_wfss[nwfs].llty)
193  self.uiExpert.wao_wfsLGSpower.setValue(
194  self.sim.config.p_wfss[nwfs].laserpower)
195  self.uiExpert.wao_wfsReturnPerWatt.setValue(
196  self.sim.config.p_wfss[nwfs].lgsreturnperwatt)
197  self.uiExpert.wao_wfsBeamSize.setValue(self.sim.config.p_wfss[nwfs].beamsize)
198  self.uiExpert.wao_selectLGSProfile.setCurrentIndex(
199  self.uiExpert.wao_selectLGSProfile.findText(
200  str(self.sim.config.p_wfss[nwfs].proftype)))
201 
202  else:
203  self.uiExpert.wao_wfsIsLGS.setChecked(False)
204 
205  if (self.sim.config.p_wfss[nwfs].type == "pyrhr" or
206  self.sim.config.p_wfss[nwfs].type == "pyr"):
207  self.uiExpert.wao_wfs_plotSelector.setCurrentIndex(3)
208  self.updatePlotWfs()
209 
210  def updateAtmosPanel(self) -> None:
211  nscreen = self.uiExpert.wao_selectAtmosLayer.currentIndex()
212  if (nscreen < 0):
213  nscreen = 0
214  self.uiExpert.wao_r0.setValue(self.sim.config.p_atmos.r0)
215  self.uiExpert.wao_atmosNlayers.setValue(self.sim.config.p_atmos.nscreens)
216  self.uiExpert.wao_atmosAlt.setValue(self.sim.config.p_atmos.alt[nscreen])
217  self.uiExpert.wao_atmosFrac.setValue(self.sim.config.p_atmos.frac[nscreen])
218  self.uiExpert.wao_atmosL0.setValue(self.sim.config.p_atmos.L0[nscreen])
219  self.uiExpert.wao_windSpeed.setValue(self.sim.config.p_atmos.windspeed[nscreen])
220  self.uiExpert.wao_windDirection.setValue(
221  self.sim.config.p_atmos.winddir[nscreen])
222  if (self.sim.config.p_atmos.dim_screens is not None):
223  self.uiExpert.wao_atmosDimScreen.setText(
224  str(self.sim.config.p_atmos.dim_screens[nscreen]))
225  self.uiExpert.wao_atmosWindow.canvas.axes.cla()
226  width = (self.sim.config.p_atmos.alt.max() / 20. + 0.1) / 1000.
227  self.uiExpert.wao_atmosWindow.canvas.axes.barh(
228  self.sim.config.p_atmos.alt / 1000. - width / 2.,
229  self.sim.config.p_atmos.frac, width, color="blue")
230  self.uiExpert.wao_atmosWindow.canvas.draw()
231 
232  def updateRtcPanel(self) -> None:
233  # Centroider panel
234  ncentro = self.uiExpert.wao_selectCentro.currentIndex()
235  if (ncentro < 0):
236  ncentro = 0
237  type = self.sim.config.p_centroiders[ncentro].type
238  self.uiExpert.wao_centroTypeSelector.setCurrentIndex(
239  self.uiExpert.wao_centroTypeSelector.findText(str(type)))
240 
241  self.uiExpert.wao_centroThresh.setValue(
242  self.sim.config.p_centroiders[ncentro].thresh)
243  if type == scons.CentroiderType.BPCOG:
244  self.uiExpert.wao_centroNbrightest.setValue(
245  self.sim.config.p_centroiders[ncentro].nmax)
246  if type == scons.CentroiderType.TCOG:
247  self.uiExpert.wao_centroThresh.setValue(
248  self.sim.config.p_centroiders[ncentro].thresh)
249  if type in [scons.CentroiderType.CORR, scons.CentroiderType.WCOG]:
250  self.uiExpert.wao_centroFunctionSelector.setCurrentIndex(
251  self.uiExpert.wao_centroFunctionSelector.findText(
252  str(self.sim.config.p_centroiders[ncentro].type_fct)))
253  self.uiExpert.wao_centroWidth.setValue(
254  self.sim.config.p_centroiders[ncentro].width)
255 
256  # Controller panel
257  type_contro = self.sim.config.p_controllers[0].type
258  if (type_contro == scons.ControllerType.LS and
259  self.sim.config.p_controllers[0].modopti == 0):
260  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(0)
261  elif (type_contro == scons.ControllerType.MV):
262  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(1)
263  elif (type_contro == scons.ControllerType.GEO):
264  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(2)
265  elif (type_contro == scons.ControllerType.LS and
266  self.sim.config.p_controllers[0].modopti):
267  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(3)
268  elif (type_contro == scons.ControllerType.CURED):
269  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(4)
270  elif (type_contro == scons.ControllerType.GENERIC):
271  self.uiExpert.wao_controlTypeSelector.setCurrentIndex(5)
272  else:
273  print("Controller type enumeration invalid.")
274 
275  self.uiExpert.wao_controlCond.setValue(self.sim.config.p_controllers[0].maxcond)
276  self.uiExpert.wao_controlDelay.setValue(self.sim.config.p_controllers[0].delay)
277  self.uiExpert.wao_controlGain.setValue(self.sim.config.p_controllers[0].gain)
278  self.uiExpert.wao_controlTTcond.setValue(
279  self.sim.config.p_controllers[0].maxcond) # TODO : TTcond
280 
281  def updateTargetPanel(self) -> None:
282  ntarget = self.uiExpert.wao_selectTarget.currentIndex()
283  if (ntarget < 0):
284  ntarget = 0
285  self.uiExpert.wao_numberofTargets.setText(str(len(self.sim.config.p_targets)))
286  self.uiExpert.wao_targetMag.setValue(self.sim.config.p_target[ntarget].mag)
287  self.uiExpert.wao_targetXpos.setValue(self.sim.config.p_target[ntarget].xpos)
288  self.uiExpert.wao_targetYpos.setValue(self.sim.config.p_target[ntarget].ypos)
289  self.uiExpert.wao_targetLambda.setValue(self.sim.config.p_target[ntarget].Lambda)
290 
291  def updatePanels(self) -> None:
292  self.updateTelescopePanel()
293  self.updateAtmosPanel()
294  self.updateWfsPanel()
295  self.updateDmPanel()
296  self.updateRtcPanel()
297  self.updateTargetPanel()
298 
299  def setTelescopeParams(self) -> None:
300  self.sim.config.p_tel.set_diam(self.uiExpert.wao_diamTel.value())
301  self.sim.config.p_tel.set_cobs(self.uiExpert.wao_cobs.value())
302  self.sim.config.p_geom.set_zenithangle(self.uiExpert.wao_zenithAngle.value())
303  print("New telescope parameters set")
304 
305  def setAtmosParams(self) -> None:
306  nscreen = self.uiExpert.wao_selectAtmosLayer.currentIndex()
307  if (nscreen < 0):
308  nscreen = 0
309  self.sim.config.p_atmos.alt[nscreen] = self.uiExpert.wao_atmosAlt.value()
310  self.sim.config.p_atmos.frac[nscreen] = self.uiExpert.wao_atmosFrac.value()
311  self.sim.config.p_atmos.L0[nscreen] = self.uiExpert.wao_atmosL0.value()
312  self.sim.config.p_atmos.windspeed[nscreen] = self.uiExpert.wao_windSpeed.value()
313  self.sim.config.p_atmos.winddir[nscreen] = self.uiExpert.wao_windDirection.value(
314  )
315  print("New atmos parameters set")
316 
317  def setRtcParams(self) -> None:
318  # Centroider params
319  ncentro = self.uiExpert.wao_selectCentro.currentIndex()
320  if (ncentro < 0):
321  ncentro = 0
322  self.sim.config.p_centroiders[ncentro].set_type(
323  str(self.uiExpert.wao_centroTypeSelector.currentText()))
324  self.sim.config.p_centroiders[ncentro].set_thresh(
325  self.uiExpert.wao_centroThresh.value())
326  self.sim.config.p_centroiders[ncentro].set_nmax(
327  self.uiExpert.wao_centroNbrightest.value())
328  self.sim.config.p_centroiders[ncentro].set_thresh(
329  self.uiExpert.wao_centroThresh.value())
330  self.sim.config.p_centroiders[ncentro].set_type_fct(
331  str(self.uiExpert.wao_centroFunctionSelector.currentText()))
332  self.sim.config.p_centroiders[ncentro].set_width(
333  self.uiExpert.wao_centroWidth.value())
334 
335  # Controller panel
336  type_contro = str(self.uiExpert.wao_controlTypeSelector.currentText())
337  if (type_contro == "LS"):
338  self.sim.config.p_controllers[0].set_type(scons.ControllerType.LS)
339  elif (type_contro == "MV"):
340  self.sim.config.p_controllers[0].set_type(scons.ControllerType.MV)
341  elif (type_contro == "PROJ"):
342  self.sim.config.p_controllers[0].set_type(scons.ControllerType.GEO)
343  elif (type_contro == "OptiMods"):
344  self.sim.config.p_controllers[0].set_type(scons.ControllerType.LS)
345  self.sim.config.p_controllers[0].set_modopti(1)
346 
347  self.sim.config.p_controllers[0].set_maxcond(
348  self.uiExpert.wao_controlCond.value())
349  self.sim.config.p_controllers[0].set_delay(
350  self.uiExpert.wao_controlDelay.value())
351  self.sim.config.p_controllers[0].set_gain(self.uiExpert.wao_controlGain.value())
352  # self.sim.config.p_controllers[0].set_TTcond(self.uiExpert.wao_controlTTcond.value())
353  # # TODO : TTcond
354  print("New RTC parameters set")
355 
356  def setWfsParams(self) -> None:
357  nwfs = self.uiExpert.wao_selectWfs.currentIndex()
358  if (nwfs < 0):
359  nwfs = 0
360  self.sim.config.p_wfss[nwfs].set_nxsub(self.uiExpert.wao_wfsNxsub.value())
361  self.sim.config.p_wfss[nwfs].set_npix(self.uiExpert.wao_wfsNpix.value())
362  self.sim.config.p_wfss[nwfs].set_pixsize(self.uiExpert.wao_wfsPixSize.value())
363  self.sim.config.p_wfss[nwfs].set_xpos(self.uiExpert.wao_wfsXpos.value())
364  self.sim.config.p_wfss[nwfs].set_ypos(self.uiExpert.wao_wfsYpos.value())
365  self.sim.config.p_wfss[nwfs].set_fracsub(self.uiExpert.wao_wfsFracsub.value())
366  self.sim.config.p_wfss[nwfs].set_Lambda(self.uiExpert.wao_wfsLambda.value())
367  self.sim.config.p_wfss[nwfs].set_gsmag(self.uiExpert.wao_wfsMagnitude.value())
368  # TODO: find a way to correctly set zerop (limited by the maximum value
369  # allowed by the double spin box)
370  self.sim.config.p_wfss[nwfs].set_zerop(10**(self.uiExpert.wao_wfsZp.value()))
371  self.sim.config.p_wfss[nwfs].set_optthroughput(
372  self.uiExpert.wao_wfsThrough.value())
373  self.sim.config.p_wfss[nwfs].set_noise(self.uiExpert.wao_wfsNoise.value())
374 
375  # LGS params
376  if (self.uiExpert.wao_wfsIsLGS.isChecked()):
377  self.sim.config.p_wfss[nwfs].set_gsalt(self.uiExpert.wao_wfsGsAlt.value())
378  self.sim.config.p_wfss[nwfs].set_lltx(self.uiExpert.wao_wfsLLTx.value())
379  self.sim.config.p_wfss[nwfs].set_llty(self.uiExpert.wao_wfsLLTy.value())
380  self.sim.config.p_wfss[nwfs].set_laserpower(
381  self.uiExpert.wao_wfsLGSpower.value())
382  self.sim.config.p_wfss[nwfs].set_lgsreturnperwatt(
383  self.uiExpert.wao_wfsReturnPerWatt.value())
384  self.sim.config.p_wfss[nwfs].set_beamsize(
385  self.uiExpert.wao_wfsBeamSize.value())
386  self.sim.config.p_wfss[nwfs].set_proftype(
387  str(self.uiExpert.wao_selectLGSProfile.currentText()))
388  print("New WFS parameters set")
389 
390  def setDmParams(self) -> None:
391  ndm = self.uiExpert.wao_selectDM.currentIndex()
392  if (ndm < 0):
393  ndm = 0
394  self.sim.config.p_dms[ndm].set_type(
395  str(self.uiExpert.wao_dmTypeSelector.currentText()))
396  self.sim.config.p_dms[ndm].set_alt(self.uiExpert.wao_dmAlt.value())
397  self.sim.config.p_dms[ndm].set_nact(self.uiExpert.wao_dmNactu.value())
398  self.sim.config.p_dms[ndm].set_unitpervolt(
399  self.uiExpert.wao_dmUnitPerVolt.value())
400  self.sim.config.p_dms[ndm].set_coupling(self.uiExpert.wao_dmCoupling.value())
401  self.sim.config.p_dms[ndm].set_thresh(self.uiExpert.wao_dmThresh.value())
402  print("New DM parameters set")
403 
404  def reset_dm(self) -> None:
405  if (self.sim.dms):
406  ndm = self.uiExpert.wao_selectDM.currentIndex()
407  if (ndm > -1):
408  self.sim.dms.resetdm(
409  str(self.uiExpert.wao_dmTypeSelector.currentText()),
410  self.uiExpert.wao_dmAlt.value())
411  self.updateDisplay()
412  print("DM #%d reset" % ndm)
413  else:
414  print("Invalid DM : please select a DM to reset")
415  else:
416  print("There is no DM to reset")
417 
418  def BttCommand(self) -> None:
419  if (self.sim.rtc):
420  nfilt = int(self.uiExpert.wao_filterBtt.value())
421  ao.command_on_Btt(self.sim.rtc, self.sim.dms, self.sim.config.p_dms,
422  self.sim.config.p_geom, nfilt)
423  print("Loop is commanded from Btt basis now")
424 
425  def KLCommand(self) -> None:
426  if (self.sim.rtc):
427  nfilt = int(self.uiExpert.wao_filterBtt.value())
428  cmat = ao.command_on_KL(
429  self.sim.rtc, self.sim.dms, self.sim.config.p_controllers[0],
430  self.sim.config.p_dms, self.sim.config.p_geom,
431  self.sim.config.p_atmos, self.sim.config.p_tel, nfilt)
432  self.sim.rtc.set_cmat(0, cmat.astype(np.float32))
433  print("Loop is commanded from KL basis now")
434 
435  def updatePlotWfs(self) -> None:
436  typeText = str(self.uiExpert.wao_wfs_plotSelector.currentText())
437  n = self.uiExpert.wao_selectWfs.currentIndex()
438  self.uiExpert.wao_wfsWindow.canvas.axes.clear()
439  ax = self.uiExpert.wao_wfsWindow.canvas.axes
440  if ((self.sim.config.p_wfss[n].type == scons.WFSType.PYRHR or
441  self.sim.config.p_wfss[n].type == scons.WFSType.PYRLR) and
442  typeText == "Pyramid mod. pts" and self.sim.is_init):
443  scale_fact = 2 * np.pi / self.sim.config.p_wfss[n]._Nfft * \
444  self.sim.config.p_wfss[n].Lambda * \
445  1e-6 / self.sim.config.p_tel.diam / \
446  self.sim.config.p_wfss[n]._qpixsize * CONST.RAD2ARCSEC
447  cx = self.sim.config.p_wfss[n]._pyr_cx / scale_fact
448  cy = self.sim.config.p_wfss[n]._pyr_cy / scale_fact
449  ax.scatter(cx, cy)
450 
451  def displayRtcMatrix(self) -> None:
452  if not self.sim.is_init:
453  # print(" widget not fully initialized")
454  return
455 
456  data = None
457  if (self.sim.rtc):
458  type_matrix = str(self.uiExpert.wao_selectRtcMatrix.currentText())
459  if (
460  type_matrix == "imat" and
461  self.sim.config.p_controllers[0].type != scons.ControllerType.GENERIC
462  and
463  self.sim.config.p_controllers[0].type != scons.ControllerType.GEO):
464  data = self.sim.rtc.get_imat(0)
465  elif (type_matrix == "cmat"):
466  data = self.sim.rtc.get_cmat(0)
467  elif (type_matrix == "Eigenvalues"):
468  if (self.sim.config.p_controllers[0].type == scons.ControllerType.LS or
469  self.sim.config.p_controllers[0].type == scons.
470  ControllerType.MV):
471  data = self.sim.rtc.getEigenvals(0)
472  elif (type_matrix == "Cmm" and
473  self.sim.config.p_controllers[0].type == scons.ControllerType.MV):
474  tmp = self.sim.rtc.get_cmm(0)
475  ao.do_tomo_matrices(0, self.sim.rtc, self.sim.config.p_wfss,
476  self.sim.dms, self.sim.atm, self.sim.wfs,
477  self.sim.config.p_rtc, self.sim.config.p_geom,
478  self.sim.config.p_dms, self.sim.config.p_tel,
479  self.sim.config.p_atmos)
480  data = self.sim.rtc.get_cmm(0)
481  self.sim.rtc.set_cmm(0, tmp)
482  elif (type_matrix == "Cmm inverse" and
483  self.sim.config.p_controllers[0].type == "mv"):
484  data = self.sim.rtc.get_cmm(0)
485  elif (type_matrix == "Cmm eigen" and
486  self.sim.config.p_controllers[0].type == "mv"):
487  data = self.sim.rtc.getCmmEigenvals(0)
488  elif (type_matrix == "Cphim" and
489  self.sim.config.p_controllers[0].type == "mv"):
490  data = self.sim.rtc.get_cphim(0)
491 
492  if (data is not None):
493  self.uiExpert.wao_rtcWindow.canvas.axes.clear()
494  ax = self.uiExpert.wao_rtcWindow.canvas.axes
495  if (len(data.shape) == 2):
496  self.uiExpert.wao_rtcWindow.canvas.axes.matshow(
497  data, aspect="auto", origin="lower", cmap="gray")
498  elif (len(data.shape) == 1):
499  # TODO : plot it properly, interactivity ?
500  self.uiExpert.wao_rtcWindow.canvas.axes.plot(
501  list(range(len(data))), data, color="black")
502  ax.set_yscale('log')
503  if (type_matrix == "Eigenvalues"):
504  # major_ticks = np.arange(0, 101, 20)
505  # minor_ticks = np.arange(0, 101, 5)
506 
507  # self.uiExpert.wao_rtcWindow.canvas.axes.set_xticks(major_ticks)
508  # self.uiExpert.wao_rtcWindow.canvas.axes.set_xticks(minor_ticks, minor=True)
509  # self.uiExpert.wao_rtcWindow.canvas.axes.set_yticks(major_ticks)
510  # self.uiExpert.wao_rtcWindow.canvas.axes.set_yticks(minor_ticks, minor=True)
511 
512  # and a corresponding grid
513 
514  self.uiExpert.wao_rtcWindow.canvas.axes.grid(which='both')
515 
516  # or if you want differnet settings for the grids:
517  self.uiExpert.wao_rtcWindow.canvas.axes.grid(
518  which='minor', alpha=0.2)
519  self.uiExpert.wao_rtcWindow.canvas.axes.grid(
520  which='major', alpha=0.5)
521  nfilt = self.sim.rtc.get_nfiltered(0, self.sim.config.p_rtc)
522  self.uiExpert.wao_rtcWindow.canvas.axes.plot([
523  nfilt - 0.5, nfilt - 0.5
524  ], [data.min(), data.max()], color="red", linestyle="dashed")
525  if (nfilt > 0):
526  self.uiExpert.wao_rtcWindow.canvas.axes.scatter(
527  np.arange(0, nfilt, 1), data[0:nfilt], color="red"
528  ) # TODO : plot it properly, interactivity ?
529  self.uiExpert.wao_rtcWindow.canvas.axes.scatter(
530  np.arange(nfilt, len(data),
531  1), data[nfilt:], color="blue"
532  ) # TODO : plot it properly, interactivity ?
533  tt = "%d modes Filtered" % nfilt
534  # ax.text(nfilt + 2, data[nfilt-1], tt)
535  ax.text(0.5, 0.2, tt, horizontalalignment='center',
536  verticalalignment='center', transform=ax.transAxes)
537 
538  self.uiExpert.wao_rtcWindow.canvas.draw()
539 
540  def computeDMrange(self, numdm: int, numwfs: int, push4imat: float = None,
541  unitpervolt: float = None) -> float:
542  i = numdm
543  if (push4imat is None or push4imat == 0):
544  push4imat = self.sim.config.p_dms[i].push4imat
545  if (unitpervolt is None or unitpervolt == 0):
546  unitpervolt = self.sim.config.p_dms[i].unitpervolt
547 
548  actuPushInMicrons = push4imat * unitpervolt
549  coupling = self.sim.config.p_dms[i].coupling
550  a = coupling * actuPushInMicrons
551  b = 0
552  c = actuPushInMicrons
553  d = coupling * actuPushInMicrons
554  if (self.sim.config.p_dms[i].type is not scons.DmType.TT):
555  dist = self.sim.config.p_tel.diam
556  else:
557  dist = self.sim.config.p_tel.diam / \
558  self.sim.config.p_wfss[numwfs].nxsub
559  Delta = (1e-6 * (((c + d) / 2) - ((a + b) / 2)))
560  actuPushInArcsecs = CONST.RAD2ARCSEC * Delta / dist
561  return actuPushInArcsecs
shesha.widgets.widget_ao_expert.WidgetAOExpert.setRtcParams
None setRtcParams(self)
Definition: widget_ao_expert.py:317
shesha.widgets.widget_ao_expert.ExpertClassTemplate
ExpertClassTemplate
Definition: widget_ao_expert.py:49
shesha.widgets.widget_ao_expert.WidgetAOExpert.updatePyrAmpl
None updatePyrAmpl(self)
Definition: widget_ao_expert.py:117
shesha.widgets.widget_ao_expert.WidgetAOExpert.updatePlotWfs
None updatePlotWfs(self)
Definition: widget_ao_expert.py:435
shesha.widgets.widget_ao_expert.WidgetAOExpert.setWfsParams
None setWfsParams(self)
Definition: widget_ao_expert.py:356
shesha.ao
Python package for AO operations on COMPASS simulation.
Definition: shesha/shesha/ao/__init__.py:1
shesha.constants
Numerical constants for shesha and config enumerations for safe-typing.
Definition: constants.py:1
shesha.widgets.widget_ao_expert.WidgetAOExpert.reset_dm
None reset_dm(self)
Definition: widget_ao_expert.py:404
shesha.widgets.widget_ao_expert.WidgetAOExpert.setDmParams
None setDmParams(self)
Definition: widget_ao_expert.py:390
shesha.widgets.widget_ao_expert.WidgetAOExpert.displayRtcMatrix
None displayRtcMatrix(self)
Definition: widget_ao_expert.py:451
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateAmpliComp
None updateAmpliComp(self)
Definition: widget_ao_expert.py:111
shesha.ao.wfs
On the fly modification of the WFS.
Definition: wfs.py:1
shesha.widgets.widget_ao_expert.WidgetAOExpert.updatePanels
None updatePanels(self)
Definition: widget_ao_expert.py:291
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateTelescopePanel
None updateTelescopePanel(self)
Definition: widget_ao_expert.py:140
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateDMrange
None updateDMrange(self, float push4imat=None, float unitpervolt=None)
Definition: widget_ao_expert.py:130
shesha.widgets.widget_ao_expert.WidgetAOExpert.sim
sim
Definition: widget_ao_expert.py:56
shesha.widgets.widget_ao_expert.ExpertWidgetTemplate
ExpertWidgetTemplate
Definition: widget_ao_expert.py:49
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateDmPanel
None updateDmPanel(self)
Definition: widget_ao_expert.py:145
shesha.widgets.widget_base
Abstract Widget base.
Definition: widget_base.py:1
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateWfsPanel
None updateWfsPanel(self)
Definition: widget_ao_expert.py:168
shesha.widgets.widget_ao_expert.WidgetAOExpert.setAtmosParams
None setAtmosParams(self)
Definition: widget_ao_expert.py:305
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateAtmosPanel
None updateAtmosPanel(self)
Definition: widget_ao_expert.py:210
shesha.widgets.widget_ao_expert.WidgetAOExpert.uiExpert
uiExpert
Definition: widget_ao_expert.py:58
shesha.widgets.widget_ao_expert.WidgetAOExpert.__init__
None __init__(self)
Definition: widget_ao_expert.py:54
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateRtcPanel
None updateRtcPanel(self)
Definition: widget_ao_expert.py:232
shesha.widgets.widget_ao_expert.WidgetAOExpert.BttCommand
None BttCommand(self)
Definition: widget_ao_expert.py:418
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateTargetPanel
None updateTargetPanel(self)
Definition: widget_ao_expert.py:281
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateGain
None updateGain(self)
Definition: widget_ao_expert.py:100
shesha.widgets.widget_ao_expert.WidgetAOExpert.computeDMrange
float computeDMrange(self, int numdm, int numwfs, float push4imat=None, float unitpervolt=None)
Definition: widget_ao_expert.py:540
shesha.widgets.widget_ao_expert.WidgetAOExpert.KLCommand
None KLCommand(self)
Definition: widget_ao_expert.py:425
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateAmpliCompGUI
None updateAmpliCompGUI(self)
Definition: widget_ao_expert.py:105
shesha.widgets.widget_ao_expert.WidgetAOExpert.setTelescopeParams
None setTelescopeParams(self)
Definition: widget_ao_expert.py:299
shesha.widgets.widget_ao_expert.WidgetAOExpert.setSim
None setSim(self, sim)
METHODS #.
Definition: widget_ao_expert.py:97
shesha.widgets.widget_ao_expert.WidgetAOExpert
Definition: widget_ao_expert.py:52
shesha.widgets.widget_ao_expert.WidgetAOExpert.updateDMrangeGUI
None updateDMrangeGUI(self)
Definition: widget_ao_expert.py:125