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