mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
pyramidSensorSepQuad.hpp
Go to the documentation of this file.
1/** \file
2 * \author Jared R. Males (jaredmales@gmail.com)
3 * \brief
4 * \ingroup mxAO_sim_files
5 *
6 */
7
8#ifndef __pyramidSensor_hpp__
9#define __pyramidSensor_hpp__
10
11#include "mx/imagingUtils.hpp"
12#include "mx/fraunhoferImager.hpp"
13#include "mx/timeUtils.hpp"
14#include "mx/fitsFile.hpp"
15// #include "mx/ds9_interface.h"
16#include "../../math/constants.hpp"
17
18#include "wavefront.hpp"
19
20#include "mx/imageTransforms.hpp"
21
22#ifdef DEBUG
23#define BREAD_CRUMB std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
24#else
25#define BREAD_CRUMB
26#endif
27
28namespace mx
29{
30namespace AO
31{
32namespace sim
33{
34
35template <typename _floatT, typename _detectorT>
36class pyramidSensor
37{
38 public:
39 typedef _floatT floatT;
40
41 typedef std::complex<floatT> complexT;
42
43 /// The wavefront data type
45
46 /// The wavefront complex field type
47 typedef mx::imagingArray<std::complex<floatT>, fftwAllocator<std::complex<floatT>>, 0> complexFieldT;
48
49 /// The wavefront sensor detector image type
50 typedef Eigen::Array<floatT, Eigen::Dynamic, Eigen::Dynamic> wfsImageT;
51
52 typedef _detectorT detectorT;
53
54 protected:
55 /* Standard WFS Interface: */
56 int _wfSz; ///< Size of the wavefront in pixels
57
58 int _detRows; ///< The number of rows of the WFS detector. After forming the image the WFS detector plane is
59 ///< re-binned to this.
60 int _detCols; ///< The number of columns of the WFS detector. After forming the image the WFS detector plane is
61 ///< re-binned to this.
62
63 floatT _lambda; ///< Central wavelength, in meters
64
65 int _iTime; ///< Integration time in loop steps
66
67 int _roTime; ///< Readout time in loop steps
68
69 floatT _simStep; ///< The simulation stepsize in seconds.
70
71 /* PyWFS Specific: */
72
73 floatT _wfPS; ///< Wavefront pixel scale, in meters/pixel
74
75 floatT _D; ///< Telescope diameter, in meters
76
77 int _modSteps; ///< Number of steps in the modulation simulation
78
79 floatT _modRadius; ///< Radius of the modulation in pixels
80
81 int _quadSz; ///< The size of the PyWFS quadrant
82
83 mx::fraunhoferImager<complexFieldT> fi;
84
85 bool tiltsMade;
86 std::vector<complexFieldT> tilts;
87
88 int _iTime_counter;
89
90 int _reading;
91
92 int _roTime_counter;
93
94 std::vector<wavefrontT> _wavefronts;
95
96 int _lastWavefront;
97
98 ds9_interface ds9i;
99
100 public:
101 /// Default c'tor
103
104 /* The standard WFS interface: */
105
107
108 /// The image on the detector, resized from wfsImage
110
111 /// Get the wavefront size in pixels
112 /**
113 * \returns the wavefront size in pixels
114 */
115 int wfSz();
116
117 /// Set the wavefront size in pixels.
118 /**
119 * \param sz is the new size
120 */
121 void wfSz( int sz );
122
123 /// Get the detector rows in pixels
124 /**
125 * \returns _detRows
126 */
127 int detRows();
128
129 /// Get the detector columns in pixels
130 /**
131 * \returns _detCols
132 */
133 int detCols();
134
135 /// Set the detector columns in pixels.
136 /**
137 * \param sz is the new size
138 */
139 void detSize( int nrows, int ncols );
140
141 /// Get the PyWFS central wavelength
142 /**
143 * \returns the central wavelength in meters
144 */
145 floatT lambda();
146
147 /// Set the PyWFS central wavelength
148 /**
149 * \param d is the new central wavelength in meters
150 */
151 void lambda( floatT l );
152
153 /// Get the PyWFS integration time, in time steps
154 int iTime();
155
156 /// Set the PyWFS integration time, in time steps
157 void iTime( int it );
158
159 /// Get the PyWFS detector readout time, in time steps
160 int roTime();
161
162 /// Set the PyWFS detector readout time, in time steps
163 void roTime( int rt );
164
165 /// Get the simulation step-size, in seconds.
166 floatT simStep();
167
168 /// Set the simulation step-size, in seconds.
169 void simStep( floatT st );
170
171 template <typename AOSysT>
172 void linkSystem( AOSysT &AOSys );
173
174 /// Sense the wavefront aberrations
175 /** Returns true if a new wavefront measurement is ready.
176 * Retruns false if still integrating.
177 */
178 bool senseWavefront( wavefrontT &pupilPlane );
179
180 /// Sense the wavefront aberrations in a calibration mode
181 /** Allows for faster calibrations.
182 */
183 bool senseWavefrontCal( wavefrontT &pupilPlane );
184
185 /* The PyWFS Specific Interface */
186
187 /// Get the wavefront pixel scale in meters per pixel
188 /**
189 * \returns the wavefront pixel scale in meters/pixel
190 */
191 int wfPS();
192
193 /// Set the wavefront pixel scale in meters per pixel
194 /**
195 * \param ps is the pixel scale
196 */
197 void wfPS( floatT ps );
198
199 /// Get the telescope diameter
200 /**
201 * \returns the telescope diameter in meters
202 */
203 floatT D();
204
205 /// Set the telescope diameter
206 /**
207 * \param d is the new size in meters
208 */
209 void D( floatT d );
210
211 /// Get the number of modulation steps
212 /**
213 * \returns _modSteps;
214 */
215 int modSteps();
216
217 /// Set the number of modulation steps
218 /**
219 * \param mSt is the new number of modulation steps
220 */
221 void modSteps( int mSt );
222
223 /// Get the radius of modulation
224 /**
225 * \returns _modRadius;
226 */
227 floatT modRadius();
228
229 /// Set the modulation radius
230 /**
231 * \param mR is the new modulation radius in lambda/D
232 */
233 void modRadius( floatT mR );
234
235 /// Get the quadrant size in pixels
236 /** This is the size of the quadrant in un-binned wavefront space
237 *
238 *
239 * \returns _quadSz
240 */
241 int quadSz();
242
243 /// Set the quadrant size in pixels.
244 /** This is the size of the quadrant in un-binned wavefront space
245 * It should be at least the size of the Pupil. Make larger than the pupil
246 * to have smaller pupil images on the PyWFS detector.
247 *
248 * \param sz is the new size
249 */
250 void quadSz( int sz );
251
252 protected:
253 /// The image formed by the WFS
255
256 void makeTilts();
257
258 void doSenseWavefront();
259 void doSenseWavefrontNoMod( wavefrontT & );
260
261 bool firstRun;
262};
263
264template <typename _floatT, typename _detectorT>
266{
267 _wfSz = 0;
268 _detRows = 0;
269 _detCols = 0;
270 _lambda = 0;
271
272 _modSteps = 16;
273 _modRadius = 16;
274
275 iTime( 1 );
276 _iTime_counter = 0;
277
278 _reading = 0;
279 _roTime = 1;
280 _roTime_counter = 0;
281
282 _simStep = 0.001;
283
284 tiltsMade = false;
285
286 firstRun = true;
287
288 ds9_interface_init( &ds9i );
289 ds9_interface_set_title( &ds9i, "PyWFS" );
290}
291
292template <typename _floatT, typename _detectorT>
294{
295 return _wfSz;
296}
297
298template <typename _floatT, typename _detectorT>
300{
301 if( _wfSz == sz )
302 return;
303
304 _wfSz = sz;
305
306 fi.setWavefrontSizePixels( _wfSz );
307
308 tiltsMade = false;
309}
310
311template <typename _floatT, typename _detectorT>
313{
314 return _detRows;
315}
316
317template <typename _floatT, typename _detectorT>
319{
320 return _detCols;
321}
322
323template <typename _floatT, typename _detectorT>
325{
326 if( _detRows == nrows && _detCols == ncols )
327 return;
328
329 _detRows = nrows;
330 _detCols = ncols;
331
332 detector.setSize( _detRows, _detCols );
333 detectorImage.resize( _detRows, _detCols );
334}
335
336template <typename _floatT, typename _detectorT>
338{
339 return _lambda;
340}
341
342template <typename _floatT, typename _detectorT>
344{
345 _lambda = l;
346}
347
348template <typename _floatT, typename _detectorT>
349template <typename AOSysT>
351{
352 AOSys.wfs.wfPS( AOSys._wfPS );
353 AOSys.wfs.D( AOSys._D );
354}
355
356template <typename _floatT, typename _detectorT>
358{
359 return _wfPS;
360}
361
362template <typename _floatT, typename _detectorT>
364{
365 _wfPS = ps;
366}
367
368template <typename _floatT, typename _detectorT>
370{
371 return _D;
372}
373
374template <typename _floatT, typename _detectorT>
376{
377 _D = d;
378}
379
380template <typename _floatT, typename _detectorT>
382{
383 return _modSteps;
384}
385
386template <typename _floatT, typename _detectorT>
388{
389 _modSteps = mSt;
390
391 tiltsMade = false;
392}
393
394template <typename _floatT, typename _detectorT>
396{
397 return _modRadius; // * mx::fftPlateScale(_wfSz, _wfPS, _lambda)/(_lambda/D);
398}
399
400template <typename _floatT, typename _detectorT>
402{
403 _modRadius = mR; // (_lambda/D)/mx::fftPlateScale(_wfSz, _wfPS, _lambda);
404
405 tiltsMade = false;
406}
407
408template <typename _floatT, typename _detectorT>
410{
411 return _quadSz;
412}
413
414template <typename _floatT, typename _detectorT>
416{
417 if( _quadSz == sz )
418 return;
419
420 _quadSz = sz;
421
422 wfsImage.resize( 2 * _quadSz, 2 * _quadSz );
423}
424
425template <typename _floatT, typename _detectorT>
427{
428 constexpr _floatT pi = math::pi<_floatT>();
429
430 _floatT dang = 2 * pi / _modSteps;
431 _floatT dx, dy;
432
433 tilts.resize( _modSteps );
434
435 std::cout << "WF Size: " << _wfSz << "\n";
436 std::cout << "WF PS: " << _wfPS << "\n";
437 std::cout << "Lambda: " << _lambda << "\n";
438
439 std::cout << "Pyr. PS: " << mx::fftPlateScale<floatT>( _wfSz, _wfPS, _lambda ) * 206265. << " (mas/pix)\n";
440 std::cout << "Mod rad: " << _modRadius * ( _lambda / _D ) / mx::fftPlateScale<floatT>( _wfSz, _wfPS, _lambda )
441 << " (pixels)\n";
442
443 for( int i = 0; i < _modSteps; ++i )
444 {
445 dx = _modRadius * ( _lambda / _D ) / mx::fftPlateScale<floatT>( _wfSz, _wfPS, _lambda ) *
446 cos( 0.5 * dang + dang * i );
447 dy = _modRadius * ( _lambda / _D ) / mx::fftPlateScale<floatT>( _wfSz, _wfPS, _lambda ) *
448 sin( 0.5 * dang + dang * i );
449
450 tilts[i].resize( _wfSz, _wfSz );
451 tilts[i].set( std::complex<_floatT>( 0, 1 ) );
452
453 tiltWavefront( tilts[i], dx, dy );
454 }
455
456 tiltsMade = true;
457}
458
459template <typename _floatT, typename _detectorT>
461{
462 return _iTime;
463}
464
465template <typename _floatT, typename _detectorT>
467{
468 if( it < 1 )
469 {
470 std::cerr << "iTime must be >= 1. Correcting\n";
471 it = 1;
472 }
473
474 _iTime = it;
475
476 _wavefronts.resize( _iTime + 2 );
477 _lastWavefront = -1;
478
479 detector.expTime( _simStep * _iTime );
480}
481
482template <typename _floatT, typename _detectorT>
484{
485 return roTime;
486}
487
488template <typename _floatT, typename _detectorT>
490{
491 if( rt < 1 )
492 {
493 std::cerr << "roTime must be >= 1. Correcting\n";
494 rt = 1;
495 }
496
497 _roTime = rt;
498}
499
500template <typename _floatT, typename _detectorT>
502{
503 return simStep;
504}
505
506template <typename _floatT, typename _detectorT>
508{
509
510 _simStep = st;
511
512 detector.expTime( _simStep * _iTime );
513}
514
515template <typename _floatT, typename _detectorT>
516bool pyramidSensor<_floatT, _detectorT>::senseWavefront( wavefrontT &pupilPlane )
517{
518
519 ++_lastWavefront;
520 if( _lastWavefront >= _wavefronts.size() )
521 _lastWavefront = 0;
522 _wavefronts[_lastWavefront].amplitude = pupilPlane.amplitude;
523 _wavefronts[_lastWavefront].phase = pupilPlane.phase;
524
525 // Always skip the first one for averaging to center of iTime.
526 if( firstRun )
527 {
528 firstRun = false;
529 return false;
530 }
531
532 ++_iTime_counter;
533
534 bool rv = false;
535
536 if( _reading )
537 {
538 ++_roTime_counter;
539
540 if( _roTime_counter >= _roTime )
541 {
542 std::cerr << "PyWFS: reading\n";
543 detector.exposeImage( detectorImage, wfsImage );
544 ds9_interface_display_raw( &ds9i,
545 1,
546 detectorImage.data(),
547 detectorImage.rows(),
548 detectorImage.cols(),
549 1,
550 mx::getFitsBITPIX<floatT>() );
551
552 _roTime_counter = 0;
553 _reading = 0;
554 rv = true;
555 }
556 }
557
558 if( _iTime_counter >= _iTime )
559 {
560 std::cerr << "PyWFS: sensing\n";
561 doSenseWavefront();
562 _iTime_counter = 0;
563
564 _reading = 1;
565 _roTime_counter = 0;
566 }
567
568 return rv;
569}
570
571template <typename _floatT, typename _detectorT>
573{
574
575 _lastWavefront = 1;
576
577 _wavefronts[0].amplitude = pupilPlane.amplitude;
578 _wavefronts[0].phase = pupilPlane.phase;
579
580 _wavefronts[1].amplitude = pupilPlane.amplitude;
581 _wavefronts[1].phase = pupilPlane.phase;
582
583 doSenseWavefront();
584
585 detector.exposeImage( detectorImage, wfsImage );
586
587 // ds9_interface_display_raw( &ds9i, 1, detectorImage.data(), detectorImage.rows(), detectorImage.cols(),1,
588 // mx::getFitsBITPIX<floatT>());
589
590 return true;
591}
592
593template <typename _floatT, typename _detectorT>
594void pyramidSensor<_floatT, _detectorT>::doSenseWavefront()
595{
596 constexpr _floatT pi = math::pi<_floatT>();
597
598 if( tiltsMade == false )
599 makeTilts();
600
601 // std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
602 BREAD_CRUMB;
603
604 wavefrontT pupilPlane;
605
606 /* Here make average wavefront for now */
607 int _firstWavefront = _lastWavefront - _iTime;
608 if( _firstWavefront < 0 )
609 _firstWavefront += _wavefronts.size();
610
611 pupilPlane.amplitude = _wavefronts[_firstWavefront].amplitude;
612 pupilPlane.phase = _wavefronts[_firstWavefront].phase;
613
614 // std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
615 BREAD_CRUMB;
616
617 for( int i = 0; i < _iTime; ++i )
618 {
619 ++_firstWavefront;
620 if( _firstWavefront >= _wavefronts.size() )
621 _firstWavefront = 0;
622
623 pupilPlane.amplitude += _wavefronts[_firstWavefront].amplitude;
624 pupilPlane.phase += _wavefronts[_firstWavefront].phase;
625 }
626
627 pupilPlane.amplitude /= ( _iTime + 1 );
628 pupilPlane.phase /= ( _iTime + 1 );
629
630 /*=====================================*/
631
632 if( _modRadius == 0 )
633 return doSenseWavefrontNoMod( pupilPlane );
634
635 // std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
636 BREAD_CRUMB;
637
638 wfsImage.resize( 2 * _quadSz, 2 * _quadSz );
639 wfsImage.setZero();
640
641 complexFieldT pupilPlaneCF;
642 pupilPlane.getWavefront( pupilPlaneCF, _wfSz );
643
644 complexFieldT focalPlaneCF;
645 focalPlaneCF.resize( _wfSz, _wfSz );
646
647#pragma omp parallel
648 {
649 complexFieldT tiltedPlane;
650 complexFieldT focalPlane;
651 complexFieldT sensorPlane;
652 complexFieldT temp_ul;
653 complexFieldT temp_ur;
654 complexFieldT temp_ll;
655 complexFieldT temp_lr;
656
657 wfsImageT sensorImage;
658
659 tiltedPlane.resize( _wfSz, _wfSz );
660 focalPlane.resize( _wfSz, _wfSz );
661 sensorPlane.resize( _wfSz, _wfSz );
662
663 temp_ul.resize( _wfSz, _wfSz );
664 temp_ul.set( (complexT)0 );
665
666 temp_ur.resize( _wfSz, _wfSz );
667 temp_ur.set( (complexT)0 );
668
669 temp_ll.resize( _wfSz, _wfSz );
670 temp_ll.set( (complexT)0 );
671
672 temp_lr.resize( _wfSz, _wfSz );
673 temp_lr.set( (complexT)0 );
674
675 // sensorImage.resize(_wfSz, _wfSz);
676 sensorImage.resize( _quadSz * 2, _quadSz * 2 );
677 sensorImage.setZero();
678
679 int dSz = ( 0.5 * _wfSz - 0.5 * _quadSz + 2 * _quadSz ) - _wfSz;
680 if( dSz < 0 )
681 dSz = 0;
682
683#pragma omp for
684 for( int i = 0; i < _modSteps; ++i )
685 {
686 int nelem = _wfSz * _wfSz;
687
688 complexT *tp_data = tiltedPlane.data();
689 complexT *pp_data = pupilPlaneCF.data();
690 complexT *ti_data = tilts[i].data();
691
692 for( int ii = 0; ii < nelem; ++ii )
693 {
694 tp_data[ii] = pp_data[ii] * ti_data[ii];
695 }
696
697 fi.propagatePupilToFocal( focalPlane, tiltedPlane );
698 temp_ul.set( complexT( 0, 0 ) );
699 extractBlock( temp_ul, 0, 0.5 * _wfSz, 0, 0.5 * _wfSz, focalPlane, 0, 0 );
700
701 fi.propagateFocalToPupil( sensorPlane, temp_ul );
702 extractIntensityImageAccum( sensorImage,
703 0,
704 2 * _quadSz - dSz,
705 0,
706 2 * _quadSz - dSz,
707 sensorPlane,
708 0.5 * _wfSz - 0.5 * _quadSz,
709 0.5 * _wfSz - 0.5 * _quadSz );
710
711 temp_ur.set( complexT( 0, 0 ) );
712 extractBlock( temp_ur, 0.5 * _wfSz, 0.5 * _wfSz, 0, 0.5 * _wfSz, focalPlane, 0.5 * _wfSz, 0 );
713 fi.propagateFocalToPupil( sensorPlane, temp_ur );
714 extractIntensityImageAccum( sensorImage,
715 dSz,
716 2 * _quadSz - dSz,
717 0,
718 2 * _quadSz - dSz,
719 sensorPlane,
720 0.5 * _wfSz - 1.5 * _quadSz + dSz,
721 0.5 * _wfSz - 0.5 * _quadSz );
722
723 temp_ll.set( complexT( 0, 0 ) );
724 extractBlock( temp_ll, 0, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, focalPlane, 0, 0.5 * _wfSz );
725 fi.propagateFocalToPupil( sensorPlane, temp_ll );
726 extractIntensityImageAccum( sensorImage,
727 0,
728 2 * _quadSz - dSz,
729 dSz,
730 2 * _quadSz - dSz,
731 sensorPlane,
732 0.5 * _wfSz - 0.5 * _quadSz,
733 0.5 * _wfSz - 1.5 * _quadSz + dSz );
734
735 temp_lr.set( complexT( 0, 0 ) );
737 temp_lr, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, focalPlane, 0.5 * _wfSz, 0.5 * _wfSz );
738 fi.propagateFocalToPupil( sensorPlane, temp_lr );
739 extractIntensityImageAccum( sensorImage,
740 dSz,
741 2 * _quadSz - dSz,
742 dSz,
743 2 * _quadSz - dSz,
744 sensorPlane,
745 0.5 * _wfSz - 1.5 * _quadSz + dSz,
746 0.5 * _wfSz - 1.5 * _quadSz + dSz );
747
748 } // for
749
750 BREAD_CRUMB;
751
752 // std::cerr << wfsImage.rows() << " " << wfsImage.cols() << "\n";
753 // std::cerr << sensorImage.rows() << " " << sensorImage.cols() << "\n";
754
755#pragma omp critical
756 {
757 wfsImage += sensorImage;
758 }
759
760 } // #pragma omp parallel
761
762 BREAD_CRUMB;
763
764 wfsImage /= _modSteps;
765}
766
767template <typename _floatT, typename _detectorT>
768void pyramidSensor<_floatT, _detectorT>::doSenseWavefrontNoMod( wavefrontT &pupilPlane )
769{
770 constexpr _floatT pi = math::pi<_floatT>();
771
772 BREAD_CRUMB;
773
774 wfsImage.resize( 2 * _quadSz, 2 * _quadSz );
775 wfsImage.setZero();
776
777 complexFieldT pupilPlaneCF;
778 pupilPlane.getWavefront( pupilPlaneCF, _wfSz );
779
780 complexFieldT focalPlaneCF;
781 focalPlaneCF.resize( _wfSz, _wfSz );
782
783 complexFieldT tiltedPlane;
784 complexFieldT focalPlane;
785 complexFieldT sensorPlane;
786 complexFieldT temp_ul;
787 complexFieldT temp_ur;
788 complexFieldT temp_ll;
789 complexFieldT temp_lr;
790
791 wfsImageT sensorImage;
792
793 tiltedPlane.resize( _wfSz, _wfSz );
794 focalPlane.resize( _wfSz, _wfSz );
795 sensorPlane.resize( _wfSz, _wfSz );
796
797 temp_ul.resize( _wfSz, _wfSz );
798 temp_ul.set( (complexT)0 );
799
800 temp_ur.resize( _wfSz, _wfSz );
801 temp_ur.set( (complexT)0 );
802
803 temp_ll.resize( _wfSz, _wfSz );
804 temp_ll.set( (complexT)0 );
805
806 temp_lr.resize( _wfSz, _wfSz );
807 temp_lr.set( (complexT)0 );
808
809 sensorImage.resize( _quadSz * 2, _quadSz * 2 );
810 sensorImage.setZero();
811
812 int dSz = ( 0.5 * _wfSz - 0.5 * _quadSz + 2 * _quadSz ) - _wfSz;
813 if( dSz < 0 )
814 dSz = 0;
815 int nelem = _wfSz * _wfSz;
816
817 complexT *tp_data = tiltedPlane.data();
818 complexT *pp_data = pupilPlaneCF.data();
819
820 BREAD_CRUMB;
821 for( int ii = 0; ii < nelem; ++ii )
822 {
823 tp_data[ii] = pp_data[ii]; //*ti_data[ii];
824 }
825
826 BREAD_CRUMB;
827
828 fi.propagatePupilToFocal( focalPlane, tiltedPlane );
829 temp_ul.set( complexT( 0, 0 ) );
830 extractBlock( temp_ul, 0, 0.5 * _wfSz, 0, 0.5 * _wfSz, focalPlane, 0, 0 );
831
832 fi.propagateFocalToPupil( sensorPlane, temp_ul );
833 extractIntensityImageAccum( sensorImage,
834 0,
835 2 * _quadSz - dSz,
836 0,
837 2 * _quadSz - dSz,
838 sensorPlane,
839 0.5 * _wfSz - 0.5 * _quadSz,
840 0.5 * _wfSz - 0.5 * _quadSz );
841
842 temp_ur.set( complexT( 0, 0 ) );
843 extractBlock( temp_ur, 0.5 * _wfSz, 0.5 * _wfSz, 0, 0.5 * _wfSz, focalPlane, 0.5 * _wfSz, 0 );
844 fi.propagateFocalToPupil( sensorPlane, temp_ur );
845 extractIntensityImageAccum( sensorImage,
846 dSz,
847 2 * _quadSz - dSz,
848 0,
849 2 * _quadSz - dSz,
850 sensorPlane,
851 0.5 * _wfSz - 1.5 * _quadSz + dSz,
852 0.5 * _wfSz - 0.5 * _quadSz );
853
854 temp_ll.set( complexT( 0, 0 ) );
855 extractBlock( temp_ll, 0, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, focalPlane, 0, 0.5 * _wfSz );
856 fi.propagateFocalToPupil( sensorPlane, temp_ll );
857 extractIntensityImageAccum( sensorImage,
858 0,
859 2 * _quadSz - dSz,
860 dSz,
861 2 * _quadSz - dSz,
862 sensorPlane,
863 0.5 * _wfSz - 0.5 * _quadSz,
864 0.5 * _wfSz - 1.5 * _quadSz + dSz );
865
866 temp_lr.set( complexT( 0, 0 ) );
867 extractBlock( temp_lr, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, 0.5 * _wfSz, focalPlane, 0.5 * _wfSz, 0.5 * _wfSz );
868 fi.propagateFocalToPupil( sensorPlane, temp_lr );
869 extractIntensityImageAccum( sensorImage,
870 dSz,
871 2 * _quadSz - dSz,
872 dSz,
873 2 * _quadSz - dSz,
874 sensorPlane,
875 0.5 * _wfSz - 1.5 * _quadSz + dSz,
876 0.5 * _wfSz - 1.5 * _quadSz + dSz );
877
878 BREAD_CRUMB;
879
880 wfsImage += sensorImage;
881
882 BREAD_CRUMB;
883}
884
885} // namespace sim
886} // namespace AO
887} // namespace mx
888
889#endif //__pyramidSensor_hpp__
A Pyramid Sensor Simulation.
int roTime()
Get the PyWFS detector readout time, in time steps.
realT lambda()
Get the PyWFS central wavelength.
floatT _simStep
The simulation stepsize in seconds.
floatT D()
Get the telescope diameter.
int _modSteps
Number of steps in the modulation simulation.
wfsImageT wfsImage
The image formed by the WFS.
int wfSz()
Get the wavefront size in pixels.
int _wfSz
Size of the wavefront in pixels.
realT simStep()
Get the simulation step-size, in seconds.
int _roTime
Readout time in loop steps.
mx::imagingArray< std::complex< floatT >, fftwAllocator< std::complex< floatT > >, 0 > complexFieldT
The wavefront complex field type.
int wfPS()
Get the wavefront pixel scale in meters per pixel.
pyramidSensor()
Default c'tor.
void detSize(const uint32_t &nrows, const uint32_t &ncols)
Set the detector columns in pixels.
int iTime()
Get the PyWFS integration time, in time steps.
floatT _wfPS
Wavefront pixel scale, in meters/pixel.
int _iTime
Integration time in loop steps.
floatT modRadius()
Get the radius of modulation.
void linkSystem(AOSysT &AOSys)
Link this WFS to an AO system simulation.
realT wfPS()
Get the wavefront pixel scale in meters per pixel.
int wfSz()
Get the wavefront size in pixels.
uint32_t detCols()
Get the detector columns in pixels.
int modSteps()
Get the number of modulation steps.
int roTime()
Get the PyWFS detector readout time, in time steps.
int modSteps()
Get the number of modulation steps.
floatT _lambda
Central wavelength, in meters.
int iTime()
Get the PyWFS integration time, in time steps.
floatT simStep()
Get the simulation step-size, in seconds.
wavefront< floatT > wavefrontT
The wavefront data type.
int quadSz()
Get the quadrant size in pixels.
bool senseWavefront(wavefrontT &pupilPlane)
Sense the wavefront aberrations.
uint32_t detRows()
Get the detector rows in pixels.
floatT _D
Telescope diameter, in meters.
floatT _modRadius
Radius of the modulation in pixels.
int detRows()
Get the detector rows in pixels.
realT modRadius()
Get the radius of modulation.
std::complex< realT > complexT
The complex floating point type used for calculations.
bool senseWavefrontCal(wavefrontT &pupilPlane)
Sense the wavefront aberrations in calibration mode.
int detCols()
Get the detector columns in pixels.
bool senseWavefront(wavefrontT &pupilPlane)
Sense the wavefront aberrations.
realT D()
Get the telescope diameter.
_detectorT detectorT
The wavefront sensor detector image type.
bool senseWavefrontCal(wavefrontT &pupilPlane)
Sense the wavefront aberrations in a calibration mode.
floatT lambda()
Get the PyWFS central wavelength.
int _quadSz
The size of the PyWFS quadrant.
detectorT detector
The WFS detector.
Eigen::Array< floatT, Eigen::Dynamic, Eigen::Dynamic > wfsImageT
The wavefront sensor detector image type.
wfsImageT detectorImage
The image on the detector, resized from wfsImage.
constexpr T pi()
Get the value of pi.
Definition constants.hpp:55
constexpr floatT six_fifths()
Return 6/5 in the specified precision.
void extractBlock(imageT1 &dest, int imX0, int imXsz, int imY0, int imYsz, imageT2 &src, int wfX0, int wfY0)
Extract a block from one image and insert it into a second.
The mxlib c++ namespace.
Definition mxError.hpp:40
Structure containing the phase and amplitude of a wavefront.
Definition wavefront.hpp:24