51 std::vector<realT> &spFreq,
54 const std::vector<realT> &freq,
55 const std::vector<realT> &fmPSD,
56 const std::vector<std::complex<realT>>
58 const std::vector<realT> &nPSD,
59 const std::vector<std::complex<realT>> &nXferFxn,
61 std::vector<realT> *vars =
nullptr,
62 std::vector<realT> *bins =
nullptr,
67 std::vector<realT> psd2, npsd2;
68 std::vector<std::complex<realT>> xfer2, nxfer2;
83 realT dt = 1. / ( 2 * freq.back() );
86 int Nwd = 1.0 * psd2.size();
87 int NwdStart = 0.5 * psd2.size() - 0.5 * Nwd;
89 int Nsamp = 1.0 * psd2.size();
90 int NsampStart = 0.5 * Nwd - 0.5 * Nsamp;
93 spPSD.resize( globalAvgPgram.
size() );
94 for(
size_t n = 0; n < spPSD.size(); ++n )
97 std::vector<std::vector<realT>> means;
98 if( bins !=
nullptr && vars !=
nullptr )
99 means.resize( bins->size() );
109 mx::sigproc::psdFilter<realT, 1> filt;
110 filt.psd( psd2, freq[1] - freq[0] );
112 mx::sigproc::psdFilter<realT, 1> nfilt;
113 nfilt.psd( npsd2, freq[1] - freq[0] );
116 math::ft::fftT<realT, std::complex<realT>, 1, 0> fft( psd2.size() );
120 std::vector<std::complex<realT>> tform1( psd2.size() );
121 std::vector<std::complex<realT>> tform2( psd2.size() );
123 std::vector<std::complex<realT>> Ntform1( psd2.size() );
124 std::vector<std::complex<realT>> Ntform2( psd2.size() );
131 std::vector<realT> fm_n( psd2.size() );
132 std::vector<realT> fm_nm( psd2.size() );
135 std::vector<realT> N_n( psd2.size() );
136 std::vector<realT> N_nm( psd2.size() );
139 std::vector<realT> vnl( Nwd );
140 std::vector<realT> vn( Nsamp );
147 std::vector<realT> tpgram( avgPgram.
size() );
150 for(
int k = 0; k < N; ++k )
153 for(
int i = 0; i < psd2.size(); ++i )
164 realT norm = sqrt( fmVar / actvar );
165 for(
size_t q = 0; q < fm_n.size(); ++q )
169 fft( tform1.data(), fm_n.data() );
173 nfilt.filter( N_nm );
176 norm = sqrt( nVar / Nactvar );
177 for(
size_t q = 0; q < fm_n.size(); ++q )
179 for(
size_t q = 0; q < fm_n.size(); ++q )
183 fft( Ntform1.data(), N_n.data() );
184 fft( Ntform2.data(), N_nm.data() );
186 std::complex<realT> scale = std::complex<realT>( ( tform1.size() ), 0 );
189 for(
size_t m = 0; m < tform1.size(); ++m )
195 tform1[m] *= xfer2[m] / scale;
196 tform2[m] *= xfer2[m] / scale;
200 Ntform1[m] *= nxfer2[m] / scale;
201 Ntform2[m] *= nxfer2[m] / scale;
205 fftB( fm_n.data(), tform1.data() );
206 fftB( fm_nm.data(), tform2.data() );
207 fftB( N_n.data(), Ntform1.data() );
208 fftB( N_nm.data(), Ntform2.data() );
212 for(
int i = 0; i < Nwd; ++i )
214 realT h1 = fm_n[i + NwdStart] + N_n[i + NwdStart];
215 realT h2 = fm_nm[i + NwdStart] + N_nm[i + NwdStart];
217 vnl[i] = ( pow( h1, 2 ) + pow( h2, 2 ) );
223 for(
int i = 0; i < Nsamp; ++i )
224 vn[i] = vnl[i + NsampStart] - mn;
228 avgPgram( tpgram, vn );
233 if( bins !=
nullptr && vars !=
nullptr )
235 for(
size_t i = 0; i < spPSD.size(); ++i )
236 spPSD[i] += tpgram[i];
244 realT df = ( 1.0 ) / ( 2.0 * spPSD.size() * dt );
245 spFreq.resize( spPSD.size() );
246 for(
size_t i = 0; i < spFreq.size(); ++i )
248 spFreq[i] = globalAvgPgram[i];
256 if( bins !=
nullptr && vars !=
nullptr )
258 vars->
resize( bins->size() );
259 for(
size_t i = 0; i < bins->size(); ++i )
278 std::vector<realT> &vars,
279 std::vector<realT> &bins,
280 std::vector<realT> &freq,
281 std::vector<realT> &fmPSD,
282 std::vector<std::complex<realT>> &fmXferFxn,
283 std::vector<realT> &nPSD,
284 std::vector<std::complex<realT>> &nXferFxn,
288 std::vector<realT> spFreq, spPSD;
290 return speckleAmpPSD( spFreq, spPSD, freq, fmPSD, fmXferFxn, nPSD, nXferFxn, N, &vars, &bins,
true );
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.