aopera 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aopera/__init__.py +51 -0
- aopera/aopsd.py +344 -0
- aopera/control.py +355 -0
- aopera/data/ekarus.ini +45 -0
- aopera/data/harmoni-scao.ini +43 -0
- aopera/data/ohp.ini +13 -0
- aopera/data/papyrus.ini +45 -0
- aopera/data/paranal.ini +13 -0
- aopera/data/sphere.ini +45 -0
- aopera/ffwfs.py +335 -0
- aopera/fiber.py +61 -0
- aopera/otfpsf.py +212 -0
- aopera/photometry.py +219 -0
- aopera/readconfig.py +267 -0
- aopera/shwfs.py +316 -0
- aopera/simulation.py +358 -0
- aopera/trajectory.py +120 -0
- aopera/turbulence.py +445 -0
- aopera/utils.py +142 -0
- aopera/variance.py +112 -0
- aopera/zernike.py +193 -0
- aopera-0.1.0.dist-info/METADATA +741 -0
- aopera-0.1.0.dist-info/RECORD +26 -0
- aopera-0.1.0.dist-info/WHEEL +5 -0
- aopera-0.1.0.dist-info/licenses/LICENSE +674 -0
- aopera-0.1.0.dist-info/top_level.txt +1 -0
aopera/control.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Number of controlled modes and transfer functions management
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
import numpy as np
|
|
7
|
+
import logging
|
|
8
|
+
from aopera.readconfig import read_config_file, read_config_tiptop, check_dictionary, INFO_RTC
|
|
9
|
+
from scipy.linalg import solve_discrete_are
|
|
10
|
+
|
|
11
|
+
#%% TEMPORAL FILTERING FUNCTION
|
|
12
|
+
def open_loop_transfer(freq, ao_freq, ki, nb_frame_delay, kp=0, discrete=False, leak=1.0):
|
|
13
|
+
"""
|
|
14
|
+
Return the temporal open loop transfer function for a proportional-integrator controller.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
freq : np.array
|
|
19
|
+
Array of temporal frequencies to evaluate the CLTF on.
|
|
20
|
+
ao_freq : float
|
|
21
|
+
The sampling temporal frequency of the AO loop.
|
|
22
|
+
ki : float
|
|
23
|
+
Integrator gain.
|
|
24
|
+
nb_frame_delay : float
|
|
25
|
+
Number of frame delay.
|
|
26
|
+
Must include: RTC, pixel transfert, DM rise.
|
|
27
|
+
Must not include: WFS integration, DM zero-order-hold.
|
|
28
|
+
kp : float (default:0)
|
|
29
|
+
Proportional gain.
|
|
30
|
+
discrete : bool (default:False)
|
|
31
|
+
Choose to use discrete formalism.
|
|
32
|
+
leak : float (default=1.0)
|
|
33
|
+
Leaky integrator.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
if not discrete:
|
|
37
|
+
Tp = 2j*np.pi*freq/ao_freq
|
|
38
|
+
H = kp + ki/(Tp+(1.0-leak)) # controler
|
|
39
|
+
H *= np.exp(-Tp*nb_frame_delay) # delay
|
|
40
|
+
H *= (1-np.exp(-Tp))/Tp # WFS
|
|
41
|
+
H *= 1 # zero order holder
|
|
42
|
+
else:
|
|
43
|
+
# Tp = 2j*np.pi*freq/ao_freq
|
|
44
|
+
z = np.exp(2j*np.pi*freq/ao_freq) # it is one method to pass from Tp to z
|
|
45
|
+
H = kp + ki/(1-leak/z) # controler
|
|
46
|
+
H *= 1/z**(nb_frame_delay+1) # delay + WFS + zero order hold
|
|
47
|
+
|
|
48
|
+
return H
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def closed_loop_transfer(*args, **kwargs):
|
|
52
|
+
"""
|
|
53
|
+
Return the temporal closed loop transfer function.
|
|
54
|
+
See the open_loop_transfer arguments.
|
|
55
|
+
"""
|
|
56
|
+
return 1/(1+open_loop_transfer(*args, **kwargs))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def noise_transfer(*args, **kwargs):
|
|
60
|
+
"""
|
|
61
|
+
Return the noise transfer function.
|
|
62
|
+
See the open_loop_transfer arguments.
|
|
63
|
+
"""
|
|
64
|
+
return open_loop_transfer(*args, **kwargs) * closed_loop_transfer(*args, **kwargs)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def bandwidth(ki, nb_frame_delay, ao_freq, db=0):
|
|
68
|
+
"""
|
|
69
|
+
Compute the AO bandwidth for an integrator control law.
|
|
70
|
+
|
|
71
|
+
.. math::
|
|
72
|
+
BW_{db} = \\frac{F}{2\\pi}\\frac{k_i}{\\sqrt{k_i(2N_d+1)+10^{-db}-1}}
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
ki : float
|
|
77
|
+
Gain of the integrator law
|
|
78
|
+
nb_frame_delay : float
|
|
79
|
+
Number of frame delay (exposure frame excluded)
|
|
80
|
+
ao_freq : float
|
|
81
|
+
Loop frequency [Hz]
|
|
82
|
+
|
|
83
|
+
Keywords
|
|
84
|
+
--------
|
|
85
|
+
db : float (≤0)
|
|
86
|
+
The cutoff in decibel (default=0).
|
|
87
|
+
|
|
88
|
+
References
|
|
89
|
+
----------
|
|
90
|
+
Thierry Fusco (ONERA), 2005, internal document, "AO temporal behavior".
|
|
91
|
+
Completed by R.Fetick.
|
|
92
|
+
"""
|
|
93
|
+
cst = 10**(db/10)
|
|
94
|
+
alpha = (nb_frame_delay+0.5)*ki
|
|
95
|
+
# The polynomial equation comes from the development of `sin((nd+0.5)wT)`
|
|
96
|
+
p0 = 1
|
|
97
|
+
p1 = 1 - 1/cst - 2*alpha**1 / math.factorial(1)
|
|
98
|
+
# p2 = 2*alpha**3 / math.factorial(3)
|
|
99
|
+
# delta = p1**2 - 4*p0*p2
|
|
100
|
+
# rsol = (np.sqrt(delta)-p1)/(2*p2) # order 2 solution
|
|
101
|
+
rsol = -p0/p1 # order 1 solution
|
|
102
|
+
bw = np.sqrt(rsol)*ki*ao_freq/(2*np.pi)
|
|
103
|
+
|
|
104
|
+
# Check afterwards if the 1st order development of sine was valid
|
|
105
|
+
sine_argu = (nb_frame_delay+0.5)*2*np.pi*bw/ao_freq
|
|
106
|
+
rel_error = np.abs(sine_argu - np.sin(sine_argu))/sine_argu
|
|
107
|
+
if np.max(rel_error) > 0.07:
|
|
108
|
+
logging.warning('Bandwidth computation might be unconsistent')
|
|
109
|
+
|
|
110
|
+
return bw
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def bandwidth_noise(ki, nb_frame_delay, ao_freq, db=-4):
|
|
114
|
+
"""
|
|
115
|
+
Compute the noise bandwidth for an integrator control law.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
ki : float
|
|
120
|
+
Gain of the integrator law
|
|
121
|
+
nb_frame_delay : float
|
|
122
|
+
Number of frame delay (exposure frame excluded)
|
|
123
|
+
ao_freq : float
|
|
124
|
+
Loop frequency [Hz]
|
|
125
|
+
|
|
126
|
+
Keywords
|
|
127
|
+
--------
|
|
128
|
+
db : float (<0)
|
|
129
|
+
The cutoff in decibel (default=-4).
|
|
130
|
+
|
|
131
|
+
Note
|
|
132
|
+
----
|
|
133
|
+
A bandwidth at -4 dB is chosen so we get the equality between the integration
|
|
134
|
+
of |NTF|² (in the discrete domain) and the bandwidth_noise expression.
|
|
135
|
+
|
|
136
|
+
.. math::
|
|
137
|
+
BW_{noise} \\simeq \\int_0^{+\\infty}|NTF(f)|^2 df
|
|
138
|
+
|
|
139
|
+
So it has to be multiplied by 2 to account for both positive and negative frequencies.
|
|
140
|
+
|
|
141
|
+
Reference
|
|
142
|
+
---------
|
|
143
|
+
R.Fetick, personnal work.
|
|
144
|
+
"""
|
|
145
|
+
cst = 10**(db/10)
|
|
146
|
+
alpha = (nb_frame_delay+0.5)*ki
|
|
147
|
+
# The polynomial equation comes from the development of `sin((nd+0.5)wT)`
|
|
148
|
+
p3 = - 2 * alpha**5 / math.factorial(5)
|
|
149
|
+
p2 = 2 * alpha**3 / math.factorial(3)
|
|
150
|
+
p1 = 1 - 2 * alpha**1 / math.factorial(1)
|
|
151
|
+
p0 = 1 - 1/cst
|
|
152
|
+
r = np.roots([p3,p2,p1,p0])
|
|
153
|
+
rsol = min(r[r>0]) # the bandwidth is >0, and I choose the min solution (justified?)
|
|
154
|
+
bwn = np.sqrt(rsol)*ki*ao_freq/(2*np.pi)
|
|
155
|
+
return bwn
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
#%% LQG
|
|
159
|
+
def lqg_controller(fx, fy, phase_psd, noise_psd, cn2dh_ratio, wind_speed, wind_direction, ao_freq, delta_wind_speed=0.1, diameter=np.inf, verbose=False):
|
|
160
|
+
"""
|
|
161
|
+
Compute LQG controller for each spatial frequency (fx,fy).
|
|
162
|
+
Only valid for two frames delay (1 for WFS integration, 1 for pixel transfer and RTC computation).
|
|
163
|
+
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
fx : list of floats
|
|
167
|
+
Spatial frequencies [1/m] along X.
|
|
168
|
+
fy : list of floats
|
|
169
|
+
Spatial frequencies [1/m] along Y.
|
|
170
|
+
phase_psd : list of floats
|
|
171
|
+
PSD of the turbulent phase [rad²m²] at (fx,fy).
|
|
172
|
+
noise_psd : list of floats
|
|
173
|
+
PSD of the noise [rad²m²] at (fx,fy).
|
|
174
|
+
cn2dh_ratio : list of floats
|
|
175
|
+
Cn²*dh ratio (sum=1) of turbulence layers.
|
|
176
|
+
wind_speed : list of floats
|
|
177
|
+
Wind speed [m/s] of turbulence layers.
|
|
178
|
+
wind_direction : list of floats
|
|
179
|
+
Wind direction [deg] of turbulence layers.
|
|
180
|
+
ao_freq : float
|
|
181
|
+
AO loop frequency [Hz].
|
|
182
|
+
|
|
183
|
+
Keywords
|
|
184
|
+
--------
|
|
185
|
+
delta_wind_speed : float
|
|
186
|
+
Uncertainty on wind speed estimation [m/s].
|
|
187
|
+
diameter : float
|
|
188
|
+
Telescope diameter [m].
|
|
189
|
+
verbose : bool
|
|
190
|
+
Print iterations while you drink a cup of tea.
|
|
191
|
+
|
|
192
|
+
Return
|
|
193
|
+
------
|
|
194
|
+
List of LQG controllers (functions) for each spatial frequency, to be evaluated on Z transform domain.
|
|
195
|
+
Thus `output[i](z)` is the LQG controller of (fx[i], fy[i]) evaluated at `z`.
|
|
196
|
+
|
|
197
|
+
Reference
|
|
198
|
+
---------
|
|
199
|
+
Correia et al, 2017,
|
|
200
|
+
Modelling astronomical adaptive optics performance with temporally-filtered Wiener reconstruction of slope data
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
logging.warning('Check LQG state covariance V and command regularization R')
|
|
204
|
+
|
|
205
|
+
controllers = []
|
|
206
|
+
RG = 1.0 # Measurement and reconstructor
|
|
207
|
+
eigval_dump = 0.99999 # ensure solution for LQG
|
|
208
|
+
Ts = 1/ao_freq
|
|
209
|
+
# ff = np.sqrt(np.array(fx)**2+np.array(fy)**2)
|
|
210
|
+
nfreq = len(fx)
|
|
211
|
+
nlayer = len(wind_speed)
|
|
212
|
+
dk = 1/diameter # aocutoff / (pupil.nact-1) / 2 # attempt to account for integral over frequencies for one mode
|
|
213
|
+
|
|
214
|
+
# DISCRETE ARE
|
|
215
|
+
# x{k+1} = A.x{k} + B.u{k} + v{k} (state evolution)
|
|
216
|
+
# y{k} = C.x{k} + w{k} (measurement)
|
|
217
|
+
# J = ||xT.Q.x + uT.R.u|| (criterion)
|
|
218
|
+
|
|
219
|
+
A = np.zeros((nlayer+5, nlayer+5), dtype=complex)
|
|
220
|
+
B = np.zeros((nlayer+5,1))
|
|
221
|
+
C = np.zeros((1,nlayer+5))
|
|
222
|
+
Q = np.zeros((nlayer+5,nlayer+5))
|
|
223
|
+
V = np.zeros((nlayer+5,nlayer+5), dtype=complex)
|
|
224
|
+
|
|
225
|
+
vx = wind_speed*np.cos(wind_direction*np.pi/180)
|
|
226
|
+
vy = wind_speed*np.sin(wind_direction*np.pi/180)
|
|
227
|
+
poke_freq_avg = np.sinc(Ts*vx*dk) * np.sinc(Ts*vy*dk) # frequency averaging (modal frequencial width)
|
|
228
|
+
# cvx = 2 - np.cos(2*np.pi*Ts*vx*dk/2)
|
|
229
|
+
# cvy = 2 - np.cos(2*np.pi*Ts*vy*dk/2)
|
|
230
|
+
# poke_avg_x = cvx - np.sqrt(cvx**2 - 1)
|
|
231
|
+
# poke_avg_y = cvy - np.sqrt(cvy**2 - 1)
|
|
232
|
+
# poke_freq_avg = poke_avg_x * poke_avg_y
|
|
233
|
+
|
|
234
|
+
# FILL MATRICES with CONSTANT TERMS
|
|
235
|
+
Q[nlayer+2, nlayer+2] = 1
|
|
236
|
+
Q[nlayer+4, nlayer+4] = 1
|
|
237
|
+
Q[nlayer+4, nlayer+2] = -1
|
|
238
|
+
Q[nlayer+2, nlayer+4] = -1
|
|
239
|
+
|
|
240
|
+
A[nlayer+1,nlayer] = 1
|
|
241
|
+
A[nlayer+2,nlayer+1] = 1
|
|
242
|
+
A[nlayer+4,nlayer+3] = 1
|
|
243
|
+
|
|
244
|
+
B[nlayer+3,0] = 1
|
|
245
|
+
|
|
246
|
+
C[0,nlayer+2] = RG
|
|
247
|
+
C[0,nlayer+4] = -RG
|
|
248
|
+
|
|
249
|
+
# DEFINE LQG CONTROLLER (cf. Correia et al, 2017)
|
|
250
|
+
class CTRL:
|
|
251
|
+
def __init__(self, A, B, C, K, L):
|
|
252
|
+
self.I = np.eye(nlayer+5)
|
|
253
|
+
self.K = np.copy(K)
|
|
254
|
+
self.L = np.copy(L)
|
|
255
|
+
self.B_KCB = B - self.K @ C @ B
|
|
256
|
+
self.KCA_A = self.K @ C @ A - A
|
|
257
|
+
def __call__(self, z):
|
|
258
|
+
if hasattr(z, '__len__'): # object is iterable
|
|
259
|
+
return [self.__call__(elem) for elem in z]
|
|
260
|
+
else:
|
|
261
|
+
L_Lambda_e = self.L @ np.linalg.pinv(self.I + self.KCA_A/z) # Eq 44 du papier
|
|
262
|
+
return - (L_Lambda_e@self.K)[0,0] / (1+L_Lambda_e@self.B_KCB/z)[0,0]
|
|
263
|
+
|
|
264
|
+
# ITERATE OVER SPATIAL FREQUENCIES
|
|
265
|
+
for i in range(nfreq):
|
|
266
|
+
|
|
267
|
+
if verbose and ((((i+1)%10) == 0) or (i == (nfreq-1))):
|
|
268
|
+
print('\rLQG controller %4u/%u'%(i+1,nfreq), end='')
|
|
269
|
+
|
|
270
|
+
nu = vx*fx[i] + vy*fy[i]
|
|
271
|
+
ccx = 2 - np.cos(2*np.pi*Ts*fx[i]*delta_wind_speed/2)
|
|
272
|
+
ccy = 2 - np.cos(2*np.pi*Ts*fy[i]*delta_wind_speed/2)
|
|
273
|
+
wind_avg_x = ccx - np.sqrt(ccx**2 - 1) # np.sinc(Ts*fx[i]*delta_wind_speed) * np.sinc(Ts*fy[i]*delta_wind_speed) # windspeed averaging (uncertainty)
|
|
274
|
+
wind_avg_y = ccy - np.sqrt(ccy**2 - 1)
|
|
275
|
+
a_jj = np.exp(2j*np.pi*Ts*nu) * eigval_dump * poke_freq_avg * wind_avg_x * wind_avg_y
|
|
276
|
+
|
|
277
|
+
np.fill_diagonal(A[0:nlayer,0:nlayer], a_jj)
|
|
278
|
+
A[nlayer,0:nlayer] = a_jj
|
|
279
|
+
|
|
280
|
+
# MODEL NOISE (EXCITATION)
|
|
281
|
+
V[0:nlayer, 0:nlayer] = phase_psd[i] * np.diag(cn2dh_ratio) * (1-np.abs(a_jj)**2) # Yule-Walker
|
|
282
|
+
|
|
283
|
+
# MEASUREMENT NOISE
|
|
284
|
+
W = np.eye(1) * noise_psd[i]
|
|
285
|
+
|
|
286
|
+
# REGUL COMMANDE #TODO: pondérer par rapport à Q
|
|
287
|
+
logging.debug('LQG command matrix should be properly scaled.')
|
|
288
|
+
R = np.ones(1) * 1e-3
|
|
289
|
+
|
|
290
|
+
P = solve_discrete_are(np.conjugate(A.T), C.T, V, W, balanced=True)
|
|
291
|
+
K = P@C.T@np.linalg.pinv(C@P@C.T+W) # Kalman estimation gain
|
|
292
|
+
|
|
293
|
+
S = solve_discrete_are(A, B, Q, R, balanced=True)
|
|
294
|
+
L = np.linalg.pinv(B.T@S@B+R)@B.T@S@A # command gain
|
|
295
|
+
|
|
296
|
+
controllers += [CTRL(A, B, C, K, L)]
|
|
297
|
+
|
|
298
|
+
return controllers
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
#%% RTC CLASS
|
|
302
|
+
class RTC:
|
|
303
|
+
def __init__(self, dictionary):
|
|
304
|
+
self.kp = 0.0 # proportional gain
|
|
305
|
+
self.leak = 1.0 # leaky gain (default = no leaky)
|
|
306
|
+
self.discrete = True # discrete time controler
|
|
307
|
+
self.predictive_factor = 1 # temporal PSD reducing due to predictive controler
|
|
308
|
+
check_dictionary(dictionary, 'rtc')
|
|
309
|
+
for k in INFO_RTC.keys():
|
|
310
|
+
setattr(self, k, INFO_RTC[k][0](dictionary[k]))
|
|
311
|
+
|
|
312
|
+
def __repr__(self):
|
|
313
|
+
s = 'aopera.RTC\n'
|
|
314
|
+
s += '-----------\n'
|
|
315
|
+
s += 'freq : %u Hz\n'%self.freq
|
|
316
|
+
s += 'delay : %.1f ms\n'%self.delay
|
|
317
|
+
s += 'ki : %.2f\n'%self.ki
|
|
318
|
+
if self.predictive_factor != 1:
|
|
319
|
+
s += 'predic: %.2f\n'%self.predictive_factor
|
|
320
|
+
return s
|
|
321
|
+
|
|
322
|
+
@staticmethod
|
|
323
|
+
def from_file(filepath, category='rtc'):
|
|
324
|
+
return RTC(read_config_file(filepath, category))
|
|
325
|
+
|
|
326
|
+
@staticmethod
|
|
327
|
+
def from_file_tiptop(filepath):
|
|
328
|
+
return RTC(read_config_tiptop(filepath)[3])
|
|
329
|
+
|
|
330
|
+
@staticmethod
|
|
331
|
+
def from_oopao(ao_freq, oopao_frame_delay, gainCL, leak=1):
|
|
332
|
+
rtc = RTC({'freq':ao_freq, 'ki':gainCL, 'delay':(oopao_frame_delay-1)/ao_freq*1000})
|
|
333
|
+
rtc.leak = leak
|
|
334
|
+
return rtc
|
|
335
|
+
|
|
336
|
+
@property
|
|
337
|
+
def nb_frame_delay(self):
|
|
338
|
+
return self.delay*1e-3 * self.freq
|
|
339
|
+
|
|
340
|
+
@property
|
|
341
|
+
def bandwidth(self):
|
|
342
|
+
return bandwidth(self.ki, self.nb_frame_delay, self.freq)
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def bandwidth_noise(self):
|
|
346
|
+
return bandwidth_noise(self.ki, self.nb_frame_delay, self.freq)
|
|
347
|
+
|
|
348
|
+
def open_loop_transfer(self, ft):
|
|
349
|
+
return open_loop_transfer(ft, self.freq, self.ki, self.nb_frame_delay, kp=self.kp, discrete=self.discrete, leak=self.leak)
|
|
350
|
+
|
|
351
|
+
def closed_loop_transfer(self, ft):
|
|
352
|
+
return closed_loop_transfer(ft, self.freq, self.ki, self.nb_frame_delay, kp=self.kp, discrete=self.discrete, leak=self.leak)
|
|
353
|
+
|
|
354
|
+
def noise_transfer(self, ft):
|
|
355
|
+
return noise_transfer(ft, self.freq, self.ki, self.nb_frame_delay, kp=self.kp, discrete=self.discrete, leak=self.leak)
|
aopera/data/ekarus.ini
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[source_science]
|
|
2
|
+
; central wavelength [nm]
|
|
3
|
+
wvl_nm = 1400
|
|
4
|
+
; zenithal angle [deg]
|
|
5
|
+
zenith_deg = 30
|
|
6
|
+
|
|
7
|
+
[source_wfs]
|
|
8
|
+
; central wavelength [nm]
|
|
9
|
+
wvl_nm = 635
|
|
10
|
+
; flux [ph/m²/s]
|
|
11
|
+
flux = 1e8
|
|
12
|
+
; source size [arcsec]
|
|
13
|
+
size = 0
|
|
14
|
+
; separation distance [arcsec]
|
|
15
|
+
separation = 0.
|
|
16
|
+
; separation angle [deg]
|
|
17
|
+
angle = 0
|
|
18
|
+
|
|
19
|
+
[pupil]
|
|
20
|
+
; diameter [m]
|
|
21
|
+
diameter = 1.8
|
|
22
|
+
; central obstruction diameter ratio
|
|
23
|
+
occultation = 0.3
|
|
24
|
+
; number of actuators across diameter
|
|
25
|
+
nact = 32
|
|
26
|
+
; ratio of number of controlled modes vs total nb of modes
|
|
27
|
+
nmode_ratio = 0.9
|
|
28
|
+
|
|
29
|
+
[rtc]
|
|
30
|
+
; AO loop frequency [Hz]
|
|
31
|
+
freq = 1000
|
|
32
|
+
; RTC delay [ms]
|
|
33
|
+
delay = 1
|
|
34
|
+
; integrator gain
|
|
35
|
+
ki = 0.5
|
|
36
|
+
|
|
37
|
+
[pwfs]
|
|
38
|
+
; number of lenslet across diameter
|
|
39
|
+
lenslet = 50
|
|
40
|
+
; readout noise [e-/pix]
|
|
41
|
+
ron = 0.3
|
|
42
|
+
; is the camera an EMCCD
|
|
43
|
+
emccd = true
|
|
44
|
+
; modulation radius [lambda/D]
|
|
45
|
+
modulation = 3
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[source_science]
|
|
2
|
+
; central wavelength [nm]
|
|
3
|
+
wvl_nm = 2200
|
|
4
|
+
; zenithal angle [deg]
|
|
5
|
+
zenith_deg = 30
|
|
6
|
+
|
|
7
|
+
[source_wfs]
|
|
8
|
+
; central wavelength [nm]
|
|
9
|
+
wvl_nm = 850
|
|
10
|
+
; flux [ph/m²/s] magnitude 8, donc fort flux, je me base sur AO analysis : 84 ph/frame/sous-pupille @ 500Hz
|
|
11
|
+
flux = 7e6
|
|
12
|
+
; source size [arcsec]
|
|
13
|
+
size = 2.5
|
|
14
|
+
; separation distance [arcsec]
|
|
15
|
+
separation = 0.
|
|
16
|
+
; separation angle [deg]
|
|
17
|
+
angle = 0
|
|
18
|
+
|
|
19
|
+
[pupil]
|
|
20
|
+
; diameter [m]
|
|
21
|
+
diameter = 38.
|
|
22
|
+
; central obstruction diameter ratio
|
|
23
|
+
occultation = 0.3
|
|
24
|
+
; number of actuators across diameter
|
|
25
|
+
nact = 74
|
|
26
|
+
|
|
27
|
+
[rtc]
|
|
28
|
+
; AO loop frequency [Hz]
|
|
29
|
+
freq = 500
|
|
30
|
+
; RTC delay [ms]
|
|
31
|
+
delay = 2
|
|
32
|
+
; integrator gain
|
|
33
|
+
ki = 0.5
|
|
34
|
+
|
|
35
|
+
[pwfs]
|
|
36
|
+
; number of lenslet across diameter
|
|
37
|
+
lenslet = 100
|
|
38
|
+
; readout noise [e-/pix]
|
|
39
|
+
ron = 1.0
|
|
40
|
+
; is the camera an EMCCD
|
|
41
|
+
emccd = true
|
|
42
|
+
; modulation radius [lambda/D]
|
|
43
|
+
modulation = 3
|
aopera/data/ohp.ini
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[atmosphere]
|
|
2
|
+
; seeing at 550 nm [arcsec]
|
|
3
|
+
seeing = 2.0
|
|
4
|
+
; layers turbulence ratio
|
|
5
|
+
cn2dh_ratio = [8.672e-01, 3.480e-02, 9.700e-03, 1.180e-02, 5.700e-03, 4.300e-03, 3.700e-03, 3.200e-03, 2.500e-03, 1.800e-03, 1.200e-03, 1.100e-03, 1.100e-03, 1.800e-03, 4.100e-03, 1.000e-02, 1.490e-02, 9.600e-03, 4.700e-03, 3.100e-03, 1.900e-03, 9.000e-04, 5.000e-04, 2.000e-04, 1.000e-04, 1.000e-04, 1.000e-04]
|
|
6
|
+
; layers altitudes [m]
|
|
7
|
+
altitude = [0, 40, 84, 212, 477, 839, 1321, 1948, 2728, 3650, 4673, 5735, 6801, 7869, 8939, 10028, 11175, 12381, 13629, 14910, 16228, 17626, 19142, 20814, 22685, 24773, 27135]
|
|
8
|
+
; turbulence external scale [m]
|
|
9
|
+
lext = 30
|
|
10
|
+
; wind speed [m/s]
|
|
11
|
+
wind_speed = [ 5.39, 5.4, 5.42, 5.47, 5.59, 5.79, 6.15, 6.81, 8.05, 10.26, 13.8 , 18.65, 24.23, 29.57, 33.47, 34.87, 33.14, 28.4 , 21.95, 15.6 , 10.65, 7.47, 5.84, 5.21, 5.03, 5. , 5. ]
|
|
12
|
+
; wind direction [deg]
|
|
13
|
+
wind_direction = [ 0, 3, 6, 10, 13, 17, 20, 24, 27, 31, 34, 38, 41, 45, 48, 51, 55, 58, 62, 65, 69, 72, 76, 79, 83, 86, 90]
|
aopera/data/papyrus.ini
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[source_science]
|
|
2
|
+
; central wavelength [nm]
|
|
3
|
+
wvl_nm = 1400
|
|
4
|
+
; zenithal angle [deg]
|
|
5
|
+
zenith_deg = 30
|
|
6
|
+
|
|
7
|
+
[source_wfs]
|
|
8
|
+
; central wavelength [nm]
|
|
9
|
+
wvl_nm = 635
|
|
10
|
+
; flux [ph/m²/s]
|
|
11
|
+
flux = 1e9
|
|
12
|
+
; source size [arcsec]
|
|
13
|
+
size = 0
|
|
14
|
+
; separation distance [arcsec]
|
|
15
|
+
separation = 0.
|
|
16
|
+
; separation angle [deg]
|
|
17
|
+
angle = 0
|
|
18
|
+
|
|
19
|
+
[pupil]
|
|
20
|
+
; diameter [m]
|
|
21
|
+
diameter = 1.52
|
|
22
|
+
; central obstruction diameter ratio
|
|
23
|
+
occultation = 0.3
|
|
24
|
+
; number of actuators across diameter
|
|
25
|
+
nact = 16
|
|
26
|
+
; ratio of number of controlled modes vs total nb of modes
|
|
27
|
+
nmode_ratio = 0.9
|
|
28
|
+
|
|
29
|
+
[rtc]
|
|
30
|
+
; AO loop frequency [Hz]
|
|
31
|
+
freq = 500
|
|
32
|
+
; RTC delay [ms]
|
|
33
|
+
delay = 1.7
|
|
34
|
+
; integrator gain
|
|
35
|
+
ki = 0.5
|
|
36
|
+
|
|
37
|
+
[pwfs]
|
|
38
|
+
; number of lenslet across diameter
|
|
39
|
+
lenslet = 77
|
|
40
|
+
; readout noise [e-/pix]
|
|
41
|
+
ron = 0.5
|
|
42
|
+
; is the camera an EMCCD
|
|
43
|
+
emccd = true
|
|
44
|
+
; modulation radius [lambda/D]
|
|
45
|
+
modulation = 5
|
aopera/data/paranal.ini
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[atmosphere]
|
|
2
|
+
; seeing at 550 nm [arcsec]
|
|
3
|
+
seeing = 0.8
|
|
4
|
+
; layers turbulence ratio
|
|
5
|
+
cn2dh_ratio = [0.241954, 0.119977, 0.0968817, 0.0589889, 0.0472911, 0.0472911, 0.0472911, 0.0472911, 0.0398925, 0.0323939, 0.0161969, 0.0260951, 0.0155971, 0.0103980, 0.00999811, 0.0119977, 0.00400924, 0.0139974, 0.0129975, 0.00700868, 0.0159970, 0.0258951, 0.0190964, 0.00986813, 0.00616883, 0.00400924, 0.00246953, 0.00215959, 0.00184965, 0.00135974, 0.00110979, 0.000616883, 0.000925825, 0.000493907, 0.000431918]
|
|
6
|
+
; layers altitudes [m]
|
|
7
|
+
altitude = [30, 90, 150, 200, 245, 300, 390, 600, 1130, 1880, 2630, 3500, 4500, 5500, 6500, 7500, 8500, 9500, 10500, 11500, 12500, 13500, 14500, 15500, 16500, 17500, 18500, 19500, 20500, 21500, 22500, 23500, 24500, 25500, 26500]
|
|
8
|
+
; turbulence external scale [m]
|
|
9
|
+
lext = 50
|
|
10
|
+
; wind speed [m/s]
|
|
11
|
+
wind_speed = [5.5, 5.5, 5.1, 5.5, 5.6, 5.7, 5.8, 6.0, 6.5, 7.0, 7.5, 8.5, 9.5, 11.5, 17.5, 23.0, 26.0, 29.0, 32.0, 27.0, 22.0, 14.5, 9.5, 6.3, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0, 10.0]
|
|
12
|
+
; wind direction [deg]
|
|
13
|
+
wind_direction = [0, -10, 0, 0, 10, 20, 0, 0, 0, -20, 0, 0, -10, 0, 10, -20, 10, 0, -20, -20, 0, -20, 0, 0, 80, 80, 70, 60, 90, 80, 80, 100, 70, 80, 70]
|
aopera/data/sphere.ini
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[source_science]
|
|
2
|
+
; central wavelength with Zimpol filter N_R [nm]
|
|
3
|
+
wvl_nm = 646
|
|
4
|
+
; zenithal angle [deg]
|
|
5
|
+
zenith_deg = 30
|
|
6
|
+
|
|
7
|
+
[source_wfs]
|
|
8
|
+
; central wavelength [nm]
|
|
9
|
+
wvl_nm = 600
|
|
10
|
+
; flux [ph/m²/s]
|
|
11
|
+
flux = 1e9
|
|
12
|
+
; source size [arcsec]
|
|
13
|
+
size = 0
|
|
14
|
+
; separation distance [arcsec]
|
|
15
|
+
separation = 0.
|
|
16
|
+
; separation angle [deg]
|
|
17
|
+
angle = 0
|
|
18
|
+
|
|
19
|
+
[pupil]
|
|
20
|
+
; diameter [m]
|
|
21
|
+
diameter = 8
|
|
22
|
+
; central obstruction diameter ratio
|
|
23
|
+
occultation = 0.14
|
|
24
|
+
; number of actuators across diameter
|
|
25
|
+
nact = 41
|
|
26
|
+
|
|
27
|
+
[rtc]
|
|
28
|
+
; AO loop frequency [Hz]
|
|
29
|
+
freq = 1200
|
|
30
|
+
; RTC delay [ms]
|
|
31
|
+
delay = 1.14
|
|
32
|
+
; integrator gain
|
|
33
|
+
ki = 0.4
|
|
34
|
+
|
|
35
|
+
[shwfs]
|
|
36
|
+
; number of lenslet across diameter
|
|
37
|
+
lenslet = 40
|
|
38
|
+
; readout noise [e-/pix]
|
|
39
|
+
ron = 0.3
|
|
40
|
+
; is the camera an EMCCD
|
|
41
|
+
emccd = true
|
|
42
|
+
; spot sampling
|
|
43
|
+
samp = 2
|
|
44
|
+
; total nb pixels for center of gravity
|
|
45
|
+
npix_cog = 10
|