44 #include "../network/networknode.h"
45 #include "../network/networkedge.h"
46 #include "../network/network.h"
55 #include <QtConcurrent>
61 #include <unsupported/Eigen/FFT>
67 using namespace CONNECTIVITYLIB;
68 using namespace Eigen;
69 using namespace UTILSLIB;
92 if(connectivitySettings.isEmpty()) {
93 qDebug() <<
"Coherency::calculateReal - Input data is empty";
97 #ifdef EIGEN_FFTW_DEFAULT
98 fftw_make_planner_thread_safe();
101 int iSignalLength = connectivitySettings.at(0).matData.cols();
102 int iNfft = connectivitySettings.getFFTSize();
105 QPair<MatrixXd, VectorXd> tapers = Spectral::generateTapers(iSignalLength, connectivitySettings.getWindowType());
108 int iNRows = connectivitySettings.at(0).matData.rows();
109 int iNFreqs = int(floor(iNfft / 2.0)) + 1;
116 connectivitySettings.getIntermediateSumData().matPsdSum,
117 connectivitySettings.getIntermediateSumData().vecPairCsdSum,
129 QFuture<void> result = QtConcurrent::map(connectivitySettings.getTrialData(),
131 result.waitForFinished();
138 std::function<void(QPair<int,MatrixXcd>&)> computePSDCSDLambda = [&](QPair<int,MatrixXcd>& pairInput) {
139 computePSDCSDAbs(mutex,
142 connectivitySettings.getIntermediateSumData().matPsdSum);
145 QFuture<void> resultCSDPSD = QtConcurrent::map(connectivitySettings.getIntermediateSumData().vecPairCsdSum,
146 computePSDCSDLambda);
147 resultCSDPSD.waitForFinished();
163 if(connectivitySettings.isEmpty()) {
164 qDebug() <<
"Coherency::calculateImag - Input data is empty";
168 #ifdef EIGEN_FFTW_DEFAULT
169 fftw_make_planner_thread_safe();
172 int iSignalLength = connectivitySettings.at(0).matData.cols();
173 int iNfft = connectivitySettings.getFFTSize();
176 QPair<MatrixXd, VectorXd> tapers = Spectral::generateTapers(iSignalLength, connectivitySettings.getWindowType());
179 int iNRows = connectivitySettings.at(0).matData.rows();
180 int iNFreqs = int(floor(iNfft / 2.0)) + 1;
187 connectivitySettings.getIntermediateSumData().matPsdSum,
188 connectivitySettings.getIntermediateSumData().vecPairCsdSum,
200 QFuture<void> result = QtConcurrent::map(connectivitySettings.getTrialData(),
202 result.waitForFinished();
209 std::function<void(QPair<int,MatrixXcd>&)> computePSDCSDLambda = [&](QPair<int,MatrixXcd>& pairInput) {
210 computePSDCSDImag(mutex,
213 connectivitySettings.getIntermediateSumData().matPsdSum);
216 QFuture<void> resultCSDPSD = QtConcurrent::map(connectivitySettings.getIntermediateSumData().vecPairCsdSum,
217 computePSDCSDLambda);
218 resultCSDPSD.waitForFinished();
229 QVector<QPair<int,MatrixXcd> >& vecPairCsdSum,
234 const QPair<MatrixXd, VectorXd>& tapers)
240 if(inputData.vecPairCsd.size() == iNRows) {
249 bool bNfftEven =
false;
255 fft.SetFlag(fft.HalfSpectrum);
257 double denomPSD = tapers.second.cwiseAbs2().sum() / 2.0;
259 RowVectorXd vecInputFFT, rowData;
260 RowVectorXcd vecTmpFreq;
262 MatrixXcd matTapSpectrum(tapers.first.rows(), iNFreqs);
266 inputData.matPsd = MatrixXd(iNRows, m_iNumberBinAmount);
268 for (i = 0; i < iNRows; ++i) {
270 rowData.array() = inputData.matData.row(i).array() - inputData.matData.row(i).mean();
273 if(inputData.vecTapSpectra.size() != iNRows) {
274 for(j = 0; j < tapers.first.rows(); j++) {
276 if (rowData.cols() < iNfft) {
277 vecInputFFT.setZero(iNfft);
278 vecInputFFT.block(0,0,1,rowData.cols()) = rowData.cwiseProduct(tapers.first.row(j));;
280 vecInputFFT = rowData.cwiseProduct(tapers.first.row(j));
284 fft.fwd(vecTmpFreq, vecInputFFT, iNfft);
285 matTapSpectrum.row(j) = vecTmpFreq * tapers.second(j);
288 inputData.vecTapSpectra.append(matTapSpectrum);
292 inputData.matPsd.row(i) = inputData.vecTapSpectra.at(i).block(0,m_iNumberBinStart,inputData.vecTapSpectra.at(i).rows(),m_iNumberBinAmount).cwiseAbs2().colwise().sum() / denomPSD;
295 if(m_iNumberBinStart == 0) {
296 inputData.matPsd.row(i)(0) /= 2.0;
299 if(bNfftEven && m_iNumberBinStart + m_iNumberBinAmount >= iNFreqs) {
300 inputData.matPsd.row(i).tail(1) /= 2.0;
306 if(matPsdSum.rows() == 0 || matPsdSum.cols() == 0) {
307 matPsdSum = inputData.matPsd;
309 matPsdSum += inputData.matPsd;
319 if(inputData.vecPairCsd.size() != iNRows) {
320 inputData.vecPairCsd.clear();
323 MatrixXcd matCsd = MatrixXcd(iNRows, m_iNumberBinAmount);
325 double denomCSD = sqrt(tapers.second.cwiseAbs2().sum()) * sqrt(tapers.second.cwiseAbs2().sum()) / 2.0;
327 for (i = 0; i < iNRows; ++i) {
328 for (j = i; j < iNRows; ++j) {
330 matCsd.row(j) = inputData.vecTapSpectra.at(i).block(0,m_iNumberBinStart,inputData.vecTapSpectra.at(i).rows(),m_iNumberBinAmount).cwiseProduct(inputData.vecTapSpectra.at(j).block(0,m_iNumberBinStart,inputData.vecTapSpectra.at(j).rows(),m_iNumberBinAmount).conjugate()).colwise().sum() / denomCSD;
333 if(m_iNumberBinStart == 0) {
334 matCsd.row(j)(0) /= 2.0;
337 if(bNfftEven && m_iNumberBinStart + m_iNumberBinAmount >= iNFreqs) {
338 matCsd.row(j).tail(1) /= 2.0;
342 inputData.vecPairCsd.append(QPair<int,MatrixXcd>(i,matCsd));
347 if(vecPairCsdSum.isEmpty()) {
348 vecPairCsdSum = inputData.vecPairCsd;
350 for (j = 0; j < vecPairCsdSum.size(); ++j) {
351 vecPairCsdSum[j].second += inputData.vecPairCsd.at(j).second;
363 if(!m_bStorageModeIsActive) {
364 inputData.vecPairCsd.clear();
365 inputData.vecTapSpectra.clear();
375 void Coherency::computePSDCSDAbs(QMutex& mutex,
377 const QPair<int,MatrixXcd>& pairInput,
378 const MatrixXd& matPsdSum)
380 MatrixXd matPSDtmp(matPsdSum.rows(), matPsdSum.cols());
381 RowVectorXd rowPsdSum = matPsdSum.row(pairInput.first);
383 for(
int j = 0; j < matPSDtmp.rows(); ++j) {
384 matPSDtmp.row(j) = rowPsdSum.cwiseProduct(matPsdSum.row(j));
388 MatrixXcd matCohy = pairInput.second.cwiseQuotient(matPSDtmp.cwiseSqrt());
390 QSharedPointer<NetworkEdge> pEdge;
393 int i = pairInput.first;
395 for(j = i; j < matCohy.rows(); ++j) {
396 matWeight = matCohy.row(j).cwiseAbs().transpose();
397 pEdge = QSharedPointer<NetworkEdge>(
new NetworkEdge(i, j, matWeight));
400 finalNetwork.
getNodeAt(i)->append(pEdge);
401 finalNetwork.
getNodeAt(j)->append(pEdge);
402 finalNetwork.
append(pEdge);
409 void Coherency::computePSDCSDImag(QMutex& mutex,
411 const QPair<int,MatrixXcd>& pairInput,
412 const MatrixXd& matPsdSum)
414 MatrixXd matPSDtmp(matPsdSum.rows(), matPsdSum.cols());
415 RowVectorXd rowPsdSum = matPsdSum.row(pairInput.first);
417 for(
int j = 0; j < matPSDtmp.rows(); ++j) {
418 matPSDtmp.row(j) = rowPsdSum.cwiseProduct(matPsdSum.row(j));
421 MatrixXcd matCohy = pairInput.second.cwiseQuotient(matPSDtmp.cwiseSqrt());
423 QSharedPointer<NetworkEdge> pEdge;
426 int i = pairInput.first;
428 for(j = i; j < matCohy.rows(); ++j) {
429 matWeight = matCohy.row(j).imag().transpose();
430 pEdge = QSharedPointer<NetworkEdge>(
new NetworkEdge(i, j, matWeight));
433 finalNetwork.
getNodeAt(i)->append(pEdge);
434 finalNetwork.
getNodeAt(j)->append(pEdge);
435 finalNetwork.
append(pEdge);