2 Created on Wed Apr 27 09:28:23 2016
12 import carmaWrap
as ch
15 import matplotlib.pyplot
as pl
17 import hdf5_util
as h5u
19 from scipy.sparse
import csr_matrix
21 c = ch.carmaWrap_context(devices=np.array([6], dtype=np.int32))
33 if (hasattr(config,
"simul_name")):
34 if (config.simul_name
is None):
37 simul_name = config.simul_name
40 print(
"simul name is", simul_name)
43 if (simul_name == b
""):
47 param_dict = h5u.params_dictionary(config)
48 matricesToLoad = h5u.checkMatricesDataBase(os.environ[
"SHESHA_ROOT"] +
"/data/",
58 wfs, tel = ao.wfs_init(config.p_wfss, config.p_atmos, config.p_tel, config.p_geom,
59 config.p_target, config.p_loop, config.p_dms)
63 atm = ao.atmos_init(c, config.p_atmos, config.p_tel, config.p_geom, config.p_loop,
64 config.p_wfss, wfs, config.p_target, rank=0, clean=clean,
69 dms = ao.dm_init(config.p_dms, config.p_wfss, wfs, config.p_geom, config.p_tel)
73 tar = ao.target_init(c, tel, config.p_target, config.p_atmos, config.p_geom,
74 config.p_tel, config.p_dms)
78 rtc = ao.rtc_init(tel, wfs, config.p_wfss, dms, config.p_dms, config.p_geom,
79 config.p_rtc, config.p_atmos, atm, config.p_tel, config.p_loop,
80 clean=clean, simul_name=simul_name, load=matricesToLoad)
83 h5u.validDataBase(os.environ[
"SHESHA_ROOT"] +
"/data/", matricesToLoad)
85 print(
"====================")
87 print(
"====================")
88 print(
"objects initialzed on GPU:")
89 print(
"--------------------------------------------------------")
96 print(
"----------------------------------------------------")
97 print(
"iter# | SE SR image | LE SR image | Fitting | LE SR phase var")
98 print(
"----------------------------------------------------")
100 error_flag =
True in [w.roket
for w
in config.p_wfss]
102 return atm, wfs, tel, dms, tar, rtc
114 Performs the main AO loop for n interations. First, initialize buffers
115 for error breakdown computations. Then, at the end of each iteration, just
116 before applying the new DM shape, calls the error_breakdown function.
118 :param n: (int) : number of iterations
121 com : (np.array((n,nactus))) : full command buffer
123 noise_com : (np.array((n,nactus))) : noise contribution for error breakdown
125 alias_wfs_com : (np.array((n,nactus))) : aliasing estimation in the WFS direction
127 tomo_com : (np.array((n,nactus))) : tomography error estimation
129 H_com : (np.array((n,nactus))) : Filtered modes contribution for error breakdown
131 trunc_com : (np.array((n,nactus))) : Truncature and sampling error of WFS
133 bp_com : (np.array((n,nactus))) : Bandwidth error estimation on target
135 mod_com : (np.array((n,nactus))) : Commanded modes expressed on the actuators
137 fit : (float) : fitting (mean variance of the residual target phase after projection)
139 SR : (float) : final strehl ratio returned by the simulation
143 nactu = rtc.get_command(0).size
144 com = np.zeros((n, nactu), dtype=np.float32)
145 noise_com = np.zeros((n, nactu), dtype=np.float32)
146 alias_wfs_com = np.copy(noise_com)
147 wf_com = np.copy(noise_com)
148 tomo_com = np.copy(noise_com)
149 trunc_com = np.copy(noise_com)
150 H_com = np.copy(noise_com)
151 mod_com = np.copy(noise_com)
152 bp_com = np.copy(noise_com)
154 psf_ortho = tar.get_image(0,
'se') * 0.
160 if (config.p_controllers[0].type == b
"geo"):
161 for t
in range(config.p_target.ntargets):
162 tar.atmos_trace(t, atm, tel)
163 rtc.docontrol_geo(0, dms, tar, 0)
164 rtc.applycontrol(0, dms)
167 for t
in range(config.p_target.ntargets):
168 tar.atmos_trace(t, atm, tel)
170 for w
in range(len(config.p_wfss)):
171 wfs.sensors_trace(w,
"all", tel, atm, dms)
172 wfs.sensors_compimg(w)
179 trunc_com, bp_com, wf_com, mod_com, fit, psf_ortho, i)
181 rtc.applycontrol(0, dms)
183 if ((i + 1) % 10 == 0
and i > -1):
184 strehltmp = tar.get_strehl(0)
185 print(i + 1,
"\t", strehltmp[0],
"\t", strehltmp[1],
"\t",
186 np.exp(-strehltmp[2]),
"\t", np.exp(-strehltmp[3]))
188 print(
" loop execution time:", t1 - t0,
" (", n,
"iterations), ", (t1 - t0) / n,
189 "(mean) ", n / (t1 - t0),
"Hz")
192 SR2 = np.exp(-tar.get_strehl(0, comp_strehl=
False)[3])
193 SR = tar.get_strehl(0, comp_strehl=
False)[1]
196 return com, noise_com, alias_wfs_com, tomo_com, H_com, trunc_com, bp_com, mod_com, np.mean(
197 fit[N_preloop:]), SR, SR2, psf_ortho
202 Performs the main AO loop for n interations. First, initialize buffers
203 for error breakdown computations. Then, at the end of each iteration, just
204 before applying the new DM shape, calls the error_breakdown function.
206 :param n: (int) : number of iterations
209 com : (np.array((n,nactus))) : full command buffer
211 noise_com : (np.array((n,nactus))) : noise contribution for error breakdown
213 alias_wfs_com : (np.array((n,nactus))) : aliasing estimation in the WFS direction
215 tomo_com : (np.array((n,nactus))) : tomography error estimation
217 H_com : (np.array((n,nactus))) : Filtered modes contribution for error breakdown
219 trunc_com : (np.array((n,nactus))) : Truncature and sampling error of WFS
221 bp_com : (np.array((n,nactus))) : Bandwidth error estimation on target
223 mod_com : (np.array((n,nactus))) : Commanded modes expressed on the actuators
225 fit : (float) : fitting (mean variance of the residual target phase after projection)
227 SR : (float) : final strehl ratio returned by the simulation
229 for i
in range(0, n):
232 if (config.p_controllers[0].type == b
"geo"):
233 for t
in range(config.p_target.ntargets):
234 tar.atmos_trace(t, atm, tel)
235 rtc.docontrol_geo(0, dms, tar, 0)
236 rtc.applycontrol(0, dms)
238 for t
in range(config.p_target.ntargets):
239 tar.atmos_trace(t, atm, tel)
240 for w
in range(len(config.p_wfss)):
241 wfs.sensors_trace(w,
"all", tel, atm, dms)
242 wfs.sensors_compimg(w)
246 rtc.applycontrol(0, dms)
255 def error_breakdown(com, noise_com, alias_wfs_com, tomo_com, H_com, trunc_com, bp_com,
256 wf_com, mod_com, fit, psf_ortho, i):
258 Compute the error breakdown of the AO simulation. Returns the error commands of
259 each contributors. Suppose no delay (for now) and only 2 controllers : the main one, controller #0, (specified on the parameter file)
260 and the geometric one, controller #1 (automatically added if roket is asked in the parameter file)
261 Commands are computed by applying the loop filter on various kind of commands : (see schema_simulation_budget_erreur_v2)
263 - Ageom : Aliasing contribution on WFS direction
264 Obtained by computing commands from DM orthogonal phase (projection + slopes_geom)
266 - B : Projection on the target direction
267 Obtained as the commmands output of the geometric controller
270 Obtained by computing commands from DM parallel phase (RD*B)
272 - E : Wavefront + aliasing + ech/trunc + tomo
273 Obtained by performing the AO loop iteration without noise on the WFS
275 - F : Wavefront + aliasing + tomo
276 Obtained by performing the AO loop iteration without noise on the WFS and using phase deriving slopes
280 Note : rtc.get_err returns to -CMAT.slopes
283 noise_com : np.array((niter,nactu)) : Noise contribution
286 alias_wfs_com : np.array((niter,nactu)) : Aliasing on WFS direction contribution
289 tomo_com : np.array((niter,nactu)) : Tomographic error contribution
292 H_com : np.array((niter,nactu)) : Filtered modes error
295 trunc_com : np.array((niter,nactu)) : sampling/truncature error contribution
298 bp_com : np.array((niter,nactu)) : Bandwidth error
300 wf_com : np.array((niter,nactu)) : Reconstructed wavefront
302 mod_com : np.array((niter,nactu)) : commanded modes
304 fit : np.array((niter)) : fitting value
306 i : (int) : current iteration number
309 g = config.p_controllers[0].gain
310 Dcom = rtc.get_command(0)
311 Derr = rtc.get_err(0)
313 tarphase = tar.get_phase(0)
317 if (config.p_wfss[0].type == b
"sh"):
318 ideal_bincube = wfs.get_bincubeNotNoisy(0)
319 bincube = wfs.get_bincube(0)
320 if (config.p_centroiders[0].type == b
"tcog"
322 invalidpix = np.where(bincube <= config.p_centroiders[0].thresh)
323 ideal_bincube[invalidpix] = 0
324 rtc.setthresh(0, -1e16)
325 wfs.set_bincube(0, ideal_bincube)
326 elif (config.p_wfss[0].type == b
"pyrhr"):
327 ideal_pyrimg = wfs.get_binimg_notnoisy(0)
328 wfs.set_pyrimg(0, ideal_pyrimg)
331 if (config.p_centroiders[0].type == b
"tcog"):
332 rtc.setthresh(0, config.p_centroiders[0].thresh)
337 if (i + 1 < config.p_loop.niter):
338 noise_com[i + 1, :] = gRD.dot(noise_com[i, :]) + g * (Derr - E)
343 rtc.docentroids_geom(0)
347 if (i + 1 < config.p_loop.niter):
348 trunc_com[i + 1, :] = gRD.dot(trunc_com[i, :]) + g * (E - F)
353 rtc.docontrol_geo_onwfs(1, dms, wfs, 0)
354 rtc.applycontrol(1, dms)
355 for w
in range(len(config.p_wfss)):
356 wfs.sensors_trace(w,
"dm", tel, atm, dms)
358 wfs.sensors_compimg(0)
359 if(config.p_wfss[0].type == b"sh"):
360 ideal_bincube = wfs.get_bincubeNotNoisy(0)
361 bincube = wfs.get_bincube(0)
362 if(config.p_centroiders[0].type == b"tcog"): # Select the same pixels with or without noise
363 invalidpix = np.where(bincube <= config.p_centroiders[0].thresh)
364 ideal_bincube[invalidpix] = 0
365 rtc.setthresh(0,-1e16)
366 wfs.set_bincube(0,ideal_bincube)
367 elif(config.p_wfss[0].type == b"pyrhr"):
368 ideal_pyrimg = wfs.get_binimg_notnoisy(0)
369 wfs.set_pyrimg(0,ideal_pyrimg)
371 rtc.docentroids_geom(0)
373 Ageom = rtc.get_err(0)
374 if (i + 1 < config.p_loop.niter):
375 alias_wfs_com[i + 1, :] = gRD.dot(alias_wfs_com[i, :]) + g * (Ageom)
380 tar.atmos_trace(0, atm, tel)
381 rtc.docontrol_geo(1, dms, tar, 0)
382 B = rtc.get_command(1)
387 rtc.applycontrol(1, dms)
388 tar.dmtrace(0, dms, do_phase_var=0)
389 fit[i] = tar.get_strehl(0, comp_strehl=
False)[2]
391 psf_ortho += tar.get_image(0,
'se') / niters
397 modes_filt = modes.copy() * 0.
398 modes_filt[-nfiltered - 2:-2] = modes[-nfiltered - 2:-2]
399 H_com[i, :] = Btt.dot(modes_filt)
400 modes[-nfiltered - 2:-2] = 0
401 mod_com[i, :] = Btt.dot(modes)
406 C = mod_com[i, :] - mod_com[i - 1, :]
408 bp_com[i, :] = gRD.dot(bp_com[i - 1, :]) - C
414 for w
in range(len(config.p_wfss)):
415 wfs.sensors_trace(w,
"atmos", tel, atm, dms)
416 rtc.docontrol_geo_onwfs(1, dms, wfs, 0)
417 G = rtc.get_command(1)
419 modes[-nfiltered - 2:-2] = 0
420 wf_com[i, :] = Btt.dot(modes)
422 G = mod_com[i, :] - wf_com[i, :]
423 if (i + 1 < config.p_loop.niter):
424 tomo_com[i + 1, :] = gRD.dot(tomo_com[i, :]) - g * RD.dot(G)
427 tar.set_phase(0, tarphase)
438 IF = rtc.get_IFsparse(1).T
446 delta = IF.T.dot(IF).toarray() / N
449 Tp = np.ones((T.shape[0], T.shape[1] + 1))
451 deltaT = IF.T.dot(Tp) / N
453 tau = np.linalg.inv(delta).dot(deltaT)
457 tdt = tau.T.dot(delta).dot(tau)
458 subTT = tau.dot(np.linalg.inv(tdt)).dot(tau.T).dot(delta)
462 gdg = G.T.dot(delta).dot(G)
463 U, s, V = np.linalg.svd(gdg)
464 U = U[:, :U.shape[1] - 3]
466 L = np.identity(s.size) / np.sqrt(s)
471 Btt = np.zeros((n + 2, n - 1))
472 Btt[:B.shape[0], :B.shape[1]] = B
473 mini = 1. / np.sqrt(TT)
476 Btt[n:, n - 3:] = mini
479 delta = np.zeros((n + T.shape[1], n + T.shape[1]))
481 delta[:-2, :-2] = IF.T.dot(IF).toarray() / N
482 delta[-2:, -2:] = T.T.dot(T) / N
485 return Btt.astype(np.float32), P.astype(np.float32)
489 IF = rtc.get_IFsparse(1).T
492 T = IF[:, -2:].copy()
496 delta = IF.T.dot(IF).toarray() / N
499 Tp = np.ones((T.shape[0], T.shape[1] + 1))
500 Tp[:, :2] = T.toarray()
501 deltaT = IF.T.dot(Tp) / N
503 tau = np.linalg.inv(delta).dot(deltaT)
507 tdt = tau.T.dot(delta).dot(tau)
508 subTT = tau.dot(np.linalg.inv(tdt)).dot(tau.T).dot(delta)
512 gdg = G.T.dot(delta).dot(G)
513 U, s, V = np.linalg.svd(gdg)
514 U = U[:, :U.shape[1] - 3]
516 L = np.identity(s.size) / np.sqrt(s)
520 TT = T.T.dot(T).toarray() / N
521 Btt = np.zeros((n + 2, n - 1))
522 Btt[:B.shape[0], :B.shape[1]] = B
523 mini = 1. / np.sqrt(TT)
526 Btt[n:, n - 3:] = mini
529 IF = rtc.get_IFsparse(1).T
530 delta = IF.T.dot(IF).toarray() / N
533 return Btt.astype(np.float32), P.astype(np.float32)
540 Btt_filt = np.zeros((Btt.shape[0], Btt.shape[1] - nfilt))
541 Btt_filt[:, :Btt_filt.shape[1] - 2] = Btt[:, :Btt.shape[1] - (nfilt + 2)]
542 Btt_filt[:, Btt_filt.shape[1] - 2:] = Btt[:, Btt.shape[1] - 2:]
547 Dmp = np.linalg.inv(Dm.T.dot(Dm)).dot(Dm.T)
549 cmat = Btt_filt.dot(Dmp)
551 return Dm.astype(np.float32), cmat.astype(np.float32)
561 U, s, V = np.linalg.svd(DmtDm)
563 s[s.shape[0] - nfilt - 2:s.shape[0] - 2] = 0.
564 DmtDm1 = U.dot(np.diag(s)).dot(U.T)
565 Dmp = DmtDm1.dot(Dm.T)
569 return Dm.astype(np.float32), cmat.astype(np.float32)
581 def cov_cor(P, noise, trunc, alias, H, bp, tomo):
582 cov = np.zeros((6, 6))
591 for i
in range(cov.shape[0]):
592 for j
in range(cov.shape[1]):
594 tmpi = P.dot(bufdict[str(i)])
595 tmpj = P.dot(bufdict[str(j)])
597 np.mean(tmpi * tmpj, axis=1) -
598 np.mean(tmpi, axis=1) * np.mean(tmpj, axis=1))
600 cov[i, j] = cov[j, i]
602 s = np.reshape(np.diag(cov), (cov.shape[0], 1))
604 cor = cov / np.sqrt(sst)
618 IF = rtc.get_IFsparse(1)
621 tmp = (config.p_geom._ipupil.shape[0] -
622 (config.p_dms[0]._n2 - config.p_dms[0]._n1 + 1)) / 2
623 tmp_e0 = config.p_geom._ipupil.shape[0] - tmp
624 tmp_e1 = config.p_geom._ipupil.shape[1] - tmp
625 pup = config.p_geom._ipupil[tmp:tmp_e0, tmp:tmp_e1]
626 indx_pup = np.where(pup.flatten() > 0)[0].astype(np.int32)
627 dm_dim = config.p_dms[0]._n2 - config.p_dms[0]._n1 + 1
628 cov, cor =
cov_cor(P, noise_com, trunc_com, alias_wfs_com, H_com, bp_com, tomo_com)
629 psf = tar.get_image(0,
"le", fluxNorm=
False)
631 fname =
"/home/fferreira/Data/" + filename
633 "noise": noise_com.T,
634 "aliasing": alias_wfs_com.T,
635 "tomography": tomo_com.T,
636 "filtered modes": H_com.T,
637 "non linearity": trunc_com.T,
638 "bandwidth": bp_com.T,
643 "IF.indices": IF.indices,
644 "IF.indptr": IF.indptr,
647 "indx_pup": indx_pup,
653 "psfortho": np.fft.fftshift(psf_ortho),
654 "dm.xpos": config.p_dms[0]._xpos,
655 "dm.ypos": config.p_dms[0]._ypos
657 h5u.save_h5(fname,
"psf", config, psf)
659 for k
in list(pdict.keys()):
660 h5u.save_hdf5(fname, k, pdict[k])
670 param_file =
"/home/fferreira/compass/trunk/shesha/data/par/par4roket/correlation_study/roket_8m_1layer.py"
672 if (param_file.split(
'.')[-1] == b
"py"):
673 filename = param_file.split(
'/')[-1]
674 param_path = param_file.split(filename)[0]
675 sys.path.insert(0, param_path)
676 exec(
"import %s as config" % filename.split(
".py")[0])
680 niters = config.p_loop.niter
681 config.p_loop.set_niter(niters + N_preloop)
682 winddirs = [0, 45, 90, 135, 180]
683 windspeeds = [5., 10., 15., 20.]
685 d = float(sys.argv[1])
686 s = float(sys.argv[2])
687 g = float(sys.argv[3])
689 savename =
"roket_8m_1layer_dir%d_speed%d_g%d_cpu.h5" % (d, s, g * 10)
690 config.p_atmos.set_winddir([d])
691 config.p_atmos.set_windspeed([s])
692 config.p_controllers[0].set_gain(g)
697 rtc.load_Btt(1, Btt.dot(Btt.T))
699 rtc.set_cmat(0, cmat)
701 imat = rtc.get_imat(0)
702 RD = np.dot(R, imat).astype(np.float32)
703 gRD = (np.identity(RD.shape[0]) - config.p_controllers[0].gain * RD).astype(np.float32)
705 com, noise_com, alias_wfs_com, tomo_com, H_com, trunc_com, bp_com, wf_com, fit, SR, SR2, psf_ortho =
loop(
707 noise_com = noise_com[N_preloop:, :]
708 trunc_com = trunc_com[N_preloop:, :]
709 alias_wfs_com = alias_wfs_com[N_preloop:, :]
710 H_com = H_com[N_preloop:, :]
711 bp_com = bp_com[N_preloop:, :]
712 tomo_com = tomo_com[N_preloop:, :]