38 from collections
import OrderedDict
41 from typing
import NoReturn, Dict
44 """ Shesha parameters configuration class. It embeds all the
45 parameters classes instances needed for the simulation run.
47 This class also exposes most useful getters from its components
48 to allow an easier access and exposition through Pyro
51 simul_name : (str) : Simulation run name
53 p_atmos : (Param_atmos) : A Param_atmos instance
55 p_geom : (Param_geom) : A Param_geom instance
57 p_tel : (Param_tel) : A Param_tel instance
59 p_dms : (List of Param_dm) : List of Param_dm instance
61 p_wfss : (List of Param_wfs) : List of Param_wfs instance
63 p_targets : (List of Param_target) : List of Param_target instance
65 p_loop : (Param_loop) : A Param_loop instance
67 p_centroiders : (List of Param_centroider) : List of Param_centroider instance
69 p_controllers : (List of Param_controller) : List of Param controller instance
71 _config : (configuration module from parfile) : Raw parameter file module
73 def __init__(self, param_file : str):
87 def _load_config_from_file(self, filename_path: str) -> NoReturn:
88 """ Load the parameters from the parameters file
91 filename_path: (str): path to the parameters file
93 path = os.path.dirname(os.path.abspath(filename_path))
94 filename = os.path.basename(filename_path)
95 name, ext = os.path.splitext(filename)
98 if (path
not in sys.path):
99 sys.path.insert(0, path)
104 sys.path.remove(path)
105 elif importlib.util.find_spec(filename_path)
is not None:
108 raise ValueError(
"Config file must be .py or a module")
111 def _load_config_from_module(self, filepath: str) -> NoReturn:
113 Load the parameters from the parameters module
116 filename_path: (str): path to the parameters file
119 config : (config) : a config module
121 filename = filepath.split(
'.')[-1]
122 print(
"loading: %s" % filename)
124 config = importlib.import_module(filepath)
125 del sys.modules[config.__name__]
126 self.
_config_config = importlib.import_module(filepath)
128 if hasattr(config,
'par'):
129 self.
_config_config = getattr(
"config.par.par4bench", filename)
132 if not hasattr(self.
_config_config,
'p_loop'):
133 self.
_config_config.p_loop =
None
134 if not hasattr(self.
_config_config,
'p_geom'):
135 self.
_config_config.p_geom =
None
136 if not hasattr(self.
_config_config,
'p_tel'):
137 self.
_config_config.p_tel =
None
138 if not hasattr(self.
_config_config,
'p_atmos'):
139 self.
_config_config.p_atmos =
None
140 if not hasattr(self.
_config_config,
'p_dms'):
141 self.
_config_config.p_dms =
None
142 if not hasattr(self.
_config_config,
'p_targets'):
143 self.
_config_config.p_targets =
None
144 if not hasattr(self.
_config_config,
'p_wfss'):
145 self.
_config_config.p_wfss =
None
146 if not hasattr(self.
_config_config,
'p_centroiders'):
147 self.
_config_config.p_centroiders =
None
148 if not hasattr(self.
_config_config,
'p_controllers'):
149 self.
_config_config.p_controllers =
None
150 if not hasattr(self.
_config_config,
'p_coronos'):
151 self.
_config_config.p_coronos =
None
153 if not hasattr(self.
_config_config,
'simul_name'):
154 self.
_config_config.simul_name =
None
156 def get_pupil(self, pupil_type) -> np.ndarray:
157 """ Returns the specified pupil of COMPASS.
159 Possible args value are :
160 - "i" or "ipupil" : returns the biggest pupil of size (Nfft x Nfft)
161 - "m" or "mpupil" : returns the medium pupil, used for WFS computation
162 - "s" or "spupil" : returns the smallest pupil of size (p_geom.pupdiam x p_geom.pupdiam)
165 pupil : (np.ndarray) : pupil
167 if scons.PupilType(pupil_type)
is scons.PupilType.SPUPIL:
168 return self.
p_geomp_geom.get_spupil()
169 if scons.PupilType(pupil_type)
is scons.PupilType.MPUPIL:
170 return self.
p_geomp_geom.get_mpupil()
171 if scons.PupilType(pupil_type)
is scons.PupilType.IPUPIL:
172 return self.
p_geomp_geom.get_ipupil()
176 Extract and convert compass supervisor configuration parameters
177 into 2 dictionnaries containing relevant AO parameters
179 Returns : 2 dictionnaries
181 aodict = OrderedDict()
184 if (self.
p_telp_tel
is not None):
185 aodict.update({
"teldiam": self.
p_telp_tel.diam})
186 aodict.update({
"telobs": self.
p_telp_tel.cobs})
187 aodict.update({
"pixsize": self.
p_geomp_geom._pixsize})
189 aodict.update({
"r0": self.
p_atmosp_atmos.r0})
190 aodict.update({
"Fe": 1 / self.
p_loopp_loop.ittime})
191 aodict.update({
"nbTargets": len(self.
p_targetsp_targets)})
193 aodict.update({
"nbTargets": 1})
196 aodict.update({
"nbWfs": len(self.
p_wfssp_wfss)})
197 aodict.update({
"nbCam": aodict[
"nbWfs"]})
198 aodict.update({
"nbOffaxis": 0})
199 aodict.update({
"nbNgsWFS": 1})
200 aodict.update({
"nbLgsWFS": 0})
201 aodict.update({
"nbFigSensor": 0})
202 aodict.update({
"nbSkyWfs": aodict[
"nbWfs"]})
203 aodict.update({
"nbOffNgs": 0})
206 aodict.update({
"nbDms": len(self.
p_dmsp_dms)})
207 aodict.update({
"Nactu": self.
p_controllersp_controllers[0].nactu})
209 aodict.update({
"list_NgsOffAxis": []})
210 aodict.update({
"list_Fig": []})
211 aodict.update({
"list_Cam": [0]})
212 aodict.update({
"list_SkyWfs": [0]})
213 aodict.update({
"list_ITS": []})
214 aodict.update({
"list_Woofer": []})
215 aodict.update({
"list_Tweeter": []})
216 aodict.update({
"list_Steering": []})
218 listOfNstatesPerController = []
219 listOfcommandLawTypePerController = []
221 listOfNstatesPerController.append(control.nstates)
222 listOfcommandLawTypePerController.append(control.type)
223 aodict.update({
"list_nstatesPerController": listOfNstatesPerController})
224 aodict.update({
"list_controllerType": listOfcommandLawTypePerController})
232 pyrModulationList = []
249 for i
in range(aodict[
"nbWfs"]):
252 dataDict[
"wfsValid_" + str(i)] = self.
p_wfssp_wfss[i]._isvalid
254 xytab = np.zeros((2, self.
p_wfssp_wfss[i]._validsubsx.shape[0]))
255 xytab[0, :] = self.
p_wfssp_wfss[i]._validsubsx
256 xytab[1, :] = self.
p_wfssp_wfss[i]._validsubsy
257 dataDict[
"wfsValidXY_" + str(i)] = xytab
261 pixsize.append(self.
p_wfssp_wfss[i].pixsize)
263 if (self.p_centroiders[i].type == "maskedpix"):
268 self.p_wfss[i]._nvalid * factor) # slopes per wfs
270 listCentroType.append(
273 NsubapList.append(self.
p_wfssp_wfss[i]._nvalid)
274 listWfsType.append(self.
p_wfssp_wfss[i].type)
275 xPosList.append(self.
p_wfssp_wfss[i].xpos)
276 yPosList.append(self.
p_wfssp_wfss[i].ypos)
277 fstopsize.append(self.
p_wfssp_wfss[i].fssize)
278 fstoptype.append(self.
p_wfssp_wfss[i].fstop)
279 nxsubList.append(self.
p_wfssp_wfss[i].nxsub)
280 nysubList.append(self.
p_wfssp_wfss[i].nxsub)
281 lambdaList.append(self.
p_wfssp_wfss[i].Lambda)
282 if (self.
p_wfssp_wfss[i].dms_seen
is not None):
283 dms_seen.append(list(self.
p_wfssp_wfss[i].dms_seen))
284 noise.append(self.
p_wfssp_wfss[i].noise)
286 if (self.
p_centroidersp_centroiders[i].type == scons.CentroiderType.MASKEDPIX):
287 NslopesList.append(self.
p_wfssp_wfss[i]._nvalid * 4)
289 NslopesList.append(self.
p_wfssp_wfss[i]._nvalid * 2)
291 if (self.
p_wfssp_wfss[i].type ==
"pyrhr"):
292 pyrModulationList.append(self.
p_wfssp_wfss[i].pyr_ampl)
293 pyr_npts.append(self.
p_wfssp_wfss[i].pyr_npts)
294 pyr_pupsep.append(self.
p_wfssp_wfss[i].pyr_pup_sep)
297 pyrModulationList.append(0)
300 npixPerSub.append(self.
p_wfssp_wfss[i].npix)
302 confname = filepath.split("/")[-1].split('.conf')[0]
303 print(filepath.split(".conf")[0] + '_wfsConfig.fits')
305 filepath.split(".conf")[0] + '_wfsConfig.fits', overwrite=True)
306 new_hduwfsSubapXY.writeto(
307 filepath.split(".conf")[0] + '_wfsValidXYConfig.fits', overwrite=True)
309 if (len(dms_seen) != 0):
310 aodict.update({
"listWFS_dms_seen": dms_seen})
312 aodict.update({
"listWFS_NslopesList": NslopesList})
313 aodict.update({
"listWFS_NsubapList": NsubapList})
314 aodict.update({
"listWFS_CentroType": listCentroType})
315 aodict.update({
"listWFS_WfsType": listWfsType})
316 aodict.update({
"listWFS_pixarc": pixsize})
317 aodict.update({
"listWFS_pyrModRadius": pyrModulationList})
318 aodict.update({
"listWFS_pyrModNPts": pyr_npts})
319 aodict.update({
"listWFS_pyrPupSep": pyr_pupsep})
320 aodict.update({
"listWFS_fstopsize": fstopsize})
321 aodict.update({
"listWFS_fstoptype": fstoptype})
322 aodict.update({
"listWFS_NsubX": nxsubList})
323 aodict.update({
"listWFS_NsubY": nysubList})
324 aodict.update({
"listWFS_Nsub": nysubList})
325 aodict.update({
"listWFS_NpixPerSub": npixPerSub})
326 aodict.update({
"listWFS_Lambda": lambdaList})
327 if (len(noise) != 0):
328 aodict.update({
"listWFS_noise": noise})
339 for j
in range(aodict[
"nbDms"]):
340 listDmsType.append(self.
p_dmsp_dms[j].type)
342 self.
p_dmsp_dms[j].nact)
343 Nactu.append(self.
p_dmsp_dms[j]._ntotact)
344 unitPerVolt.append(self.
p_dmsp_dms[j].unitpervolt)
345 push4imat.append(self.
p_dmsp_dms[j].push4imat)
346 coupling.append(self.
p_dmsp_dms[j].coupling)
348 if (self.
p_dmsp_dms[j]._i1
is
350 if (self.
p_dmsp_dms[j].type !=
'tt'):
351 tmpdata = np.zeros((4, len(self.
p_dmsp_dms[j]._i1)))
352 tmpdata[0, :] = self.
p_dmsp_dms[j]._j1
353 tmpdata[1, :] = self.
p_dmsp_dms[j]._i1
354 tmpdata[2, :] = self.
p_dmsp_dms[j]._xpos
355 tmpdata[3, :] = self.
p_dmsp_dms[j]._ypos
357 tmpdata = np.zeros((4, 2))
359 dataDict[
"dmData" + str(j)] = tmpdata
361 new_hdudmsl.append(pfits.ImageHDU(tmpdata)) # Valid subap array
362 new_hdudmsl[j].header["DATATYPE"] = "valid_dm%d" % j
367 push4iMatArcSec.append(tmp)
370 if (len(push4iMatArcSec) != 0):
371 aodict.update({
"listDMS_push4iMat": push4imat})
372 aodict.update({
"listDMS_unitPerVolt": unitPerVolt})
373 aodict.update({
"listDMS_Nxactu": NactuX})
374 aodict.update({
"listDMS_Nyactu": NactuX})
375 aodict.update({
"listDMS_Nactu": Nactu})
377 aodict.update({
"listDMS_type": listDmsType})
378 aodict.update({
"listDMS_coupling": coupling})
380 if (self.
p_targetsp_targets
is not None):
381 listTargetsLambda = []
384 listTargetsDmsSeen = []
386 listTARGETS_pixsize = []
387 for k
in range(aodict[
"nbTargets"]):
388 listTargetsLambda.append(self.
p_targetsp_targets[k].Lambda)
389 listTargetsXpos.append(self.
p_targetsp_targets[k].xpos)
390 listTargetsYpos.append(self.
p_targetsp_targets[k].ypos)
391 listTargetsMag.append(self.
p_targetsp_targets[k].mag)
392 listTargetsDmsSeen.append(list(self.
p_targetsp_targets[k].dms_seen))
393 PSFPixsize = (self.
p_targetsp_targets[k].Lambda * 1e-6) / (
394 self.
p_geomp_geom._pixsize *
395 self.
p_geomp_geom.get_ipupil().shape[0]) * 206265.
396 listTARGETS_pixsize.append(PSFPixsize)
398 aodict.update({
"listTARGETS_Lambda": listTargetsLambda})
399 aodict.update({
"listTARGETS_Xpos": listTargetsXpos})
400 aodict.update({
"listTARGETS_Ypos": listTargetsYpos})
401 aodict.update({
"listTARGETS_Mag": listTargetsMag})
402 aodict.update({
"listTARGETS_DmsSeen": listTargetsDmsSeen})
403 aodict.update({
"listTARGETS_pixsize": listTARGETS_pixsize})
406 Nslopes = sum(NslopesList)
407 Nsubap = sum(NsubapList)
408 aodict.update({
"Nslopes": Nslopes})
409 aodict.update({
"Nsubap": Nsubap})
410 return aodict, dataDict
Shesha parameters configuration class.
[Dict, Dict] export_config(self)
Extract and convert compass supervisor configuration parameters into 2 dictionnaries containing relev...
p_targets
(List of Param_target) : List of Param_target instance
p_controllers
(List of Param_controller) : List of Param controller instance
p_wfss
(List of Param_wfs) : List of Param_wfs instance
simul_name
(str) : Simulation run name
p_tel
(Param_tel) : A Param_tel instance
NoReturn _load_config_from_module(self, str filepath)
p_centroiders
(List of Param_centroider) : List of Param_centroider instance
p_geom
(Param_geom) : A Param_geom instance
NoReturn _load_config_from_file(self, str filename_path)
p_loop
(Param_loop) : A Param_loop instance
def __init__(self, str param_file)
p_atmos
(Param_atmos) : A Param_atmos instance
np.ndarray get_pupil(self, pupil_type)
Returns the specified pupil of COMPASS.
p_dms
(List of Param_dm) : List of Param_dm instance
Numerical constants for shesha and config enumerations for safe-typing.