46 from typing
import List
49 def do_tomo_matrices(ncontrol: int, rtc: Rtc, p_wfss: List[conf.Param_wfs], dms: Dms,
50 atmos: Atmos, wfs: Sensors, p_controller: conf.Param_controller,
51 p_geom: conf.Param_geom, p_dms: list, p_tel: conf.Param_tel,
52 p_atmos: conf.Param_atmos):
53 """ Compute Cmm and Cphim matrices for the MV controller on GPU
57 ncontrol: (int): controller index
59 rtc: (Rtc) : rtc object
61 p_wfss: (list of Param_wfs) : wfs settings
63 dms: (Dms) : Dms object
65 atmos: (Atmos) : Atmos object
67 wfs: (Sensors) : Sensors object
69 p_controller: (Param_controller): controller settings
71 p_geom: (Param_geom) : geom settings
73 p_dms: (list of Param_dms) : dms settings
75 p_tel: (Param_tel) : telescope settings
77 p_atmos: (Param_atmos) : atmos settings
79 nvalidperwfs = np.array([o._nvalid
for o
in p_wfss], dtype=np.int64)
83 s2ipup = (ipup.shape[0] - spup.shape[0]) / 2.
85 nvalid = sum([nvalidperwfs[j]
for j
in p_controller.nwfs])
88 X = np.zeros(nvalid, dtype=np.float64)
90 Y = np.zeros(nvalid, dtype=np.float64)
92 for k
in p_controller.nwfs:
93 posx = p_wfss[k]._validpuppixx + s2ipup
96 posx = posx - ipup.shape[0] / 2 - 1
97 posy = p_wfss[k]._validpuppixy + s2ipup
98 posy = posy.T - ipup.shape[0] / 2 - 1
99 p2m = (p_tel.diam / p_wfss[k].nxsub) / \
103 X[ind:ind + p_wfss[k]._nvalid] = posx
104 Y[ind:ind + p_wfss[k]._nvalid] = posy
105 ind += p_wfss[k]._nvalid
110 for k
in p_controller.ndm:
111 if (p_dms[k].type == scons.DmType.PZT):
112 nactu += p_dms[k]._ntotact
115 Xactu = np.zeros(nactu, dtype=np.float64)
116 Yactu = np.zeros(nactu, dtype=np.float64)
117 k2 = np.zeros(npzt, dtype=np.float64)
118 pitch = np.zeros(npzt, dtype=np.float64)
119 alt_DM = np.zeros(npzt, dtype=np.float64)
122 for k
in p_controller.ndm:
123 if (p_dms[k].type == scons.DmType.PZT):
124 p2m = p_tel.diam / p_geom.pupdiam
126 actu_x = (p_dms[k]._xpos - ipup.shape[0] / 2) * p2m
127 actu_y = (p_dms[k]._ypos - ipup.shape[0] / 2) * p2m
128 pitch[indk] = actu_x[1] - actu_x[0]
129 k2[indk] = p_wfss[0].Lambda / 2. / np.pi / p_dms[k].unitpervolt
130 alt_DM[indk] = p_dms[k].alt
131 Xactu[ind:ind + p_dms[k]._ntotact] = actu_x
132 Yactu[ind:ind + p_dms[k]._ntotact] = actu_y
134 ind += p_dms[k]._ntotact
138 NlayersDM = np.zeros(npzt, dtype=np.int64)
144 wfs_distance = np.zeros(len(p_controller.nwfs), dtype=np.float64)
146 for k
in p_controller.nwfs:
147 wfs_distance[ind] = np.sqrt(p_wfss[k].xpos**2 + p_wfss[k].ypos**2)
149 FoV = np.max(wfs_distance) / CONST.RAD2ARCSEC
152 alphaX = np.zeros(len(p_controller.nwfs))
153 alphaY = np.zeros(len(p_controller.nwfs))
156 for k
in p_controller.nwfs:
157 alphaX[ind] = p_wfss[k].xpos / CONST.RAD2ARCSEC
158 alphaY[ind] = p_wfss[k].ypos / CONST.RAD2ARCSEC
161 L0_d = np.copy(p_atmos.L0).astype(np.float64)
162 frac_d = np.copy(p_atmos.frac * (p_atmos.r0**(-5.0 / 3.0))).astype(np.float64)
164 print(
"Computing Cphim...")
165 rtc.d_control[ncontrol].compute_Cphim(atmos, wfs, dms, L0_d, frac_d, alphaX, alphaY,
166 X, Y, Xactu, Yactu, p_tel.diam, k2, NlayersDM,
167 indlayersDM, FoV, pitch,
168 alt_DM.astype(np.float64))
171 print(
"Computing Cmm...")
172 rtc.d_control[ncontrol].compute_Cmm(atmos, wfs, L0_d, frac_d, alphaX, alphaY,
173 p_tel.diam, p_tel.cobs)
176 Nact = np.zeros([nactu, nactu], dtype=np.float32)
177 F = np.zeros([nactu, nactu], dtype=np.float32)
179 for k
in range(len(p_controller.ndm)):
180 if (p_dms[k].type ==
"pzt"):
181 Nact[ind:ind + p_dms[k]._ntotact, ind:ind +
183 F[ind:ind + p_dms[k]._ntotact, ind:ind +
185 ind += p_dms[k]._ntotact
186 rtc.d_control[ncontrol].filter_cphim(F, Nact)
189 def selectDMforLayers(p_atmos: conf.Param_atmos, p_controller: conf.Param_controller,
191 """ For each atmos layer, select the DM which have to handle it in the Cphim computation for MV controller
195 p_atmos : (Param_atmos) : atmos parameters
197 p_controller : (Param_controller) : controller parameters
199 p_dms :(list of Param_dm) : dms parameters
203 indlayersDM : (np.array(dtype=np.int32)) : for each atmos layer, the Dm number corresponding to it
205 indlayersDM = np.zeros(p_atmos.nscreens, dtype=np.int64)
206 for i
in range(p_atmos.nscreens):
208 for j
in p_controller.ndm:
209 alt_diff = np.abs(p_dms[j].alt - p_atmos.alt[i])
210 if (alt_diff < mindif):
218 """ Compute the DM coupling matrix
222 p_dm : (Param_dm) : dm parameters
226 Nact : (np.array(dtype=np.float64)) : the DM coupling matrix
228 nactu = p_dm._ntotact
229 Nact = np.zeros([nactu, nactu], dtype=np.float32)
230 coupling = p_dm.coupling
231 dim = p_dm._n2 - p_dm._n1 + 1
232 mask = np.zeros([dim, dim], dtype=np.float32)
233 shape = np.zeros([dim, dim], dtype=np.float32)
235 for i
in range(len(p_dm._i1)):
236 mask[p_dm._j1[i]][p_dm._i1[i]] = 1
238 mask_act = np.where(mask)
240 pitch = int(p_dm._pitch)
242 for i
in range(nactu):
245 shape[p_dm._j1[i]][p_dm._i1[i]] = 1
247 shape[p_dm._j1[i]][p_dm._i1[i] - pitch] = coupling
248 shape[p_dm._j1[i] - pitch][p_dm._i1[i]] = coupling
249 shape[p_dm._j1[i]][p_dm._i1[i] + pitch] = coupling
250 shape[p_dm._j1[i] + pitch][p_dm._i1[i]] = coupling
252 shape[p_dm._j1[i] - pitch][p_dm._i1[i] - pitch] = coupling**2
253 shape[p_dm._j1[i] - pitch][p_dm._i1[i] + pitch] = coupling**2
254 shape[p_dm._j1[i] + pitch][p_dm._i1[i] + pitch] = coupling**2
255 shape[p_dm._j1[i] + pitch][p_dm._i1[i] - pitch] = coupling**2
257 Nact[:, i] = shape[mask_act]
263 """ Create the piston filter matrix
267 p_dm: (Param_dm): dm settings
269 nactu = p_dm._ntotact
270 F = np.ones([nactu, nactu], dtype=np.float32)
271 F = F * (-1.0 / nactu)
272 for i
in range(nactu):
273 F[i][i] = 1 - 1.0 / nactu
def create_piston_filter(conf.Param_dm p_dm)
Create the piston filter matrix.
def do_tomo_matrices(int ncontrol, Rtc rtc, List[conf.Param_wfs] p_wfss, Dms dms, Atmos atmos, Sensors wfs, conf.Param_controller p_controller, conf.Param_geom p_geom, list p_dms, conf.Param_tel p_tel, conf.Param_atmos p_atmos)
Compute Cmm and Cphim matrices for the MV controller on GPU.
def selectDMforLayers(conf.Param_atmos p_atmos, conf.Param_controller p_controller, list p_dms)
For each atmos layer, select the DM which have to handle it in the Cphim computation for MV controlle...
def create_nact_geom(conf.Param_dm p_dm)
Compute the DM coupling matrix.
Parameter classes for COMPASS.
Numerical constants for shesha and config enumerations for safe-typing.