50 sh = shape[0], a.shape[0] // shape[0], shape[1], a.shape[1] // shape[1]
51 return np.mean(a.reshape(sh), axis=(1, 3))
55 """find best size for a fft from size s
61 return 2**(int(np.log2(s)) + 1)
64 def bin2d(data_in, binfact):
66 Returns the input 2D array "array", binned with the binning factor "binfact".
67 The input array X and/or Y dimensions needs not to be a multiple of
68 "binfact"; The final/edge pixels are in effect replicated if needed.
69 This routine prepares the parameters and calls the C routine _bin2d.
70 The input array can be of type int, float or double.
71 Last modified: Dec 15, 2003.
77 data_in: (np.ndarray) : data to binned
79 binfact: (int) : binning factor
82 raise ValueError(
"binfact has to be >= 1")
86 fx = int(np.ceil(nx / float(binfact)))
87 fy = int(np.ceil(ny / float(binfact)))
89 data_out = np.zeros((fx, fy), dtype=data_in.dtype)
93 for i2
in range(binfact):
94 for j2
in range(binfact):
101 data_out[i1, j1] += data_in[i, j]
115 padded = np.zeros((N, N))
116 padded[D1:D1 + S[0], D2:D2 + S[1]] = A
120 def dist(dim, xc=-1, yc=-1):
131 dx = np.tile(np.arange(dim) - xc, (dim, 1))
132 dy = np.tile(np.arange(dim) - yc, (dim, 1)).T
134 d = np.sqrt(dx**2 + dy**2)
140 Returns a centered gaussian of specified size and fwhm.
141 norm returns normalized 2d gaussian
145 :param fwhm: (float) :
147 :param xc: (float) : (optional) center position on x axis
149 :param yc: (float) : (optional) center position on y axis
151 :param norm: (int) : (optional) normalization
153 tmp = np.exp(-(
dist(size, xc, yc) / (fwhm / 1.66))**2.)
155 tmp = tmp / (fwhm**2. * 1.140075)
161 Load the parameters from the parameters file
164 filename_path: (str): path to the parameters file
167 config : (config) : a config module
169 path = os.path.dirname(os.path.abspath(filename_path))
170 filename = os.path.basename(filename_path)
171 name, ext = os.path.splitext(filename)
174 if (path
not in sys.path):
175 sys.path.insert(0, path)
180 sys.path.remove(path)
181 elif importlib.util.find_spec(filename_path)
is not None:
184 raise ValueError(
"Config file must be .py or a module")
189 Load the parameters from the parameters module
192 filename_path: (str): path to the parameters file
195 config : (config) : a config module
197 filename = filepath.split(
'.')[-1]
198 print(
"loading: %s" % filename)
200 config = importlib.import_module(filepath)
201 del sys.modules[config.__name__]
202 config = importlib.import_module(filepath)
204 if hasattr(config,
'par'):
205 config = getattr(
"config.par.par4bench", filename)
208 if not hasattr(config,
'p_loop'):
210 if not hasattr(config,
'p_geom'):
212 if not hasattr(config,
'p_tel'):
214 if not hasattr(config,
'p_atmos'):
215 config.p_atmos =
None
216 if not hasattr(config,
'p_dms'):
218 if not hasattr(config,
'p_targets'):
219 config.p_targets =
None
220 if not hasattr(config,
'p_wfss'):
222 if not hasattr(config,
'p_centroiders'):
223 config.p_centroiders =
None
224 if not hasattr(config,
'p_controllers'):
225 config.p_controllers =
None
227 if not hasattr(config,
'simul_name'):
228 config.simul_name =
None
233 """ Generate modulation points positions following a square pattern
236 radius : (float) : half the length of a side in lambda/D
238 density : (float), optional) : number of psf per lambda/D. Default is 1
241 cx : (np.ndarray) : X-positions of the modulation points
243 cy : (np.ndarray) : Y-positions of the modulation points
245 x = np.linspace(-radius, radius, 1 + 2 * int(radius * density))
246 cx, cy = np.meshgrid(x, x, indexing=
'ij')
252 """ Generate modulation points positions following a circular pattern
255 radius : (float) : half the length of a side in lambda/D
257 density : (float), optional) : number of psf per lambda/D. Default is 1
260 cx : (np.ndarray) : X-positions of the modulation points
262 cy : (np.ndarray) : Y-positions of the modulation points
265 r = cx * cx + cy * cy <= radius**2
266 return (cx[r], cy[r])
268 def generate_pseudo_source(radius: float, additional_psf=0, density=1.):
269 """ Used to generate a pseudo source for PYRWFS
272 radius : (float) : TODO description
274 additional_psf : (int) :TODO description
276 density : (float, optional) :TODO description
279 ox : TODO description & explicit naming
281 oy : TODO description & explicit naming
283 w : TODO description & explicit naming
285 xc : TODO description & explicit naming
287 yc : TODO description & explicit naming
289 struct_size = (1 + 2 * additional_psf)**2
291 center_weight = (1 + 2 * int(additional_psf * density))**2 * [1]
292 center_size = 1 + 2 * int(additional_psf * density)
294 weight_edge = [(1 + 2 * int(radius * density) - center_size) // 2]
296 for k
in range(additional_psf):
297 line_length = np.sum(yc == (k + 1))
299 weight_edge.append((line_length - center_size) // 2)
301 edge_dist = (radius + additional_psf) // 2
307 V_edge_y.append(m * edge_dist)
308 V_edge_weight.append(weight_edge[0])
309 for k, val
in enumerate(weight_edge[1:]):
312 V_edge_x.append(l * (k + 1) * density)
313 V_edge_y.append(m * edge_dist)
314 V_edge_weight.append(val)
319 H_edge_x.append(m * edge_dist)
321 H_edge_weight.append(weight_edge[0])
322 for k, val
in enumerate(weight_edge[1:]):
325 H_edge_x.append(m * edge_dist)
326 H_edge_y.append(l * (k + 1) * density)
327 H_edge_weight.append(val)
330 pup_cent_weight = 4 * [(len(xc) - 2 * np.sum(H_edge_weight) - struct_size) / 4]
331 pup_cent_dist = int(edge_dist // np.sqrt(2))
334 pup_cent_x.append(l * pup_cent_dist)
335 pup_cent_y.append(m * pup_cent_dist)
336 ox = np.concatenate((center_x, V_edge_x, H_edge_x, pup_cent_x))
337 oy = np.concatenate((center_y, V_edge_y, H_edge_y, pup_cent_y))
338 w = np.concatenate((center_weight, V_edge_weight, H_edge_weight,
340 return (ox, oy, w, xc, yc)
343 invalid_val: int = -1) -> np.ndarray:
344 """ Find the first non zero element of an array
347 array : (np.ndarray) : input array
349 axis : (int) : axis index
351 invalid_val : (int, optional) : Default is -1
354 non_zeros_pos : (np.ndarray) : Index of the first non-zero element
355 for each line or column following the axis
358 return np.where(mask.any(axis=axis), mask.argmax(axis=axis), invalid_val)