COMPASS  5.4.4
End-to-end AO simulation tool using GPU acceleration
fits.py
1 import numpy as np
2 from shesha.util.writers.common import dm
3 from shesha.util.writers.common import wfs
4 from shesha.util.writers.common import imat
5 from astropy.io import fits
6 
7 def wfs_to_fits_hdu(sup, wfs_id):
8  """Return a fits Header Data Unit (HDU) representation of a single WFS
9 
10  Args:
11  sup : (compasSSupervisor) : supervisor
12 
13  wfs_id : (int) : index of the WFS in the supervisor
14 
15  Returns:
16  hdu : (ImageHDU) : fits representation of the WFS
17  """
18  hdu_name = "WFS" + str(wfs_id)
19  X,Y = wfs.get_subap_pos_meter(sup, wfs_id)
20  valid_subap = np.array([X,Y],dtype=np.float64)
21  hdu = fits.ImageHDU( valid_subap, name=hdu_name)
22  hdu.header["NSSP"] = sup.config.p_wfss[wfs_id].get_nxsub()
23  hdu.header["SSPSIZE"] = sup.config.p_wfss[wfs_id].get_subapd()
24  return hdu
25 
26 def dm_to_fits_hdu(sup, dm_id):
27  """Return a fits Header Data Unit (HDU) representation of a single DM
28 
29  Args:
30  sup : (compasSSupervisor) : supervisor
31 
32  wfs_id : (int) : index of the DM in the supervisor
33 
34  Returns:
35  hdu : (ImageHDU) : fits representation of the DM
36  """
37  hdu_name = "DM" + str(dm_id)
38  X,Y = dm.get_actu_pos_meter(sup, dm_id)
39  valid_subap = np.array([X,Y],dtype=np.float64)
40  hdu = fits.ImageHDU( valid_subap, name=hdu_name)
41  hdu.header["NACTU"] = sup.config.p_dms[dm_id].get_nact()
42  hdu.header["PITCH"] = sup.config.p_dms[dm_id].get_pitch()
43  hdu.header["COUPLING"] = sup.config.p_dms[dm_id].get_coupling()
44  hdu.header["ALT"] = sup.config.p_dms[dm_id].get_alt()
45  return hdu
46 
47 def dm_influ_to_fits_hdu(sup, dm_id, *, influ_index=-1):
48  """Return a fits Header Data Unit (HDU) holding the influence functions of a specific DM
49 
50  Args:
51  sup : (compasSSupervisor) : supervisor
52 
53  wfs_id : (int) : index of the DM in the supervisor
54 
55  Kwargs:
56  influ_index : (int) : (optional) default -1, index of the actuator to get the influence function from. -1 : get all influence functions
57 
58  Returns:
59  hdu : (ImageHDU) : hdu holding the DM influence functions
60  """
61  hdu_name = "INFLU_DM" + str(dm_id)
62  if influ_index < 0 :
63  influ_fct = sup.config.p_dms[dm_id].get_influ().astype(np.float64)
64  else :
65  influ_fct = sup.config.p_dms[dm_id].get_influ()[:,:,influ_index].astype(np.float64)
66  hdu = fits.ImageHDU( influ_fct, name=hdu_name)
67  return hdu
68 
69 def write_data(file_name, sup, *, wfss_indices=None, dms_indices=None,
70  controller_id=0, influ=0, compose_type="controller"):
71  """ Write data for yao compatibility
72 
73  write into a single fits:
74  * number of valide subapertures
75  * number of actuators
76  * subapertures position (2-dim array x,y) in meters centered
77  * actuator position (2-dim array x,y) in pixels starting from 0
78  * interaction matrix (2*nSubap , nactu)
79  * command matrix (nacy , 2*nSubap)
80 
81  Args:
82  file_name : (str) : data file name
83 
84  sup : (compasSSupervisor) : supervisor
85 
86  Kargs:
87  wfss_indices : (list[int]) : optional, default all, list of the wfs indices to include
88 
89  dms_indices : (list[int]) : optional, default all, list of the DM indices to include
90 
91  controller_id : (int) : optional, index of the controller passed to yao
92 
93  influ : (int) : optional, actuator index for the influence function
94 
95  compose_type : (str) : optional, possibility to specify split tomography case ("controller" or "splitTomo")
96  """
97  print("writing data to" + file_name)
98  hdul=fits.HDUList([])
99 
100  # setting list of wfs and dm
101  conf = sup.config
102  if(wfss_indices is None):
103  wfss_indices = np.arange(len(conf.p_wfss))
104  if(dms_indices is None):
105  dms_indices = []
106  for i in range(len(conf.p_dms)):
107  if( conf.p_dms[i].type != "tt"):
108  dms_indices.append(i)
109 
110  #cout the number of lgs
111  n_lgs = 0
112  for i in wfss_indices :
113  if(conf.p_wfss[i].get_gsalt() > 0):
114  n_lgs += 1
115 
116  #primary hdu contains only keywords for sanity check
117  hdu = fits.PrimaryHDU(np.zeros(1,dtype=np.int32))
118  hdu.header["DIAM"] = conf.p_tel.get_diam()
119  hdu.header["COBS"] = conf.p_tel.get_cobs()
120  hdu.header["NLGS"] = n_lgs
121  hdu.header["NNGS"] = len(wfss_indices) - n_lgs
122  hdu.header["NDM" ] = len(dms_indices)
123  hdu.header["PIXSIZE"] = conf.p_geom.get_pixsize()
124 
125  #add primary hdu to list
126  hdul.append(hdu)
127 
128  # add wfss
129  for i in wfss_indices:
130  hdul.append( wfs_to_fits_hdu(sup, i))
131 
132  # add dm
133  for i in dms_indices:
134  hdul.append(dm_to_fits_hdu(sup, i))
135  hdul.append(dm_influ_to_fits_hdu(sup, i, influ_index = influ))
136 
137  if(controller_id > -1):
138  # IMAT
139  interaction_mat=imat.compose_imat(sup, compose_type=compose_type,
140  controller_id=controller_id)
141  hdu_imat=fits.ImageHDU(interaction_mat,name="IMAT")
142 
143  # CMAT
144  hdu_cmat=fits.ImageHDU(sup.rtc.get_command_matrix(controller_id),
145  name="CMAT")
146 
147  print("\t* number of subaperture per WFS")
148  print("\t* subapertures position")
149  print("\t* number of actuator per DM")
150  print("\t* actuators position")
151  print("\t* Imat")
152  print("\t* Cmat")
153 
154  hdul.writeto(file_name, overwrite=1)
def write_data(file_name, sup, *wfss_indices=None, dms_indices=None, controller_id=0, influ=0, compose_type="controller")
Write data for yao compatibility.
Definition: fits.py:96
def wfs_to_fits_hdu(sup, wfs_id)
Return a fits Header Data Unit (HDU) representation of a single WFS.
Definition: fits.py:17
def dm_influ_to_fits_hdu(sup, dm_id, *influ_index=-1)
Return a fits Header Data Unit (HDU) holding the influence functions of a specific DM.
Definition: fits.py:60
def dm_to_fits_hdu(sup, dm_id)
Return a fits Header Data Unit (HDU) representation of a single DM.
Definition: fits.py:36