8#ifndef directPhaseSensor_hpp
9#define directPhaseSensor_hpp
11#include "../../math/randomT.hpp"
13#include "../../ioutils/fits/fitsFile.hpp"
14#include "../../improc/eigenCube.hpp"
17#include "../../sigproc/psdFilter.hpp"
19#include "wavefront.hpp"
22#define BREAD_CRUMB std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
34template <
typename _realT>
42 typedef Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> imageT;
47template <
typename _realT,
typename _detectorT>
48class directPhaseSensor
53 typedef std::complex<_realT> complexT;
56 typedef wavefront<_realT> wavefrontT;
59 typedef improc::eigenImage<realT> pupilT;
62 typedef mx::wfp::imagingArray<std::complex<_realT>, mx::wfp::fftwAllocator<std::complex<_realT>>, 0> complexFieldT;
64 typedef _detectorT detectorT;
86 realT m_simStep{ 0.001 };
93 int m_iTime_counter{ 0 };
97 int m_roTime_counter{ 0 };
99 bool m_firstRun{
true };
101 std::vector<wavefrontT> m_wavefronts;
106 wfsImageT<realT> m_wfsImage;
109 bool m_poissonNoise{
true };
116 detectorT m_detector;
119 wfsImageT<realT> m_detectorImage;
140 void detRows(
int sz );
152 void detCols(
int sz );
158 void detSize(
int nrows,
int ncols );
170 void lambda( realT l );
176 void iTime(
int it );
182 void roTime(
int rt );
188 void simStep( realT st );
199 void npix( realT np );
210 void Fbg( realT bg );
212 template <
typename AOSysT>
213 void linkSystem( AOSysT &AOSys );
219 int recordWavefront( wavefrontT &pupilPlane );
225 bool senseWavefront( wavefrontT &pupilPlane );
230 bool senseWavefrontCal( wavefrontT &pupilPlane );
232 void doSenseWavefront();
238 bool m_applyFilter{
false };
243 sigproc::psdFilter<realT, 2> m_filter;
247 void applyFilter(
bool af );
261 void filterWidth(
int width );
273 const sigproc::psdFilter<realT, 2> &filter();
284 norm_distT m_normVar;
285 poisson_distT m_poissonVar;
297 pupilT *m_pupil{
nullptr };
300 typename wfsImageT<realT>::imageT m_noiseIm;
304 void beta_p( realT bp );
315 void pupil( pupilT *pupil );
320 void pupil( pupilT &pupil );
331template <
typename _realT,
typename _detectorT>
332directPhaseSensor<_realT, _detectorT>::directPhaseSensor()
340template <
typename _realT,
typename _detectorT>
341int directPhaseSensor<_realT, _detectorT>::wfSz()
346template <
typename _realT,
typename _detectorT>
347void directPhaseSensor<_realT, _detectorT>::wfSz(
int sz )
355template <
typename _realT,
typename _detectorT>
356int directPhaseSensor<_realT, _detectorT>::detRows()
361template <
typename _realT,
typename _detectorT>
362int directPhaseSensor<_realT, _detectorT>::detCols()
367template <
typename _realT,
typename _detectorT>
368void directPhaseSensor<_realT, _detectorT>::detSize(
int nrows,
int ncols )
370 if( m_detRows == nrows && m_detCols == ncols )
376 m_detector.setSize( m_detRows, m_detCols );
377 m_detectorImage.image.resize( m_detRows, m_detCols );
380template <
typename _realT,
typename _detectorT>
381_realT directPhaseSensor<_realT, _detectorT>::lambda()
386template <
typename _realT,
typename _detectorT>
387void directPhaseSensor<_realT, _detectorT>::lambda( _realT l )
392template <
typename _realT,
typename _detectorT>
393template <
typename AOSysT>
394void directPhaseSensor<_realT, _detectorT>::linkSystem( AOSysT &AOSys )
396 static_cast<void>( AOSys );
399template <
typename _realT,
typename _detectorT>
400int directPhaseSensor<_realT, _detectorT>::iTime()
405template <
typename _realT,
typename _detectorT>
406void directPhaseSensor<_realT, _detectorT>::iTime(
int it )
410 std::cerr <<
"iTime must be >= 1. Correcting\n";
416 m_wavefronts.resize( m_iTime + 2 + 100 );
417 m_lastWavefront = -1;
419 m_detector.expTime( m_simStep * m_iTime );
422template <
typename _realT,
typename _detectorT>
423int directPhaseSensor<_realT, _detectorT>::roTime()
428template <
typename _realT,
typename _detectorT>
429void directPhaseSensor<_realT, _detectorT>::roTime(
int rt )
433 std::cerr <<
"roTime must be >= 1. Correcting\n";
440template <
typename _realT,
typename _detectorT>
441_realT directPhaseSensor<_realT, _detectorT>::simStep()
446template <
typename _realT,
typename _detectorT>
447void directPhaseSensor<_realT, _detectorT>::simStep( _realT st )
452 m_detector.expTime( m_simStep * m_iTime );
455template <
typename realT,
typename _detectorT>
456realT directPhaseSensor<realT, _detectorT>::npix()
461template <
typename realT,
typename _detectorT>
462void directPhaseSensor<realT, _detectorT>::npix( realT np )
467template <
typename realT,
typename _detectorT>
468realT directPhaseSensor<realT, _detectorT>::Fbg()
473template <
typename realT,
typename _detectorT>
474void directPhaseSensor<realT, _detectorT>::Fbg( realT bg )
479template <
typename _realT,
typename _detectorT>
480int directPhaseSensor<_realT, _detectorT>::recordWavefront( wavefrontT &pupilPlane )
484 if( (
size_t)m_lastWavefront >= m_wavefronts.size() )
487 wavefrontT pPlane = pupilPlane;
489 m_wavefronts[m_lastWavefront].amplitude = pPlane.amplitude;
490 m_wavefronts[m_lastWavefront].phase = pPlane.phase;
491 m_wavefronts[m_lastWavefront].iterNo = pPlane.iterNo;
496template <
typename _realT,
typename _detectorT>
497bool directPhaseSensor<_realT, _detectorT>::senseWavefront( wavefrontT &pupilPlane )
499 using poisson_param_t =
typename std::poisson_distribution<long>::param_type;
502 if( (
size_t)m_lastWavefront >= m_wavefronts.size() )
505 wavefrontT pPlane = pupilPlane;
507 m_wavefronts[m_lastWavefront].amplitude = pPlane.amplitude;
508 m_wavefronts[m_lastWavefront].phase = pPlane.phase;
509 m_wavefronts[m_lastWavefront].iterNo = pPlane.iterNo;
527 if( m_roTime_counter >= m_roTime )
529 m_detectorImage.image = m_wfsImage.image.block(
530 0.5 * ( m_wfsImage.image.rows() - 1 ) - 0.5 * ( m_detectorImage.image.rows() - 1 ),
531 0.5 * ( m_wfsImage.image.cols() - 1 ) - 0.5 * ( m_detectorImage.image.cols() - 1 ),
532 m_detectorImage.image.rows(),
533 m_detectorImage.image.cols() );
535 m_detectorImage.iterNo = m_wfsImage.iterNo;
537 m_roTime_counter = 0;
543 if( m_iTime_counter >= m_iTime )
550 m_roTime_counter = 0;
553 m_detectorImage.image =
554 m_wfsImage.image.block( 0.5 * ( m_wfsImage.image.rows() - 1 ) - 0.5 * ( m_detectorImage.image.rows() - 1 ),
555 0.5 * ( m_wfsImage.image.cols() - 1 ) - 0.5 * ( m_detectorImage.image.cols() - 1 ),
556 m_detectorImage.image.rows(),
557 m_detectorImage.image.cols() );
563 m_filter.filter( m_detectorImage.image );
564 if( m_pupil !=
nullptr )
565 m_detectorImage.image *= *m_pupil;
569 if( m_beta_p > 0 && m_pupil !=
nullptr )
571 m_noiseIm.resize( m_detectorImage.image.rows(), m_detectorImage.image.cols() );
574 for(
int c = 0;
c < m_noiseIm.cols(); ++
c )
576 for(
int r = 0; r < m_noiseIm.rows(); ++r )
579 pow( pupilPlane.amplitude( r, c ), 2 ) * ( *m_pupil )( r,
c ) * m_detector.expTime();
584 realT sqrtFbg = sqrt( m_Fbg * m_detector.expTime() );
587 for(
int c = 0;
c < m_noiseIm.cols(); ++
c )
589 for(
int r = 0; r < m_noiseIm.rows(); ++r )
591 if( m_noiseIm( r, c ) == 0 )
597 realT err = sqrt( m_noiseIm( r, c ) ) * m_normVar;
599 err += sqrtFbg * m_normVar;
600 if( m_detector.ron() > 0 )
601 err += m_detector.ron() * m_normVar;
603 m_detectorImage.image( r, c ) +=
604 m_beta_p * err / m_noiseIm( r, c );
611 m_detectorImage.iterNo = m_wfsImage.iterNo;
613 m_roTime_counter = 0;
623template <
typename _realT,
typename _detectorT>
624bool directPhaseSensor<_realT, _detectorT>::senseWavefrontCal( wavefrontT &pupilPlane )
629 m_wavefronts[0].amplitude = pupilPlane.amplitude;
630 m_wavefronts[0].phase = pupilPlane.phase;
632 m_wavefronts[1].amplitude = pupilPlane.amplitude;
633 m_wavefronts[1].phase = pupilPlane.phase;
637 m_detectorImage.image =
638 m_wfsImage.image.block( 0.5 * ( m_wfsImage.image.rows() - 1 ) - 0.5 * ( m_detectorImage.image.rows() - 1 ),
639 0.5 * ( m_wfsImage.image.cols() - 1 ) - 0.5 * ( m_detectorImage.image.cols() - 1 ),
640 m_detectorImage.image.rows(),
641 m_detectorImage.image.cols() );
645 m_filter.filter( m_detectorImage.image );
651template <
typename _realT,
typename _detectorT>
652void directPhaseSensor<_realT, _detectorT>::doSenseWavefront()
654 wavefrontT pupilPlane;
659 int _firstWavefront = m_lastWavefront - m_iTime;
660 if( _firstWavefront < 0 )
661 _firstWavefront += m_wavefronts.size();
665 pupilPlane.amplitude = 0.5 * m_wavefronts[_firstWavefront].amplitude;
666 pupilPlane.phase = 0.5 * m_wavefronts[_firstWavefront].phase;
668 pupilPlane.iterNo = 0.5 * m_wavefronts[_firstWavefront].iterNo;
673 if( m_wavefronts[_firstWavefront].iterNo < m_iTime )
675 m_wfsImage.image = pupilPlane.phase;
676 m_wfsImage.iterNo = pupilPlane.iterNo;
680 for(
int i = 0; i < m_iTime - 1; ++i )
683 if( (
size_t)_firstWavefront >= m_wavefronts.size() )
688 pupilPlane.amplitude += m_wavefronts[_firstWavefront].amplitude;
689 pupilPlane.phase += m_wavefronts[_firstWavefront].phase;
690 pupilPlane.iterNo += m_wavefronts[_firstWavefront].iterNo;
694 if( (
size_t)_firstWavefront >= m_wavefronts.size() )
699 pupilPlane.amplitude += 0.5 * m_wavefronts[_firstWavefront].amplitude;
700 pupilPlane.phase += 0.5 * m_wavefronts[_firstWavefront].phase;
701 pupilPlane.iterNo += 0.5 * m_wavefronts[_firstWavefront].iterNo;
703 pupilPlane.amplitude /= ( m_iTime );
704 pupilPlane.phase /= ( m_iTime );
705 pupilPlane.iterNo /= ( m_iTime );
707 m_wfsImage.image = pupilPlane.phase;
708 m_wfsImage.iterNo = pupilPlane.iterNo;
711template <
typename _realT,
typename _detectorT>
712void directPhaseSensor<_realT, _detectorT>::applyFilter(
bool af )
717template <
typename _realT,
typename _detectorT>
718bool directPhaseSensor<_realT, _detectorT>::applyFilter()
720 return m_applyFilter;
723template <
typename _realT,
typename _detectorT>
724void directPhaseSensor<_realT, _detectorT>::filterWidth(
int width )
726 int nr = m_detectorImage.image.rows();
727 int nc = m_detectorImage.image.cols();
729 typename wfsImageT<_realT>::imageT filterMask;
731 filterMask.resize( nr, nc );
732 filterMask.setZero();
734 filterMask.block( 0, 0, width + 1, width + 1 ).setConstant( 1.0 );
735 filterMask.block( 0, nc - width, width + 1, width ).setConstant( 1.0 );
736 filterMask.block( nr - width, 0, width, width + 1 ).setConstant( 1.0 );
737 filterMask.block( nr - width, nc - width, width, width ).setConstant( 1.0 );
739 m_filter.psdSqrt( filterMask,
static_cast<realT
>( 1 ) / nr,
static_cast<realT
>( 1 ) / nc );
741 m_filterWidth = width;
744template <
typename _realT,
typename _detectorT>
745int directPhaseSensor<_realT, _detectorT>::filterWidth()
747 return m_filterWidth;
750template <
typename realT,
typename detectorT>
751const sigproc::psdFilter<realT, 2> &directPhaseSensor<realT, detectorT>::filter()
756template <
typename _realT,
typename _detectorT>
757void directPhaseSensor<_realT, _detectorT>::beta_p( realT bp )
762template <
typename realT,
typename detectorT>
763realT directPhaseSensor<realT, detectorT>::beta_p()
768template <
typename realT,
typename detectorT>
769void directPhaseSensor<realT, detectorT>::pupil( pupilT *pupil )
774template <
typename realT,
typename detectorT>
775void directPhaseSensor<realT, detectorT>::pupil( pupilT &pupil )
780template <
typename realT,
typename detectorT>
781typename directPhaseSensor<realT, detectorT>::pupilT *directPhaseSensor<realT, detectorT>::pupil()
A random number type, which functions like any other arithmetic type.
constexpr units::realT c()
The speed of light.