8#ifndef mx_AO_sim_pyramidSensor_hpp
9#define mx_AO_sim_pyramidSensor_hpp
11#include "../../mxException.hpp"
13#include "../../wfp/imagingUtils.hpp"
14#include "../../wfp/fraunhoferPropagator.hpp"
15#include "../../sys/timeUtils.hpp"
17#include "../../improc/eigenImage.hpp"
18#include "../../improc/imageMasks.hpp"
20#include "../../math/constants.hpp"
21#include "../../math/geo.hpp"
23#include "wavefront.hpp"
26#define BREAD_CRUMB std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
38template <
typename _realT>
46 typedef Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> imageT;
60template <
typename _realT,
typename _detectorT>
68 typedef std::complex<realT> complexT;
71 typedef wavefront<realT> wavefrontT;
74 typedef wfp::imagingArray<std::complex<realT>, wfp::fftwAllocator<std::complex<realT>>, 0> complexFieldT;
77 typedef _detectorT detectorT;
92 uint32_t m_detRows{ 0 };
95 uint32_t m_detCols{ 0 };
102 std::vector<realT> m_wavelengths;
103 std::vector<realT> _wavelengthWeights;
109 realT m_simStep{ 0.001 };
121 void wfSz(
const uint32_t & sz );
122 void wfSz(
const uint32_t & sz );
139 void detSize(
const uint32_t &nrows,
140 const uint32_t &ncols
152 void lambda(
const realT &l );
158 void iTime(
const uint32_t &it );
164 void roTime(
const uint32_t &rt );
170 void simStep(
const realT &st );
173 template <
typename AOSysT>
174 void linkSystem( AOSysT &AOSys );
180 bool senseWavefront( wavefrontT &pupilPlane );
185 bool senseWavefrontCal( wavefrontT &pupilPlane );
192 wfsImageT<realT> detectorImage;
201 uint32_t m_nSides {4};
202 uint32_t m_nSides {4};
208 uint32_t m_pupilSz{ 0 };
235 realT m_pupilSep {1};
242 realT m_angleOffset {0};
243 realT m_pupilSep {1};
250 realT m_angleOffset {0};
260 uint32_t m_imageSz {0};
262 bool m_imageSzAuto{
true };
270 uint32_t m_modSteps{ 20 };
276 realT m_modRadius{ 3.0 };
288 void nSides(
const uint32_t & ns );
289 void nSides(
const uint32_t & ns );
301 void perStep(
const realT &prStp );
319 void modRadius(
const realT &mR );
337 void D(
const realT &d );
352 void pupilSz(
const uint32_t &sz );
369 void pupilSep(
const realT & sz );
382 void angleOffset(
const realT & ao );
383 void pupilSep(
const realT & sz );
396 void angleOffset(
const realT & ao );
410 void imageSz(
const uint32_t &is );
423 void imageSzAuto(
const bool &ia );
426 wfp::fraunhoferPropagator<complexFieldT> m_frProp;
428 bool m_opdMaskMade{
false };
429 complexFieldT m_opdMask;
431 bool m_tiltsMade{
false };
432 std::vector<complexFieldT> m_tilts;
434 bool m_preAllocated{
false };
435 complexFieldT m_pupilPlaneCF;
439 std::vector<complexFieldT> m_th_tiltedPlane;
441 std::vector<complexFieldT> m_th_focalPlane;
443 std::vector<typename wfsImageT<realT>::imageT> m_th_focalImage;
445 std::vector<complexFieldT> m_th_sensorPlane;
447 std::vector<typename wfsImageT<realT>::imageT>
450 int m_iTime_counter{ 0 };
454 int m_roTime_counter{ 0 };
456 std::vector<wavefrontT> _wavefronts;
458 int m_lastWavefront{ 0 };
461 wfsImageT<realT> m_wfsImage;
464 wfsImageT<realT> wfsTipImage;
471 void allocThreadMem();
475 void doSenseWavefront();
476 void doSenseWavefront( wavefrontT & );
477 void doSenseWavefrontNoMod( wavefrontT & );
479 bool m_firstRun{
true };
482template <
typename realT,
typename detectorT>
483pyramidSensor<realT, detectorT>::pyramidSensor()
487 m_frProp.wholePixel( 0 );
490template <
typename realT,
typename detectorT>
491int pyramidSensor<realT, detectorT>::wfSz()
496template <
typename realT,
typename detectorT>
497void pyramidSensor<realT, detectorT>::wfSz(
const uint32_t & sz)
498void pyramidSensor<realT, detectorT>::wfSz(
const uint32_t & sz)
508 m_opdMaskMade =
false;
509 m_preAllocated =
false;
512template <
typename realT,
typename detectorT>
513uint32_t pyramidSensor<realT, detectorT>::detRows()
514uint32_t pyramidSensor<realT, detectorT>::detRows()
519template <
typename realT,
typename detectorT>
520uint32_t pyramidSensor<realT, detectorT>::detCols()
521uint32_t pyramidSensor<realT, detectorT>::detCols()
526template <
typename realT,
typename detectorT>
527void pyramidSensor<realT, detectorT>::detSize(
const uint32_t &nrows,
const uint32_t &ncols )
529 if( m_detRows == nrows && m_detCols == ncols )
535 detector.setSize(m_detRows, m_detCols);
536 detectorImage.image.resize(m_detRows, m_detCols);
538 m_opdMaskMade =
false;
540 m_opdMaskMade =
false;
543template <
typename realT,
typename detectorT>
544realT pyramidSensor<realT, detectorT>::lambda()
549template <
typename realT,
typename detectorT>
550void pyramidSensor<realT, detectorT>::lambda(
const realT &l )
557 if( m_wavelengths.size() == 0 )
559 m_wavelengths.resize( 1, m_lambda );
560 _wavelengthWeights.resize( 1, 1.0 );
564template <
typename realT,
typename detectorT>
565int pyramidSensor<realT, detectorT>::iTime()
570template <
typename realT,
typename detectorT>
571void pyramidSensor<realT, detectorT>::iTime(
const uint32_t &it )
580 _wavefronts.resize( m_iTime + 2 );
581 m_lastWavefront = -1;
583 detector.expTime( m_simStep * m_iTime );
586template <
typename realT,
typename detectorT>
587int pyramidSensor<realT, detectorT>::roTime()
592template <
typename realT,
typename detectorT>
593void pyramidSensor<realT, detectorT>::roTime(
const uint32_t &rt )
603template <
typename realT,
typename detectorT>
604realT pyramidSensor<realT, detectorT>::simStep()
609template <
typename realT,
typename detectorT>
610void pyramidSensor<realT, detectorT>::simStep(
const realT &st )
615 detector.expTime( m_simStep * m_iTime );
618template <
typename realT,
typename detectorT>
619template <
typename AOSysT>
620void pyramidSensor<realT, detectorT>::linkSystem( AOSysT &AOSys )
622 AOSys.wfs.wfPS( AOSys.m_wfPS );
623 AOSys.wfs.D( AOSys.m_D );
626template <
typename realT,
typename detectorT>
627bool pyramidSensor<realT, detectorT>::senseWavefront( wavefrontT &pupilPlane )
631 if( m_lastWavefront >= _wavefronts.size() )
633 _wavefronts[m_lastWavefront].amplitude = pupilPlane.amplitude;
634 _wavefronts[m_lastWavefront].phase = pupilPlane.phase;
635 _wavefronts[m_lastWavefront].iterNo = pupilPlane.iterNo;
652 if( m_roTime_counter >= m_roTime )
654 detector.exposeImage( detectorImage.image, m_wfsImage.image );
656 detectorImage.tipImage = wfsTipImage.image;
657 detectorImage.iterNo = m_wfsImage.iterNo;
659 m_roTime_counter = 0;
665 if( m_iTime_counter >= m_iTime )
671 m_roTime_counter = 0;
677template <
typename realT,
typename detectorT>
678bool pyramidSensor<realT, detectorT>::senseWavefrontCal( wavefrontT &pupilPlane )
683 doSenseWavefront(pupilPlane);
688 detector.exposeImage( detectorImage.image, m_wfsImage.image );
692 detectorImage.tipImage = wfsTipImage.image;
701template <
typename realT,
typename detectorT>
702int pyramidSensor<realT, detectorT>::nSides()
707template <
typename realT,
typename detectorT>
708void pyramidSensor<realT, detectorT>::nSides(
const uint32_t & ns)
709void pyramidSensor<realT, detectorT>::nSides(
const uint32_t & ns)
712 m_opdMaskMade =
false;
715template <
typename realT,
typename detectorT>
716realT pyramidSensor<realT, detectorT>::wfPS()
721template <
typename realT,
typename detectorT>
722realT pyramidSensor<realT, detectorT>::D()
727template <
typename realT,
typename detectorT>
728void pyramidSensor<realT, detectorT>::D(
const realT &d )
734 m_wfPS = m_D/m_pupilSz;
742 m_opdMaskMade =
false;
743 m_preAllocated =
false;
744 m_opdMaskMade =
false;
745 m_preAllocated =
false;
748template <
typename realT,
typename detectorT>
749realT pyramidSensor<realT, detectorT>::perStep()
754template <
typename realT,
typename detectorT>
755void pyramidSensor<realT, detectorT>::perStep(
const realT &prStp )
759 if( m_modRadius <= 0 )
765 realT radPerStep = m_perStep / m_modRadius;
779template <
typename realT,
typename detectorT>
780int pyramidSensor<realT, detectorT>::modSteps()
785template <
typename realT,
typename detectorT>
786realT pyramidSensor<realT, detectorT>::modRadius()
791template <
typename realT,
typename detectorT>
792void pyramidSensor<realT, detectorT>::modRadius(
const realT &mR )
795 perStep( m_perStep );
800template <
typename realT,
typename detectorT>
801uint32_t pyramidSensor<realT, detectorT>::pupilSz()
806template <
typename realT,
typename detectorT>
807void pyramidSensor<realT, detectorT>::pupilSz(
const uint32_t &sz )
809 if( m_pupilSz == sz )
818 m_wfPS = m_D/m_pupilSz;
827 m_wfPS = m_D/m_pupilSz;
835 m_opdMaskMade =
false;
836 m_preAllocated =
false;
839template <
typename realT,
typename detectorT>
840realT pyramidSensor<realT, detectorT>::pupilSep()
841realT pyramidSensor<realT, detectorT>::pupilSep()
846template <
typename realT,
typename detectorT>
847void pyramidSensor<realT, detectorT>::pupilSep(
const realT & sz)
848void pyramidSensor<realT, detectorT>::pupilSep(
const realT & sz)
850 if( m_pupilSep == sz )
857 m_opdMaskMade =
false;
858 m_preAllocated =
false;
861template <
typename realT,
typename detectorT>
862realT pyramidSensor<realT, detectorT>::angleOffset()
864 return m_angleOffset;
867template <
typename realT,
typename detectorT>
868void pyramidSensor<realT, detectorT>::angleOffset(
const realT & ao)
870 if (m_angleOffset == ao)
877 m_opdMaskMade =
false;
878 m_preAllocated =
false;
881template <
typename realT,
typename detectorT>
882realT pyramidSensor<realT, detectorT>::angleOffset()
884 return m_angleOffset;
887template <
typename realT,
typename detectorT>
888void pyramidSensor<realT, detectorT>::angleOffset(
const realT & ao)
890 if (m_angleOffset == ao)
897 m_opdMaskMade =
false;
898 m_preAllocated =
false;
901template <
typename realT,
typename detectorT>
902uint32_t pyramidSensor<realT, detectorT>::imageSz()
912template <
typename realT,
typename detectorT>
913void pyramidSensor<realT, detectorT>::imageSz(
const uint32_t &sz )
915 if( m_imageSz == sz )
924 m_imageSzAuto =
true;
928 m_imageSzAuto =
false;
931 m_opdMaskMade =
false;
932 m_preAllocated =
false;
935template <
typename realT,
typename detectorT>
936bool pyramidSensor<realT, detectorT>::imageSzAuto()
938 return m_imageSzAuto;
941template <
typename realT,
typename detectorT>
942void pyramidSensor<realT, detectorT>::imageSzAuto(
const bool &ia )
946 m_opdMaskMade =
false;
948 m_preAllocated =
false;
951template <
typename realT,
typename detectorT>
952void pyramidSensor<realT, detectorT>::makeOpdMask()
954 complexFieldT opdMaskQ;
958 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"wavefront platescale (m_wfPS) is 0. Must set pupilSz and D first.");
961 if(!std::isfinite(m_wfPS) || !std::isnormal(m_wfPS))
963 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"wavefront platescale (m_wfPS) is infinite. Must set pupilSz and D first.");
966 std::cerr << m_wfPS <<
" " << m_D <<
"\n";
970 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"pupil diameter is 0. Must set D > 0 first.");
974 m_frProp.setWavefrontSizePixels(m_wfSz);
976 m_opdMask.resize(m_wfSz, m_wfSz);
977 opdMaskQ.resize(m_wfSz, m_wfSz);
981 mask.resize(m_opdMask.rows(), m_opdMask.cols());
985 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"wavefront platescale (m_wfPS) is 0. Must set pupilSz and D first.");
988 if(!std::isfinite(m_wfPS) || !std::isnormal(m_wfPS))
990 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"wavefront platescale (m_wfPS) is infinite. Must set pupilSz and D first.");
993 std::cerr << m_wfPS <<
" " << m_D <<
"\n";
997 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask()",
"pupil diameter is 0. Must set D > 0 first.");
1001 m_frProp.setWavefrontSizePixels(m_wfSz);
1003 m_opdMask.resize(m_wfSz, m_wfSz);
1004 opdMaskQ.resize(m_wfSz, m_wfSz);
1008 mask.resize(m_opdMask.rows(), m_opdMask.cols());
1016 realT pupilRad = m_pupilSep*m_pupilSz /(2*sin(dang/2.0));
1022 realT pupilRad = m_pupilSep*m_pupilSz /(2*sin(dang/2.0));
1024 for(
int n = 0; n < m_nSides; ++n)
1026 realT ang = m_angleOffset*math::degreesT<realT>::radians + 0.5*dang + n * dang;
1027 for(
int n = 0; n < m_nSides; ++n)
1029 realT ang = m_angleOffset*math::degreesT<realT>::radians + 0.5*dang + n * dang;
1031 realT dx = pupilRad * cos(ang);
1032 realT dx = pupilRad * cos(ang);
1034 if(dx < minx) minx = dx;
1035 if(dx > maxx) maxx = dx;
1036 if(dx < minx) minx = dx;
1037 if(dx > maxx) maxx = dx;
1039 realT dy = pupilRad * sin(ang);
1040 realT dy = pupilRad * sin(ang);
1042 if(dy < miny) miny = dy;
1043 if(dy > maxy) maxy = dy;
1044 if(dy < miny) miny = dy;
1045 if(dy > maxy) maxy = dy;
1047 opdMaskQ.set(std::complex<realT>(0, 1));
1051 wfp::extractMaskedPixels(m_opdMask, opdMaskQ, mask);
1053 opdMaskQ.set(std::complex<realT>(0, 1));
1057 wfp::extractMaskedPixels(m_opdMask, opdMaskQ, mask);
1060 int xsz = 2*std::max( {fabs(maxx), fabs(minx)} ) + 2*std::max({(pupilRad/2),((realT)m_pupilSz/2)});
1061 int ysz = 2*std::max( {fabs(maxy), fabs(miny)} ) + 2*std::max({(pupilRad/2), ((realT)m_pupilSz/2)});
1062 int xsz = 2*std::max( {fabs(maxx), fabs(minx)} ) + 2*std::max({(pupilRad/2),((realT)m_pupilSz/2)});
1063 int ysz = 2*std::max( {fabs(maxy), fabs(miny)} ) + 2*std::max({(pupilRad/2), ((realT)m_pupilSz/2)});
1067 m_imageSz = std::max(xsz, ysz);
1071 if(m_imageSz > m_wfSz)
1073 std::string msg =
"image size (m_imageSz = " + std::to_string(m_imageSz) +
") ";
1074 msg +=
"> wavefront size (m_wfSz = " + std::to_string(m_wfSz) +
"). ";
1075 msg +=
"Decrease number of sides (m_nSides = " + std::to_string(m_nSides) +
") or increase wavefront size. ";
1079 m_imageSz = std::max(xsz, ysz);
1083 if(m_imageSz > m_wfSz)
1085 std::string msg =
"image size (m_imageSz = " + std::to_string(m_imageSz) +
") ";
1086 msg +=
"> wavefront size (m_wfSz = " + std::to_string(m_wfSz) +
"). ";
1087 msg +=
"Decrease number of sides (m_nSides = " + std::to_string(m_nSides) +
") or increase wavefront size. ";
1091 m_wfsImage.image.resize(m_imageSz, m_imageSz);
1093 if(m_detRows == 0 || m_detCols == 0)
1098 if(m_detRows > m_imageSz || m_detCols > m_imageSz)
1100 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask",
"detector is larger than image size");
1103 if(m_detRows == 0 || m_detCols == 0)
1108 if(m_detRows > m_imageSz || m_detCols > m_imageSz)
1110 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeOpdMask",
"detector is larger than image size");
1113 m_opdMaskMade =
true;
1116template <
typename realT,
typename detectorT>
1117void pyramidSensor<realT, detectorT>::makeTilts()
1121 if( m_modSteps == 0 )
1124 "pyramidSensor::makeTilts()",
1125 "number of modulation steps (m_modSteps) has not been set." );
1131 "pyramidSensor::makeTilts()",
1132 "wavefront platescale (m_wfPS) is 0. Must set pupilSz and D first." );
1135 if( !std::isfinite( m_wfPS ) )
1138 "pyramidSensor::makeTilts()",
1139 "wavefront platescale (m_wfPS) is infinite. Must set pupilSz and D first." );
1144 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeTilts()",
"pupil diameter is 0. Must set D > 0 first.");
1150 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeTilts()",
"pupil diameter is 0. Must set D > 0 first.");
1156 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeTilts()",
"pupil diameter is 0. Must set D > 0 first.");
1162 mxThrowException(
mx::err::invalidconfig,
"pyramidSensor::makeTilts()",
"pupil diameter is 0. Must set D > 0 first.");
1166 realT dang = 2 *
pi / ( m_modSteps );
1169 m_tilts.resize( m_modSteps );
1171 std::cout <<
"WF Size: " << m_wfSz <<
"\n";
1172 std::cout <<
"WF PS: " << m_wfPS <<
"\n";
1173 std::cout <<
"Lambda: " << m_lambda <<
"\n";
1174 std::cout <<
"Pyr. PS: " << wfp::fftPlateScale<realT>( m_wfSz, m_wfPS, m_lambda ) * 206265. <<
" (mas/pix)\n";
1175 std::cout <<
"Mod. steps: " << m_modSteps <<
"\n";
1176 std::cout <<
"Mod rad: " << m_modRadius * ( m_lambda / m_D ) / wfp::fftPlateScale<realT>( m_wfSz, m_wfPS, m_lambda )
1179 for(
int i = 0; i < m_modSteps; ++i )
1181 dx = m_modRadius * ( m_lambda / m_D ) / wfp::fftPlateScale<realT>( m_wfSz, m_wfPS, m_lambda ) *
1182 cos( 0.0 * dang + dang * i );
1183 dy = m_modRadius * ( m_lambda / m_D ) / wfp::fftPlateScale<realT>( m_wfSz, m_wfPS, m_lambda ) *
1184 sin( 0.0 * dang + dang * i );
1186 m_tilts[i].resize( m_wfSz, m_wfSz );
1187 m_tilts[i].set( std::complex<realT>( 0, 1 ) );
1195template <
typename realT,
typename detectorT>
1196void pyramidSensor<realT, detectorT>::allocThreadMem()
1198 if( !m_opdMaskMade )
1203 m_pupilPlaneCF.resize( m_wfSz, m_wfSz );
1205 int maxTh = omp_get_max_threads();
1206 m_th_tiltedPlane.resize( maxTh );
1208 m_th_focalPlane.resize( maxTh );
1210 m_th_focalImage.resize( maxTh );
1212 m_th_sensorPlane.resize( maxTh );
1214 m_th_sensorImage.resize( maxTh );
1216 for(
int nTh = 0; nTh < maxTh; ++nTh )
1218 m_th_tiltedPlane[nTh].resize( m_wfSz, m_wfSz );
1220 m_th_focalPlane[nTh].resize( m_wfSz, m_wfSz );
1222 m_th_focalImage[nTh].resize( m_wfSz, m_wfSz );
1224 m_th_sensorPlane[nTh].resize( m_wfSz, m_wfSz );
1226 m_th_sensorImage[nTh].resize( m_imageSz, m_imageSz );
1229 m_preAllocated =
true;
1232template <
typename realT,
typename detectorT>
1233void pyramidSensor<realT, detectorT>::preAllocate()
1240 if( !m_opdMaskMade )
1245 if( !m_preAllocated )
1251template <
typename realT,
typename detectorT>
1252void pyramidSensor<realT, detectorT>::doSenseWavefront()
1256 wavefrontT pupilPlane;
1259 int _firstWavefront = m_lastWavefront - m_iTime;
1260 if( _firstWavefront < 0 )
1261 _firstWavefront += _wavefronts.size();
1263 pupilPlane.amplitude = _wavefronts[_firstWavefront].amplitude;
1264 pupilPlane.phase = _wavefronts[_firstWavefront].phase;
1266 realT avgIt = _wavefronts[_firstWavefront].iterNo;
1270 for(
int i = 0; i < m_iTime; ++i )
1273 if( (
size_t)_firstWavefront >= _wavefronts.size() )
1274 _firstWavefront = 0;
1276 pupilPlane.amplitude += _wavefronts[_firstWavefront].amplitude;
1277 pupilPlane.phase += _wavefronts[_firstWavefront].phase;
1278 avgIt += _wavefronts[_firstWavefront].iterNo;
1283 pupilPlane.amplitude /= ( m_iTime + 1 );
1284 pupilPlane.phase /= ( m_iTime + 1 );
1286 avgIt /= ( m_iTime + 1.0 );
1289 doSenseWavefront( pupilPlane );
1291 m_wfsImage.iterNo = avgIt;
1294template <
typename realT,
typename detectorT>
1295void pyramidSensor<realT, detectorT>::doSenseWavefront( wavefrontT &pupilPlane )
1297 if( m_modRadius == 0 )
1299 return doSenseWavefrontNoMod( pupilPlane );
1302 if( !m_preAllocated )
1309 m_wfsImage.image.resize( m_imageSz, m_imageSz );
1310 m_wfsImage.image.setZero();
1312 wfsTipImage.image.resize( m_wfSz, m_wfSz );
1313 wfsTipImage.image.setZero();
1315 for(
size_t l = 0; l < m_wavelengths.size(); ++l )
1317 pupilPlane.lambda = m_lambda;
1318 pupilPlane.getWavefront( m_pupilPlaneCF, m_wavelengths[l], m_wfSz );
1322 int nTh = omp_get_thread_num();
1324 m_th_sensorImage[nTh].setZero();
1325 m_th_focalImage[nTh].setZero();
1331 complexT *opdm_Data;
1333 ppm_Data = m_pupilPlaneCF.data();
1334 tpm_Data = m_th_tiltedPlane[nTh].data();
1335 fpm_Data = m_th_focalPlane[nTh].data();
1336 opdm_Data = m_opdMask.data();
1338 int nelem = m_wfSz * m_wfSz;
1341 for(
int i = 0; i < m_modSteps; ++i )
1344 tim_Data = m_tilts[i].data();
1349 for(
int ii = 0; ii < nelem; ++ii )
1351 tpm_Data[ii] = ppm_Data[ii] * tim_Data[ii];
1357 m_frProp.propagatePupilToFocal( m_th_focalPlane[nTh], m_th_tiltedPlane[nTh],
true );
1362 wfp::extractIntensityImageAccum(
1363 m_th_focalImage[nTh], 0, m_wfSz, 0, m_wfSz, m_th_focalPlane[nTh], 0, 0 );
1368 for(
int ii = 0; ii < nelem; ++ii )
1370 fpm_Data[ii] = fpm_Data[ii] * opdm_Data[ii];
1376 m_frProp.propagateFocalToPupil( m_th_sensorPlane[nTh], m_th_focalPlane[nTh],
true );
1381 wfp::extractIntensityImageAccum( m_th_sensorImage[nTh],
1386 m_th_sensorPlane[nTh],
1387 0.5 * m_wfSz - m_imageSz / 2,
1388 0.5 * m_wfSz - m_imageSz / 2 );
1396 m_wfsImage.image += m_th_sensorImage[nTh] * _wavelengthWeights[l];
1397 wfsTipImage.image += m_th_focalImage[nTh] * _wavelengthWeights[l];
1405 m_wfsImage.image /= m_modSteps;
1406 wfsTipImage.image /= m_modSteps;
1409template <
typename realT,
typename detectorT>
1410void pyramidSensor<realT, detectorT>::doSenseWavefrontNoMod( wavefrontT &pupilPlane )
1414 if( !m_opdMaskMade )
1419 m_wfsImage.image.resize( m_imageSz, m_imageSz );
1420 m_wfsImage.image.setZero();
1422 wfsTipImage.image.resize( m_wfSz, m_wfSz );
1423 wfsTipImage.image.setZero();
1425 complexFieldT m_pupilPlaneCF;
1427 pupilPlane.getWavefront( m_pupilPlaneCF, m_wfSz );
1429 complexFieldT tiltedPlane;
1430 complexFieldT focalPlane;
1431 complexFieldT sensorPlane;
1433 tiltedPlane.resize( m_wfSz, m_wfSz );
1434 focalPlane.resize( m_wfSz, m_wfSz );
1435 sensorPlane.resize( m_wfSz, m_wfSz );
1437 int nelem = m_wfSz * m_wfSz;
1439 complexT *tpm_Data = tiltedPlane.data();
1440 complexT *ppm_Data = m_pupilPlaneCF.data();
1441 complexT *opdm_Data = m_opdMask.data();
1442 complexT *fpm_Data = focalPlane.data();
1449 for(
int ii = 0; ii < nelem; ++ii )
1451 tpm_Data[ii] = ppm_Data[ii];
1459 m_frProp.propagatePupilToFocal( focalPlane, tiltedPlane,
true );
1466 wfp::extractIntensityImageAccum( wfsTipImage.image, 0, m_wfSz, 0, m_wfSz, focalPlane, 0, 0 );
1473 for(
int ii = 0; ii < nelem; ++ii )
1475 fpm_Data[ii] = fpm_Data[ii] * opdm_Data[ii];
1483 m_frProp.propagateFocalToPupil( sensorPlane, focalPlane,
true );
1490 wfp::extractIntensityImageAccum( m_wfsImage.image,
1496 0.5 * m_wfSz - m_imageSz / 2,
1497 0.5 * m_wfSz - m_imageSz / 2 );
mxException for invalid config settings
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
constexpr T pi()
Get the value of pi.
constexpr floatT six_fifths()
Return 6/5 in the specified precision.
realT rtod(realT q)
Convert from radians to degrees.
void maskWedge(arrayT &m, typename arrayT::Scalar xcen, typename arrayT::Scalar ycen, typename arrayT::Scalar angCen, typename arrayT::Scalar angHW, typename arrayT::Scalar val=0)
Mask a wedge in an image.
void tiltWavefront(wavefrontT &complexWavefront, typename wavefrontT::Scalar::value_type xTilt, typename wavefrontT::Scalar::value_type yTilt)
Apply a tilt to a wavefront.