COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
writer.py
1 import numpy as np
2 import astropy.io.fits as fits
3 import shutil
4 
5 #filtering
6 #for:
7 #mavis_ltao keep 1320 values
8 #mavis_mcao keep 5400 values
9 #mavis_moao keep 1320 values
10 #
11 
12 
13 def used_actu(xpos, ypos,*, Np=-1):
14  """return the indices of the used actuators
15 
16  Args:
17  xpos: (np.ndarray[ndim=1, dtype=np.int32]): (optional) actuator position in x
18 
19  ypos: (np.ndarray[ndim=1, dtype=np.int32]): (optional) actuator position in y
20 
21  Kwargs:
22  Np: (int): (optional) number of actuators along the diameter
23  """
24 
25  u = np.unique(xpos)
26  pMin = u.min()
27  u -= pMin
28  if (Np > 0 and Np != u.size):
29  raise ValueError("Number of actuator along the diameter unconsistent")
30  else:
31  Np = u.size
32  #if(not np.testing.assert_array_almost_equal(np.arange(Np)*u[1],u,1)):
33  # print((np.arange(Np)*u[1]-u).max())
34  # raise ValueError("non uniform positions")
35  X = (xpos - pMin) / u[1]
36  Y = (ypos - pMin) / u[1]
37  return (Y * Np + X).astype(np.int32)
38 
39 
40 def get_idx(p_dm, *, xpos=None, ypos=None):
41  """return a correspondance between the covariance matrix indices and the covariance map indices
42 
43  Args:
44  p_dm: (Param_dm): dm settings
45 
46  Kwargs:
47  xpos: (np.ndarray[ndim=1, dtype=np.int32]): (optional) actuator position in x
48 
49  ypos: (np.ndarray[ndim=1, dtype=np.int32]): (optional) actuator position in y
50 
51  Returns:
52  index_map : (np.ndarray[ndim=1, dtype=np.int32]) : correspondance between the covariance matrix indices and the covariance map indices
53  """
54 
55  if (xpos is not None and ypos is not None):
56  csI = used_actu(xpos, ypos)
57  else:
58  csI = p_dm.csI
59 
60  Np = p_dm.nact
61  # dm.csI: valid actuators
62  xx = np.tile(np.arange(Np), (Np, 1)).flatten('C')[csI]
63  xx = -np.tile(xx, (xx.size, 1))
64  dx = xx - xx.T
65 
66  yy = np.tile(np.arange(Np), (Np, 1)).flatten('F')[csI]
67  yy = -np.tile(yy, (yy.size, 1))
68  dy = yy - yy.T
69  # // transformation des decalages en indice de tableau
70  dx += Np
71  dy += Np
72 
73  return dx.flatten("F") + (p_dm.nact * 2 - 1) * (dy.flatten("F") - 1)
74 
75 
76 def get_abs2fi(sup, *,dm=0):
77  size = sup.config.p_geom.pupdiam
78  N = 2**(int(np.log(2 * size) / np.log(2) + 1)) #SutraTarget:138,
79 
80  supportFi = np.zeros((N, N), dtype=np.float32)
81  fi = sup.config.p_dms[0]._influ[:, :, 0] * 1e-6
82  supportFi[:fi.shape[0], :fi.shape[1]] = fi
83 
84  abs2fi = np.abs(np.fft.fft2(supportFi.T))**2
85 
86  return abs2fi.T
87 
88 
89 def OTF_telescope(sup):
90  """otf = OTF_telescope(fourier)
91 
92  Computes the OTF of the telescope, so that
93  > fft(OTF_telescope()).re
94  produces a PSF normalized with max(psf)=SR=1.0
95 
96  """
97  size = sup.config.p_geom.pupdiam
98  N = 2**(int(np.log(2 * size) / np.log(2) + 1)) #SutraTarget:138,
99  ud = sup.config.p_tel.diam / sup.config.p_geom.pupdiam
100  # computation of pupil
101  x = ud / (sup.config.p_tel.diam / 2.) * (np.arange(N) + 1 -
102  (N / 2 + 1)) # x exprime en rayon pupille
103  x2 = np.tile(x * x, (x.size, 1))
104  r = np.sqrt(x2 + x2.T)
105 
106  #pup=(r<=1.0)*1 * (r>sup.config.p_tel.cobs)*1
107  pup = sup.config.p_geom._ipupil
108  # factor that will normalize the psf
109  # with PSF(0)=1.00 when diffraction-limited
110  # surface_pup_m2 = tomo.tel.diam^2*(1-tomo.tel.obs^2)*pi/4;
111  surface_pup_m2 = sup.config.p_tel.diam**2 * (
112  1 - sup.config.p_tel.cobs**2) * np.pi / 4.
113  surface_pup_pix = surface_pup_m2 / ud**2
114  factnorm = surface_pup_pix**2
115  # compute FTO of telescope. Computing the psf using
116  # just fft(FTO).re produces a psf with max(psf)=SR
117  # In fact, FTOtel is normalized so that sum(FTOtel)=1.
118  # FTOtel = autocorrelation(pup) / factnorm;
119  #FTOtel=autocorrelation(pup)/factnorm
120  FTOtel = autocorrelation(pup) / np.sum(pup)**2
121  return FTOtel
122 
123 
124 def get_subaps(sup, *, wfs="all"):
125  """ Return the number of valid subaps (per wfs) as well as their position
126 
127  Args:
128  sup : (CompassSupervisor) : current supervisor
129 
130  Kwargs:
131  wfs : (str) : (optional), default "all" wfs used by tao ( among "all", "lgs", "ngs")
132 
133  """
134  #X=(sup.config.p_wfss[0]._validpuppixx-mpup.shape[0]/2-1)*(sup.config.p_tel.diam/sup.config.p_wfss[0].nxsub/sup.config.p_wfss[0]._pdiam )
135  nsubap = []
136  X = []
137  Y = []
138  if (wfs == "ngs"):
139  p_wfss = sup.config.p_wfs_ngs
140  elif (wfs == "lgs"):
141  p_wfss = sup.config.p_wfs_lgs + [sup.config.p_wfs_ngs[-1]]
142  else: # case all
143  p_wfss = sup.config.p_wfs_lgs + sup.config.p_wfs_ngs
144  for wfs in p_wfss:
145  validX = wfs._validpuppixx
146  validY = wfs._validpuppixy
147  toMeter = (sup.config.p_tel.diam / wfs.nxsub / wfs._pdiam)
148  validX = (validX - validX.max() / 2) * toMeter
149  validY = (validY - validY.max() / 2) * toMeter
150  X += list(validX)
151  Y += list(validY)
152  nsubap.append(len(validX))
153  return nsubap, X, Y
154 
155 
156 def autocorrelation(a):
157  """ computes the autocorrelation so that
158 
159  max(aa) == sum(a^2)
160 
161  Args:
162  a: (np.ndarray[ndim=2, dtype=np.float32]): matrix to compute the autocorrelation on
163 
164  """
165  if (a.ndim == 2):
166  b = np.abs(np.fft.fft2(a))
167  b = np.fft.ifft2(b * b).real * a.size
168  elif (a.ndim == 1):
169  b = np.abs(np.fft.fft(a))
170  b = np.fft.ifft(b * b).real
171  else:
172  print("error: autocorrelation: expect dim 1 or 2")
173  return
174  n2 = a.size # N*N
175  b /= n2
176  return b
177 
178 
179 def func_influ(x, y, x0):
180  #/* DOCUMENT opd_metres = func_influ(x,y,x0)
181  #
182  # The arguments <x>, <y> and <x0> must all be in the same units.
183  #
184  # In the particular case where <x0> is set to x0=dm.x0, <x> and <y>
185  # must be expressed with no unit, they are variables defined over the
186  # unitary circle of R=1.
187  #
188  # In any case, the function returns the influence function (=OPD,
189  # optical path difference) of the actuators expressed in METERS.
190  #
191  #
192  # // allez on va dire que ce sont des metres !
193  return 1.e-6 * np.exp(-(x * x + y * y) / (2 * x0 * x0))
194 
195 
196 def generate_files(sup, *,path=".", single_file=False, dm_use_tt=False, wfs="all",
197  lgs_filter_cst=0.1, tar=-1):
198  """write inputs parameters
199 
200  sys-params.txt: contains the system parameters
201  idx.fits :
202  otftel.fits :
203  abs2fi.fits :
204  subaps.fits : number and position of the subapertures
205 
206  Args:
207  sup : (CompassSupervisor) : current supervisor
208 
209  Kwargs:
210  path : (str): (optional), default './' path where the files are written
211 
212  single_file : (bool): (optional), default=False write a single fits File
213 
214  wfs : (str) : (optional), default "all" wfs used by tao ( among "all", "lgs", "ngs")
215 
216  lgs_filter_cst : (float) : (optional) add constant to filter out lgs tt
217 
218  tar : (list) : (optional), default -1 index of the target
219  """
220  p_dm = sup.config.p_dms[0]
221  if (p_dm.type == 'tt'):
222  print("ERROR: first dm must not be a 'tip-tilt")
223  return
224  nact = p_dm.nact
225  ntotact = p_dm._ntotact
226 
227  if (dm_use_tt):
228  p_dm_tt = sup.config.p_dms[-1]
229  if (p_dm_tt.type != 'tt'):
230  print("ERROR: tip-tilt dm must be the last one")
231  return
232  ntotact += 2
233 
234  write_sys_param(sup, path=path, wfs=wfs, lgs_filter_cst=lgs_filter_cst, tar=tar)
235  write_atm_param(sup, path=path)
236  idx = get_idx(p_dm, xpos=p_dm._xpos, ypos=p_dm._ypos)
237  otf = OTF_telescope(sup)
238  abs2fi = get_abs2fi(sup)
239  nsubaps, X, Y = get_subaps(sup, wfs=wfs)
240  if (not single_file):
241  hdu_idx = fits.PrimaryHDU(idx)
242  hdu_idx.header["NACT"] = nact
243  hdu_idx.header["NTOTACT"] = ntotact
244  hdul = fits.HDUList([hdu_idx])
245  hdul.writeto(path + "/idx.fits", overwrite=1)
246  fits.writeto(path + "/otftel.fits", otf, overwrite=1)
247  fits.writeto(path + "/abs2fi.fits", abs2fi, overwrite=1)
248 
249  hdu_prime = fits.PrimaryHDU(np.zeros(0))
250  hdu_nsubap = fits.ImageHDU(nsubaps, name="NSUBAP")
251  hdu_Xpos = fits.ImageHDU(X, name="XPOS")
252  hdu_Ypos = fits.ImageHDU(Y, name="YPOS")
253  hdul = fits.HDUList([hdu_prime, hdu_nsubap, hdu_Xpos, hdu_Ypos])
254  hdul.writeto(path + "/subaps.fits", overwrite=1)
255  else:
256  hdu_prime = fits.PrimaryHDU(np.zeros(0))
257  hdu_nsubap = fits.ImageHDU(nsubaps, name="NSUBAP")
258  hdu_Xpos = fits.ImageHDU(X, name="XPOS")
259  hdu_Ypos = fits.ImageHDU(Y, name="YPOS")
260  hdu_idx = fits.ImageHDU(idx, name="IDX")
261  hdu_idx.header["NACT"] = nact
262  hdu_idx.header["NTOTACT"] = ntotact
263  hdu_abs2fi = fits.ImageHDU(abs2fi, name="ABS2FI")
264  hdu_otf = fits.ImageHDU(otf, name="OTF")
265  hdul = fits.HDUList([
266  hdu_prime, hdu_nsubap, hdu_Xpos, hdu_Ypos, hdu_idx, hdu_abs2fi, hdu_otf
267  ])
268  hdul.writeto(path + "/sys-inputs.fits", overwrite=1)
269 
270 
271 def to_str(a=""):
272  """ transform a np.array into a string
273 
274  Kwargs:
275  a : (np.ndarray[ndim=1, dtype=np.int32]) : input array
276  """
277  string = ""
278  if (type(a) is np.ndarray):
279  for i in range(a.size):
280  string += str(a[i]) + " "
281  if (type(a) is list):
282  for i in range(len(a)):
283  string += str(a[i]) + " "
284  else:
285  string = str(a)
286 
287  return string
288 
289 def write_sys_param(sup, path=".", wfs="all", lgs_filter_cst=0.1, tar=-1):
290  """ Write a sysParam file for tao based on the compass configuration
291 
292  Args:
293  sup : (CompassSupervisor) : current supervisor
294 
295  Kwargs:
296  path : (str) : (optional), "./" path to the sysParam file
297 
298  wfs : (str) : (optional), default "all" wfs used by tao ( among "all", "lgs", "ngs")
299 
300  lgs_filter_cst : (float) : (optional) add constant to filter out lgs tt
301 
302  tar : (list) : (optional), default -1 index of the target
303  """
304  bdw = 3.3e-7
305  lgs_depth = 5000.
306  through_atm = 1.
307  p_wfs_ngs = sup.config.p_wfs_ngs
308  p_wfs_lgs = sup.config.p_wfs_lgs
309  if (wfs == "ngs"):
310  p_wfss = p_wfs_ngs
311  elif (wfs == "lgs"):
312  p_wfss = p_wfs_lgs + [p_wfs_ngs[-1]]
313  else: # case all
314  p_wfss = p_wfs_lgs + p_wfs_ngs
315  p_wfs_ts = sup.config.p_wfs_ts
316  p_targets = sup.config.p_targets
317  p_tel = sup.config.p_tel
318  p_loop = sup.config.p_loop
319 
320  if (len(p_wfs_lgs) > 0):
321  lgs_flux = p_wfs_lgs[0].lgsreturnperwatt * p_wfs_lgs[0].laserpower * p_wfs_lgs[
322  0].optthroughput * 10**4
323  lgs_pix_size = p_wfs_lgs[0].pixsize
324  lambda_lgs = p_wfs_lgs[0].Lambda * 1e-6
325  through_lgs = p_wfs_lgs[0].optthroughput
326  spot_width = p_wfs_lgs[0].beamsize
327  lgs_alt = p_wfs_lgs[0].gsalt
328  else:
329  lgs_flux = 7.e6
330  lgs_pix_size = 0.7
331  lambda_lgs = 5.89e-07
332  through_lgs = 0.382
333  spot_width = 0.8
334  lgs_alt = 90000
335 
336  if (len(p_wfs_ts) > 0):
337  ts_xpos = [w.xpos for w in p_wfs_ts]
338  ts_ypos = [w.ypos for w in p_wfs_ts]
339  else:
340  ts_xpos = []
341  ts_ypos = []
342 
343  f = open(path + "/sys-params.txt", "w")
344  f.write("diam : meter : Telescope diameter\n")
345  f.write(to_str(p_tel.diam))
346  f.write("\nobs : percent : Central obscuration\n")
347  f.write(to_str(p_tel.cobs))
348  f.write("\ntFrame : second : frame rate\n")
349  f.write(to_str(p_loop.ittime))
350  f.write("\nnW : : number of WFS\n")
351  f.write(to_str(len(p_wfss)))
352  f.write("\nnLgs : : number of LGS\n")
353  f.write(to_str(len(p_wfs_lgs)))
354  f.write("\nnTS : : number of Truth Sensor\n")
355  f.write(to_str(len(p_wfs_ts)))
356  f.write("\nnTarget : : number of Target\n")
357  if(tar==-1):
358  f.write(to_str(len(p_targets)))
359  else:
360  f.write("1")
361  f.write("\nNssp : : number of subaperture per wfs along the diameter\n")
362  f.write(to_str([wfs.nxsub for wfs in p_wfss]))
363  f.write("\nfracsub : % : Minimal illumination fraction for valid subap\n")
364  f.write("-1") #to_str(p_wfss[0].fracsub))
365  f.write("\ngsAlt : meter^-1 : inverse of lazer altitude\n")
366  f.write(to_str([1 / w.gsalt for w in p_wfs_lgs] + [0 for w in p_wfs_ngs]))
367  f.write("\ntype : : guide star type (1:NGS, 2:LGS)\n")
368  f.write(to_str([2 for w in p_wfs_lgs] + [1 for w in p_wfs_ngs]))
369  f.write("\nalphaX_as : arcsec : pointing direction of the wfs on x axis\n")
370  f.write(to_str([w.xpos for w in p_wfss]))
371  f.write("\nalphaY_as : arcsec : pointing direction of the wfs on y axis\n")
372  f.write(to_str([w.ypos for w in p_wfss]))
373  f.write("\nXPup : meter : pupil shift of the WFS\n")
374  f.write(to_str([0 for i in range(len(p_wfss))]))
375  f.write("\nYPup : meter : pupil shift of the WFS\n")
376  f.write(to_str([0 for i in range(len(p_wfss))]))
377  f.write("\nthetaML : : rotation of the microlenses\n")
378  f.write(to_str([0 for i in range(len(p_wfss))]))
379  f.write("\nthetaCam : : rotation of the camera\n")
380  f.write(to_str([0 for i in range(len(p_wfss))]))
381  f.write("\nsensibility: : sensitivity coeff of this WFS\n")
382  f.write(to_str([1 for i in range(len(p_wfss))]))
383  f.write("\ntracking : arcsec^2 : telescope tracking error parameters (x^2, y^2 and xy)\n"
384  )
385  f.write(to_str("1 1 1"))
386  f.write("\npasDPHI : : Precision of DPHI precomputation. //deprecated\n"
387  )
388  f.write(to_str(0.0001))
389  f.write("\nncpu : : Number of CPU used (only with openMP)\n")
390  f.write(to_str(1))
391  f.write("\nmrNGS : : magnitude of NGS\n")
392  if (len(p_wfs_ngs) > 0):
393  f.write(to_str([w.gsmag for w in p_wfs_ngs]))
394  else:
395  f.write(to_str([0.0]))
396  f.write("\nlgsFlux : (ph/m2/s) : LGS photon return at M1\n")
397  f.write(to_str(lgs_flux))
398  f.write("\nngsPixSize : arcsec : NGS pixel size\n")
399  if (len(p_wfs_ngs) > 0):
400  f.write(to_str(p_wfs_ngs[0].pixsize))
401  else:
402  f.write(to_str(0.0))
403  f.write("\nlgsPixSize : arcsec : LGS pixel size\n")
404  f.write(to_str(lgs_pix_size))
405  f.write("\nlambdaNGS : meter : wave length for NGS\n")
406  if (len(p_wfs_ngs) > 0):
407  f.write(to_str(p_wfs_ngs[0].Lambda * 1e-6))
408  else:
409  f.write(to_str(0.0))
410  f.write("\nlambdaLGS : meter : wave length for LGS\n")
411  f.write(to_str(lambda_lgs))
412  f.write("\nbdw_m : meter : bandwidth\n")
413  f.write(to_str(bdw))
414  f.write("\nthroughNGS : percent : transmission for NGS\n")
415  if (len(p_wfs_ngs) > 0):
416  f.write(to_str(p_wfs_ngs[0].optthroughput))
417  else:
418  f.write(to_str(0.0))
419  f.write("\nthroughLGS : percent : transmission for LGS\n")
420  f.write(to_str(through_lgs))
421  f.write("\nthroughAtm : percent : atmosphere transmission\n")
422  f.write(to_str(through_atm))
423  f.write("\nRON : nb of e- : Read Out Noise \n")
424  f.write(to_str(int(np.ceil(p_wfss[0].noise))))
425  f.write("\nlgsCst : : constant on lgs (simulate that LGS cannot measure tip-tilt and focus)\n")
426  f.write(to_str(lgs_filter_cst))
427  f.write("\nspotWidth : arcsec : lazer width\n")
428  f.write(to_str(spot_width))
429  f.write("\nlgsAlt : meter : sodium layer altitude\n")
430  f.write(to_str(lgs_alt))
431  f.write("\nlgsDepth : meter : depth of the sodium layer\n")
432  f.write(to_str(lgs_depth))
433  f.write("\ntargetX_as : arcsec : taget direction on x axis\n")
434  if(tar==-1):
435  f.write(to_str(ts_xpos + [t.xpos for t in p_targets]))
436  elif(isinstance(tar,(list,np.ndarray))):
437  f.write(to_str(ts_xpos + [tar[0]]))
438  else:
439  f.write(to_str(ts_xpos + [p_targets[tar].xpos]))
440  f.write("\ntargetY_as : arcsec : taget direction on y axis\n")
441  if(tar==-1):
442  f.write(to_str(ts_ypos + [t.ypos for t in p_targets]))
443  elif(isinstance(tar,(list,np.ndarray))):
444  f.write(to_str(ts_ypos + [tar[1]]))
445  else:
446  f.write(to_str(ts_ypos + [p_targets[tar].ypos]))
447 
448 
449 def write_atm_param(sup, *,path="."):
450  """ Write a atmParam file for tao based on the compass configuration
451 
452  Args:
453  sup : (CompassSupervisor) : current supervisor
454 
455  Kwargs:
456  path : (str) : (optional), default "./" path to the atmParam file
457  """
458  f = open(path + "/prof-1-atmos-night0.txt", "w")
459  f.write("Nlayer\n")
460  f.write(to_str(sup.config.p_atmos.nscreens))
461  f.write("\nr0 @ wfs lambda\n")
462  f.write(to_str(sup.config.p_atmos.r0))
463  f.write("\ncn2 ESO units\n")
464  f.write(to_str(sup.config.p_atmos.get_frac().tolist()))
465  f.write("\nh in meters\n")
466  f.write(to_str(sup.config.p_atmos.get_alt().tolist()))
467  f.write("\nl0 in meters\n")
468  f.write(to_str(sup.config.p_atmos.get_L0().tolist()))
469  f.write("\nwind direction \n")
470  f.write(to_str(sup.config.p_atmos.get_winddir().tolist()))
471  f.write("\nwind speed meter/s^-1\n")
472  f.write(to_str(sup.config.p_atmos.get_windspeed().tolist()))
473  f.close()
474  shutil.copyfile(path + "/prof-1-atmos-night0.txt", path + "/prof0-atmos-night0.txt")
475 
476 
477 def write_meta_Dx(meta_Dx, *,nTS=0, nmeas=None, trans=True, path="."):
478  """Write command matrices
479 
480  split the meta command matrix
481 
482  Args:
483  meta_Dx: (np.ndarray[ndim=2, dtype=np.float32]): "meta" command matrix
484 
485  Kwargs:
486  nTS: (int): (optional), default=0. Number of truth sensors, command matrices are written as Di.fits where 'i' belongs to [0,nTS[ , if nTS<1 write the whole matrix as Dx.fits
487 
488  nmeas: (np.ndarray[ndim=1, dtype=np.int32]): (optional) if set, must contains the number of measurements for each TS, the matrix is split according to theses numbers. By default, the matrix is split evenly between the nTS truth sensors
489 
490  trans: (bool): (optional), default=True. Transpose the matrix if true
491 
492  path: (str): (optional), default './' path where the files are written
493  """
494  if (nTS < 1):
495  if (trans):
496  fits.writeto(path + "/Dx.fits", meta_Dx.T, overwrite=True)
497  else:
498  fits.writeto(path + "/Dx.fits", meta_Dx, overwrite=True)
499  return
500 
501  if (nmeas is None):
502  n = meta_Dx.shape[1] // nTS
503  nmeas = np.arange(0, meta_Dx.shape[1] + n, n)
504  else:
505  nmeas = np.append(0, nmeas.cumsum())
506 
507  for i in range(nTS):
508  print(i + 1, "out of", nTS, end='\r')
509  Dx = meta_Dx[:, nmeas[i]:nmeas[i + 1]]
510  if (trans):
511  fits.writeto(path + "/Dx" + str(i) + ".fits", Dx.T, overwrite=True)
512  else:
513  fits.writeto(path + "/Dx" + str(i) + ".fits", Dx, overwrite=True)
def get_abs2fi(sup, *dm=0)
Definition: writer.py:76
def write_atm_param(sup, *path=".")
Write a atmParam file for tao based on the compass configuration.
Definition: writer.py:459
def func_influ(x, y, x0)
Definition: writer.py:181
def autocorrelation(a)
computes the autocorrelation so that
Definition: writer.py:166
def write_meta_Dx(meta_Dx, *nTS=0, nmeas=None, trans=True, path=".")
Write command matrices.
Definition: writer.py:495
def used_actu(xpos, ypos, *Np=-1)
return the indices of the used actuators
Definition: writer.py:23
def write_sys_param(sup, path=".", wfs="all", lgs_filter_cst=0.1, tar=-1)
Write a sysParam file for tao based on the compass configuration.
Definition: writer.py:305
def get_subaps(sup, *wfs="all")
Return the number of valid subaps (per wfs) as well as their position.
Definition: writer.py:133
def OTF_telescope(sup)
otf = OTF_telescope(fourier)
Definition: writer.py:96
def to_str(a="")
transform a np.array into a string
Definition: writer.py:278
def get_idx(p_dm, *xpos=None, ypos=None)
return a correspondance between the covariance matrix indices and the covariance map indices
Definition: writer.py:53
def generate_files(sup, *path=".", single_file=False, dm_use_tt=False, wfs="all", lgs_filter_cst=0.1, tar=-1)
write inputs parameters
Definition: writer.py:221