39 import scipy.special
as sp
63 B = sp.jn(0, sp.jn_zeros(0, n)[n - 1] * r)
65 B = sp.jn(m, sp.jn_zeros(m, n)[n - 1] * r) * np.sin(m * phi)
68 sp.jn_zeros(np.abs(m), n)[n - 1] * r) * np.cos(np.abs(m) * phi)
91 influ = np.zeros(xx.shape, dtype=np.float32)
100 r = np.sqrt(xx**2 + yy**2)
101 phi = np.arctan2(yy, xx)
105 0.3826, 0.5207, 0.2841, -0.0146, -0.1103, -0.0818, -0.0141, 0.0123, 0.0196,
108 am = [-0.0454, -0.1114, -0.1125, -0.0397, 0.0146, 0.0217, 0.0085, -0.0012, -0.0040]
109 a = [-0.0002, -0.0004, -0.0001, 0.0004, 0.0005, 0.0003, 0.0001, 0, 0]
116 if type_i == PatternType.HEXA
or type_i == PatternType.HEXAM4:
123 for i
in range(len(a0)):
124 btemp = (a0[i] *
besel_orth(0, i + 1, phi, r))
126 influ = influ + btemp
130 for i
in range(len(a)):
131 influ = influ + (a[i] *
besel_orth(sym, i + 1, phi, r))
135 for i
in range(len(am)):
136 influ = influ + (am[i] *
besel_orth(-sym, i + 1, phi, r))
142 def makeRigaut(pitch: float, coupling: float, x=
None, y=
None):
143 """ Compute 'Rigaut-like' influence function
147 pitch: (float) : pitch of the DM expressed in pixels
149 coupling: (float) : coupling of the actuators
151 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
153 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
157 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
159 irc = 1.16136 + 2.97422 * coupling + \
160 (-13.2381) * coupling**2 + 20.4395 * coupling**3
162 p1 = 4.49469 + (7.25509 + (-32.1948 + 17.9493 * coupling) * coupling) * coupling
163 p2 = 2.49456 + (-0.65952 + (8.78886 - 6.23701 * coupling) * coupling) * coupling
165 tmp_c = 1.0 / np.abs(irc)
166 ccc = (coupling - 1. + tmp_c**p1) / (np.log(tmp_c) * tmp_c**p2)
168 smallsize = int(np.ceil(2 * irc * pitch + 10))
169 if (smallsize % 2 != 0):
172 if (x
is None or y
is None):
176 x = np.abs(x) / (irc * pitch)
177 y = np.abs(y) / (irc * pitch)
183 tmp = (1. - x**p1 + ccc * np.log(x) * x**p2) * \
184 (1. - y**p1 + ccc * np.log(y) * y**p2)
185 tmp = tmp * (x <= 1.0) * (y <= 1.0)
190 """ Compute radial Schwartz influence function
194 pitch: (float) : pitch of the DM expressed in pixels
196 coupling: (float) : coupling of the actuators
198 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
200 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
204 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
208 a = pitch / np.sqrt(k / (np.log(coupling) - k) + 1.)
209 smallsize = int(2 * np.ceil(a) + 2)
210 if (x
is None or y
is None):
213 r = (x * x + y * y) / (a * a)
215 sc = np.zeros(r.shape)
216 sc[ok] = np.exp((k / (r[ok] - 1.0)) + k)
222 """ Compute Square Schwartz influence function
226 pitch: (float) : pitch of the DM expressed in pixels
228 coupling: (float) : coupling of the actuators
230 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
232 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
236 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
240 a = pitch / np.sqrt(k / (np.log(coupling) - k) + 1.)
242 if (x
is None or y
is None):
243 smallsize = int(2 * np.ceil(a) + 2)
248 ok = np.where((xx < 1) * (yy < 1))
249 sc = np.zeros(xx.shape)
250 sc[ok] = np.exp((k / (xx[ok] - 1)) + k) * \
251 np.exp((k / (yy[ok] - 1)) + k)
255 def makeBlacknutt(pitch: float, coupling: float, x=
None, y=
None):
256 """ Compute Blacknutt influence function
257 Attention, ici on ne peut pas choisir la valeur de coupling.
258 La variable a ete laissee dans le code juste pour compatibilité avec les
259 autres fonctions, mais elle n'est pas utilisee.
263 pitch: (float): pitch of the DM expressed in pixels
265 coupling: (float) : coupling of the actuators
267 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
269 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
273 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
275 smallsize = int(np.ceil(4 * pitch + 1))
276 if (x
is None or y
is None):
282 a = np.array([0.355768, 0.487396, 0.144232, 0.012604], dtype=np.float32)
283 ok = np.where((np.abs(xx) < 1) * (np.abs(yy) < 1))
284 sc = np.zeros(xx.shape)
285 sc[ok] = (a[0] + a[1] * np.cos(np.pi * xx[ok]) +
286 a[2] * np.cos(2 * np.pi * xx[ok]) + a[3] * np.cos(3 * np.pi * xx[ok])) *\
287 (a[0] + a[1] * np.cos(np.pi * yy[ok]) +
288 a[2] * np.cos(2 * np.pi * yy[ok]) + a[3] * np.cos(3 * np.pi * yy[ok]))
293 def makeGaussian(pitch: float, coupling: float, x=
None, y=
None):
294 """ Compute Gaussian influence function. Coupling parameter is not taken into account
298 pitch: (float) : pitch of the DM expressed in pixels
300 coupling: (float) : coupling of the actuators
302 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
304 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
308 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
310 irc = 1.16136 + 2.97422 * coupling + \
311 (-13.2381) * coupling**2 + 20.4395 * coupling**3
312 tmp_c = 1.0 / np.abs(irc)
314 smallsize = int(np.ceil(2 * irc * pitch + 10))
315 if (smallsize % 2 != 0):
318 if (x
is None or y
is None):
321 sig = pitch / np.sqrt(-2 * np.log(coupling))
322 gauss = np.exp(-0.5 * ((x / sig)**2 + (y / sig)**2))
336 def makeBessel(pitch: float, coupling: float, x: np.ndarray =
None, y: np.ndarray =
None,
337 patternType: bytes = PatternType.SQUARE):
338 """ Compute Bessel influence function
342 pitch: (float) : pitch of the DM expressed in pixels
344 coupling: (float) : coupling of the actuators
346 x: indices of influence function in relative position x local coordinates (float). 0 = top of the influence function
348 y: indices of influence function in relative position y local coordinates (float). 0 = top of the influence function
352 influ: (np.ndarray(dims=3,dtype=np.float64)) : cube of the IF for each actuator
354 smallsize = int(np.ceil(pitch * 3.2))
356 if (x
is None or y
is None):
363 influ_u =
bessel_influence(x / (1.6 * pitch), y / (1.6 * pitch), patternType)
364 influ_u = influ_u * (influ_u >= 0)