38 Initialization and execution of an AO 2-stages manager.
39 It instanciates in one process two compass simulations:
40 1 for first stage and 1 for the second stage (as defined in their relative .par files)
43 The next method of this manager --superseeds-- the compass next method so that the loop is fully handled by the manager.
46 twoStagesManager.py <parameters_filename1> <parameters_filename2> <freqratio> [options]
48 with 'parameters_filename1' the path to the parameters file the first stage
49 with 'parameters_filename2' the path to the parameters file the second stage
50 with 'freqratio' the ratio of the frequencies of the two stages
52 -a, --adopt used to connect optional ADOPT client to the manager (via pyro + shm cacao)
55 ipython -i twoStagesManager.py ../../data/par/SPHERE+/sphere.py ../../data/par/SPHERE+/sphere+.py 3
56 ipython -i twoStagesManager.py ../../data/par/SPHERE+/sphere.py ../../data/par/SPHERE+/sphere+.py 3 -- --adopt
61 from typing
import Any, Dict, Tuple, Callable, List
66 Class handling both supervisors of first stage and second stage.
69 first_stage : (StageSupervisor) : first stage StageSupervisor instance
71 second_stage : (StageSupervisor) : second stage StageSupervisor instance
73 iterations : (int) : frame counter
75 second_stage_input : (array) : input phase screen for second stage
77 mpup_offset : (int) : number of padding pixel from first stage s_pupil to second stage m_pupil
79 frequency_ratio : (int) : second stage simulated frequency over first stage simulated frequency
81 def __init__(self, first_stage : StageSupervisor, second_stage : StageSupervisor, frequency_ratio : int):
83 Init of the TwoStagesManager object
86 first_stage : (StageSupervisor) : first stage StageSupervisor instance
88 second_stage : (StageSupervisor) : second stage StageSupervisor instance
90 frequency_ratio : (int) : ratio between second stage frequency and first stage frequency. Only integers are accepted.
97 mpup_shape = self.
second_stagesecond_stage.config.p_geom._mpupil.shape
98 self.
second_stage_inputsecond_stage_input = np.zeros((mpup_shape[0], mpup_shape[1], 1))
99 residual_shape = self.
first_stagefirst_stage.config.p_geom._spupil.shape
100 self.
mpup_offsetmpup_offset = (mpup_shape[0] - residual_shape[0]) // 2
107 def next(self, *, do_control: bool =
True) ->
None:
109 MAIN method that allows to manage properly the 2 AO stages of SAXO+ system.
110 The phase residuals (including turbulence + AO loop residuals) of the first stage simulation is sent to second stage simulation
111 at each iteration of the manager.
112 The manager disable the seconds stage turbulence simulation (as it is propageated through the first stage residals if any).
113 This next method sould ALWAYS be called to perform a regular SAXO+ simulation
114 instead of the individual stage next methods to ensure the correct synchronisation of the 2 systems.
130 first_stage_control = first_stage_centroids
132 apply_control =
True,
133 do_centroids = first_stage_centroids,
134 compute_tar_psf =
True,
135 stack_wfs_image = first_stage_stack_wfs)
140 compute_tar_psf =
True)
147 first_stage_residual = self.
first_stagefirst_stage.target.get_tar_phase(0)
161 """ Enable coronagraphic image computation for both stages.
164 stage: (str, optional): If 'first', enable only first stage coronagrapic image computation.
165 If 'second', enable only second stage coronagraphic image computation.
170 elif stage ==
'second':
177 """ Disable all coronagraphic image computation
183 """ Reset long exposure psf and coronagraphic images for both stages
191 """ Returns the current iteration number of the manager
194 iterations : (int) : Number of manager iterations already performed
198 def loop(self, number_of_iter: int, *, monitoring_freq: int = 100, **kwargs):
199 """ Perform the AO loop for <number_of_iter> iterations
202 number_of_iter: (int) : Number of iteration that will be done
205 monitoring_freq: (int) : Monitoring frequency [frames]. Default is 100
208 print(
"----------------------------------------------------")
209 print(
"iter# | S.E. SR | L.E. SR | ETR (s) | Framerate (Hz)")
210 print(
"----------------------------------------------------")
214 if number_of_iter == -1:
217 if ((self.
iterationsiterations + 1) % monitoring_freq == 0):
218 self.
second_stagesecond_stage._print_strehl(monitoring_freq, time.time() - t1, number_of_iter)
221 for _
in range(number_of_iter):
223 if ((self.
iterationsiterations + 1) % monitoring_freq == 0):
224 self.
second_stagesecond_stage._print_strehl(monitoring_freq, time.time() - t1, number_of_iter)
227 print(
" loop execution time:", t1 - t0,
" (", number_of_iter,
"iterations), ",
228 (t1 - t0) / number_of_iter,
"(mean) ", number_of_iter / (t1 - t0),
"Hz")
244 if __name__ ==
'__main__':
245 from docopt
import docopt
247 arguments = docopt(__doc__)
248 adopt = arguments[
"--adopt"]
250 config1 =
ParamConfig(arguments[
"<parameters_filename1>"])
252 frequency_ratio = arguments[
"<freqratio>"]
260 supervisor1 = manager.first_stage
261 supervisor2 = manager.second_stage
265 from subprocess
import Popen, PIPE
266 from hraa.server.pyroServer
import PyroServer
268 Pyro4.config.REQUIRE_EXPOSE =
False
269 p = Popen(
"whoami", shell=
True, stdout=PIPE, stderr=PIPE)
270 out, err = p.communicate()
273 raise Exception(
"ERROR CANNOT RECOGNIZE USER")
275 user = out.split(b
"\n")[0].decode(
"utf-8")
276 print(
"User is " + user)
279 if (supervisor1.corono ==
None):
283 coro2pyro1 = supervisor1.corono
285 if (supervisor2.corono ==
None):
289 coro2pyro2 = supervisor2.corono
293 supervisor1, supervisor1.rtc, supervisor1.wfs, supervisor1.target,
294 supervisor1.tel, supervisor1.basis, supervisor1.calibration,
295 supervisor1.atmos, supervisor1.dms, supervisor1.config, supervisor1.modalgains,
299 supervisor2, supervisor2.rtc, supervisor2.wfs, supervisor2.target,
300 supervisor2.tel, supervisor2.basis, supervisor2.calibration,
301 supervisor2.atmos, supervisor2.dms, supervisor2.config, supervisor2.modalgains,
305 "supervisor",
"supervisor_rtc",
"supervisor_wfs",
"supervisor_target",
306 "supervisor_tel",
"supervisor_basis",
"supervisor_calibration",
307 "supervisor_atmos",
"supervisor_dms",
"supervisor_config",
"supervisor_modalgains",
314 nname.append(name +
"_" + user +
"_" +label)
316 label =
"secondStage"
318 nname.append(name +
"_" + user +
"_" +label)
320 nname.append(
'twoStagesManager'+
"_" + user )
321 devices = devices1 + devices2 + [manager]
322 server = PyroServer(listDevices=devices, listNames=nname)
326 raise EnvironmentError(
327 "Missing dependencies (code HRAA or Pyro4 or Dill Serializer)")
Shesha parameters configuration class.
This class implements a single stage (e.g.
Class handling both supervisors of first stage and second stage.
None next(self, *bool do_control=True)
MAIN method that allows to manage properly the 2 AO stages of SAXO+ system.
def __init__(self, StageSupervisor first_stage, StageSupervisor second_stage, int frequency_ratio)
iterations
(int) : frame counter
def loop(self, int number_of_iter, *int monitoring_freq=100, **kwargs)
Perform the AO loop for <number_of_iter> iterations.
def disable_corono(self)
Disable all coronagraphic image computation.
second_stage
(StageSupervisor) : second stage StageSupervisor instance
frequency_ratio
(int) : second stage simulated frequency over first stage simulated frequency
second_stage_input
(array) : input phase screen for second stage
def enable_corono(self, stage=None)
Enable coronagraphic image computation for both stages.
compute_first_stage_corono
def get_frame_counter(self)
Returns the current iteration number of the manager.
mpup_offset
(int) : number of padding pixel from first stage s_pupil to second stage m_pupil
compute_second_stage_corono
def reset_exposure(self)
Reset long exposure psf and coronagraphic images for both stages.
first_stage
(StageSupervisor) : first stage StageSupervisor instance
This file is here only to avoid pyro server crash when a coronograph class is not in the pramam file.
Parameter classes for COMPASS.
Initialization and execution of a single stage supervisor for cascaded AO systems.