8 #ifndef speckleAmpPSD_hpp
9 #define speckleAmpPSD_hpp
13 #include <Eigen/Dense>
15 #include "../../math/constants.hpp"
16 #include "../../math/randomT.hpp"
17 #include "../../math/vectorUtils.hpp"
19 #include "../../sigproc/signalWindows.hpp"
20 #include "../../sigproc/psdUtils.hpp"
21 #include "../../sigproc/psdFilter.hpp"
22 #include "../../sigproc/psdVarMean.hpp"
23 #include "../../sigproc/averagePeriodogram.hpp"
53 template<
typename realT>
55 std::vector<realT> & spPSD,
56 const std::vector<realT> & freq,
57 const std::vector<realT> & fmPSD,
58 const std::vector<std::complex<realT>> & fmXferFxn,
59 const std::vector<realT> & nPSD,
60 const std::vector<std::complex<realT>> & nXferFxn,
62 std::vector<realT> * vars =
nullptr,
63 std::vector<realT> * bins =
nullptr,
68 std::vector<realT> psd2, npsd2;
69 std::vector<std::complex<realT>> xfer2, nxfer2;
72 if(freq[0] == 0) hasZero =
true;
84 realT dt = 1./(2*freq.back());
87 int Nwd = 1.0*psd2.size();
88 int NwdStart = 0.5*psd2.size() - 0.5*Nwd;
90 int Nsamp = 1.0*psd2.size();
91 int NsampStart = 0.5*Nwd - 0.5*Nsamp;
94 spPSD.resize(globalAvgPgram.
size());
95 for(
size_t n=0; n<spPSD.size(); ++n) spPSD[n] = 0;
97 std::vector<std::vector<realT>> means;
98 if( bins !=
nullptr && vars !=
nullptr) means.resize(bins->size());
108 mx::sigproc::psdFilter<realT,1> filt;
109 filt.psd(psd2,freq[1]-freq[0]);
111 mx::sigproc::psdFilter<realT,1> nfilt;
112 nfilt.psd(npsd2,freq[1]-freq[0]);
115 math::fft::fftT<realT, std::complex<realT>, 1, 0> fft(psd2.size());
116 math::fft::fftT<std::complex<realT>, realT, 1, 0> fftB(psd2.size(), MXFFT_BACKWARD);
119 std::vector<std::complex<realT>> tform1(psd2.size());
120 std::vector<std::complex<realT>> tform2(psd2.size());
122 std::vector<std::complex<realT>> Ntform1(psd2.size());
123 std::vector<std::complex<realT>> Ntform2(psd2.size());
130 std::vector<realT> fm_n(psd2.size());
131 std::vector<realT> fm_nm(psd2.size());
134 std::vector<realT> N_n(psd2.size());
135 std::vector<realT> N_nm(psd2.size());
138 std::vector<realT> vnl( Nwd );
139 std::vector<realT> vn( Nsamp );
146 std::vector<realT> tpgram(avgPgram.
size());
149 for(
int k=0;
k < N; ++
k)
152 for(
int i=0; i< psd2.size(); ++i)
163 realT norm = sqrt(fmVar/actvar);
164 for(
size_t q=0; q<fm_n.size(); ++q) fm_n[q] *= norm;
167 fft(tform1.data(), fm_n.data());
175 norm = sqrt(nVar/Nactvar);
176 for(
size_t q=0; q<fm_n.size(); ++q) N_n[q] *= norm;
177 for(
size_t q=0; q<fm_n.size(); ++q) N_nm[q] *= norm;
180 fft(Ntform1.data(), N_n.data());
181 fft(Ntform2.data(), N_nm.data());
183 std::complex<realT> scale = std::complex<realT>((tform1.size()),0) ;
186 for(
size_t m=0;m<tform1.size();++m)
189 tform2[m] = tform1[m]*exp( std::complex<realT>(0, math::half_pi<realT>() ));
192 tform1[m] *= xfer2[m]/scale;
193 tform2[m] *= xfer2[m]/scale;
197 Ntform1[m] *= nxfer2[m]/scale;
198 Ntform2[m] *= nxfer2[m]/scale;
202 fftB(fm_n.data(), tform1.data());
203 fftB(fm_nm.data(), tform2.data());
204 fftB(N_n.data(), Ntform1.data());
205 fftB(N_nm.data(), Ntform2.data());
209 for(
int i= 0; i< Nwd; ++i)
211 realT h1 = fm_n[i+NwdStart]+N_n[i+NwdStart];
212 realT h2 = fm_nm[i+NwdStart]+N_nm[i+NwdStart];
214 vnl[i] = (pow(h1,2) + pow(h2,2));
220 for(
int i=0; i<Nsamp; ++i) vn[i] = vnl[i+NsampStart] - mn;
223 if(!noPSD) avgPgram(tpgram, vn);
229 for(
size_t i=0; i< spPSD.size(); ++i) spPSD[i] += tpgram[i];
238 realT df = (1.0)/(2.0*spPSD.size()*dt);
239 spFreq.resize(spPSD.size());
240 for(
size_t i =0; i< spFreq.size(); ++i)
242 spFreq[i] = globalAvgPgram[i];
251 if( bins !=
nullptr && vars !=
nullptr)
253 vars->
resize(bins->size());
254 for(
size_t i=0; i< bins->size(); ++i)
272 template<
typename realT>
274 std::vector<realT> & bins,
275 std::vector<realT> & freq,
276 std::vector<realT> & fmPSD,
277 std::vector<std::complex<realT>> & fmXferFxn,
278 std::vector<realT> & nPSD,
279 std::vector<std::complex<realT>> & nXferFxn,
283 std::vector<realT> spFreq, spPSD;
285 return speckleAmpPSD( spFreq, spPSD,freq, fmPSD, fmXferFxn, nPSD, nXferFxn, N, &vars, &bins,
true);
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.
constexpr units::realT k()
Boltzmann Constant.
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.
realT psdVar(const std::vector< realT > &f, const std::vector< realT > &PSD, realT half=0.5)
Calculate the variance of a 1-D PSD.
void hann(realT *filt, int N)
The Hann Window.
void vectorMeanSub(valueT *vec, size_t sz)
Subtract the mean from a vector.
int vectorBinMeans(std::vector< vectorT > &means, binVectorT &binSzs, const vectorT &v)
Calculate and accumulate the means of a timeseries in bins of various sizes.
valueT vectorVariance(const valueT *vec, size_t sz, valueT mean)
Calculate the variance of a vector relative to a supplied mean value.
The +/- Jinc functions for analyzing contrast.
int speckleAmpVarMean(std::vector< realT > &vars, std::vector< realT > &bins, std::vector< realT > &freq, std::vector< realT > &fmPSD, std::vector< std::complex< realT >> &fmXferFxn, std::vector< realT > &nPSD, std::vector< std::complex< realT >> &nXferFxn, int N)
Calculate the variance of the mean vs bin size in a speckle time-series.
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.