mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
directPhaseReconstructorOrtho.hpp
1 #ifndef directPhaseReconstructor_hpp
2 #define directPhaseReconstructor_hpp
3 
4 
5 #include "../../improc/eigenImage.hpp"
6 #include "../../improc/eigenCube.hpp"
7 #include "../../improc/fitsFile.hpp"
8 using namespace mx::improc;
9 
10 #include "../../sigproc/signalWindows.hpp"
11 
12 #ifdef DEBUG
13 #define BREAD_CRUMB std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
14 #else
15 #define BREAD_CRUMB
16 #endif
17 
18 namespace mx
19 {
20 namespace AO
21 {
22 namespace sim
23 {
24 
25 
26 struct directPhaseReconstructorSpec
27 {
28  std::string dmName;
29  std::string basisName;
30 
31  std::string rMatId;
32 };
33 
34 ///A Pyramid Wavefront Sensor slope reconstructor.
35 /** Calculates slopes, normalized by total flux in the image.
36  */
37 template<typename realT>
38 class directPhaseReconstructor
39 {
40 public:
41 
42  ///The type of the measurement (i.e. the slope vector)
43  //typedef Eigen::Array<realT,-1,-1> measurementT;
44 
45  ///The type of the WFS image
46  typedef Eigen::Array<realT, -1, -1> imageT;
47 
48  ///The type of the response matrix
49  typedef Eigen::Array<realT, -1, -1> rmatT;
50 
51  typedef directPhaseReconstructorSpec specT;
52 
53 protected:
54  Eigen::Array<realT,-1,-1> _recon; ///< The reconstructor matrix.
55 
56  int _nModes; ///<The number of modes to be reconstructed
57 
58  int _detRows; ///<The size of the WFS image, in rows
59  int _detCols;///<The size of the WFS image, in columns
60 
61  int _measurementSize; ///<The number of values in the measurement
62 
63  realT _calAmp; ///<The calibration amplitude used for response matrix acquisition
64 
65  imageT _rMat; ///<The response matrix
66 
67  eigenCube<realT> _rImages;
68 
69  //The mirror modes
71 
72 
73 
74 
75  imageT * _pupil;
76 
77 
78 
79  realT norm;
80 
81 public:
82 
83  //The orthogonalized basis
85 
86  //The orthogonal spectrum
88 
89  std::vector<realT> b;
90 
91  imageT _mask;
92 
94 
95  imageT * _gains;
96 
97  int _npix;
98 
99 public:
100  ///Default c'tor
102 
103  template<typename AOSysT>
104  void initialize(AOSysT & AOSys, specT & spec)
105  {
106 
107  _modes = &AOSys.dm._infF;
108 
109  _nModes = _modes->planes();
110  _detRows = _modes->rows();
111  _detCols = _modes->cols();
112 
113  _measurementSize = _detRows*_detCols;
114 
115  _pupil = &AOSys._pupil;
116 
117  _mask = *_pupil;
118  }
119 
120  template<typename AOSysT>
121  void linkSystem(AOSysT & AOSys);
122 
123  ///Get the calibration amplitude used in response matrix acquisition (_calAmp)
124  realT calAmp();
125 
126 
127  ///Set the calibration amplitude used in response matrix acquisition (_calAmp)
128  /**
129  * \param ca [in] the new calibration amplitude
130  */
131  void calAmp(realT ca);
132 
133  ///Get the number of modes (_nModes)
134  int nModes();
135 
136  ///Get the number of detector rows (_detRows)
137  int detRows();
138 
139  ///Set the number of detector rows (_detRows)
140  void detRows(int dr);
141 
142  ///Get the number of detector columns (_detCols)
143  int detCols();
144 
145  ///Set the number of detector columns (_detCols)
146  void detCols(int dc);
147 
148  ///Load the reconstrutor from the specified FITS file
149  /**
150  * \param fname is the name of the FITS file, including path
151  */
152  void loadRecon(const std::string & fname);
153 
154  ///Return the size of the unbinned measurement
156 
157 
158  ///Calculate the slope measurement
159  /**
160  * \param slopes [out] a (_measurementSize X 2) array of slopes
161  * \param wfsImage [in] the WFS image from which to measure the slopes
162  */
163  template<typename measurementT, typename wfsImageT>
164  void calcMeasurement(measurementT & slopes, wfsImageT & wfsImage);
165 
166  ///Reconstruct the wavefront from the input image, producing the modal amplitude vector
167  template<typename measurementT, typename wfsImageT>
168  void reconstruct(measurementT & commandVect, wfsImageT & wfsImage);
169 
170  ///Initialize the response matrix for acquisition
171  /**
172  * \param nmodes the number of modes
173  * \param calamp the calibration amplitude
174  * \param detrows the number of detector rows
175  * \param detcols the number of detector columns
176  */
177  void initializeRMat(int nmodes, realT calamp, int detrows,int detcols);
178 
179  ///Accumalte the next measurement in the response matrix
180  /**
181  * \param i the measurement index
182  * \param measureVec is the i-th measurement vector
183  */
184  template<typename measurementT>
185  void accumulateRMat(int i, measurementT &measureVec);
186 
187 
188  template<typename measurementT, typename wfsImageT>
189  void accumulateRMat(int i, measurementT &measureVec, wfsImageT & wfsImage);
190 
191 
192 
193 
194  ///Write the accumulated response matrix to disk
195  /**
196  * \param fname the name, including path, of the response matrix
197  */
198  void saveRMat(std::string fname);
199 
200  void saveRImages(std::string fname);
201 };
202 
203 
204 template<typename realT>
206 {
207  _nModes = 0;
208 
209  norm = 0;
210 
211  _gains =0;
212 
213  _npix = 0;
214 }
215 
216 template<typename realT>
217 template<typename AOSysT>
218 void directPhaseReconstructor<realT>::linkSystem(AOSysT & AOSys)
219 {
220  _modes = &AOSys.dm._modes;
221 
222  _nModes = _modes->planes();
223  _detRows = _modes->rows();
224  _detCols = _modes->cols();
225 
226  _measurementSize = _detRows*_detCols;
227 
228  _pupil = &AOSys._pupil;
229 
230  _mask = *_pupil;
231 }
232 
233 template<typename realT>
234 realT directPhaseReconstructor<realT>::calAmp()
235 {
236  return 0.5*780.0e-9/two_pi<realT>();
237 }
238 
239 template<typename realT>
240 void directPhaseReconstructor<realT>::calAmp(realT ca)
241 {
242  return;
243 }
244 
245 template<typename realT>
246 int directPhaseReconstructor<realT>::nModes()
247 {
248  return _nModes;
249 }
250 
251 template<typename realT>
252 int directPhaseReconstructor<realT>::detRows()
253 {
254  return _detRows;
255 }
256 
257 template<typename realT>
258 int directPhaseReconstructor<realT>::detCols()
259 {
260  return _detCols;
261 }
262 
263 template<typename realT>
264 void directPhaseReconstructor<realT>::loadRecon(const std::string & fname)
265 {
266 }
267 
268 template<typename realT>
269 int directPhaseReconstructor<realT>::measurementSize()
270 {
271  return _measurementSize;
272 }
273 
274 template<typename realT>
275 template<typename measurementT, typename wfsImageT>
276 void directPhaseReconstructor<realT>::calcMeasurement(measurementT & slopes, wfsImageT & wfsImage)
277 {
278 
279 }
280 
281 template<typename realT>
282 template<typename measurementT, typename wfsImageT>
283 void directPhaseReconstructor<realT>::reconstruct(measurementT & commandVect, wfsImageT & wfsImage)
284 {
285 
286  BREAD_CRUMB;
287 
288  if(_npix == 0)
289  {
290  _npix = _pupil->sum();
291 
292  }
293 
294  BREAD_CRUMB;
295 
296  wfsImage.image *= _mask;
297 
298  BREAD_CRUMB;
299 
300 
301 
302  b.resize(_nModes);
303 
304  #pragma omp parallel for
305  for(int j=0; j< _nModes; ++j)
306  {
307  b[j] = (wfsImage.image*ortho.image(j)).sum()/ _npix;
308  }
309 
310  //commandVect.measurement.setZero();
311 
312  //#pragma omp parallel for
313  for(int j=0; j< modes.planes(); ++j)
314  {
315  realT amp = b[0]*spectrum(0,j);
316 
317  for(int i=1;i<modes.planes();++i)
318  {
319  amp += b[i]*spectrum(i,j);
320  }
321  commandVect.measurement(0,j) = amp;
322  }
323 
324  //std::cerr << "--- " << b[0] << " " << b[0]*spectrum(0,0) << " " << commandVect.measurement(0,0) << "\n";
325  for(int k=0; k< _nModes; ++k)
326  {
327  std::cerr << commandVect.measurement(0,k) << " ";
328  }
329  std::cerr << "\n";
330 
331  commandVect.iterNo = wfsImage.iterNo;
332 }
333 
334 template<typename realT>
335 void directPhaseReconstructor<realT>::initializeRMat(int nModes, realT calamp, int detRows, int detCols)
336 {
337  _nModes = nModes;
338 
339  _detRows = detRows;
340  _detCols = detCols;
341 
342  _rMat.resize(measurementSize(), nModes);
343  _rMat.setZero();
344 
345  _rImages.resize(_detRows, _detCols, _nModes);
346 }
347 
348 template<typename realT>
349 template<typename measurementT>
350 void directPhaseReconstructor<realT>::accumulateRMat(int i, measurementT &measureVec)
351 {
352  int l = 0;
353  for(int j=0; j<measureVec.measurement.rows(); ++j)
354  {
355  for(int k=0; k<measureVec.measurement.cols(); ++k)
356  {
357  _rMat(l, i) = measureVec.measurement(j,k);
358  ++l;
359  }
360  }
361 
362  //_rMat.col(i) = measureVec.measurement.row(0);
363 }
364 
365 template<typename realT>
366 template<typename measurementT,typename wfsImageT>
367 void directPhaseReconstructor<realT>::accumulateRMat(int i, measurementT &measureVec, wfsImageT & wfsImage)
368 {
369  accumulateRMat(i, measureVec);
370  _rImages.image(i) = wfsImage.image;
371 }
372 
373 template<typename realT>
374 void directPhaseReconstructor<realT>::saveRMat(std::string fname)
375 {
376  fitsFile<realT> ff;
377  fitsHeader head;
378 
379  head.append("DETROWS", _detRows, "WFS detector rows");
380  head.append("DETCOLS", _detCols, "WFS detector cols");
381  head.append("CALAMP", _calAmp, "DM Calibration amplitude");
382  head.append("NMODES", _nModes, "Number of modes included in the response matrix.");
383 
384  ff.write(fname, _rMat, head);
385 }
386 
387 template<typename realT>
388 void directPhaseReconstructor<realT>::saveRImages(std::string fname)
389 {
390  fitsFile<realT> ff;
391  fitsHeader head;
392 
393 
394  head.append("DETROWS", _detRows, "WFS detector rows");
395  head.append("DETCOLS", _detCols, "WFS detector cols");
396  head.append("CALAMP", _calAmp, "DM Calibration amplitude");
397  head.append("NMODES", _nModes, "Number of modes included in the response matrix.");
398 
399  //ff.write(fname, _rImages.data(), _rImages.rows(), _rImages.cols(), _rImages.planes(), &head);
400  ff.write(fname, _rImages, head);
401 }
402 
403 } //namespace sim
404 } //namespace AO
405 } //namespace mx
406 
407 #endif //directPhaseReconstructor_hpp
408 
409 
410 //--- Code for mean and tip/tilt subtraction in reconstruct:
411 // realT mean = (wfsImage.image * *_pupil).sum()/npix;
412 //
413 // wfsImage.image -= mean;
414 // wfsImage.image *= *_pupil;
415 
416 #if 0
417 
418  BREAD_CRUMB;
419  if(norm == 0)
420  {
421  for(int i = 0; i < wfsImage.rows(); ++i)
422  {
423  for(int j=0; j < wfsImage.cols(); ++j)
424  {
425  norm += pow((i - 0.5*(wfsImage.rows()-1.0))*(*_pupil)(i,j),2);
426  }
427  }
428  BREAD_CRUMB;
429  norm = sqrt(norm);
430 
431  //std::cout << "NORM: === " << norm << "\n";
432  }
433  BREAD_CRUMB;
434 
435  //std::cout << "NORM: === " << norm << "\n";
436 
437  //Remove tip/tilt:
438  realT ampx = 0, ampy = 0;
439  BREAD_CRUMB;
440  for(int i = 0; i < wfsImage.rows(); ++i)
441  {
442  for(int j=0; j < wfsImage.cols(); ++j)
443  {
444  ampx += wfsImage(i,j) * (i - 0.5*(wfsImage.rows()-1.0))/norm;
445  ampy += wfsImage(i,j) * (j - 0.5*(wfsImage.cols()-1.0))/norm;
446  }
447  }
448  BREAD_CRUMB;
449  for(int i = 0; i < wfsImage.rows(); ++i)
450  {
451  for(int j=0; j < wfsImage.cols(); ++j)
452  {
453  wfsImage(i,j) -= ampx * (i - 0.5*(wfsImage.rows()-1.0))/norm * (*_pupil)(i,j);
454  wfsImage(i,j) -= ampy * (j - 0.5*(wfsImage.cols()-1.0))/norm * (*_pupil)(i,j);
455  }
456  }
457 #endif
458 
void saveRMat(std::string fname)
Write the accumulated response matrix to disk.
int detRows()
Get the number of detector rows (_detRows)
void loadRecon(const std::string &fname)
Load the reconstrutor from the specified FITS file.
void detCols(int dc)
Set the number of detector columns (_detCols)
Eigen::Array< realT, -1, -1 > imageT
The type of the WFS image.
realT _calAmp
The calibration amplitude used for response matrix acquisition.
int measurementSize()
Return the size of the unbinned measurement.
void calcMeasurement(measurementT &slopes, wfsImageT &wfsImage)
Calculate the slope measurement.
void initializeRMat(int nmodes, realT calamp, int detrows, int detcols)
Initialize the response matrix for acquisition.
realT calAmp()
Get the calibration amplitude used in response matrix acquisition (_calAmp)
directPhaseReconstructorSpec specT
The specificaion type.
void accumulateRMat(int i, measurementT &measureVec)
Accumalte the next measurement in the response matrix.
void reconstruct(measurementT &commandVect, wfsImageT &wfsImage)
Reconstruct the wavefront from the input image, producing the modal amplitude vector.
Eigen::Array< realT, -1, -1 > rmatT
The type of the response matrix.
int detCols()
Get the number of detector columns (_detCols)
void calAmp(realT ca)
Set the calibration amplitude used in response matrix acquisition (_calAmp)
int nModes()
Get the number of modes (_nModes)
void detRows(int dr)
Set the number of detector rows (_detRows)
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > image(Index n)
Returns a 2D Eigen::Eigen::Map pointed at the specified image.
Definition: eigenCube.hpp:376
constexpr units::realT k()
Boltzmann Constant.
Definition: constants.hpp:71
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
Definition: eigenImage.hpp:44
The mxlib c++ namespace.
Definition: mxError.hpp:107