27 #ifndef fourierTemporalPSD_hpp
28 #define fourierTemporalPSD_hpp
35 #include <gsl/gsl_integration.h>
36 #include <gsl/gsl_errno.h>
38 #include <Eigen/Dense>
40 #include "../../math/constants.hpp"
41 #include "../../math/func/jinc.hpp"
42 #include "../../math/func/airyPattern.hpp"
43 #include "../../math/vectorUtils.hpp"
44 #include "../../ioutils/fits/fitsFile.hpp"
45 #include "../../sigproc/fourierModes.hpp"
46 #include "../../sigproc/psdVarMean.hpp"
47 #include "../../ioutils/stringUtils.hpp"
48 #include "../../ioutils/readColumns.hpp"
49 #include "../../ioutils/binVector.hpp"
50 #include "../../ioutils/fileUtils.hpp"
52 #include "../../ipc/ompLoopWatcher.hpp"
53 #include "../../mxError.hpp"
89 template<
typename realT,
typename aosysT>
90 realT
F_basic (realT kv,
void * params) ;
93 template<
typename realT,
typename aosysT>
94 realT
F_mod (realT kv,
void * params);
97 template<
typename realT,
typename aosysT>
112 template<
typename _realT,
typename aosysT>
131 realT m_opticalGain {1.0};
141 gsl_integration_workspace *
_w;
152 std::vector<realT> Jps;
153 std::vector<realT> Jms;
155 std::vector<realT> ms;
156 std::vector<realT> ns;
158 void initProjection()
169 sigproc::fourierModeCoordinates( m, n, p, i);
251 std::vector<realT> &freq,
264 template<
bool m_parallel>
268 int m_multiLayerPSD( std::vector<realT> & PSD,
269 std::vector<realT> & freq,
274 isParallel<true> parallel );
277 int m_multiLayerPSD( std::vector<realT> & PSD,
278 std::vector<realT> & freq,
283 isParallel<false> parallel );
297 template<
bool parallel=true>
299 std::vector<realT> & freq,
328 const std::string & psdDir,
333 std::vector<realT> & mags,
334 int lifetimeTrials = 0,
335 bool uncontrolledLifetimes =
false,
336 bool writePSDs =
false,
337 bool writeXfer =
false
341 const std::string & psdDir,
342 const std::string & CvdPath,
345 const std::string & si_or_lp,
346 std::vector<realT> & mags,
376 const std::string & dir
383 const std::string & dir,
392 std::vector<realT> & psd,
393 const std::string & dir,
401 template<
typename realT,
typename aosysT>
408 template<
typename realT,
typename aosysT>
416 _w = gsl_integration_workspace_alloc (WSZ);
420 template<
typename realT,
typename aosysT>
425 gsl_integration_workspace_free (_w);
429 template<
typename realT,
typename aosysT>
432 _useBasis = basis::modified;
439 template<
typename realT,
typename aosysT>
445 template<
typename realT,
typename aosysT>
451 template<
typename realT,
typename aosysT>
457 template<
typename realT,
typename aosysT>
463 template<
typename realT,
typename aosysT>
469 ku = ( (
realT) m / m_aosys->D());
470 kv = ( (
realT) n / m_aosys->D());
474 for(
size_t i=0; i< m_aosys->atm.n_layers(); ++i)
476 vu = m_aosys->atm.layer_v_wind(i) * cos(m_aosys->atm.layer_dir(i));
477 vv = m_aosys->atm.layer_v_wind(i) * sin(m_aosys->atm.layer_dir(i));
479 f = fabs(ku*vu + kv*vv);
480 if(f > fmax) fmax = f;
486 template<
typename realT,
typename aosysT>
488 std::vector<realT> &freq,
495 if(fmax == 0) fmax = freq[freq.size()-1];
497 realT v_wind = m_aosys->atm.layer_v_wind(layer_i);
498 realT q_wind = m_aosys->atm.layer_dir(layer_i);
502 realT cq = cos(q_wind);
503 realT sq = sin(q_wind);
506 realT scale = 2*(1/v_wind);
509 gsl_set_error_handler_off();
516 params.
m_m = m*cq + n*sq;
517 params.
m_n = -m*sq + n*cq;
520 if(m_aosys->spatialFilter_ku() < std::numeric_limits<realT>::max() || m_aosys->spatialFilter_kv() < std::numeric_limits<realT>::max()) params.
m_spatialFilter =
true;
527 params.m_minCoeffVal = m_minCoeffVal;
536 func.function = &F_basic<realT, aosysT>;
538 case basis::modified:
539 func.function = &F_mod<realT, aosysT>;
541 case basis::projected_basic:
542 mxError(
"fourierTemporalPSD::singleLayerPSD", MXE_NOTIMPL,
"Projected basic-basis modes are not implemented.");
544 case basis::projectedm_modified:
552 func.function = &Fm_projMod<realT, aosysT>;
556 mxError(
"fourierTemporalPSD::singleLayerPSD", MXE_INVALIDARG,
"value of _useBasis is not valid.");
560 func.params = ¶ms;
565 while( freq[i] <= fmax )
567 params.
m_f = freq[i];
569 int ec = gsl_integration_qagi (&func, _absTol, _relTol, WSZ, params.
_w, &result, &error);
571 if(ec == GSL_EDIVERGE)
573 std::cerr <<
"GSL_EDIVERGE:" << p <<
" " << freq[i] <<
" " << v_wind <<
" " << m <<
" " << n <<
" " << m_m <<
" " << m_n <<
"\n";
574 std::cerr <<
"ignoring . . .\n";
577 PSD[i] = scale*result;
580 if(i >= freq.size())
break;
586 if(j == freq.size())
return 0;
589 PSD[j] = PSD[i-50] * pow( freq[i-50]/freq[j], m_aosys->atm.alpha(layer_i)+2);
590 for(
size_t k=49;
k> 0; --
k)
592 PSD[j] += PSD[i-
k] * pow( freq[i-
k]/freq[j], m_aosys->atm.alpha(layer_i)+2);
597 if(j == freq.size())
return 0;
598 while(j < freq.size())
600 PSD[j] = PSD[i-1] * pow( freq[i-1]/freq[j], m_aosys->atm.alpha(layer_i)+2);
609 template<
typename realT,
typename aosysT>
611 std::vector<realT> & freq,
616 isParallel<true> parallel )
618 static_cast<void>(parallel);
623 std::vector<realT> single_PSD(freq.size());
626 for(
size_t i=0; i< m_aosys->atm.n_layers(); ++i)
628 singleLayerPSD(single_PSD, freq, m, n, i, p, fmax);
632 for(
size_t j=0; j<freq.size(); ++j)
634 PSD[j] += m_aosys->atm.layer_Cn2(i)*single_PSD[j];
642 template<
typename realT,
typename aosysT>
643 int fourierTemporalPSD<realT, aosysT>::m_multiLayerPSD( std::vector<realT> & PSD,
644 std::vector<realT> & freq,
649 isParallel<false> parallel )
651 static_cast<void>(parallel);
654 std::vector<realT> single_PSD(freq.size());
656 for(
size_t i=0; i< m_aosys->atm.n_layers(); ++i)
658 singleLayerPSD(single_PSD, freq, m, n, i, p, fmax);
661 for(
size_t j=0; j<freq.size(); ++j)
663 PSD[j] += m_aosys->atm.layer_Cn2(i)*single_PSD[j];
671 template<
typename realT,
typename aosysT>
672 template<
bool parallel>
674 std::vector<realT> & freq,
681 for(
size_t j=0;j<PSD.size(); ++j) PSD[j] = 0;
685 fmax = 150 + 2*fastestPeak(m, n);
688 return m_multiLayerPSD( PSD, freq, m, n, p, fmax, isParallel<parallel>());
693 template<
typename realT,
typename aosysT>
701 std::vector<realT> freq;
703 std::vector<sigproc::fourierModeDef> spf;
707 sigproc::makeFourierModeFreqs_Rect(spf, 2*mnMax);
710 int N = (int) (maxFreq/dFreq);
711 if( N * dFreq < maxFreq) N += 1;
715 mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
718 fn = dir +
'/' +
"params.txt";
721 fout <<
"#---------------------------\n";
722 m_aosys->dumpAOSystem(fout);
723 fout <<
"#---------------------------\n";
724 fout <<
"# PSD Grid Parameters\n";
725 fout <<
"# absTol " << _absTol <<
'\n';
726 fout <<
"# relTol " << _relTol <<
'\n';
727 fout <<
"# useBasis " << _useBasis <<
'\n';
728 fout <<
"# makePSDGrid call:\n";
729 fout <<
"# mnMax = " << mnMax <<
'\n';
730 fout <<
"# dFreq = " << dFreq <<
'\n';
731 fout <<
"# maxFreq = " << maxFreq <<
'\n';
732 fout <<
"# fmax = " << fmax <<
'\n';
733 fout <<
"#---------------------------\n";
741 fn = dir +
'/' +
"freq.binv";
745 size_t nLoops = 0.5*spf.size();
751 std::vector<realT> PSD;
758 for(
size_t i=0; i<nLoops; ++i)
763 if(fabs((
realT)m/m_aosys->D()) >= m_aosys->spatialFilter_ku() || fabs((
realT)n/m_aosys->D()) >= m_aosys->spatialFilter_kv())
769 multiLayerPSD<false>( PSD, freq, m, n, 1, fmax);
780 template<
typename realT,
typename aosysT>
782 const std::string & psdDir,
787 std::vector<realT> & mags,
789 bool uncontrolledLifetimes,
795 std::string dir = psdDir +
"/" + subDir;
798 mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
801 std::string fn = dir +
'/' +
"params.txt";
804 fout <<
"#---------------------------\n";
805 m_aosys->dumpAOSystem(fout);
806 fout <<
"#---------------------------\n";
807 fout <<
"# Analysis Parameters\n";
808 fout <<
"# mnMax = " << mnMax <<
'\n';
809 fout <<
"# mnCon = " << mnCon <<
'\n';
810 fout <<
"# lpNc = " << lpNc <<
'\n';
812 for(
size_t i=0; i<mags.size()-1; ++i) fout << mags[i] <<
",";
813 fout << mags[mags.size()-1] <<
'\n';
814 fout <<
"# lifetimeTrials = " << lifetimeTrials <<
'\n';
815 fout <<
"# uncontrolledLifetimes = " << uncontrolledLifetimes <<
'\n';
816 fout <<
"# writePSDs = " << std::boolalpha << writePSDs <<
'\n';
817 fout <<
"# writeXfer = " << std::boolalpha << writeXfer <<
'\n';
827 realT fs = 1.0/m_aosys->tauWFS();
828 realT tauWFS = m_aosys->tauWFS();
829 realT deltaTau = m_aosys->deltaTau();
831 std::vector<sigproc::fourierModeDef> fms;
833 sigproc::makeFourierModeFreqs_Rect(fms, 2*mnMax);
834 size_t nModes = 0.5*fms.size();
836 Eigen::Array<
realT, -1, -1> gains, vars, speckleLifetimes, gains_lp, vars_lp, speckleLifetimes_lp;
838 gains.resize(2*mnMax+1, 2*mnMax+1);
839 vars.resize(2*mnMax+1, 2*mnMax+1);
840 speckleLifetimes.resize(2*mnMax+1, 2*mnMax+1);
842 gains(mnMax, mnMax) = 0;
843 vars(mnMax, mnMax) = 0;
844 speckleLifetimes(mnMax, mnMax) = 0;
846 gains_lp.resize(2*mnMax+1, 2*mnMax+1);
847 vars_lp.resize(2*mnMax+1, 2*mnMax+1);
848 speckleLifetimes_lp.resize(2*mnMax+1, 2*mnMax+1);
850 gains_lp(mnMax, mnMax) = 0;
851 vars_lp(mnMax, mnMax) = 0;
852 speckleLifetimes_lp(mnMax, mnMax) = 0;
855 if(lpNc > 1) doLP =
true;
856 Eigen::Array<
realT, -1, -1> lpC;
860 lpC.resize(nModes, lpNc);
864 std::vector<realT> S_si, S_lp;
868 for(
size_t s=0; s< mags.size(); ++s)
871 mkdir(psdOutDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
876 mkdir(psdOutDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
884 for(
size_t s = 0; s < mags.size(); ++s)
888 realT localMag = mags[s];
894 realT gopt_lp, var_lp;
896 std::vector<realT> tfreq;
897 std::vector<realT> tPSDp;
898 std::vector<realT> tPSDpPOL;
900 std::vector<realT> tfreqHF;
901 std::vector<realT> tPSDpHF;
904 getGridPSD( tfreq, tPSDp, psdDir, 0, 1 );
907 while( tfreq[imax] <= 0.5*fs )
910 if(imax > tfreq.size()-1)
break;
913 if(imax < tfreq.size()-1 && tfreq[imax] <= 0.5*fs*(1.0 + 1e-7))
920 tfreqHF.assign(tfreq.begin(), tfreq.end());
923 tfreq.erase(tfreq.begin() + imax, tfreq.end());
925 tPSDpPOL.resize(tfreq.size());
928 std::vector<realT> tPSDn;
929 tPSDn.resize(tfreq.size());
933 mx::AO::analysis::clGainOpt<realT> go_si(tauWFS, deltaTau);
934 mx::AO::analysis::clGainOpt<realT> go_lp(tauWFS, deltaTau);
947 std::vector<std::complex<realT>> ETFxn;
948 std::vector<std::complex<realT>> NTFxn;
950 if(lifetimeTrials > 0)
952 ETFxn.resize(tfreq.size());
953 NTFxn.resize(tfreq.size());
975 #pragma omp for schedule(dynamic, 5)
976 for(
size_t i=0; i<nModes; ++i)
982 if( fabs((
realT)m/m_aosys->D()) >= m_aosys->spatialFilter_ku()
983 || fabs((
realT)n/m_aosys->D()) >= m_aosys->spatialFilter_kv() )
985 gains( mnMax + m, mnMax + n ) = 0;
986 gains( mnMax - m, mnMax - n ) = 0;
988 gains_lp( mnMax + m, mnMax + n ) = 0;
989 gains_lp( mnMax - m, mnMax - n ) = 0;
991 vars( mnMax + m, mnMax + n) = 0;
992 vars( mnMax - m, mnMax - n ) = 0;
994 vars_lp( mnMax + m, mnMax + n) = 0;
995 vars_lp( mnMax - m, mnMax - n ) = 0;
996 speckleLifetimes( mnMax + m, mnMax + n ) = 0;
997 speckleLifetimes( mnMax - m, mnMax - n ) = 0;
998 speckleLifetimes_lp( mnMax + m, mnMax + n ) = 0;
999 speckleLifetimes_lp( mnMax - m, mnMax - n ) = 0;
1004 realT k = sqrt(m*m + n*n)/m_aosys->D();
1007 wfsNoisePSD<realT>( tPSDn, m_aosys->beta_p(m,n), m_aosys->Fg(localMag), tauWFS, m_aosys->npix_wfs((
size_t) 0), m_aosys->Fbg((
size_t) 0), m_aosys->ron_wfs((
size_t) 0));
1010 getGridPSD( tPSDp, psdDir, m, n );
1017 tPSDpHF.assign(tPSDp.begin() + imax, tPSDp.end());
1021 tPSDp.erase(tPSDp.begin() + imax, tPSDp.end());
1028 for(
size_t n =0; n < tPSDp.size(); ++n)
1030 tPSDpPOL[n] = tPSDp[n]*pow(m_opticalGain,2);
1035 bool inside =
false;
1037 if( m_aosys->circularLimit() )
1039 if( m*m + n*n <= mnCon*mnCon) inside =
true;
1043 if(fabs(m) <= mnCon && fabs(n) <= mnCon) inside =
true;
1054 var = go_si.clVariance(tPSDp, tPSDn, gopt);
1059 gopt = go_si.optGainOpenLoop(var, tPSDpPOL, tPSDn, gmax);
1060 gopt *= m_opticalGain;
1062 var = go_si.clVariance(tPSDp, tPSDn, gopt);
1070 for(
int n=0; n< lpNc; ++n)
1072 lpC(i,n) = go_lp.a(n);
1074 go_lp.aScale(m_opticalGain);
1075 go_lp.bScale(m_opticalGain);
1076 gopt_lp *= m_opticalGain;
1078 var_lp = go_lp.clVariance(tPSDp, tPSDn, gopt_lp);
1092 go_lp.a(std::vector<realT>({1}));
1093 go_lp.b(std::vector<realT>({1}));
1102 if(gopt > 0 && var > mult*var0)
1108 if(gopt_lp > 0 && var_lp > mult*var0)
1116 gains( mnMax + m, mnMax + n ) = gopt;
1117 gains( mnMax - m, mnMax - n ) = gopt;
1119 gains_lp( mnMax + m, mnMax + n ) = gopt_lp;
1120 gains_lp( mnMax - m, mnMax - n ) = gopt_lp;
1122 vars( mnMax + m, mnMax + n) = var;
1123 vars( mnMax - m, mnMax - n ) = var;
1125 vars_lp( mnMax + m, mnMax + n) = var_lp;
1126 vars_lp( mnMax - m, mnMax - n ) = var_lp;
1130 if( (lifetimeTrials > 0 || writeXfer) && ( uncontrolledLifetimes || inside ))
1132 std::vector<realT> spfreq, sppsd;
1136 for(
size_t i=0;i<tfreq.size();++i)
1138 ETFxn[i] = go_si.clETF(i, gopt);
1139 NTFxn[i] = go_si.clNTF(i, gopt);
1144 for(
size_t i=0;i<tfreq.size();++i)
1163 std::string fOutFile = tfOutFile +
"freq.binv";
1168 if(lifetimeTrials > 0)
1170 speckleAmpPSD( spfreq, sppsd, tfreq, tPSDp, ETFxn, tPSDn, NTFxn, lifetimeTrials);
1173 realT splifeT = 100.0;
1176 realT tau = pvm(error, spfreq, sppsd, splifeT) * (splifeT)/spvar;
1178 speckleLifetimes( mnMax + m, mnMax + n ) = tau;
1179 speckleLifetimes( mnMax - m, mnMax - n ) = tau;
1186 for(
size_t i=0;i<tfreq.size();++i)
1188 ETFxn[i] = go_lp.clETF(i, gopt_lp);
1189 NTFxn[i] = go_lp.clNTF(i, gopt_lp);
1194 for(
size_t i=0;i<tfreq.size();++i)
1213 std::string fOutFile = tfOutFile +
"freq.binv";
1218 if(lifetimeTrials > 0)
1220 speckleAmpPSD( spfreq, sppsd, tfreq, tPSDp, ETFxn, tPSDn, NTFxn, lifetimeTrials);
1223 realT splifeT = 100.0;
1226 realT tau = pvm(error, spfreq, sppsd, splifeT) * (splifeT)/spvar;
1228 speckleLifetimes_lp( mnMax + m, mnMax + n ) = tau;
1229 speckleLifetimes_lp( mnMax - m, mnMax - n ) = tau;
1241 std::vector<realT> psdOut(tPSDp.size()+tPSDpHF.size());
1248 for(
size_t i=0; i< tfreq.size(); ++i)
1250 go_si.clTF2( ETF, NTF, i,gopt);
1251 psdOut[i] = tPSDp[i]*ETF + tPSDn[i]*NTF;
1254 for(
size_t i=0; i< tPSDpHF.size(); ++i)
1256 psdOut[tfreq.size() + i] = tPSDpHF[i];
1262 for(
size_t i=0; i< tfreq.size(); ++i)
1264 psdOut[i] = tPSDp[i];
1267 for(
size_t i=0; i< tPSDpHF.size(); ++i)
1269 psdOut[tfreq.size() + i] = tPSDpHF[i];
1293 for(
size_t i=0; i < tfreq.size(); ++i)
1295 go_lp.clTF2( ETF, NTF, i, gopt_lp);
1296 psdOut[i] = tPSDp[i]*ETF + tPSDn[i]*NTF;
1298 for(
size_t i=0; i< tPSDpHF.size(); ++i)
1300 psdOut[tfreq.size() + i] = tPSDpHF[i];
1305 for(
size_t i=0; i< tfreq.size(); ++i)
1307 psdOut[i] = tPSDp[i];
1310 for(
size_t i=0; i< tPSDpHF.size(); ++i)
1312 psdOut[tfreq.size() + i] = tPSDpHF[i];
1331 Eigen::Array<
realT, -1,-1> cim, psf;
1335 for(
int i=0;i<psf.rows();++i)
1337 for(
int j=0;j<psf.cols();++j)
1345 ff.
write( fn, gains);
1348 ff.
write( fn, vars);
1368 realT S = exp(-1*cim.sum());
1376 if(lifetimeTrials > 0)
1379 ff.
write( fn, speckleLifetimes);
1386 ff.
write( fn, gains_lp);
1392 ff.
write( fn, vars_lp);
1410 realT S = exp(-1*cim.sum());
1417 if(lifetimeTrials > 0)
1420 ff.
write( fn, speckleLifetimes_lp);
1426 fn = dir +
"/strehl_si.txt";
1428 for(
size_t i=0;i<mags.size(); ++i)
1430 fout << mags[i] <<
" " << S_si[i] <<
"\n";
1437 fn = dir +
"/strehl_lp.txt";
1439 for(
size_t i=0;i<mags.size(); ++i)
1441 fout << mags[i] <<
" " << S_lp[i] <<
"\n";
1451 template<
typename realT,
typename aosysT>
1453 const std::string & psdDir,
1454 const std::string & CvdPath,
1457 const std::string & si_or_lp,
1458 std::vector<realT> & mags,
1464 std::string dir = psdDir +
"/" + subDir;
1467 mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1470 std::string fn = dir +
'/' +
"splife_params.txt";
1473 fout <<
"#---------------------------\n";
1474 m_aosys->dumpAOSystem(fout);
1475 fout <<
"#---------------------------\n";
1476 fout <<
"# Analysis Parameters\n";
1477 fout <<
"# mnMax = " << mnMax <<
'\n';
1478 fout <<
"# mnCon = " << mnCon <<
'\n';
1479 fout <<
"# mags = ";
1480 for(
size_t i=0; i<mags.size()-1; ++i) fout << mags[i] <<
",";
1481 fout << mags[mags.size()-1] <<
'\n';
1482 fout <<
"# lifetimeTrials = " << lifetimeTrials <<
'\n';
1484 fout <<
"# writePSDs = " << std::boolalpha << writePSDs <<
'\n';
1488 realT fs = 1.0/m_aosys->tauWFS();
1489 realT tauWFS = m_aosys->tauWFS();
1490 realT deltaTau = m_aosys->deltaTau();
1493 std::vector<sigproc::fourierModeDef> fms;
1495 sigproc::makeFourierModeFreqs_Rect(fms, 2*mnMax);
1496 size_t nModes = 0.5*fms.size();
1497 std::cerr <<
"nModes: " << nModes <<
" (" << fms.size() <<
")\n";
1499 Eigen::Array<
realT, -1, -1> speckleLifetimes;
1500 Eigen::Array<
realT, -1, -1> speckleLifetimes_lp;
1502 speckleLifetimes.resize(2*mnMax+1, 2*mnMax+1);
1503 speckleLifetimes(mnMax, mnMax) = 0;
1505 speckleLifetimes_lp.resize(2*mnMax+1, 2*mnMax+1);
1506 speckleLifetimes_lp(mnMax, mnMax) = 0;
1512 std::vector<realT> tfreq;
1513 std::vector<realT> tPSDp;
1514 std::vector<realT> tPSDn;
1515 std::vector<complexT> tETF;
1516 std::vector<complexT> tNTF;
1518 if(getGridFreq( tfreq, psdDir) < 0)
return -1;
1522 while( tfreq[imax] <= 0.5*fs )
1525 if(imax > tfreq.size()-1)
break;
1528 if(imax < tfreq.size()-1 && tfreq[imax] <= 0.5*fs*(1.0 + 1e-7)) ++imax;
1530 tfreq.erase(tfreq.begin() + imax, tfreq.end());
1533 tPSDn.resize(tfreq.size());
1534 std::vector<std::vector<realT>> sqrtOPDPSD;
1535 sqrtOPDPSD.resize(nModes);
1537 std::vector<std::vector<realT>> opdPSD;
1538 opdPSD.resize(nModes);
1540 std::vector<realT> psd2sided;
1543 std::vector<realT> modeVar;
1544 modeVar.resize(nModes);
1550 for(
size_t i=0; i<nModes; ++i)
1557 if(getGridPSD( tPSDp, psdDir, m, n ) < 0)
return -1;
1558 tPSDp.erase(tPSDp.begin() + imax, tPSDp.end());
1565 opdPSD[i].resize(psd2sided.size());
1566 sqrtOPDPSD[i].resize(psd2sided.size());
1568 for(
size_t j=0;j<psd2sided.size();++j)
1570 opdPSD[i][j] = psd2sided[j]*modeVar[i];
1571 sqrtOPDPSD[i][j] = sqrt(psd2sided[j]);
1575 size_t sz2Sided = psd2sided.size();
1577 std::vector<realT> freq2sided;
1578 freq2sided.resize(sz2Sided);
1582 tPSDp.resize(tfreq.size());
1583 tETF.resize(tfreq.size());
1584 tNTF.resize(tfreq.size());
1586 std::vector<std::vector<realT>> sqrtNPSD;
1587 sqrtNPSD.resize(nModes);
1589 std::vector<realT> noiseVar;
1590 noiseVar.resize(nModes);
1592 std::vector<std::vector<complexT>> ETFsi;
1593 std::vector<std::vector<complexT>> ETFlp;
1594 ETFsi.resize(nModes);
1595 ETFlp.resize(nModes);
1597 std::vector<std::vector<complexT>> NTFsi;
1598 std::vector<std::vector<complexT>> NTFlp;
1599 NTFsi.resize(nModes);
1600 NTFlp.resize(nModes);
1602 std::string tfInFile;
1603 std::string etfInFile;
1604 std::string ntfInFile;
1608 ff.
read(Cvd, CvdPath);
1610 std::vector<std::complex<realT>> tPSDc, psd2sidedc;
1616 for(
size_t s = 0; s < mags.size(); ++s)
1621 for(
size_t i=0; i<nModes; ++i)
1628 bool inside =
false;
1630 if( m_aosys->circularLimit() )
1632 if( m*m + n*n <= mnCon*mnCon) inside =
true;
1636 if(fabs(m) <= mnCon && fabs(n) <= mnCon) inside =
true;
1640 wfsNoisePSD<realT>( tPSDn, m_aosys->beta_p(m,n), m_aosys->Fg(mags[s]), tauWFS, m_aosys->npix_wfs((
size_t) 0), m_aosys->Fbg((
size_t) 0), m_aosys->ron_wfs((
size_t) 0));
1646 sqrtNPSD[i].resize(psd2sided.size());
1647 for(
size_t j =0 ; j < psd2sided.size();++j) sqrtNPSD[i][j] = sqrt(psd2sided[j]);
1649 ETFsi[i].resize(sz2Sided);
1650 ETFlp[i].resize(sz2Sided);
1651 NTFsi[i].resize(sz2Sided);
1652 NTFlp[i].resize(sz2Sided);
1661 for(
size_t j =0 ; j < psd2sidedc.size();++j) ETFsi[i][j] = psd2sidedc[j];
1666 for(
size_t j =0 ; j < psd2sidedc.size();++j) NTFsi[i][j] = psd2sidedc[j];
1673 for(
size_t j =0 ; j < psd2sidedc.size();++j) ETFlp[i][j] = psd2sidedc[j];
1678 for(
size_t j =0 ; j < psd2sidedc.size();++j) NTFlp[i][j] = psd2sidedc[j];
1683 for(
int q=0;q<ETFsi.size();++q)
1694 std::vector<std::vector<realT>> spPSDs;
1695 spPSDs.resize(nModes);
1696 for(
size_t pp=0; pp < spPSDs.size(); ++pp)
1698 spPSDs[pp].resize(tavgPgram.
size());
1699 for(
size_t nn=0; nn < spPSDs[pp].size(); ++nn) spPSDs[pp][nn] = 0;
1702 std::vector<std::vector<realT>> spPSDslp;
1703 spPSDslp.resize(nModes);
1704 for(
size_t pp=0; pp < spPSDslp.size(); ++pp)
1706 spPSDslp[pp].resize(tavgPgram.
size());
1707 for(
size_t nn=0; nn < spPSDslp[pp].size(); ++nn) spPSDslp[pp][nn] = 0;
1710 #pragma omp parallel
1717 math::fft::fftT<realT, std::complex<realT>, 1, 0> fftF(sqrtOPDPSD[0].size());
1718 math::fft::fftT<std::complex<realT>,
realT, 1, 0> fftB(sqrtOPDPSD[0].size(), MXFFT_BACKWARD);
1721 std::vector<std::complex<realT>> tform1(sqrtOPDPSD[0].size());
1722 std::vector<std::complex<realT>> tform2(sqrtOPDPSD[0].size());
1723 std::vector<std::complex<realT>> Ntform1(sqrtOPDPSD[0].size());
1724 std::vector<std::complex<realT>> Ntform2(sqrtOPDPSD[0].size());
1726 std::vector<std::complex<realT>> tform1lp(sqrtOPDPSD[0].size());
1727 std::vector<std::complex<realT>> tform2lp(sqrtOPDPSD[0].size());
1728 std::vector<std::complex<realT>> Ntform1lp(sqrtOPDPSD[0].size());
1729 std::vector<std::complex<realT>> Ntform2lp(sqrtOPDPSD[0].size());
1732 sigproc::psdFilter<realT,1> pfilt;
1733 pfilt.psdSqrt(&sqrtOPDPSD[0], tfreq[1]-tfreq[0]);
1736 sigproc::psdFilter<realT,1> nfilt;
1737 nfilt.psdSqrt(&sqrtNPSD[0], tfreq[1]-tfreq[0]);
1740 std::vector<std::vector<realT>> hts;
1741 hts.resize(2*nModes);
1744 std::vector<std::vector<realT>> htsCorr;
1745 htsCorr.resize(2*nModes);
1747 for(
size_t pp=0; pp < hts.size(); ++pp)
1749 hts[pp].resize(sqrtOPDPSD[0].size());
1750 htsCorr[pp].resize(sqrtOPDPSD[0].size());
1754 std::vector<realT> N_n;
1755 N_n.resize(sz2Sided);
1757 std::vector<realT> N_nm;
1758 N_nm.resize(sz2Sided);
1766 std::vector<realT> tpgram(avgPgram.
size());
1770 spTS.resize(2*mnMax+1, 2*mnMax+1, tform1.size());
1773 spTSlp.resize(2*mnMax+1, 2*mnMax+1, tform1.size());
1778 for(
int cc =0; cc<psf.cols(); ++cc)
1780 for(
int rr=0;rr<psf.rows();++rr)
1782 realT x = sqrt( pow(rr - 0.5*(psf.rows()-1),2) + pow(cc - 0.5*(psf.cols()-1),2));
1786 psf /= psf.maxCoeff();
1790 for(
int zz=0; zz<lifetimeTrials; ++zz)
1792 std::complex<realT> scale = exp( std::complex<realT>(0, math::half_pi<realT>() ))/std::complex<realT>((tform1.size()),0) ;
1797 for(
size_t pp=0; pp < nModes; ++pp)
1800 for(
size_t nn=0; nn< hts[2*pp].size(); ++nn)
1802 hts[2*pp][nn] = normVar;
1806 pfilt.psdSqrt(&sqrtOPDPSD[pp], tfreq[1]-tfreq[0]);
1813 fftF(tform1.data(), hts[2*pp].data());
1816 for(
size_t nn=0; nn< hts[2*pp].size(); ++nn) tform1[nn] = tform1[nn]*scale;
1818 fftB(hts[2*pp+1].data(), tform1.data());
1827 for(
size_t pp=0; pp < hts.size(); ++pp)
1829 for(
size_t nn=0; nn< hts[0].size(); ++nn)
1831 htsCorr[pp][nn] = 0;
1834 for(
size_t qq=0; qq <= pp; ++qq)
1836 realT cvd = Cvd(qq,pp);
1837 realT * d1 = htsCorr[pp].data();
1838 realT * d2 = hts[qq].data();
1839 for(
size_t nn=0; nn< hts[0].size(); ++nn)
1841 d1[nn] += d2[nn]*cvd;
1859 for(
size_t pp=0; pp < nModes; ++pp)
1865 realT norm = sqrt(modeVar[pp]/var);
1866 for(
size_t nn=0; nn < htsCorr[2*pp].size(); ++nn) htsCorr[2*pp][nn]*=norm;
1869 norm = sqrt(modeVar[pp]/var);
1870 for(
size_t nn=0; nn < htsCorr[2*pp+1].size(); ++nn) htsCorr[2*pp+1][nn]*=norm;
1874 scale = std::complex<realT>(tform1.size(),0);
1879 for(
size_t pp=0; pp < nModes; ++pp)
1884 fftF(tform1.data(), htsCorr[2*pp].data());
1885 fftF(tform2.data(), htsCorr[2*pp+1].data());
1888 for(
int nn=0; nn < sz2Sided; ++nn)
1896 pfilt.psdSqrt(&sqrtNPSD[pp], tfreq[1]-tfreq[0]);
1902 realT norm = sqrt(noiseVar[pp]/Nactvar);
1903 for(
size_t q=0; q<N_n.size(); ++q) N_n[q] *= norm;
1904 for(
size_t q=0; q<N_nm.size(); ++q) N_nm[q] *= norm;
1907 fftF(Ntform1.data(), N_n.data());
1908 fftF(Ntform2.data(), N_nm.data());
1911 for(
size_t mm=0;mm<tform1.size();++mm)
1914 tform1lp[mm] = tform1[mm]*ETFlp[pp][mm]/scale;
1915 tform2lp[mm] = tform2[mm]*ETFlp[pp][mm]/scale;
1917 Ntform1lp[mm] = Ntform1[mm]*NTFlp[pp][mm]/scale;
1918 Ntform2lp[mm] = Ntform2[mm]*NTFlp[pp][mm]/scale;
1920 tform1[mm] *= ETFsi[pp][mm]/scale;
1921 tform2[mm] *= ETFsi[pp][mm]/scale;
1923 Ntform1[mm] *= NTFsi[pp][mm]/scale;
1924 Ntform2[mm] *= NTFsi[pp][mm]/scale;
1928 int m = fms[2*pp].m;
1929 int n = fms[2*pp].n;
1932 fftB(htsCorr[2*pp].data(), tform1.data());
1933 fftB(htsCorr[2*pp+1].data(), tform2.data());
1934 fftB(N_n.data(), Ntform1.data());
1935 fftB(N_nm.data(), Ntform2.data());
1937 for(
int i= 0; i< hts[2*pp].size(); ++i)
1939 realT h1 = htsCorr[2*pp][i]+N_n[i];
1940 realT h2 = htsCorr[2*pp+1][i]+N_nm[i];
1942 spTS.
image(i)(mnMax+m, mnMax+n) = (pow(h1,2) + pow(h2,2));
1943 spTS.
image(i)(mnMax-m, mnMax-n) = spTS.
image(i)(mnMax+m, mnMax+n);
1946 fftB(htsCorr[2*pp].data(), tform1lp.data());
1947 fftB(htsCorr[2*pp+1].data(), tform2lp.data());
1948 fftB(N_n.data(), Ntform1lp.data());
1949 fftB(N_nm.data(), Ntform2lp.data());
1951 for(
int i= 0; i< hts[2*pp].size(); ++i)
1953 realT h1 = htsCorr[2*pp][i]+N_n[i];
1954 realT h2 = htsCorr[2*pp+1][i]+N_nm[i];
1956 spTSlp.
image(i)(mnMax+m, mnMax+n) = (pow(h1,2) + pow(h2,2));
1957 spTSlp.
image(i)(mnMax-m, mnMax-n) = spTSlp.
image(i)(mnMax+m, mnMax+n);
1977 std::vector<realT> speckAmp(spTS.planes());
1978 std::vector<realT> speckAmplp(spTS.planes());
1980 for(
size_t pp=0; pp < nModes; ++pp)
1982 int m = fms[2*pp].m;
1983 int n = fms[2*pp].n;
1987 for(
int i= 0; i< spTS.planes(); ++i)
1989 speckAmp[i] = spTS.
image(i)(mnMax + m, mnMax + n);
1990 speckAmplp[i] = spTSlp.
image(i)(mnMax + m, mnMax + n);
1993 mnlp += speckAmplp[i];
1995 mn /= speckAmp.size();
1996 mnlp /= speckAmplp.size();
1999 for(
int i=0; i<speckAmp.size(); ++i) speckAmp[i] -= mn;
2000 for(
int i=0; i<speckAmplp.size(); ++i) speckAmplp[i] -= mnlp;
2003 avgPgram(tpgram, speckAmp);
2004 for(
size_t nn=0; nn < spPSDs[pp].size(); ++nn) spPSDs[pp][nn] += tpgram[nn];
2006 avgPgram(tpgram, speckAmplp);
2007 for(
size_t nn=0; nn < spPSDslp[pp].size(); ++nn) spPSDslp[pp][nn] += tpgram[nn];
2014 std::vector<realT> spFreq(spPSDs[0].size());
2015 for(
size_t nn=0; nn< spFreq.size(); ++nn) spFreq[nn] = tavgPgram[nn];
2019 taus.
resize(2*mnMax+1, 2*mnMax+1);
2020 tauslp.resize(2*mnMax+1, 2*mnMax+1);
2023 std::vector<realT> clPSD;
2027 imc.resize(2*mnMax+1, 2*mnMax+1, spPSDs[0].size());
2028 imclp.resize(2*mnMax+1, 2*mnMax+1, spPSDs[0].size());
2029 clPSD.resize(sz2Sided);
2036 for(
size_t pp=0; pp < nModes; ++pp)
2038 spPSDs[pp][0] = spPSDs[pp][1];
2039 spPSDslp[pp][0] = spPSDslp[pp][1];
2041 int m = fms[2*pp].m;
2042 int n = fms[2*pp].n;
2047 for(
size_t nn=0; nn < spPSDs[pp].size(); ++nn)
2049 spPSDs[pp][nn] /= lifetimeTrials;
2052 for(
size_t nn=0; nn < sz2Sided; ++nn)
2054 clPSD[nn] = opdPSD[pp][nn]*norm(ETFsi[pp][nn]) + pow(sqrtNPSD[pp][nn],2)*norm(NTFsi[pp][nn]);
2061 for(
size_t nn=0; nn < spPSDs[pp].size(); ++nn)
2063 spPSDs[pp][nn] *= var/pvar;
2064 imc.
image(nn)(mnMax + m, mnMax+n) = spPSDs[pp][nn];
2065 imc.
image(nn)(mnMax - m, mnMax - n) = spPSDs[pp][nn];
2069 for(
size_t nn=0; nn < spPSDslp[pp].size(); ++nn)
2071 spPSDslp[pp][nn] /= lifetimeTrials;
2074 for(
size_t nn=0; nn < sz2Sided; ++nn)
2076 clPSD[nn] = opdPSD[pp][nn]*norm(ETFlp[pp][nn]) + pow(sqrtNPSD[pp][nn],2)*norm(NTFlp[pp][nn]);
2083 for(
size_t nn=0; nn < spPSDslp[pp].size(); ++nn)
2085 spPSDslp[pp][nn] *= var/pvar;
2086 imclp.
image(nn)(mnMax + m, mnMax+n) = spPSDslp[pp][nn];
2087 imclp.
image(nn)(mnMax - m, mnMax - n) = spPSDslp[pp][nn];
2093 realT T = (1.0/(spFreq[1]-spFreq[0]))*10;
2095 realT tau = pvm(error, spFreq, spPSDs[pp], T) *(T)/var;
2096 taus(mnMax+m,mnMax+n) = tau;
2097 taus(mnMax-m,mnMax-n) = tau;
2101 tau = pvm(error, spFreq, spPSDslp[pp], T) *(T)/var;
2102 tauslp(mnMax+m,mnMax+n) = tau;
2103 tauslp(mnMax-m,mnMax-n) = tau;
2110 ff.
write( fn, taus);
2113 ff.
write( fn, tauslp);
2121 ff.
write( fn, imclp);
2132 template<
typename realT,
typename aosysT>
2134 const std::string & dir )
2137 fn = dir +
'/' +
"freq.binv";
2141 template<
typename realT,
typename aosysT>
2143 const std::string & dir,
2152 template<
typename realT,
typename aosysT>
2154 std::vector<realT> & psd,
2155 const std::string & dir,
2159 int rv = getGridFreq( freq, dir );
2160 if(rv < 0)
return rv;
2162 return getGridPSD(psd, dir, m, n);
2168 template<
typename realT,
typename aosysT>
2181 realT ku = f/v_wind;
2183 realT kp = sqrt( pow(ku + m/D,2) + pow(kv + n/D,2) );
2184 realT kpp = sqrt( pow(ku - m/D,2) + pow(kv - n/D,2) );
2190 realT Q = (Q1 + p*Q2);
2197 template<
typename realT>
2198 void turbBoilCubic( realT & a,
2210 b = -(3*Vu*Vu*f + pm*f0*f0*f0);
2212 d = -(f*f*f + pm*f0*f0*f0*kv*kv);
2218 template<
typename realT,
typename aosysT>
2231 realT f0 = Fp->
m_f0;
2241 realT dku = ku*Fp->
m_cq - kv*Fp->
m_sq;
2242 realT dkv = ku*Fp->
m_sq + kv*Fp->
m_cq;
2244 if(fabs(dku) >= Fp->
m_aosys->spatialFilter_ku())
return 0;
2246 if(fabs(dkv) >= Fp->
m_aosys->spatialFilter_kv())
return 0;
2249 realT kp = sqrt( pow(ku + m/D,2) + pow(kv + n/D,2) );
2250 realT kpp = sqrt( pow(ku - m/D,2) + pow(kv - n/D,2) );
2256 realT QQ = 2*(Jp*Jp + Jm*Jm);
2264 realT a,b,
c,d, p, q;
2266 turbBoilCubic(a,b,
c,d,kv,f, v_wind, f0, 1);
2267 mx::math::cubicDepressed(p,q, a, b,
c, d);
2268 realT t = mx::math::cubicRealRoot(p,q);
2275 realT dku = ku*Fp->
m_cq - kv*Fp->
m_sq;
2276 realT dkv = ku*Fp->
m_sq + kv*Fp->
m_cq;
2278 if(fabs(dku) >= Fp->
m_aosys->spatialFilter_ku())
return 0;
2280 if(fabs(dkv) >= Fp->
m_aosys->spatialFilter_kv())
return 0;
2283 realT kp = sqrt( pow(ku + m/D,2) + pow(kv + n/D,2) );
2284 realT kpp = sqrt( pow(ku - m/D,2) + pow(kv - n/D,2) );
2290 realT QQ = 2*(Jp*Jp + Jm*Jm);
2298 turbBoilCubic(a,b,
c,d,kv,f, v_wind, f0, -1);
2299 mx::math::cubicDepressed(p,q, a, b,
c, d);
2300 t = mx::math::cubicRealRoot(p,q);
2307 realT dku = ku*Fp->
m_cq - kv*Fp->
m_sq;
2308 realT dkv = ku*Fp->
m_sq + kv*Fp->
m_cq;
2310 if(fabs(dku) >= Fp->
m_aosys->spatialFilter_ku())
return 0;
2312 if(fabs(dkv) >= Fp->
m_aosys->spatialFilter_kv())
return 0;
2315 kp = sqrt( pow(ku + m/D,2) + pow(kv + n/D,2) );
2316 kpp = sqrt( pow(ku - m/D,2) + pow(kv - n/D,2) );
2322 QQ = 2*(Jp*Jp + Jm*Jm);
2339 template<
typename realT,
typename aosysT>
2350 realT cq = cos(q_wind);
2351 realT sq = sin(q_wind);
2361 realT ku = f/v_wind;
2363 realT kp, km, Jp, Jpp, Jm, Jmp, QQ;
2371 m = Fp->ms[i]*cq + Fp->ns[i]*sq;
2372 n = -Fp->ms[i]*sq + Fp->ns[i]*cq;
2374 kp = sqrt( pow(ku + m/D,2) + pow(kv + n/D,2) );
2375 km = sqrt( pow(ku - m/D,2) + pow(kv - n/D,2) );
2386 for(
int i=0; i< N ; ++i)
2396 for(
int j=(i+1); j < N; ++j)
2412 QQ += 2*2*( Jp*Jpp + Jm*Jmp)*sc;
2416 QQ += 2*2*( Jp*Jmp + Jm*Jpp)*sc;
2437 struct fourierTemporalPSD<double, aoSystem<double, vonKarmanSpectrum<double>, std::ostream>>;
Calculate and provide constants related to adaptive optics.
Spatial power spectra used in adaptive optics.
Declares and defines an analytical AO system.
Provides a class to manage closed loop gain linear predictor determination.
Provides a class to manage closed loop gain optimization.
Class to manage interactions with a FITS file.
int write(const dataT *im, int d1, int d2, int d3, fitsHeader *head)
Write the contents of a raw array to the FITS file.
int read(dataT *data)
Read the contents of the FITS file into an array.
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > image(Index n)
Returns a 2D Eigen::Eigen::Map pointed at the specified image.
A class to track the number of iterations in an OMP parallelized loop.
void incrementAndOutputStatus()
Increment and output status.
void seed(typename ranengT::result_type seedval)
Set the seed of the random engine.
Calculate the average periodogram of a time-series.
int resize(size_t avgLen)
Resize the periodogram working memory, setting up the 1/2-overlapped optimum case.
size_t size()
Return the size of the periodogram.
std::vector< realT > & win()
Get a reference to the window vector.
@ modified
The modified Fourier basis from .
@ basic
The basic sine and cosine Fourier modes.
int writeBinVector(const std::string &fname, std::vector< dataT > &vec)
Write a BinVector file to disk.
int readBinVector(std::vector< dataT > &vec, const std::string &fname)
Read a BinVector file from disk.
constexpr units::realT c()
The speed of light.
constexpr units::realT k()
Boltzmann Constant.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
int createDirectories(const std::string &path)
Create a directory or directories.
realT airyPattern(realT x)
The classical Airy pattern.
T jinc(const T &x)
The Jinc function.
realT Fm_projMod(realT kv, void *params)
Worker function for GSL Integration for a basis projected onto the modified Fourier modes.
realT F_basic(realT kv, void *params)
Worker function for GSL Integration for the basic sin/cos Fourier modes.
realT F_mod(realT kv, void *params)
Worker function for GSL Integration for the modified Fourier modes.
void augment1SidedPSD(vectorTout &psdTwoSided, vectorTin &psdOneSided, bool addZeroFreq=false, typename vectorTin::value_type scale=0.5)
Augment a 1-sided PSD to standard 2-sided FFT form.
void augment1SidedPSDFreq(std::vector< T > &freqTwoSided, std::vector< T > &freqOneSided)
Augment a 1-sided frequency scale to standard FFT form.
realT psdVar(const std::vector< realT > &f, const std::vector< realT > &PSD, realT half=0.5)
Calculate the variance of a 1-D PSD.
int normPSD(std::vector< floatT > &psd, std::vector< floatT > &f, floatParamT normT, floatT fmin=std::numeric_limits< floatT >::min(), floatT fmax=std::numeric_limits< floatT >::max())
Normalize a 1-D PSD to have a given variance.
void hann(realT *filt, int N)
The Hann Window.
std::string convertToString(const typeT &value, int precision=0)
Convert a numerical value to a string.
void vectorMeanSub(valueT *vec, size_t sz)
Subtract the mean from a vector.
void vectorScale(vectorT &vec, size_t N=0, typename vectorT::value_type scale=0, typename vectorT::value_type offset=0)
Fill in a vector with a regularly spaced scale.
valueT vectorVariance(const valueT *vec, size_t sz, valueT mean)
Calculate the variance of a vector relative to a supplied mean value.
Calculates the PSD of speckle intensity given a modified Fourier mode amplitude PSD.
int speckleAmpPSD(std::vector< realT > &spFreq, std::vector< realT > &spPSD, const std::vector< realT > &freq, const std::vector< realT > &fmPSD, const std::vector< std::complex< realT >> &fmXferFxn, const std::vector< realT > &nPSD, const std::vector< std::complex< realT >> &nXferFxn, int N, std::vector< realT > *vars=nullptr, std::vector< realT > *bins=nullptr, bool noPSD=false)
Calculate the PSD of the speckle intensity given the PSD of Fourier mode amplitude.
Class to manage the calculation of linear predictor coefficients for a closed-loop AO system.
int regularizeCoefficients(realT &gmax_lp, realT &gopt_lp, realT &var_lp, clGainOpt< realT > &go_lp, std::vector< realT > &PSDt, std::vector< realT > &PSDn, int Nc)
Regularize the PSD and calculate the associated LP coefficients.
Class to manage the calculation of temporal PSDs of the Fourier modes in atmospheric turbulence.
int _layer_i
The index of the current layer.
gsl_integration_workspace * _w
Workspace for the gsl integrators, allocated to WSZ if constructed as worker (with allocate == true).
int multiLayerPSD(std::vector< realT > &PSD, std::vector< realT > &freq, realT m, realT n, int p, realT fmax=0)
Calculate the temporal PSD for a Fourier mode in a multi-layer model.
int getGridFreq(std::vector< realT > &freq, const std::string &dir)
Get the frequency scale for a PSD grid.
realT m_f0
the Berdja boiling parameter
int intensityPSD(const std::string &subDir, const std::string &psdDir, const std::string &CvdPath, int mnMax, int mnCon, const std::string &si_or_lp, std::vector< realT > &mags, int lifetimeTrials, bool writePSDs)
int getGridPSD(std::vector< realT > &psd, const std::string &dir, int m, int n)
Get a single PSD from a PSD grid.
realT relTol()
Get the current relative tolerance.
realT _absTol
The absolute tolerance to use in the GSL integrator.
Eigen::Array< realT, -1, -1 > m_modeCoeffs
Coeeficients of the projection onto the Fourier modes.
realT m_cq
The cosine of the wind direction.
~fourierTemporalPSD()
Destructor.
aosysT * m_aosys
Pointer to an AO system structure.
realT m_spatialFilter
Flag indicating if a spatial filter is applied.
realT _relTol
The relative tolerance to use in the GSL integrator.
_realT realT
The type for arithmetic.
int _useBasis
Set to MXAO_FTPSD_BASIS_BASIC/MODIFIED/PROJECTED_* to use the basic sin/cos modes,...
int analyzePSDGrid(const std::string &subDir, const std::string &psdDir, int mnMax, int mnCon, realT gfixed, int lpNc, std::vector< realT > &mags, int lifetimeTrials=0, bool uncontrolledLifetimes=false, bool writePSDs=false, bool writeXfer=false)
Analyze a PSD grid under closed-loop control.
std::complex< realT > complexT
The complex type for arithmetic
int singleLayerPSD(std::vector< realT > &PSD, std::vector< realT > &freq, realT m, realT n, int layer_i, int p, realT fmax=0)
Calculate the temporal PSD for a Fourier mode for a single layer.
realT m_sq
The sine of the wind direction.
void makePSDGrid(const std::string &dir, int mnMax, realT dFreq, realT maxFreq, realT fmax=0)
Calculate PSDs over a grid of spatial frequencies.
void initialize()
Initialize parameters to default values.
realT fastestPeak(int m, int n)
Determine the frequency of the highest V-dot-k peak.
int m_p
The parity of the mode, +/- 1. If _useBasis==MXAO_FTPSD_BASIS_BASIC then +1 indicates cosine,...
realT m_f
the current temporal frequency
realT m_m
the spatial frequency m index
int m_mode_i
Projected basis mode index.
realT m_n
the spatial frequency n index
realT absTol()
Get the current absolute tolerance.
fourierTemporalPSD()
Default c'tor.
Calculate the variance of the mean for a process given its PSD.
A utility to convert a wavefront variance map to an intensity image.
Declares and defines a function to calculate the measurement noise PSD.