760 const std::string &psdDir,
765 realT lpRegPrecision,
766 std::vector<realT> &mags,
768 bool uncontrolledLifetimes,
773 std::string dir = psdDir +
"/" + subDir;
776 mkdir( dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
779 std::string fn = dir +
'/' +
"params.txt";
782 fout <<
"#---------------------------\n";
783 m_aosys->dumpAOSystem( fout );
784 fout <<
"#---------------------------\n";
785 fout <<
"# Analysis Parameters\n";
786 fout <<
"# mnMax = " << mnMax <<
'\n';
787 fout <<
"# mnCon = " << mnCon <<
'\n';
788 fout <<
"# lpNc = " << lpNc <<
'\n';
790 for(
size_t i = 0; i < mags.size() - 1; ++i )
791 fout << mags[i] <<
",";
792 fout << mags[mags.size() - 1] <<
'\n';
793 fout <<
"# lifetimeTrials = " << lifetimeTrials <<
'\n';
794 fout <<
"# uncontrolledLifetimes = " << uncontrolledLifetimes <<
'\n';
795 fout <<
"# writePSDs = " << std::boolalpha << writePSDs <<
'\n';
796 fout <<
"# writeXfer = " << std::boolalpha << writeXfer <<
'\n';
802 realT fs = 1.0 / m_aosys->tauWFS();
803 realT tauWFS = m_aosys->tauWFS();
804 realT deltaTau = m_aosys->deltaTau();
806 std::vector<sigproc::fourierModeDef> fms;
809 size_t nModes = 0.5 * fms.size();
811 Eigen::Array<
realT, -1, -1> gains, vars, speckleLifetimes, gains_lp, vars_lp, speckleLifetimes_lp;
813 gains.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
814 vars.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
815 speckleLifetimes.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
817 gains( mnMax, mnMax ) = 0;
818 vars( mnMax, mnMax ) = 0;
819 speckleLifetimes( mnMax, mnMax ) = 0;
821 gains_lp.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
822 vars_lp.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
823 speckleLifetimes_lp.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
825 gains_lp( mnMax, mnMax ) = 0;
826 vars_lp( mnMax, mnMax ) = 0;
827 speckleLifetimes_lp( mnMax, mnMax ) = 0;
832 Eigen::Array<
realT, -1, -1> lpC;
836 lpC.resize( nModes, lpNc );
840 std::vector<realT> S_si, S_lp;
844 for(
size_t s = 0; s < mags.size(); ++s )
846 std::string psdOutDir = std::format(
"{}/outputPSDS_{}_si",dir, mags[s]);
848 mkdir( psdOutDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
852 std::string psdOutDir = std::format(
"{}/outputPSDS_{}_lp",dir, mags[s]);
854 mkdir( psdOutDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
859 m_aosys->beta_p( 1, 1 );
863 for(
size_t s = 0; s < mags.size(); ++s )
865 m_aosys->starMag( mags[s] );
869 realT opticalGain{ 1.0 };
875 realT ncp = m_aosys->ncp_wfe();
876 m_aosys->ncp_wfe( 0 );
878 realT lam_sci = m_aosys->lam_sci();
879 m_aosys->lam_sci( m_aosys->lam_wfs() );
881 realT S = m_aosys->strehl();
882 std::cerr << S <<
"\n";
884 for(
int s = 0; s < 4; ++s )
886 m_aosys->opticalGain( S );
887 m_aosys->optd( m_aosys->optd() );
888 S = m_aosys->strehl();
889 std::cerr << S <<
"\n";
894 m_aosys->lam_sci( lam_sci );
895 m_aosys->ncp_wfe( ncp );
898 m_aosys->optd( m_aosys->optd() );
899 realT strehl = m_aosys->strehl();
903 realT localMag = mags[s];
909 realT gopt_lp, var_lp;
911 std::vector<realT> tfreq;
912 std::vector<realT> tPSDp;
916 std::vector<realT> tfreqHF;
917 std::vector<realT> tPSDpHF;
921 getGridPSD( tfreq, tPSDp, psdDir, 0, 1 );
924 while( tfreq[imax] <= 0.5 * fs )
927 if( imax > tfreq.size() - 1 )
931 if( imax < tfreq.size() - 1 && tfreq[imax] <= 0.5 * fs * ( 1.0 + 1e-7 ) )
938 tfreqHF.assign( tfreq.begin(), tfreq.end() );
941 tfreq.erase( tfreq.begin() + imax, tfreq.end() );
943 tPSDpPOL.resize( tfreq.size() );
946 std::vector<realT> tPSDn;
947 tPSDn.resize( tfreq.size() );
951 tflp.m_precision0 = lpRegPrecision;
969 std::vector<std::complex<realT>> ETFxn;
970 std::vector<std::complex<realT>> NTFxn;
972 if( lifetimeTrials > 0 )
974 ETFxn.resize( tfreq.size() );
975 NTFxn.resize( tfreq.size() );
979 std::string tfOutFile = std::format(
"{}/outputTF_{}_si", dir, mags[s]);
988 std::string tfOutFile = std::format(
"{}/outputTF_{}_lp", dir, mags[s]);
1002#pragma omp for schedule( dynamic, 5 )
1003 for(
size_t i = 0; i < nModes; ++i )
1009 if( fabs( (
realT)m / m_aosys->D() ) >= m_aosys->spatialFilter_ku() ||
1010 fabs( (
realT)n / m_aosys->D() ) >= m_aosys->spatialFilter_kv() )
1012 gains( mnMax + m, mnMax + n ) = 0;
1013 gains( mnMax - m, mnMax - n ) = 0;
1015 gains_lp( mnMax + m, mnMax + n ) = 0;
1016 gains_lp( mnMax - m, mnMax - n ) = 0;
1018 vars( mnMax + m, mnMax + n ) = 0;
1019 vars( mnMax - m, mnMax - n ) = 0;
1021 vars_lp( mnMax + m, mnMax + n ) = 0;
1022 vars_lp( mnMax - m, mnMax - n ) = 0;
1023 speckleLifetimes( mnMax + m, mnMax + n ) = 0;
1024 speckleLifetimes( mnMax - m, mnMax - n ) = 0;
1025 speckleLifetimes_lp( mnMax + m, mnMax + n ) = 0;
1026 speckleLifetimes_lp( mnMax - m, mnMax - n ) = 0;
1031 realT k = sqrt( m * m + n * n ) / m_aosys->D();
1034 getGridPSD( tPSDp, psdDir, m, n );
1041 tPSDpHF.assign( tPSDp.begin() + imax, tPSDp.end() );
1045 tPSDp.erase( tPSDp.begin() + imax, tPSDp.end() );
1052 if( m_uncorrectedOG )
1054 for(
size_t n = 0; n < tPSDp.size(); ++n )
1056 tPSDpPOL[n] = tPSDp[n] * pow( opticalGain, 2 );
1061 for(
size_t n = 0; n < tPSDp.size(); ++n )
1063 tPSDpPOL[n] = tPSDp[n];
1069 bool inside =
false;
1071 if( m_aosys->circularLimit() )
1073 if( m * m + n * n <= mnCon * mnCon )
1078 if( fabs( m ) <= mnCon && fabs( n ) <= mnCon )
1089 wfsNoisePSD<realT>( tPSDn,
1090 m_aosys->beta_p( m, n ) / sqrt( opticalGain ),
1091 m_aosys->Fg( localMag ),
1093 m_aosys->npix_wfs( (
size_t)0 ),
1094 m_aosys->Fbg( (
size_t)0 ),
1095 m_aosys->ron_wfs( (
size_t)0 ) );
1101 var = go_si.
clVariance( tPSDp, tPSDn, gopt );
1108 if( m_uncorrectedOG )
1110 gopt *= opticalGain;
1114 var = go_si.
clVariance( tPSDp, tPSDn, gopt );
1154 <<
"fourierTemporalPSD::analyzePSDGrid: regularizeCoefficients returned error ";
1155 std::cerr << rv <<
' ';
1156 std::cerr << __FILE__ <<
' ' << __LINE__ <<
'\n';
1159 for(
int n = 0; n < lpNc; ++n )
1161 lpC( i, n ) = go_lp.
a( n );
1164 if( m_uncorrectedOG )
1166 go_lp.aScale( opticalGain );
1167 go_lp.bScale( opticalGain );
1168 gopt_lp *= opticalGain;
1171 var_lp = go_lp.
clVariance( tPSDp, tPSDn, gopt_lp );
1182 tPSDn.assign( tPSDn.size(), 0.0 );
1188 go_lp.
a( std::vector<realT>( { 1 } ) );
1189 go_lp.
b( std::vector<realT>( { 1 } ) );
1194 if( gopt > 0 && var > var0 )
1200 if( gopt_lp > gopt && var_lp > var )
1205 go_lp.
a( std::vector<realT>( { 1 } ) );
1206 go_lp.
b( std::vector<realT>( { 1 } ) );
1211 gains( mnMax + m, mnMax + n ) = gopt;
1212 gains( mnMax - m, mnMax - n ) = gopt;
1214 gains_lp( mnMax + m, mnMax + n ) = gopt_lp;
1215 gains_lp( mnMax - m, mnMax - n ) = gopt_lp;
1217 vars( mnMax + m, mnMax + n ) = var;
1218 vars( mnMax - m, mnMax - n ) = var;
1220 vars_lp( mnMax + m, mnMax + n ) = var_lp;
1221 vars_lp( mnMax - m, mnMax - n ) = var_lp;
1225 if( ( lifetimeTrials > 0 || writeXfer ) && ( uncontrolledLifetimes || inside ) )
1227 std::vector<realT> spfreq, sppsd;
1231 for(
size_t i = 0; i < tfreq.size(); ++i )
1233 ETFxn[i] = go_si.
clETF( i, gopt );
1234 NTFxn[i] = go_si.
clNTF( i, gopt );
1239 for(
size_t i = 0; i < tfreq.size(); ++i )
1248 std::string tfOutFile = std::format(
"{}/outputTF_{}_si", dir, mags[s]);
1251 std::string etfOutFile = std::format(
"{}/etf_{}_{}.binv", tfOutFile,m, n);
1256 std::string ntfOutFile = std::format(
"{}/ntf_{}_{}.binv",tfOutFile, m, n);
1263 std::string fOutFile = tfOutFile +
"freq.binv";
1268 if( lifetimeTrials > 0 )
1270 speckleAmpPSD( spfreq, sppsd, tfreq, tPSDp, ETFxn, tPSDn, NTFxn, lifetimeTrials );
1273 realT splifeT = 100.0;
1276 realT tau = pvm(
error, spfreq, sppsd, splifeT ) * ( splifeT ) / spvar;
1278 speckleLifetimes( mnMax + m, mnMax + n ) = tau;
1279 speckleLifetimes( mnMax - m, mnMax - n ) = tau;
1286 for(
size_t i = 0; i < tfreq.size(); ++i )
1288 ETFxn[i] = go_lp.
clETF( i, gopt_lp );
1289 NTFxn[i] = go_lp.
clNTF( i, gopt_lp );
1294 for(
size_t i = 0; i < tfreq.size(); ++i )
1303 std::string tfOutFile = std::format(
"{}/outputTF_{}_lp",dir,mags[s]);
1306 std::string etfOutFile = std::format(
"{}/etf_{}_{}.binv", tfOutFile, m, n);
1311 std::string ntfOutFile = std::format(
"{}/ntf_{}_{}.binv", tfOutFile, m, n);
1318 std::string fOutFile = tfOutFile +
"freq.binv";
1323 if( lifetimeTrials > 0 )
1325 speckleAmpPSD( spfreq, sppsd, tfreq, tPSDp, ETFxn, tPSDn, NTFxn, lifetimeTrials );
1328 realT splifeT = 100.0;
1331 realT tau = pvm(
error, spfreq, sppsd, splifeT ) * ( splifeT ) / spvar;
1333 speckleLifetimes_lp( mnMax + m, mnMax + n ) = tau;
1334 speckleLifetimes_lp( mnMax - m, mnMax - n ) = tau;
1343 std::string psdOutFile = std::format(
"{}/outputPSDs_{}_si/psd_{}_{}.binv",dir,mags[s],m,n);
1349 std::vector<realT> psdOut( tPSDp.size() + tPSDpHF.size() );
1356 for(
size_t i = 0; i < tfreq.size(); ++i )
1358 go_si.
clTF2( ETF, NTF, i, gopt );
1359 psdOut[i] = tPSDp[i] * ETF + tPSDn[i] * NTF;
1362 for(
size_t i = 0; i < tPSDpHF.size(); ++i )
1364 psdOut[tfreq.size() + i] = tPSDpHF[i];
1369 for(
size_t i = 0; i < tfreq.size(); ++i )
1371 psdOut[i] = tPSDp[i];
1374 for(
size_t i = 0; i < tPSDpHF.size(); ++i )
1376 psdOut[tfreq.size() + i] = tPSDpHF[i];
1384 psdOutFile = std::format(
"{}/outputPSDs_{}_si/freq.binv", dir, mags[s]);
1391 std::string psdOutFile = std::format(
"{}/outputPSDs_{}_lp/psd_{}_{}.binv",dir,mags[s],m,n);
1402 for(
size_t i = 0; i < tfreq.size(); ++i )
1404 go_lp.
clTF2( ETF, NTF, i, gopt_lp );
1405 psdOut[i] = tPSDp[i] * ETF + tPSDn[i] * NTF;
1407 for(
size_t i = 0; i < tPSDpHF.size(); ++i )
1409 psdOut[tfreq.size() + i] = tPSDpHF[i];
1414 for(
size_t i = 0; i < tfreq.size(); ++i )
1416 psdOut[i] = tPSDp[i];
1419 for(
size_t i = 0; i < tPSDpHF.size(); ++i )
1421 psdOut[tfreq.size() + i] = tPSDpHF[i];
1429 psdOutFile = std::format(
"{}/outputPSDs_{}_lp/freq.binv", dir, mags[s]);
1442 Eigen::Array<
realT, -1, -1> cim;
1445 std::string fn = std::format(
"{}/gainmap_{}_si.fits",dir, mags[s]);
1447 ff.
write( fn, gains );
1449 fn = std::format(
"{}/varmap_{}_si.fits",dir, mags[s]);
1451 ff.
write( fn, vars );
1455 realT Ssi = exp( -1 * cim.sum() );
1456 S_si.push_back( strehl );
1459 fn = std::format(
"{}/contrast_{}_si.fits",dir, mags[s]);
1461 ff.
write( fn, cim );
1463 if( lifetimeTrials > 0 )
1465 fn = std::format(
"{}/speckleLifetimes_{}_si.fits",dir, mags[s]);
1467 ff.
write( fn, speckleLifetimes );
1472 fn = std::format(
"{}/gainmap_{}_lp.fits",dir, mags[s]);
1474 ff.
write( fn, gains_lp );
1476 fn = std::format(
"{}/lpcmap_{}_lp.fits",dir, mags[s]);
1478 ff.
write( fn, lpC );
1480 fn = std::format(
"{}/varmap_{}_lp.fits",dir, mags[s]);
1482 ff.
write( fn, vars_lp );
1487 realT Slp = strehl * exp( -1 * cim.sum() ) /
1489 S_lp.push_back( Slp );
1492 fn = std::format(
"{}/contrast_{}_lp.fits",dir, mags[s]);
1494 ff.
write( fn, cim );
1496 if( lifetimeTrials > 0 )
1498 fn = std::format(
"{}/speckleLifetimes_{}_lp.fits",dir, mags[s]);
1500 ff.
write( fn, speckleLifetimes_lp );
1506 fn = dir +
"/strehl_si.txt";
1508 for(
size_t i = 0; i < mags.size(); ++i )
1510 fout << mags[i] <<
" " << S_si[i] <<
"\n";
1517 fn = dir +
"/strehl_lp.txt";
1519 for(
size_t i = 0; i < mags.size(); ++i )
1521 fout << mags[i] <<
" " << S_lp[i] <<
"\n";
1532 const std::string &subDir,
1534 const std::string &psdDir,
1535 const std::string &CvdPath,
1538 std::vector<realT> &mags,
1543 std::string dir = psdDir +
"/" + subDir;
1546 mkdir( dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
1549 std::string fn = dir +
'/' +
"splife_params.txt";
1552 fout <<
"#---------------------------\n";
1553 m_aosys->dumpAOSystem( fout );
1554 fout <<
"#---------------------------\n";
1555 fout <<
"# Analysis Parameters\n";
1556 fout <<
"# mnMax = " << mnMax <<
'\n';
1557 fout <<
"# mnCon = " << mnCon <<
'\n';
1558 fout <<
"# mags = ";
1559 for(
size_t i = 0; i < mags.size() - 1; ++i )
1560 fout << mags[i] <<
",";
1561 fout << mags[mags.size() - 1] <<
'\n';
1562 fout <<
"# lifetimeTrials = " << lifetimeTrials <<
'\n';
1564 fout <<
"# writePSDs = " << std::boolalpha << writePSDs <<
'\n';
1568 realT fs = 1.0 / m_aosys->tauWFS();
1569 realT tauWFS = m_aosys->tauWFS();
1570 realT deltaTau = m_aosys->deltaTau();
1573 std::vector<sigproc::fourierModeDef> fms;
1576 size_t nModes = 0.5 * fms.size();
1577 std::cerr <<
"nModes: " << nModes <<
" (" << fms.size() <<
")\n";
1579 Eigen::Array<
realT, -1, -1> speckleLifetimes;
1580 Eigen::Array<
realT, -1, -1> speckleLifetimes_lp;
1582 speckleLifetimes.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
1583 speckleLifetimes( mnMax, mnMax ) = 0;
1585 speckleLifetimes_lp.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
1586 speckleLifetimes_lp( mnMax, mnMax ) = 0;
1592 std::vector<realT> tfreq;
1593 std::vector<realT> tPSDp;
1594 std::vector<realT> tPSDn;
1595 std::vector<complexT> tETF;
1596 std::vector<complexT> tNTF;
1598 if( getGridFreq( tfreq, psdDir ) < 0 )
1602 while( tfreq[imax] <= 0.5 * fs )
1605 if( imax > tfreq.size() - 1 )
1609 if( imax < tfreq.size() - 1 && tfreq[imax] <= 0.5 * fs * ( 1.0 + 1e-7 ) )
1612 tfreq.erase( tfreq.begin() + imax, tfreq.end() );
1615 tPSDn.resize( tfreq.size() );
1616 std::vector<std::vector<realT>> sqrtOPDPSD;
1617 sqrtOPDPSD.resize( nModes );
1619 std::vector<std::vector<realT>> opdPSD;
1620 opdPSD.resize( nModes );
1622 std::vector<realT> psd2sided;
1625 std::vector<realT> modeVar;
1626 modeVar.resize( nModes );
1632 for(
size_t i = 0; i < nModes; ++i )
1635 int m = fms[2 * i].m;
1636 int n = fms[2 * i].n;
1639 if( getGridPSD( tPSDp, psdDir, m, n ) < 0 )
1641 tPSDp.erase( tPSDp.begin() + imax, tPSDp.end() );
1648 opdPSD[i].resize( psd2sided.size() );
1649 sqrtOPDPSD[i].resize( psd2sided.size() );
1651 for(
size_t j = 0; j < psd2sided.size(); ++j )
1653 opdPSD[i][j] = psd2sided[j] * modeVar[i];
1654 sqrtOPDPSD[i][j] = sqrt( psd2sided[j] );
1658 size_t sz2Sided = psd2sided.size();
1660 std::vector<realT> freq2sided;
1661 freq2sided.resize( sz2Sided );
1664 tPSDp.resize( tfreq.size() );
1665 tETF.resize( tfreq.size() );
1666 tNTF.resize( tfreq.size() );
1668 std::vector<std::vector<realT>> sqrtNPSD;
1669 sqrtNPSD.resize( nModes );
1671 std::vector<realT> noiseVar;
1672 noiseVar.resize( nModes );
1674 std::vector<std::vector<complexT>> ETFsi;
1675 std::vector<std::vector<complexT>> ETFlp;
1676 ETFsi.resize( nModes );
1677 ETFlp.resize( nModes );
1679 std::vector<std::vector<complexT>> NTFsi;
1680 std::vector<std::vector<complexT>> NTFlp;
1681 NTFsi.resize( nModes );
1682 NTFlp.resize( nModes );
1684 std::string tfInFile;
1685 std::string etfInFile;
1686 std::string ntfInFile;
1690 ff.
read( Cvd, CvdPath );
1692 std::vector<std::complex<realT>> tPSDc, psd2sidedc;
1698 for(
size_t s = 0; s < mags.size(); ++s )
1703 for(
size_t i = 0; i < nModes; ++i )
1706 int m = fms[2 * i].m;
1707 int n = fms[2 * i].n;
1710 bool inside =
false;
1712 if( m_aosys->circularLimit() )
1714 if( m * m + n * n <= mnCon * mnCon )
1719 if( fabs( m ) <= mnCon && fabs( n ) <= mnCon )
1724 wfsNoisePSD<realT>( tPSDn,
1725 m_aosys->beta_p( m, n ),
1726 m_aosys->Fg( mags[s] ),
1728 m_aosys->npix_wfs( (
size_t)0 ),
1729 m_aosys->Fbg( (
size_t)0 ),
1730 m_aosys->ron_wfs( (
size_t)0 ) );
1736 sqrtNPSD[i].resize( psd2sided.size() );
1737 for(
size_t j = 0; j < psd2sided.size(); ++j )
1738 sqrtNPSD[i][j] = sqrt( psd2sided[j] );
1740 ETFsi[i].resize( sz2Sided );
1741 ETFlp[i].resize( sz2Sided );
1742 NTFsi[i].resize( sz2Sided );
1743 NTFlp[i].resize( sz2Sided );
1747 tfInFile = std::format(
"{}/outputTF_{}_si",dir, mags[s]);
1750 etfInFile = std::format(
"{}/etf_{}_{}.binv",tfInFile, m, n);
1754 for(
size_t j = 0; j < psd2sidedc.size(); ++j )
1755 ETFsi[i][j] = psd2sidedc[j];
1757 ntfInFile = std::format(
"{}/ntf_{}_{}.binv",tfInFile, m, n);
1761 for(
size_t j = 0; j < psd2sidedc.size(); ++j )
1762 NTFsi[i][j] = psd2sidedc[j];
1764 tfInFile = std::format(
"{}/outputTF_{}_lp",dir, mags[s]);
1767 etfInFile = std::format(
"{}/etf_{}_{}.binv",tfInFile, m, n);
1771 for(
size_t j = 0; j < psd2sidedc.size(); ++j )
1772 ETFlp[i][j] = psd2sidedc[j];
1774 ntfInFile = std::format(
"{}/ntf_{}_{}.binv",tfInFile, m, n);
1778 for(
size_t j = 0; j < psd2sidedc.size(); ++j )
1779 NTFlp[i][j] = psd2sidedc[j];
1783 for(
int q = 0; q < ETFsi.size(); ++q )
1796 std::vector<std::vector<realT>> spPSDs;
1797 spPSDs.resize( nModes );
1798 for(
size_t pp = 0; pp < spPSDs.size(); ++pp )
1800 spPSDs[pp].resize( tavgPgram.
size() );
1801 for(
size_t nn = 0; nn < spPSDs[pp].size(); ++nn )
1805 std::vector<std::vector<realT>> spPSDslp;
1806 spPSDslp.resize( nModes );
1807 for(
size_t pp = 0; pp < spPSDslp.size(); ++pp )
1809 spPSDslp[pp].resize( tavgPgram.
size() );
1810 for(
size_t nn = 0; nn < spPSDslp[pp].size(); ++nn )
1811 spPSDslp[pp][nn] = 0;
1821 math::ft::fftT<realT, std::complex<realT>, 1, 0> fftF( sqrtOPDPSD[0].size() );
1825 std::vector<std::complex<realT>> tform1( sqrtOPDPSD[0].size() );
1826 std::vector<std::complex<realT>> tform2( sqrtOPDPSD[0].size() );
1827 std::vector<std::complex<realT>> Ntform1( sqrtOPDPSD[0].size() );
1828 std::vector<std::complex<realT>> Ntform2( sqrtOPDPSD[0].size() );
1830 std::vector<std::complex<realT>> tform1lp( sqrtOPDPSD[0].size() );
1831 std::vector<std::complex<realT>> tform2lp( sqrtOPDPSD[0].size() );
1832 std::vector<std::complex<realT>> Ntform1lp( sqrtOPDPSD[0].size() );
1833 std::vector<std::complex<realT>> Ntform2lp( sqrtOPDPSD[0].size() );
1836 sigproc::psdFilter<realT, 1> pfilt;
1837 pfilt.psdSqrt( &sqrtOPDPSD[0], tfreq[1] - tfreq[0] );
1840 sigproc::psdFilter<realT, 1> nfilt;
1841 nfilt.psdSqrt( &sqrtNPSD[0], tfreq[1] - tfreq[0] );
1844 std::vector<std::vector<realT>> hts;
1845 hts.resize( 2 * nModes );
1848 std::vector<std::vector<realT>> htsCorr;
1849 htsCorr.resize( 2 * nModes );
1851 for(
size_t pp = 0; pp < hts.size(); ++pp )
1853 hts[pp].resize( sqrtOPDPSD[0].size() );
1854 htsCorr[pp].resize( sqrtOPDPSD[0].size() );
1858 std::vector<realT> N_n;
1859 N_n.resize( sz2Sided );
1861 std::vector<realT> N_nm;
1862 N_nm.resize( sz2Sided );
1869 std::vector<realT> tpgram( avgPgram.
size() );
1873 spTS.resize( 2 * mnMax + 1, 2 * mnMax + 1, tform1.size() );
1876 spTSlp.resize( 2 * mnMax + 1, 2 * mnMax + 1, tform1.size() );
1880 for(
int zz = 0; zz < lifetimeTrials; ++zz )
1883 std::complex<realT>( ( tform1.size() ), 0 );
1888 for(
size_t pp = 0; pp < nModes; ++pp )
1891 for(
size_t nn = 0; nn < hts[2 * pp].size(); ++nn )
1893 hts[2 * pp][nn] = normVar;
1897 pfilt.psdSqrt( &sqrtOPDPSD[pp], tfreq[1] - tfreq[0] );
1900 pfilt( hts[2 * pp] );
1904 fftF( tform1.data(), hts[2 * pp].data() );
1907 for(
size_t nn = 0; nn < hts[2 * pp].size(); ++nn )
1908 tform1[nn] = tform1[nn] * scale;
1910 fftB( hts[2 * pp + 1].data(), tform1.data() );
1920 for(
size_t pp = 0; pp < hts.size(); ++pp )
1922 for(
size_t nn = 0; nn < hts[0].size(); ++nn )
1924 htsCorr[pp][nn] = 0;
1927 for(
size_t qq = 0; qq <= pp; ++qq )
1929 realT cvd = Cvd( qq, pp );
1930 realT *d1 = htsCorr[pp].data();
1931 realT *d2 = hts[qq].data();
1932 for(
size_t nn = 0; nn < hts[0].size(); ++nn )
1934 d1[nn] += d2[nn] * cvd;
1952 for(
size_t pp = 0; pp < nModes; ++pp )
1958 realT norm = sqrt( modeVar[pp] / var );
1959 for(
size_t nn = 0; nn < htsCorr[2 * pp].size(); ++nn )
1960 htsCorr[2 * pp][nn] *= norm;
1963 norm = sqrt( modeVar[pp] / var );
1964 for(
size_t nn = 0; nn < htsCorr[2 * pp + 1].size(); ++nn )
1965 htsCorr[2 * pp + 1][nn] *= norm;
1968 scale = std::complex<realT>( tform1.size(), 0 );
1973 for(
size_t pp = 0; pp < nModes; ++pp )
1978 fftF( tform1.data(), htsCorr[2 * pp].data() );
1979 fftF( tform2.data(), htsCorr[2 * pp + 1].data() );
1982 for(
int nn = 0; nn < sz2Sided; ++nn )
1990 pfilt.psdSqrt( &sqrtNPSD[pp], tfreq[1] - tfreq[0] );
1991 nfilt.filter( N_n );
1992 nfilt.filter( N_nm );
1996 realT norm = sqrt( noiseVar[pp] / Nactvar );
1997 for(
size_t q = 0; q < N_n.size(); ++q )
1999 for(
size_t q = 0; q < N_nm.size(); ++q )
2003 fftF( Ntform1.data(), N_n.data() );
2004 fftF( Ntform2.data(), N_nm.data() );
2007 for(
size_t mm = 0; mm < tform1.size(); ++mm )
2010 tform1lp[mm] = tform1[mm] * ETFlp[pp][mm] / scale;
2011 tform2lp[mm] = tform2[mm] * ETFlp[pp][mm] / scale;
2013 Ntform1lp[mm] = Ntform1[mm] * NTFlp[pp][mm] / scale;
2014 Ntform2lp[mm] = Ntform2[mm] * NTFlp[pp][mm] / scale;
2016 tform1[mm] *= ETFsi[pp][mm] / scale;
2017 tform2[mm] *= ETFsi[pp][mm] / scale;
2019 Ntform1[mm] *= NTFsi[pp][mm] / scale;
2020 Ntform2[mm] *= NTFsi[pp][mm] / scale;
2024 int m = fms[2 * pp].m;
2025 int n = fms[2 * pp].n;
2028 fftB( htsCorr[2 * pp].data(), tform1.data() );
2029 fftB( htsCorr[2 * pp + 1].data(), tform2.data() );
2030 fftB( N_n.data(), Ntform1.data() );
2031 fftB( N_nm.data(), Ntform2.data() );
2033 for(
int i = 0; i < hts[2 * pp].size(); ++i )
2035 realT h1 = htsCorr[2 * pp][i] + N_n[i];
2036 realT h2 = htsCorr[2 * pp + 1][i] + N_nm[i];
2038 spTS.
image( i )( mnMax + m, mnMax + n ) = ( pow( h1, 2 ) + pow( h2, 2 ) );
2039 spTS.
image( i )( mnMax - m, mnMax - n ) = spTS.
image( i )( mnMax + m, mnMax + n );
2042 fftB( htsCorr[2 * pp].data(), tform1lp.data() );
2043 fftB( htsCorr[2 * pp + 1].data(), tform2lp.data() );
2044 fftB( N_n.data(), Ntform1lp.data() );
2045 fftB( N_nm.data(), Ntform2lp.data() );
2047 for(
int i = 0; i < hts[2 * pp].size(); ++i )
2049 realT h1 = htsCorr[2 * pp][i] + N_n[i];
2050 realT h2 = htsCorr[2 * pp + 1][i] + N_nm[i];
2052 spTSlp.
image( i )( mnMax + m, mnMax + n ) = ( pow( h1, 2 ) + pow( h2, 2 ) );
2053 spTSlp.
image( i )( mnMax - m, mnMax - n ) = spTSlp.
image( i )( mnMax + m, mnMax + n );
2060 std::vector<realT> speckAmp( spTS.planes() );
2061 std::vector<realT> speckAmplp( spTS.planes() );
2063 for(
size_t pp = 0; pp < nModes; ++pp )
2065 int m = fms[2 * pp].m;
2066 int n = fms[2 * pp].n;
2070 for(
int i = 0; i < spTS.planes(); ++i )
2072 speckAmp[i] = spTS.
image( i )( mnMax + m, mnMax + n );
2073 speckAmplp[i] = spTSlp.
image( i )( mnMax + m, mnMax + n );
2076 mnlp += speckAmplp[i];
2078 mn /= speckAmp.size();
2079 mnlp /= speckAmplp.size();
2082 for(
int i = 0; i < speckAmp.size(); ++i )
2084 for(
int i = 0; i < speckAmplp.size(); ++i )
2085 speckAmplp[i] -= mnlp;
2088 avgPgram( tpgram, speckAmp );
2089 for(
size_t nn = 0; nn < spPSDs[pp].size(); ++nn )
2090 spPSDs[pp][nn] += tpgram[nn];
2092 avgPgram( tpgram, speckAmplp );
2093 for(
size_t nn = 0; nn < spPSDslp[pp].size(); ++nn )
2094 spPSDslp[pp][nn] += tpgram[nn];
2101 std::vector<realT> spFreq( spPSDs[0].size() );
2102 for(
size_t nn = 0; nn < spFreq.size(); ++nn )
2103 spFreq[nn] = tavgPgram[nn];
2106 taus.
resize( 2 * mnMax + 1, 2 * mnMax + 1 );
2107 tauslp.resize( 2 * mnMax + 1, 2 * mnMax + 1 );
2110 std::vector<realT> clPSD;
2114 imc.resize( 2 * mnMax + 1, 2 * mnMax + 1, spPSDs[0].size() );
2115 imclp.resize( 2 * mnMax + 1, 2 * mnMax + 1, spPSDs[0].size() );
2116 clPSD.resize( sz2Sided );
2123 for(
size_t pp = 0; pp < nModes; ++pp )
2125 spPSDs[pp][0] = spPSDs[pp][1];
2126 spPSDslp[pp][0] = spPSDslp[pp][1];
2128 int m = fms[2 * pp].m;
2129 int n = fms[2 * pp].n;
2134 for(
size_t nn = 0; nn < spPSDs[pp].size(); ++nn )
2136 spPSDs[pp][nn] /= lifetimeTrials;
2139 for(
size_t nn = 0; nn < sz2Sided; ++nn )
2142 opdPSD[pp][nn] * norm( ETFsi[pp][nn] ) + pow( sqrtNPSD[pp][nn], 2 ) * norm( NTFsi[pp][nn] );
2149 for(
size_t nn = 0; nn < spPSDs[pp].size(); ++nn )
2151 spPSDs[pp][nn] *= var / pvar;
2152 imc.
image( nn )( mnMax + m, mnMax + n ) = spPSDs[pp][nn];
2153 imc.
image( nn )( mnMax - m, mnMax - n ) = spPSDs[pp][nn];
2157 for(
size_t nn = 0; nn < spPSDslp[pp].size(); ++nn )
2159 spPSDslp[pp][nn] /= lifetimeTrials;
2162 for(
size_t nn = 0; nn < sz2Sided; ++nn )
2165 opdPSD[pp][nn] * norm( ETFlp[pp][nn] ) + pow( sqrtNPSD[pp][nn], 2 ) * norm( NTFlp[pp][nn] );
2172 for(
size_t nn = 0; nn < spPSDslp[pp].size(); ++nn )
2174 spPSDslp[pp][nn] *= var / pvar;
2175 imclp.
image( nn )( mnMax + m, mnMax + n ) = spPSDslp[pp][nn];
2176 imclp.
image( nn )( mnMax - m, mnMax - n ) = spPSDslp[pp][nn];
2182 realT T = ( 1.0 / ( spFreq[1] - spFreq[0] ) ) * 10;
2184 realT tau = pvm(
error, spFreq, spPSDs[pp], T ) * ( T ) / var;
2185 taus( mnMax + m, mnMax + n ) = tau;
2186 taus( mnMax - m, mnMax - n ) = tau;
2190 tau = pvm(
error, spFreq, spPSDslp[pp], T ) * ( T ) / var;
2191 tauslp( mnMax + m, mnMax + n ) = tau;
2192 tauslp( mnMax - m, mnMax - n ) = tau;
2198 fn = std::format(
"{}/speckleLifetimes_{}_si.fits",dir, mags[s]);
2200 ff.
write( fn, taus );
2202 fn = std::format(
"{}/speckleLifetimes_{}_lp.fits",dir, mags[s]);
2204 ff.
write( fn, tauslp );
2208 fn = std::format(
"{}/specklePSDs_{}_si.fits",dir, mags[s]);
2210 ff.
write( fn, imc );
2212 fn = std::format(
"{}/speckleLifetimes_{}_lp.fits",dir, mags[s]);
2214 ff.
write( fn, imclp );