From df1b96a65220f05a0c8e52dceb7f31bbbd018acf Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Fri, 3 Mar 2023 22:17:37 -0500 Subject: [PATCH 1/7] init new plugin timefrequency --- .../plugins/timefrquency/CMakeLists.txt | 0 .../plugins/timefrquency/timefrequency.cpp | 721 ++++++++++++++++++ .../plugins/timefrquency/timefrequency.h | 260 +++++++ .../plugins/timefrquency/timefrequency.json | 0 .../timefrquency/timefrequency_global.cpp | 0 .../timefrquency/timefrequency_global.h | 0 6 files changed, 981 insertions(+) create mode 100644 src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt create mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp create mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency.h create mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency.json create mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp create mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h diff --git a/src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt b/src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp new file mode 100644 index 00000000000..b04f2244b15 --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp @@ -0,0 +1,721 @@ +//============================================================================================================= +/** + * @file timefrequency.cpp + * @author Juan Garcia-Prieto ; + * @since 0.1.0 + * @date March, 2023 + * + * @section LICENSE + * + * Copyright (C) 2016, Christoph Dinh, Gabriel B Motta, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Definition of the TimeFrequency class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "timefrequency.h" + +// #include +// #include +// #include +// #include +// #include +// #include +// +// #include +// #include +// +// #include + +#include + +#include "FormFiles/noisereductionsetupwidget.h" + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace NOISEREDUCTIONPLUGIN; +using namespace SCMEASLIB; +using namespace UTILSLIB; +using namespace UTILSLIB; +using namespace DISPLIB; +using namespace RTPROCESSINGLIB; +using namespace FIFFLIB; +using namespace SCSHAREDLIB; +using namespace Eigen; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +NoiseReduction::NoiseReduction() +: m_bCompActivated(false) +, m_bSpharaActive(false) +, m_bProjActivated(false) +, m_bFilterActivated(false) +, m_iMaxFilterLength(1) +, m_iMaxFilterTapSize(-1) +, m_sCurrentSystem("VectorView") +, m_pCircularBuffer(QSharedPointer::create(40)) +, m_pNoiseReductionInput(Q_NULLPTR) +, m_pNoiseReductionOutput(Q_NULLPTR) +{ + if(m_sCurrentSystem == "BabyMEG") { + m_iNBaseFctsFirst = 270; + m_iNBaseFctsSecond = 105; + } else if(m_sCurrentSystem == "VectorView") { + m_iNBaseFctsFirst = 102; + m_iNBaseFctsSecond = 102; + } else { + m_iNBaseFctsFirst = 0; + m_iNBaseFctsSecond = 0; + qDebug() << "[NoiseReduction::NoiseReduction] Current system type not recognized."; + } +} + +//============================================================================================================= + +NoiseReduction::~NoiseReduction() +{ + if(this->isRunning()) { + stop(); + } +} + +//============================================================================================================= + +QSharedPointer NoiseReduction::clone() const +{ + QSharedPointer pNoiseReductionClone(new NoiseReduction); + return pNoiseReductionClone; +} + +//============================================================================================================= + +void NoiseReduction::init() +{ + // Input + m_pNoiseReductionInput = PluginInputData::create(this, "NoiseReductionIn", "NoiseReduction input data"); + connect(m_pNoiseReductionInput.data(), &PluginInputConnector::notify, + this, &NoiseReduction::update, Qt::DirectConnection); + m_inputConnectors.append(m_pNoiseReductionInput); + + // Output + m_pNoiseReductionOutput = PluginOutputData::create(this, "NoiseReductionOut", "NoiseReduction output data"); + m_pNoiseReductionOutput->measurementData()->setName(this->getName());//Provide name to auto store widget settings + m_outputConnectors.append(m_pNoiseReductionOutput); +} + +//============================================================================================================= + +void NoiseReduction::unload() +{ +} + +//============================================================================================================= + +bool NoiseReduction::start() +{ + //Start thread as soon as we have received the first data block. See update(). + + return true; +} + +//============================================================================================================= + +bool NoiseReduction::stop() +{ + requestInterruption(); + wait(500); + + m_iMaxFilterTapSize = -1; + + m_pNoiseReductionOutput->measurementData()->clear(); + + return true; +} + +//============================================================================================================= + +AbstractPlugin::PluginType NoiseReduction::getType() const +{ + return _IAlgorithm; +} + +//============================================================================================================= + +QString NoiseReduction::getName() const +{ + return "Filter"; +} + +//============================================================================================================= + +QWidget* NoiseReduction::setupWidget() +{ + NoiseReductionSetupWidget* setupWidget = new NoiseReductionSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new + return setupWidget; +} + +//============================================================================================================= + +void NoiseReduction::update(SCMEASLIB::Measurement::SPtr pMeasurement) +{ + if(QSharedPointer pRTMSA = pMeasurement.dynamicCast()) { + //Check if the fiff info was inititalized + if(!m_pFiffInfo) { + m_pFiffInfo = pRTMSA->info(); + + //Init the multiplication matrices + m_matSparseProjMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + m_matSparseCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + m_matSparseSpharaMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + m_matSparseProjCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + m_matSparseFull = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + + m_matSparseProjMult.setIdentity(); + m_matSparseCompMult.setIdentity(); + m_matSparseSpharaMult.setIdentity(); + m_matSparseProjCompMult.setIdentity(); + m_matSparseFull.setIdentity(); + + //Init output + m_pNoiseReductionOutput->measurementData()->initFromFiffInfo(m_pFiffInfo); + m_pNoiseReductionOutput->measurementData()->setMultiArraySize(1); + } + + // Check if data is present + if(pRTMSA->getMultiSampleArray().size() > 0) { + //Init widgets + if(m_iMaxFilterTapSize == -1) { + m_iMaxFilterTapSize = pRTMSA->getMultiSampleArray().first().cols(); + initPluginControlWidgets(); + QThread::start(); + } + + for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) { + // Please note that we do not need a copy here since this function will block until + // the buffer accepts new data again. Hence, the data is not deleted in the actual + // Measurement function after it emitted the notify signal. + while(!m_pCircularBuffer->push(pRTMSA->getMultiSampleArray()[i])) { + //Do nothing until the circular buffer is ready to accept new data again + } + } + } + } +} + +//============================================================================================================= + +void NoiseReduction::initPluginControlWidgets() +{ + if(m_pFiffInfo) { + QList plControlWidgets; + + // Projectors + ProjectorsView* pProjectorsView = new ProjectorsView(QString("MNESCAN/%1/").arg(this->getName())); + connect(this, &NoiseReduction::guiModeChanged, + pProjectorsView, &ProjectorsView::setGuiMode); + pProjectorsView->setObjectName("group_tab_Settings_SSP"); + plControlWidgets.append(pProjectorsView); + + connect(pProjectorsView, &ProjectorsView::projSelectionChanged, + this, &NoiseReduction::updateProjection); + + pProjectorsView->setProjectors(m_pFiffInfo->projs); + + // Compensators + CompensatorView* pCompensatorView = new CompensatorView(QString("MNESCAN/%1/").arg(this->getName())); + connect(this, &NoiseReduction::guiModeChanged, + pCompensatorView, &CompensatorView::setGuiMode); + pCompensatorView->setObjectName("group_tab_Settings_Comp"); + plControlWidgets.append(pCompensatorView); + + connect(pCompensatorView, &CompensatorView::compSelectionChanged, + this, &NoiseReduction::updateCompensator); + + pCompensatorView->setCompensators(m_pFiffInfo->comps); + + // Filter + FilterSettingsView* pFilterSettingsView = new FilterSettingsView(QString("MNESCAN/%1/").arg(this->getName())); + connect(this, &NoiseReduction::guiModeChanged, + pFilterSettingsView, &FilterSettingsView::setGuiMode); + pFilterSettingsView->setObjectName("group_tab_Settings_Filter"); + plControlWidgets.append(pFilterSettingsView); + + connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChannelTypeChanged, + this, &NoiseReduction::setFilterChannelType); + + connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChanged, + this, &NoiseReduction::setFilter); + + connect(pFilterSettingsView, &FilterSettingsView::filterActivationChanged, + this, &NoiseReduction::setFilterActive); + + pFilterSettingsView->setSamplingRate(m_pFiffInfo->sfreq); + pFilterSettingsView->getFilterView()->setMaxAllowedFilterTaps(m_iMaxFilterTapSize); + + this->setFilterActive(pFilterSettingsView->getFilterActive()); + this->setFilterChannelType(pFilterSettingsView->getFilterView()->getChannelType()); + + // SPHARA settings + SpharaSettingsView* pSpharaSettingsView = new SpharaSettingsView(QString("MNESCAN/%1").arg(this->getName())); + connect(this, &NoiseReduction::guiModeChanged, + pSpharaSettingsView, &SpharaSettingsView::setGuiMode); + pSpharaSettingsView->setObjectName("group_tab_Settings_SPHARA"); + plControlWidgets.append(pSpharaSettingsView); + + connect(pSpharaSettingsView, &SpharaSettingsView::spharaActivationChanged, + this, &NoiseReduction::setSpharaActive); + + connect(pSpharaSettingsView, &SpharaSettingsView::spharaOptionsChanged, + this, &NoiseReduction::setSpharaOptions); + + emit pluginControlWidgetsChanged(plControlWidgets, this->getName()); + } +} + +//============================================================================================================= + +void NoiseReduction::setSpharaActive(bool state) +{ + m_mutex.lock(); + m_bSpharaActive = state; + m_mutex.unlock(); +} + +//============================================================================================================= + +void NoiseReduction::setSpharaOptions(const QString& sSytemType, + int nBaseFctsFirst, + int nBaseFctsSecond) +{ + m_mutex.lock(); + m_iNBaseFctsFirst = nBaseFctsFirst; + m_iNBaseFctsSecond = nBaseFctsSecond; + m_sCurrentSystem = sSytemType; + m_mutex.unlock(); + + createSpharaOperator(); +} + +//============================================================================================================= + +void NoiseReduction::run() +{ + // Read and create SPHARA operator for the first time + initSphara(); + createSpharaOperator(); + + // Init + MatrixXd matData; + QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); + + while(!isInterruptionRequested()) { + // Get the current data + if(m_pCircularBuffer->pop(matData)) { + m_mutex.lock(); + //Do SSP's and compensators here + if(m_bCompActivated) { + if(m_bProjActivated) { + //Comp + Proj + matData = m_matSparseProjCompMult * matData; + } else { + //Comp + matData = m_matSparseCompMult * matData; + } + } else { + if(m_bProjActivated) { + //Proj + matData = m_matSparseProjMult * matData; + } else { + //None - Raw + } + } + + //Do temporal filtering here + if(m_bFilterActivated) { + matData = pRtFilter->calculate(matData, + m_filterKernel, + m_lFilterChannelList); + } + + //Do SPHARA here + if(m_bSpharaActive) { + //Set bad channels to zero so they do not get smeared into + for(int i = 0; i < m_pFiffInfo->bads.size(); ++i) { + matData.row(m_pFiffInfo->ch_names.indexOf(m_pFiffInfo->bads.at(i))).setZero(); + } + + matData = m_matSparseSpharaMult * matData; + } + + // //Common average + // MatrixXd commonAvr = MatrixXd(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + // commonAvr.setZero(); + + // int nEEGCh = 0; + + // for(int i = 0; i chs.size(); ++i) { + // if(m_pFiffInfo->chs.at(i).ch_name.contains("EEG") && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(i).ch_name)) { + // nEEGCh++; + // } + // } + + // for(int i = 0; i chs.size(); ++i) { + // for(int j = 0; j < m_pFiffInfo->chs.size(); ++j) { + // if(m_pFiffInfo->chs.at(j).ch_name.contains("EEG") && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(j).ch_name)) { + // commonAvr(i,j) = 1/nEEGCh; + // } + // } + // } + + // UTILSLIB::IOUtils::write_eigen_matrix(commonAvr, "commonAvr.txt", "common vaergae matrix"); + + m_mutex.unlock(); + + //Send the data to the connected plugins and the display + if(!isInterruptionRequested()) { + m_pNoiseReductionOutput->measurementData()->setValue(matData); + } + } + } +} + +//============================================================================================================= + +void NoiseReduction::updateProjection(const QList& projs) +{ + // Update the SSP projector + if(m_pFiffInfo) { + m_mutex.lock(); + //If a minimum of one projector is active set m_bProjActivated to true so that this model applies the ssp to the incoming data + m_bProjActivated = false; + for(qint32 i = 0; i < projs.size(); ++i) { + if(projs[i].active) { + m_bProjActivated = true; + break; + } + } + + MatrixXd matProj; + FiffProj::make_projector(projs, m_pFiffInfo->ch_names, matProj, m_pFiffInfo->bads); + + //set columns of matrix to zero depending on bad channels indexes + for(qint32 j = 0; j < m_pFiffInfo->bads.size(); ++j) { + int index = m_pFiffInfo->ch_names.indexOf(m_pFiffInfo->bads.at(j)); + if(index >= 0 && indexch_names.size()) { + matProj.col(index).setZero(); + } + } + + // Make proj sparse + qint32 nchan = this->m_pFiffInfo->nchan; + qint32 i, k; + + typedef Eigen::Triplet T; + std::vector tripletList; + tripletList.reserve(nchan); + + tripletList.clear(); + tripletList.reserve(matProj.rows()*matProj.cols()); + for(i = 0; i < matProj.rows(); ++i) { + for(k = 0; k < matProj.cols(); ++k) { + if(matProj(i,k) != 0) { + tripletList.push_back(T(i, k, matProj(i,k))); + } + } + } + + m_matSparseProjMult = SparseMatrix(matProj.rows(),matProj.cols()); + if(tripletList.size() > 0) + m_matSparseProjMult.setFromTriplets(tripletList.begin(), tripletList.end()); + + //Create full multiplication matrix + m_matSparseProjCompMult = m_matSparseProjMult * m_matSparseCompMult; + + m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; + m_mutex.unlock(); + } +} + +//============================================================================================================= + +void NoiseReduction::updateCompensator(int to) +{ + // Update the compensator + if(m_pFiffInfo) { + if(to == 0) { + m_bCompActivated = false; + } else { + m_bCompActivated = true; + } + +// qDebug()<<"to"<m_pFiffInfo->make_compensator(0, to, newComp);//Do this always from 0 since we always read new raw data, we never actually perform a multiplication on already existing data + + //this->m_pFiffInfo->set_current_comp(to); + MatrixXd matComp = newComp.data->data; + + // + // Make proj sparse + // + qint32 nchan = this->m_pFiffInfo->nchan; + qint32 i, k; + + typedef Eigen::Triplet T; + std::vector tripletList; + tripletList.reserve(nchan); + + tripletList.clear(); + tripletList.reserve(matComp.rows()*matComp.cols()); + for(i = 0; i < matComp.rows(); ++i) { + for(k = 0; k < matComp.cols(); ++k) { + if(matComp(i,k) != 0) { + tripletList.push_back(T(i, k, matComp(i,k))); + } + } + } + + m_matSparseCompMult = SparseMatrix(matComp.rows(),matComp.cols()); + if(tripletList.size() > 0) { + m_matSparseCompMult.setFromTriplets(tripletList.begin(), tripletList.end()); + } + + //Create full multiplication matrix + m_matSparseProjCompMult = m_matSparseProjMult * m_matSparseCompMult; + + m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; + } +} + +//============================================================================================================= + +void NoiseReduction::setFilterChannelType(QString sType) +{ + m_sFilterChannelType = sType; + + m_mutex.lock(); + //This version is for when all channels of a type are to be filtered (not only the visible ones). + //Create channel filter list independent from channelNames + m_lFilterChannelList.resize(0); + + for(int i = 0; i < m_pFiffInfo->chs.size(); ++i) { + if((m_pFiffInfo->chs.at(i).kind == FIFFV_MEG_CH || m_pFiffInfo->chs.at(i).kind == FIFFV_EEG_CH || + m_pFiffInfo->chs.at(i).kind == FIFFV_EOG_CH || m_pFiffInfo->chs.at(i).kind == FIFFV_ECG_CH || + m_pFiffInfo->chs.at(i).kind == FIFFV_EMG_CH)/* && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(i).ch_name)*/) { + + if(m_sFilterChannelType == "All") { + m_lFilterChannelList.conservativeResize(m_lFilterChannelList.cols() + 1); + m_lFilterChannelList[m_lFilterChannelList.cols()-1] = i; + } else if(m_pFiffInfo->chs.at(i).ch_name.contains(m_sFilterChannelType)) { + m_lFilterChannelList.conservativeResize(m_lFilterChannelList.cols() + 1); + m_lFilterChannelList[m_lFilterChannelList.cols()-1] = i; + } + } + } + m_mutex.unlock(); +} + +//============================================================================================================= + +void NoiseReduction::setFilter(const FilterKernel& filterData) +{ + m_mutex.lock(); + m_filterKernel = filterData; + + m_iMaxFilterLength = 1; + if(m_iMaxFilterLength < m_filterKernel.getFilterOrder()) { + m_iMaxFilterLength = m_filterKernel.getFilterOrder(); + } + m_mutex.unlock(); +} + +//============================================================================================================= + +void NoiseReduction::setFilterActive(bool state) +{ + m_bFilterActivated = state; +} + +//============================================================================================================= + +void NoiseReduction::initSphara() +{ + //Load SPHARA matrix + IOUtils::read_eigen_matrix(m_matSpharaVVGradLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Vectorview_SPHARA_InvEuclidean_Grad.txt")); + IOUtils::read_eigen_matrix(m_matSpharaVVMagLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Vectorview_SPHARA_InvEuclidean_Mag.txt")); + + IOUtils::read_eigen_matrix(m_matSpharaBabyMEGInnerLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/BabyMEG_SPHARA_InvEuclidean_Inner.txt")); + IOUtils::read_eigen_matrix(m_matSpharaBabyMEGOuterLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/BabyMEG_SPHARA_InvEuclidean_Outer.txt")); + + IOUtils::read_eigen_matrix(m_matSpharaEEGLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Current_SPHARA_EEG.txt")); + + //Generate indices used to create the SPHARA operators for VectorView + m_vecIndicesFirstVV.resize(0); + m_vecIndicesSecondVV.resize(0); + + for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { + //Find gardiometers + if(m_pFiffInfo->chs.at(r).chpos.coil_type == 3012) { + m_vecIndicesFirstVV.conservativeResize(m_vecIndicesFirstVV.rows()+1); + m_vecIndicesFirstVV(m_vecIndicesFirstVV.rows()-1) = r; + } + + //Find magnetometers + if(m_pFiffInfo->chs.at(r).chpos.coil_type == 3024) { + m_vecIndicesSecondVV.conservativeResize(m_vecIndicesSecondVV.rows()+1); + m_vecIndicesSecondVV(m_vecIndicesSecondVV.rows()-1) = r; + } + } + + //Generate indices used to create the SPHARA operators for babyMEG + m_vecIndicesFirstBabyMEG.resize(0); + for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { + //Find inner layer + if(m_pFiffInfo->chs.at(r).chpos.coil_type == 7002) { + m_vecIndicesFirstBabyMEG.conservativeResize(m_vecIndicesFirstBabyMEG.rows()+1); + m_vecIndicesFirstBabyMEG(m_vecIndicesFirstBabyMEG.rows()-1) = r; + } + + //TODO: Find outer layer + } + + //Generate indices used to create the SPHARA operators for EEG layouts + m_vecIndicesFirstEEG.resize(0); + for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { + //Find EEG + if(m_pFiffInfo->chs.at(r).kind == FIFFV_EEG_CH) { + m_vecIndicesFirstEEG.conservativeResize(m_vecIndicesFirstEEG.rows()+1); + m_vecIndicesFirstEEG(m_vecIndicesFirstEEG.rows()-1) = r; + } + } + +// qDebug()<<"NoiseReduction::createSpharaOperator - Read VectorView mag matrix "<chs.size(), m_pFiffInfo->chs.size()); + MatrixXd matSpharaMultSecond = MatrixXd::Identity(m_pFiffInfo->chs.size(), m_pFiffInfo->chs.size()); + + if(m_sCurrentSystem == "VectorView") { + matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaVVGradLoaded, m_vecIndicesFirstVV, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 1); //GRADIOMETERS + matSpharaMultSecond = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaVVMagLoaded, m_vecIndicesSecondVV, m_pFiffInfo->nchan, m_iNBaseFctsSecond, 0); //Magnetometers + } + + if(m_sCurrentSystem == "BabyMEG") { + matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaBabyMEGInnerLoaded, m_vecIndicesFirstBabyMEG, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 0); //InnerLayer + } + + if(m_sCurrentSystem == "EEG") { + matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaEEGLoaded, m_vecIndicesFirstEEG, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 0); //InnerLayer + } + + //Write final operator matrices to file +// IOUtils::write_eigen_matrix(matSpharaMultFirst, QString(QCoreApplication::applicationDirPath() + "resources/mne_scan/plugins/noisereduction/SPHARA/matSpharaMultFirst.txt")); +// IOUtils::write_eigen_matrix(matSpharaMultSecond, QString(QCoreApplication::applicationDirPath() + "resources/mne_scan/plugins/noisereduction/SPHARA/matSpharaMultSecond.txt")); + + // + // Make operators sparse + // + qint32 nchan = this->m_pFiffInfo->nchan; + qint32 i, k; + + typedef Eigen::Triplet T; + std::vector tripletList; + tripletList.reserve(nchan); + + //First operator + tripletList.clear(); + tripletList.reserve(matSpharaMultFirst.rows()*matSpharaMultFirst.cols()); + for(i = 0; i < matSpharaMultFirst.rows(); ++i) { + for(k = 0; k < matSpharaMultFirst.cols(); ++k) { + if(matSpharaMultFirst(i,k) != 0) { + tripletList.push_back(T(i, k, matSpharaMultFirst(i,k))); + } + } + } + + SparseMatrix matSparseSpharaMultFirst = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + + if(tripletList.size() > 0) { + matSparseSpharaMultFirst.setFromTriplets(tripletList.begin(), tripletList.end()); + } + + //Second operator + tripletList.clear(); + tripletList.reserve(matSpharaMultSecond.rows()*matSpharaMultSecond.cols()); + + for(i = 0; i < matSpharaMultSecond.rows(); ++i) { + for(k = 0; k < matSpharaMultSecond.cols(); ++k) { + if(matSpharaMultSecond(i,k) != 0) { + tripletList.push_back(T(i, k, matSpharaMultSecond(i,k))); + } + } + } + + SparseMatrixmatSparseSpharaMultSecond = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); + + if(tripletList.size() > 0) { + matSparseSpharaMultSecond.setFromTriplets(tripletList.begin(), tripletList.end()); + } + + //Create full multiplication matrix + m_matSparseSpharaMult = matSparseSpharaMultFirst * matSparseSpharaMultSecond; + + m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; + + m_mutex.unlock(); +} + +//============================================================================================================= + +QString NoiseReduction::getBuildInfo() +{ + return QString(NOISEREDUCTIONPLUGIN::buildDateTime()) + QString(" - ") + QString(NOISEREDUCTIONPLUGIN::buildHash()); +} + diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.h b/src/applications/mne_scan/plugins/timefrquency/timefrequency.h new file mode 100644 index 00000000000..42ce52205f0 --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrquency/timefrequency.h @@ -0,0 +1,260 @@ +//============================================================================================================= +/** + * @file timefrequency.h + * @author Juan Garcia-Prieto ; + * @since 0.1.0 + * @date March, 2023 + * + * @section LICENSE + * + * Copyright (C) 2023, Juan Garcia-Prieto. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the declaration of the TimeFrequency plugin class. + * + */ + +#ifndef TIMEFREQUENCY_PLUGIN_MNESCAN +#define TIMEFREQUENCY_PLUGIN_MNESCAN + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "timefrequency_global.h" +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace FIFFLIB{ +class FiffInfo; +} + +namespace RTPROCESSINGLIB{ +class Filter; +} + +namespace SCMEASLIB{ +class RealTimeMultiSampleArray; +} + +//============================================================================================================= +// DEFINE NAMESPACE NOISEREDUCTIONPLUGIN +//============================================================================================================= + +namespace TIMEFREQUENCYPLUGIN +{ + +//============================================================================================================= +// NOISEREDUCTIONPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +//============================================================================================================= +/** + * DECLARE CLASS NoiseReduction + * + * @brief The NoiseReduction class provides a tools to reduce noise of an incoming data stream. It then forwards the processed data to subsequent plugins. + */ +class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlgorithm +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "scsharedlib/1.0" FILE "timefrequency.json") // New Qt5 Plugin system replaces Q_EXPORT_PLUGIN2 macro + // Use the Q_INTERFACES() macro to tell Qt's meta-object system about the interfaces + Q_INTERFACES(SCSHAREDLIB::AbstractAlgorithm) + +public: + //========================================================================================================= + /** + * Constructs a NoiseReduction. + */ + TimeFrequency(); + + //========================================================================================================= + /** + * Destroys the TimeFrequency. + */ + ~TimeFrequency(); + + //========================================================================================================= + /** + * AbstractAlgorithm functions + */ + virtual QSharedPointer clone() const; + virtual void init(); + virtual void unload(); + virtual bool start(); + virtual bool stop(); + virtual AbstractPlugin::PluginType getType() const; + virtual QString getName() const; + virtual QWidget* setupWidget(); + virtual QString getBuildInfo(); + + //========================================================================================================= + /** + * Udates the pugin with new (incoming) data. + * + * @param[in] pMeasurement The incoming data in form of a generalized Measurement. + */ + // void update(SCMEASLIB::Measurement::SPtr pMeasurement); + + //========================================================================================================= + /** + * Inits widgets which are used to control this plugin, then emits them in form of a QList. + */ + // void initPluginControlWidgets(); + + //========================================================================================================= + /** + * Set the active flag for SPHARA processing. + * + * @param[in] state The new activity flag. + */ + // void setSpharaActive(bool state); + + //========================================================================================================= + /** + * Set the number of base functions and acquisition system for SPHARA processing. + * + * @param[in] sSytemType The acquisition system. + * @param[in] nBaseFctsGrad The number of grad/mag base functions to keep. + * @param[in] nBaseFctsMag The number of grad/mag base functions to keep. + */ + // void setSpharaOptions(const QString& sSytemType, + // int nBaseFctsFirst, + +protected: + //========================================================================================================= + /** + * AbstractAlgorithm function + */ + virtual void run(); + + //========================================================================================================= + /** + * Update the SSP projection + */ + // void updateProjection(const QList& projs); + + //========================================================================================================= + /** + * Update the compensator + * + * @param[in] to Compensator to use in fiff constant format FiffCtfComp.kind (NOT FiffCtfComp.ctfkind). + */ + // void updateCompensator(int to); + + //========================================================================================================= + /** + * Sets the type of channel which are to be filtered + * + * @param[in] sType the channel type which is to be filtered (EEG, MEG, All). + */ + // void setFilterChannelType(QString sType); + + //========================================================================================================= + /** + * Filter parameters changed + * + * @param[in] filterData currently active filter. + */ + // void setFilter(const RTPROCESSINGLIB::FilterKernel& filterData); + + //========================================================================================================= + /** + * Filter avtivated + * + * @param[in] state filter on/off flag. + */ + // void setFilterActive(bool state); + + //========================================================================================================= + /** + * Init the SPHARA method. + */ + // void initSphara(); + + //========================================================================================================= + /** + * Create/Update the SPHARA projection operator. + */ + // void createSpharaOperator(); + +private: + // QMutex m_mutex; /**< The threads mutex.*/ + // + // bool m_bCompActivated; /**< Compensator activated. */ + // bool m_bSpharaActive; /**< Flag whether thread is running.*/ + // bool m_bProjActivated; /**< Projections activated. */ + // bool m_bFilterActivated; /**< Projections activated. */ + // + // int m_iNBaseFctsFirst; /**< The number of grad/inner base functions to use for calculating the sphara opreator.*/ + // int m_iNBaseFctsSecond; /**< The number of grad/outer base functions to use for calculating the sphara opreator.*/ + // int m_iMaxFilterLength; /**< Max order of the current filters. */ + // int m_iMaxFilterTapSize; /**< maximum number of allowed filter taps. This number depends on the size of the receiving blocks. */ + // + // QString m_sCurrentSystem; /**< The current acquisition system (EEG, babyMEG, VectorView).*/ + // QString m_sFilterChannelType; /**< Kind of channel which is to be filtered. */ + // + // RTPROCESSINGLIB::FilterKernel m_filterKernel; /**< The currently active filter. */ + // + // Eigen::VectorXi m_vecIndicesFirstVV; /**< The indices of the channels to pick for the first SPHARA oerpator in case of a VectorView system.*/ + // Eigen::VectorXi m_vecIndicesSecondVV; /**< The indices of the channels to pick for the second SPHARA oerpator in case of a VectorView system.*/ + // Eigen::VectorXi m_vecIndicesFirstBabyMEG; /**< The indices of the channels to pick for the first SPHARA oerpator in case of a BabyMEG system.*/ + // Eigen::VectorXi m_vecIndicesSecondBabyMEG; /**< The indices of the channels to pick for the second SPHARA oerpator in case of a BabyMEG system.*/ + // Eigen::VectorXi m_vecIndicesFirstEEG; /**< The indices of the channels to pick for the second SPHARA operator in case of an EEG system.*/ + // + // Eigen::SparseMatrix m_matSparseSpharaMult; /**< The final sparse SPHARA operator .*/ + // Eigen::SparseMatrix m_matSparseProjCompMult; /**< The final sparse projection + compensator operator.*/ + // Eigen::SparseMatrix m_matSparseProjMult; /**< The final sparse SSP projector. */ + // Eigen::SparseMatrix m_matSparseCompMult; /**< The final sparse compensator matrix. */ + // Eigen::SparseMatrix m_matSparseFull; /**< The final sparse full multiplication matrix . */ + // + // Eigen::MatrixXd m_matSpharaVVGradLoaded; /**< The loaded VectorView gradiometer basis functions.*/ + // Eigen::MatrixXd m_matSpharaVVMagLoaded; /**< The loaded VectorView magnetometer basis functions.*/ + // Eigen::MatrixXd m_matSpharaBabyMEGInnerLoaded; /**< The loaded babyMEG inner layer basis functions.*/ + // Eigen::MatrixXd m_matSpharaBabyMEGOuterLoaded; /**< The loaded babyMEG outer layer basis functions.*/ + // Eigen::MatrixXd m_matSpharaEEGLoaded; /**< The loaded EEG basis functions.*/ + // + // Eigen::RowVectorXi m_lFilterChannelList; /**< The indices of the channels to be filtered.*/ + + QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + + // QSharedPointer m_pCircularBuffer; /**< Holds incoming raw data. */ + + SCSHAREDLIB::PluginInputData::SPtr m_pNoiseReductionInput; /**< The RealTimeMultiSampleArray of the NoiseReduction input.*/ + // SCSHAREDLIB::PluginOutputData::SPtr m_pNoiseReductionOutput; /**< The RealTimeMultiSampleArray of the NoiseReduction output.*/ + +}; + +} // NAMESPACE + +#endif // TIMEFREQUENCY_PLUGIN_MNESCAN diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.json b/src/applications/mne_scan/plugins/timefrquency/timefrequency.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp b/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h b/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h new file mode 100644 index 00000000000..e69de29bb2d From 09309e00364fdca489e5119729b7f2cc558ad91a Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Fri, 3 Mar 2023 23:34:26 -0500 Subject: [PATCH 2/7] init almost compiling --- .../mne_scan/plugins/CMakeLists.txt | 1 + .../plugins/timefrequency/CMakeLists.txt | 77 ++ .../plugins/timefrequency/timefrequency.cpp | 355 +++++++++ .../plugins/timefrequency/timefrequency.h | 141 ++++ .../timefrequency.json | 0 .../timefrequency/timefrequency_global.cpp | 55 ++ .../timefrequency/timefrequency_global.h | 84 ++ .../plugins/timefrquency/CMakeLists.txt | 0 .../plugins/timefrquency/timefrequency.cpp | 721 ------------------ .../plugins/timefrquency/timefrequency.h | 260 ------- .../timefrquency/timefrequency_global.cpp | 0 .../timefrquency/timefrequency_global.h | 0 12 files changed, 713 insertions(+), 981 deletions(-) create mode 100644 src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt create mode 100644 src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp create mode 100644 src/applications/mne_scan/plugins/timefrequency/timefrequency.h rename src/applications/mne_scan/plugins/{timefrquency => timefrequency}/timefrequency.json (100%) create mode 100644 src/applications/mne_scan/plugins/timefrequency/timefrequency_global.cpp create mode 100644 src/applications/mne_scan/plugins/timefrequency/timefrequency_global.h delete mode 100644 src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt delete mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp delete mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency.h delete mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp delete mode 100644 src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h diff --git a/src/applications/mne_scan/plugins/CMakeLists.txt b/src/applications/mne_scan/plugins/CMakeLists.txt index 775c74dbf69..cce3a3c9d80 100644 --- a/src/applications/mne_scan/plugins/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory(neuronalconnectivity) add_subdirectory(writetofile) add_subdirectory(hpi) add_subdirectory(rtfwd) +add_subdirectory(timefrequency) option(WITH_BRAINFLOW "Build brainflow plugin" OFF) option(WITH_LSL "Build LSL plugin" OFF) diff --git a/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt new file mode 100644 index 00000000000..fd00b6e862d --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.14) +project(scan_timefrequency LANGUAGES CXX) + +#Handle qt uic, moc, rrc automatically +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Svg) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Svg) + +set(SOURCES + timefrequency.cpp + timefrequency_global.cpp +) + +set(HEADERS + timefrequency_global.h + timefrequency.h +) + +set(FILE_TO_UPDATE timefrequency_global.cpp) + +set(SOURCE_PATHS ${SOURCES}) +list(TRANSFORM SOURCE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +set_source_files_properties(${FILE_TO_UPDATE} PROPERTIES OBJECT_DEPENDS "${SOURCE_PATHS}") + +add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${RESOURCES}) + +set(FFTW_LIBS "") + +if(USE_FFTW) + if (WIN32) + set(FFTW_LIBS + ${FFTW_DIR_LIBS}/libfftw3-3.dll + ${FFTW_DIR_LIBS}/libfftw3f-3.dll + ${FFTW_DIR_LIBS}/libfftwf3l-3.dll + ) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}) + elseif(UNIX AND NOT APPLE) + set(FFTW_LIBS ${FFTW_DIR_LIBS}/lib/libfftw3.so) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}/api) + endif() +endif() + +target_include_directories(${PROJECT_NAME} PUBLIC ../) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Svg + eigen + mne_disp + mne_utils + mne_fiff + # mne_fs + # mne_mne + # mne_fwd + # mne_inverse + mne_rtprocessing + # mne_connectivity + # mne_events + scDisp + scShared + scMeas + ${FFTW_LIBS}) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + SCAN_TIMEFREQUENCY_PLUGIN + MNE_GIT_HASH_SHORT="${MNE_GIT_HASH_SHORT}" + MNE_GIT_HASH_LONG="${MNE_GIT_HASH_LONG}" +) + +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_NAME} PRIVATE + STATICBUILD QT_STATICPLUGIN) +endif() diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp new file mode 100644 index 00000000000..89e296bba8e --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp @@ -0,0 +1,355 @@ +//============================================================================================================= +/** + * @file timefrequency.cpp + * @author Juan Garcia-Prieto ; + * @since 0.1.0 + * @date March, 2023 + * + * @section LICENSE + * + * Copyright (C) 2016, Christoph Dinh, Gabriel B Motta, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Definition of the TimeFrequency class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "timefrequency.h" + +// #include +// #include +// #include +// #include +// #include +// #include +// +// #include +// #include +// +#include + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +// using namespace SCMEASLIB; +// using namespace UTILSLIB; +// using namespace DISPLIB; +// using namespace RTPROCESSINGLIB; +// using namespace FIFFLIB; +// using namespace SCSHAREDLIB; +// using namespace Eigen; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= +namespace TIMEFREQUENCYPLUGIN { + + +TimeFrequency::TimeFrequency() +: m_pTimeFrequencyIntput(Q_NULLPTR) +// : m_bCompActivated(false) +// , m_bSpharaActive(false) +// , m_bProjActivated(false) +// , m_bFilterActivated(false) +// , m_iMaxFilterLength(1) +// , m_iMaxFilterTapSize(-1) +// , m_sCurrentSystem("VectorView") +// , m_pCircularBuffer(QSharedPointer::create(40)) +{ + qDebug() << "[TimeFrequency::TimeFrequency] Creating Plugin Object."; +} + +//============================================================================================================= + +TimeFrequency::~TimeFrequency() +{ + if(this->isRunning()) { + stop(); + } +} + +//============================================================================================================= + +QSharedPointer TimeFrequency::clone() const +{ + QSharedPointer pTimeFrequencyClone(new TimeFrequency); + return pTimeFrequencyClone; +} + +//============================================================================================================= + +void TimeFrequency::init() +{ + // Input + m_pTimeFrequencyInput = PluginInputData:: + create(this, "TimeFrequencyIn", "TimeFrequency input data"); + m_inputConnectors.append(m_pTimeFrequencyInput); + m_pTimeFrequencyInput->measurementData()->setName(this->getName());//Provide name to auto store widget settings + + // Output + // m_pTimeFrequencyOutput = PluginOutputData::create(this, "TimeFrequencyOut", "TimeFrequency output data"); + // m_outputConnectors.append(m_pTimeFrequencyOutput); +} + +//============================================================================================================= + +void TimeFrequency::unload() +{ +} + +//============================================================================================================= + +bool TimeFrequency::start() +{ + //Start thread as soon as we have received the first data block. See update(). + + return true; +} + +//============================================================================================================= + +bool TimeFrequency::stop() +{ + requestInterruption(); + + wait(500); + + // m_pTimeFrequencyOutput->measurementData()->clear(); + + return true; +} + +//============================================================================================================= + +AbstractPlugin::PluginType TimeFrequency::getType() const +{ + return _IAlgorithm; +} + +//============================================================================================================= + +QString TimeFrequency::getName() const +{ + return "TimeFrequency"; +} + +//============================================================================================================= + +QWidget* TimeFrequency::setupWidget() +{ + // TimeFrequencySetupWidget* setupWidget = new TimeFrequencySetupWidget(this); + // // widget is later distroyed by CentralWidget - so it has to be created everytime new + QLabel* setupWidget("Time Frequency Baby"); + return setupWidget; +} + +//============================================================================================================= + +// void TimeFrequency::update(SCMEASLIB::Measurement::SPtr pMeasurement) +// { +// if(QSharedPointer pRTMSA = pMeasurement.dynamicCast()) { +// //Check if the fiff info was inititalized +// if(!m_pFiffInfo) { +// m_pFiffInfo = pRTMSA->info(); +// +// //Init the multiplication matrices +// m_matSparseProjMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); +// m_matSparseCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); +// m_matSparseSpharaMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); +// m_matSparseProjCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); +// m_matSparseFull = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); +// +// m_matSparseProjMult.setIdentity(); +// m_matSparseCompMult.setIdentity(); +// m_matSparseSpharaMult.setIdentity(); +// m_matSparseProjCompMult.setIdentity(); +// m_matSparseFull.setIdentity(); +// +// //Init output +// m_pTimeFrequencyOutput->measurementData()->initFromFiffInfo(m_pFiffInfo); +// m_pTimeFrequencyOutput->measurementData()->setMultiArraySize(1); +// } +// +// // Check if data is present +// if(pRTMSA->getMultiSampleArray().size() > 0) { +// //Init widgets +// if(m_iMaxFilterTapSize == -1) { +// m_iMaxFilterTapSize = pRTMSA->getMultiSampleArray().first().cols(); +// initPluginControlWidgets(); +// QThread::start(); +// } +// +// for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) { +// // Please note that we do not need a copy here since this function will block until +// // the buffer accepts new data again. Hence, the data is not deleted in the actual +// // Measurement function after it emitted the notify signal. +// while(!m_pCircularBuffer->push(pRTMSA->getMultiSampleArray()[i])) { +// //Do nothing until the circular buffer is ready to accept new data again +// } +// } +// } +// } +// } +// +// //============================================================================================================= +// +// void TimeFrequency::initPluginControlWidgets() +// { +// if(m_pFiffInfo) { +// QList plControlWidgets; +// +// // Projectors +// ProjectorsView* pProjectorsView = new ProjectorsView(QString("MNESCAN/%1/").arg(this->getName())); +// connect(this, &TimeFrequency::guiModeChanged, +// pProjectorsView, &ProjectorsView::setGuiMode); +// pProjectorsView->setObjectName("group_tab_Settings_SSP"); +// plControlWidgets.append(pProjectorsView); +// +// connect(pProjectorsView, &ProjectorsView::projSelectionChanged, +// this, &TimeFrequency::updateProjection); +// +// pProjectorsView->setProjectors(m_pFiffInfo->projs); +// +// // Compensators +// CompensatorView* pCompensatorView = new CompensatorView(QString("MNESCAN/%1/").arg(this->getName())); +// connect(this, &TimeFrequency::guiModeChanged, +// pCompensatorView, &CompensatorView::setGuiMode); +// pCompensatorView->setObjectName("group_tab_Settings_Comp"); +// plControlWidgets.append(pCompensatorView); +// +// connect(pCompensatorView, &CompensatorView::compSelectionChanged, +// this, &TimeFrequency::updateCompensator); +// +// pCompensatorView->setCompensators(m_pFiffInfo->comps); +// +// // Filter +// FilterSettingsView* pFilterSettingsView = new FilterSettingsView(QString("MNESCAN/%1/").arg(this->getName())); +// connect(this, &TimeFrequency::guiModeChanged, +// pFilterSettingsView, &FilterSettingsView::setGuiMode); +// pFilterSettingsView->setObjectName("group_tab_Settings_Filter"); +// plControlWidgets.append(pFilterSettingsView); +// +// connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChannelTypeChanged, +// this, &TimeFrequency::setFilterChannelType); +// +// connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChanged, +// this, &TimeFrequency::setFilter); +// +// connect(pFilterSettingsView, &FilterSettingsView::filterActivationChanged, +// this, &TimeFrequency::setFilterActive); +// +// pFilterSettingsView->setSamplingRate(m_pFiffInfo->sfreq); +// pFilterSettingsView->getFilterView()->setMaxAllowedFilterTaps(m_iMaxFilterTapSize); +// +// this->setFilterActive(pFilterSettingsView->getFilterActive()); +// this->setFilterChannelType(pFilterSettingsView->getFilterView()->getChannelType()); +// +// // SPHARA settings +// SpharaSettingsView* pSpharaSettingsView = new SpharaSettingsView(QString("MNESCAN/%1").arg(this->getName())); +// connect(this, &TimeFrequency::guiModeChanged, +// pSpharaSettingsView, &SpharaSettingsView::setGuiMode); +// pSpharaSettingsView->setObjectName("group_tab_Settings_SPHARA"); +// plControlWidgets.append(pSpharaSettingsView); +// +// connect(pSpharaSettingsView, &SpharaSettingsView::spharaActivationChanged, +// this, &TimeFrequency::setSpharaActive); +// +// connect(pSpharaSettingsView, &SpharaSettingsView::spharaOptionsChanged, +// this, &TimeFrequency::setSpharaOptions); +// +// emit pluginControlWidgetsChanged(plControlWidgets, this->getName()); +// } +// } +// +// //============================================================================================================= +// +// void TimeFrequency::setSpharaActive(bool state) +// { +// m_mutex.lock(); +// m_bSpharaActive = state; +// m_mutex.unlock(); +// } +// +// //============================================================================================================= +// +// void TimeFrequency::setSpharaOptions(const QString& sSytemType, +// int nBaseFctsFirst, +// int nBaseFctsSecond) +// { +// m_mutex.lock(); +// m_iNBaseFctsFirst = nBaseFctsFirst; +// m_iNBaseFctsSecond = nBaseFctsSecond; +// m_sCurrentSystem = sSytemType; +// m_mutex.unlock(); +// +// createSpharaOperator(); +// } +// +//============================================================================================================= + +void TimeFrequency::run() +{ + // Read and create SPHARA operator for the first time + // initSphara(); + // createSpharaOperator(); + + // Init + MatrixXd matData; + // matData. + // QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); + + while (true) + { + // Get the current data + msleep(500); + // Send the data to the connected plugins and the display + if(!isInterruptionRequested()) { + m_pTimeFrequencyInput->measurementData()->setValue(matData); + } + } +} + +//============================================================================================================= + +QString TimeFrequency::getBuildInfo() +{ + return QString(buildDateTime()) + QString(" - ") + QString(buildHash()); +} + +} // namespace TIMEFREQUENCYPLUGIN + diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h new file mode 100644 index 00000000000..d80e144fd46 --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h @@ -0,0 +1,141 @@ +//============================================================================================================= +/** + * @file timefrequency.h + * @author Juan Garcia-Prieto ; + * @since 0.1.0 + * @date March, 2023 + * + * @section LICENSE + * + * Copyright (C) 2023, Juan Garcia-Prieto. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the declaration of the TimeFrequency plugin class. + * + */ + +#ifndef TIMEFREQUENCY_H +#define TIMEFREQUENCY_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "timefrequency_global.h" +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace FIFFLIB{ +class FiffInfo; +} + +// namespace RTPROCESSINGLIB{ +// class Filter; +// } + +namespace SCMEASLIB{ +class RealTimeMultiSampleArray; +} + +//============================================================================================================= +// DEFINE NAMESPACE TIMEFREQUENCYPLUGIN +//============================================================================================================= + +namespace TIMEFREQUENCYPLUGIN +{ + +//============================================================================================================= +// TIMEFREQUENCYPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +//============================================================================================================= +/** + * DECLARE CLASS TimeFrequency + * + * @brief The TimeFrequency class provides a tools to compute and show time-frequency maps. + */ +class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlgorithm +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "scsharedlib/1.0" FILE "timefrequency.json") + Q_INTERFACES(SCSHAREDLIB::AbstractAlgorithm) + + public: + //========================================================================================================= + /** + * Constructs a TimeFrequency. + */ + TimeFrequency(); + + //========================================================================================================= + /** + * Destroys the TimeFrequency. + */ + ~TimeFrequency(); + + //========================================================================================================= + /** + * AbstractAlgorithm functions + */ + virtual QSharedPointer clone() const; + virtual void init(); + virtual void unload(); + virtual bool start(); + virtual bool stop(); + virtual AbstractPlugin::PluginType getType() const; + virtual QString getName() const; + virtual QWidget* setupWidget(); + virtual QString getBuildInfo(); + + protected: + virtual void run(); + //========================================================================================================= + + public: + //========================================================================================================= + /** + * Other methods can go here... + */ + + private: + QSharedPointer + m_pFiffInfo; /**< Fiff measurement info.*/ + SCSHAREDLIB::PluginInputData::SPtr + m_pTimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ +}; + +} // namespace TIMEFREQUENCYPLUGIN + +#endif // TIMEFREQUENCY_PLUGIN_MNESCAN diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.json b/src/applications/mne_scan/plugins/timefrequency/timefrequency.json similarity index 100% rename from src/applications/mne_scan/plugins/timefrquency/timefrequency.json rename to src/applications/mne_scan/plugins/timefrequency/timefrequency.json diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.cpp b/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.cpp new file mode 100644 index 00000000000..4a97f66117f --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.cpp @@ -0,0 +1,55 @@ +//============================================================================================================= +/** + * @file timefrequency_global.cpp + * @author Juan G Prieto ; + * Gabriel B Motta ; + * @since 0.1.9 + * @date September, 2021 + * + * @section LICENSE + * + * Copyright (C) 2023, Juan G Prieto, Gabriel B Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief timefrequency plugin global definitions. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "timefrequency_global.h" + +//============================================================================================================= +// DEFINE METHODS +//============================================================================================================= + +const char* TIMEFREQUENCYPLUGIN::buildDateTime(){ return UTILSLIB::dateTimeNow();} + +//============================================================================================================= + +const char* TIMEFREQUENCYPLUGIN::buildHash(){ return UTILSLIB::gitHash();} + +//============================================================================================================= + +const char* TIMEFREQUENCYPLUGIN::buildHashLong(){ return UTILSLIB::gitHashLong();} + diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.h b/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.h new file mode 100644 index 00000000000..b44538d88ec --- /dev/null +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency_global.h @@ -0,0 +1,84 @@ +//============================================================================================================= +/** + @file timefrequency_global.h + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2016 + * + * @section LICENSE + * + * Copyright (C) 2016, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the TimeFrequency library export/import macros. + * + */ + +#ifndef TIMEFREQUENCY_GLOBAL_H +#define TIMEFREQUENCY_GLOBAL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// PREPROCESSOR DEFINES +//============================================================================================================= + +#if defined(SCAN_TIMEFREQUENCY_PLUGIN) +# define TIMEFREQUENCYSHARED_EXPORT Q_DECL_EXPORT /**< Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. */ +#else +# define TIMEFREQUENCYSHARED_EXPORT Q_DECL_IMPORT /**< Q_DECL_IMPORT must be added to the declarations of symbols used when compiling a client that uses the shared library. */ +#endif + +namespace TIMEFREQUENCYPLUGIN { + +//============================================================================================================= +/** + * Returns build date and time. + */ +TIMEFREQUENCYSHARED_EXPORT const char* buildDateTime(); + +//============================================================================================================= +/** + * Returns abbreviated build git hash. + */ +TIMEFREQUENCYSHARED_EXPORT const char* buildHash(); + +//============================================================================================================= +/** + * Returns full build git hash. + */ +TIMEFREQUENCYSHARED_EXPORT const char* buildHashLong(); + +} // namespace TIMEFREQUENCYPLUGIN + +#endif // TIMEFREQUENCY_GLOBAL_H + diff --git a/src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt b/src/applications/mne_scan/plugins/timefrquency/CMakeLists.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp deleted file mode 100644 index b04f2244b15..00000000000 --- a/src/applications/mne_scan/plugins/timefrquency/timefrequency.cpp +++ /dev/null @@ -1,721 +0,0 @@ -//============================================================================================================= -/** - * @file timefrequency.cpp - * @author Juan Garcia-Prieto ; - * @since 0.1.0 - * @date March, 2023 - * - * @section LICENSE - * - * Copyright (C) 2016, Christoph Dinh, Gabriel B Motta, Lorenz Esch. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that - * the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of MNE-CPP authors nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @brief Definition of the TimeFrequency class. - * - */ - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "timefrequency.h" - -// #include -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include -// -// #include - -#include - -#include "FormFiles/noisereductionsetupwidget.h" - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -//============================================================================================================= -// EIGEN INCLUDES -//============================================================================================================= - -//============================================================================================================= -// USED NAMESPACES -//============================================================================================================= - -using namespace NOISEREDUCTIONPLUGIN; -using namespace SCMEASLIB; -using namespace UTILSLIB; -using namespace UTILSLIB; -using namespace DISPLIB; -using namespace RTPROCESSINGLIB; -using namespace FIFFLIB; -using namespace SCSHAREDLIB; -using namespace Eigen; - -//============================================================================================================= -// DEFINE MEMBER METHODS -//============================================================================================================= - -NoiseReduction::NoiseReduction() -: m_bCompActivated(false) -, m_bSpharaActive(false) -, m_bProjActivated(false) -, m_bFilterActivated(false) -, m_iMaxFilterLength(1) -, m_iMaxFilterTapSize(-1) -, m_sCurrentSystem("VectorView") -, m_pCircularBuffer(QSharedPointer::create(40)) -, m_pNoiseReductionInput(Q_NULLPTR) -, m_pNoiseReductionOutput(Q_NULLPTR) -{ - if(m_sCurrentSystem == "BabyMEG") { - m_iNBaseFctsFirst = 270; - m_iNBaseFctsSecond = 105; - } else if(m_sCurrentSystem == "VectorView") { - m_iNBaseFctsFirst = 102; - m_iNBaseFctsSecond = 102; - } else { - m_iNBaseFctsFirst = 0; - m_iNBaseFctsSecond = 0; - qDebug() << "[NoiseReduction::NoiseReduction] Current system type not recognized."; - } -} - -//============================================================================================================= - -NoiseReduction::~NoiseReduction() -{ - if(this->isRunning()) { - stop(); - } -} - -//============================================================================================================= - -QSharedPointer NoiseReduction::clone() const -{ - QSharedPointer pNoiseReductionClone(new NoiseReduction); - return pNoiseReductionClone; -} - -//============================================================================================================= - -void NoiseReduction::init() -{ - // Input - m_pNoiseReductionInput = PluginInputData::create(this, "NoiseReductionIn", "NoiseReduction input data"); - connect(m_pNoiseReductionInput.data(), &PluginInputConnector::notify, - this, &NoiseReduction::update, Qt::DirectConnection); - m_inputConnectors.append(m_pNoiseReductionInput); - - // Output - m_pNoiseReductionOutput = PluginOutputData::create(this, "NoiseReductionOut", "NoiseReduction output data"); - m_pNoiseReductionOutput->measurementData()->setName(this->getName());//Provide name to auto store widget settings - m_outputConnectors.append(m_pNoiseReductionOutput); -} - -//============================================================================================================= - -void NoiseReduction::unload() -{ -} - -//============================================================================================================= - -bool NoiseReduction::start() -{ - //Start thread as soon as we have received the first data block. See update(). - - return true; -} - -//============================================================================================================= - -bool NoiseReduction::stop() -{ - requestInterruption(); - wait(500); - - m_iMaxFilterTapSize = -1; - - m_pNoiseReductionOutput->measurementData()->clear(); - - return true; -} - -//============================================================================================================= - -AbstractPlugin::PluginType NoiseReduction::getType() const -{ - return _IAlgorithm; -} - -//============================================================================================================= - -QString NoiseReduction::getName() const -{ - return "Filter"; -} - -//============================================================================================================= - -QWidget* NoiseReduction::setupWidget() -{ - NoiseReductionSetupWidget* setupWidget = new NoiseReductionSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new - return setupWidget; -} - -//============================================================================================================= - -void NoiseReduction::update(SCMEASLIB::Measurement::SPtr pMeasurement) -{ - if(QSharedPointer pRTMSA = pMeasurement.dynamicCast()) { - //Check if the fiff info was inititalized - if(!m_pFiffInfo) { - m_pFiffInfo = pRTMSA->info(); - - //Init the multiplication matrices - m_matSparseProjMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - m_matSparseCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - m_matSparseSpharaMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - m_matSparseProjCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - m_matSparseFull = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - - m_matSparseProjMult.setIdentity(); - m_matSparseCompMult.setIdentity(); - m_matSparseSpharaMult.setIdentity(); - m_matSparseProjCompMult.setIdentity(); - m_matSparseFull.setIdentity(); - - //Init output - m_pNoiseReductionOutput->measurementData()->initFromFiffInfo(m_pFiffInfo); - m_pNoiseReductionOutput->measurementData()->setMultiArraySize(1); - } - - // Check if data is present - if(pRTMSA->getMultiSampleArray().size() > 0) { - //Init widgets - if(m_iMaxFilterTapSize == -1) { - m_iMaxFilterTapSize = pRTMSA->getMultiSampleArray().first().cols(); - initPluginControlWidgets(); - QThread::start(); - } - - for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) { - // Please note that we do not need a copy here since this function will block until - // the buffer accepts new data again. Hence, the data is not deleted in the actual - // Measurement function after it emitted the notify signal. - while(!m_pCircularBuffer->push(pRTMSA->getMultiSampleArray()[i])) { - //Do nothing until the circular buffer is ready to accept new data again - } - } - } - } -} - -//============================================================================================================= - -void NoiseReduction::initPluginControlWidgets() -{ - if(m_pFiffInfo) { - QList plControlWidgets; - - // Projectors - ProjectorsView* pProjectorsView = new ProjectorsView(QString("MNESCAN/%1/").arg(this->getName())); - connect(this, &NoiseReduction::guiModeChanged, - pProjectorsView, &ProjectorsView::setGuiMode); - pProjectorsView->setObjectName("group_tab_Settings_SSP"); - plControlWidgets.append(pProjectorsView); - - connect(pProjectorsView, &ProjectorsView::projSelectionChanged, - this, &NoiseReduction::updateProjection); - - pProjectorsView->setProjectors(m_pFiffInfo->projs); - - // Compensators - CompensatorView* pCompensatorView = new CompensatorView(QString("MNESCAN/%1/").arg(this->getName())); - connect(this, &NoiseReduction::guiModeChanged, - pCompensatorView, &CompensatorView::setGuiMode); - pCompensatorView->setObjectName("group_tab_Settings_Comp"); - plControlWidgets.append(pCompensatorView); - - connect(pCompensatorView, &CompensatorView::compSelectionChanged, - this, &NoiseReduction::updateCompensator); - - pCompensatorView->setCompensators(m_pFiffInfo->comps); - - // Filter - FilterSettingsView* pFilterSettingsView = new FilterSettingsView(QString("MNESCAN/%1/").arg(this->getName())); - connect(this, &NoiseReduction::guiModeChanged, - pFilterSettingsView, &FilterSettingsView::setGuiMode); - pFilterSettingsView->setObjectName("group_tab_Settings_Filter"); - plControlWidgets.append(pFilterSettingsView); - - connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChannelTypeChanged, - this, &NoiseReduction::setFilterChannelType); - - connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChanged, - this, &NoiseReduction::setFilter); - - connect(pFilterSettingsView, &FilterSettingsView::filterActivationChanged, - this, &NoiseReduction::setFilterActive); - - pFilterSettingsView->setSamplingRate(m_pFiffInfo->sfreq); - pFilterSettingsView->getFilterView()->setMaxAllowedFilterTaps(m_iMaxFilterTapSize); - - this->setFilterActive(pFilterSettingsView->getFilterActive()); - this->setFilterChannelType(pFilterSettingsView->getFilterView()->getChannelType()); - - // SPHARA settings - SpharaSettingsView* pSpharaSettingsView = new SpharaSettingsView(QString("MNESCAN/%1").arg(this->getName())); - connect(this, &NoiseReduction::guiModeChanged, - pSpharaSettingsView, &SpharaSettingsView::setGuiMode); - pSpharaSettingsView->setObjectName("group_tab_Settings_SPHARA"); - plControlWidgets.append(pSpharaSettingsView); - - connect(pSpharaSettingsView, &SpharaSettingsView::spharaActivationChanged, - this, &NoiseReduction::setSpharaActive); - - connect(pSpharaSettingsView, &SpharaSettingsView::spharaOptionsChanged, - this, &NoiseReduction::setSpharaOptions); - - emit pluginControlWidgetsChanged(plControlWidgets, this->getName()); - } -} - -//============================================================================================================= - -void NoiseReduction::setSpharaActive(bool state) -{ - m_mutex.lock(); - m_bSpharaActive = state; - m_mutex.unlock(); -} - -//============================================================================================================= - -void NoiseReduction::setSpharaOptions(const QString& sSytemType, - int nBaseFctsFirst, - int nBaseFctsSecond) -{ - m_mutex.lock(); - m_iNBaseFctsFirst = nBaseFctsFirst; - m_iNBaseFctsSecond = nBaseFctsSecond; - m_sCurrentSystem = sSytemType; - m_mutex.unlock(); - - createSpharaOperator(); -} - -//============================================================================================================= - -void NoiseReduction::run() -{ - // Read and create SPHARA operator for the first time - initSphara(); - createSpharaOperator(); - - // Init - MatrixXd matData; - QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); - - while(!isInterruptionRequested()) { - // Get the current data - if(m_pCircularBuffer->pop(matData)) { - m_mutex.lock(); - //Do SSP's and compensators here - if(m_bCompActivated) { - if(m_bProjActivated) { - //Comp + Proj - matData = m_matSparseProjCompMult * matData; - } else { - //Comp - matData = m_matSparseCompMult * matData; - } - } else { - if(m_bProjActivated) { - //Proj - matData = m_matSparseProjMult * matData; - } else { - //None - Raw - } - } - - //Do temporal filtering here - if(m_bFilterActivated) { - matData = pRtFilter->calculate(matData, - m_filterKernel, - m_lFilterChannelList); - } - - //Do SPHARA here - if(m_bSpharaActive) { - //Set bad channels to zero so they do not get smeared into - for(int i = 0; i < m_pFiffInfo->bads.size(); ++i) { - matData.row(m_pFiffInfo->ch_names.indexOf(m_pFiffInfo->bads.at(i))).setZero(); - } - - matData = m_matSparseSpharaMult * matData; - } - - // //Common average - // MatrixXd commonAvr = MatrixXd(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - // commonAvr.setZero(); - - // int nEEGCh = 0; - - // for(int i = 0; i chs.size(); ++i) { - // if(m_pFiffInfo->chs.at(i).ch_name.contains("EEG") && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(i).ch_name)) { - // nEEGCh++; - // } - // } - - // for(int i = 0; i chs.size(); ++i) { - // for(int j = 0; j < m_pFiffInfo->chs.size(); ++j) { - // if(m_pFiffInfo->chs.at(j).ch_name.contains("EEG") && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(j).ch_name)) { - // commonAvr(i,j) = 1/nEEGCh; - // } - // } - // } - - // UTILSLIB::IOUtils::write_eigen_matrix(commonAvr, "commonAvr.txt", "common vaergae matrix"); - - m_mutex.unlock(); - - //Send the data to the connected plugins and the display - if(!isInterruptionRequested()) { - m_pNoiseReductionOutput->measurementData()->setValue(matData); - } - } - } -} - -//============================================================================================================= - -void NoiseReduction::updateProjection(const QList& projs) -{ - // Update the SSP projector - if(m_pFiffInfo) { - m_mutex.lock(); - //If a minimum of one projector is active set m_bProjActivated to true so that this model applies the ssp to the incoming data - m_bProjActivated = false; - for(qint32 i = 0; i < projs.size(); ++i) { - if(projs[i].active) { - m_bProjActivated = true; - break; - } - } - - MatrixXd matProj; - FiffProj::make_projector(projs, m_pFiffInfo->ch_names, matProj, m_pFiffInfo->bads); - - //set columns of matrix to zero depending on bad channels indexes - for(qint32 j = 0; j < m_pFiffInfo->bads.size(); ++j) { - int index = m_pFiffInfo->ch_names.indexOf(m_pFiffInfo->bads.at(j)); - if(index >= 0 && indexch_names.size()) { - matProj.col(index).setZero(); - } - } - - // Make proj sparse - qint32 nchan = this->m_pFiffInfo->nchan; - qint32 i, k; - - typedef Eigen::Triplet T; - std::vector tripletList; - tripletList.reserve(nchan); - - tripletList.clear(); - tripletList.reserve(matProj.rows()*matProj.cols()); - for(i = 0; i < matProj.rows(); ++i) { - for(k = 0; k < matProj.cols(); ++k) { - if(matProj(i,k) != 0) { - tripletList.push_back(T(i, k, matProj(i,k))); - } - } - } - - m_matSparseProjMult = SparseMatrix(matProj.rows(),matProj.cols()); - if(tripletList.size() > 0) - m_matSparseProjMult.setFromTriplets(tripletList.begin(), tripletList.end()); - - //Create full multiplication matrix - m_matSparseProjCompMult = m_matSparseProjMult * m_matSparseCompMult; - - m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; - m_mutex.unlock(); - } -} - -//============================================================================================================= - -void NoiseReduction::updateCompensator(int to) -{ - // Update the compensator - if(m_pFiffInfo) { - if(to == 0) { - m_bCompActivated = false; - } else { - m_bCompActivated = true; - } - -// qDebug()<<"to"<m_pFiffInfo->make_compensator(0, to, newComp);//Do this always from 0 since we always read new raw data, we never actually perform a multiplication on already existing data - - //this->m_pFiffInfo->set_current_comp(to); - MatrixXd matComp = newComp.data->data; - - // - // Make proj sparse - // - qint32 nchan = this->m_pFiffInfo->nchan; - qint32 i, k; - - typedef Eigen::Triplet T; - std::vector tripletList; - tripletList.reserve(nchan); - - tripletList.clear(); - tripletList.reserve(matComp.rows()*matComp.cols()); - for(i = 0; i < matComp.rows(); ++i) { - for(k = 0; k < matComp.cols(); ++k) { - if(matComp(i,k) != 0) { - tripletList.push_back(T(i, k, matComp(i,k))); - } - } - } - - m_matSparseCompMult = SparseMatrix(matComp.rows(),matComp.cols()); - if(tripletList.size() > 0) { - m_matSparseCompMult.setFromTriplets(tripletList.begin(), tripletList.end()); - } - - //Create full multiplication matrix - m_matSparseProjCompMult = m_matSparseProjMult * m_matSparseCompMult; - - m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; - } -} - -//============================================================================================================= - -void NoiseReduction::setFilterChannelType(QString sType) -{ - m_sFilterChannelType = sType; - - m_mutex.lock(); - //This version is for when all channels of a type are to be filtered (not only the visible ones). - //Create channel filter list independent from channelNames - m_lFilterChannelList.resize(0); - - for(int i = 0; i < m_pFiffInfo->chs.size(); ++i) { - if((m_pFiffInfo->chs.at(i).kind == FIFFV_MEG_CH || m_pFiffInfo->chs.at(i).kind == FIFFV_EEG_CH || - m_pFiffInfo->chs.at(i).kind == FIFFV_EOG_CH || m_pFiffInfo->chs.at(i).kind == FIFFV_ECG_CH || - m_pFiffInfo->chs.at(i).kind == FIFFV_EMG_CH)/* && !m_pFiffInfo->bads.contains(m_pFiffInfo->chs.at(i).ch_name)*/) { - - if(m_sFilterChannelType == "All") { - m_lFilterChannelList.conservativeResize(m_lFilterChannelList.cols() + 1); - m_lFilterChannelList[m_lFilterChannelList.cols()-1] = i; - } else if(m_pFiffInfo->chs.at(i).ch_name.contains(m_sFilterChannelType)) { - m_lFilterChannelList.conservativeResize(m_lFilterChannelList.cols() + 1); - m_lFilterChannelList[m_lFilterChannelList.cols()-1] = i; - } - } - } - m_mutex.unlock(); -} - -//============================================================================================================= - -void NoiseReduction::setFilter(const FilterKernel& filterData) -{ - m_mutex.lock(); - m_filterKernel = filterData; - - m_iMaxFilterLength = 1; - if(m_iMaxFilterLength < m_filterKernel.getFilterOrder()) { - m_iMaxFilterLength = m_filterKernel.getFilterOrder(); - } - m_mutex.unlock(); -} - -//============================================================================================================= - -void NoiseReduction::setFilterActive(bool state) -{ - m_bFilterActivated = state; -} - -//============================================================================================================= - -void NoiseReduction::initSphara() -{ - //Load SPHARA matrix - IOUtils::read_eigen_matrix(m_matSpharaVVGradLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Vectorview_SPHARA_InvEuclidean_Grad.txt")); - IOUtils::read_eigen_matrix(m_matSpharaVVMagLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Vectorview_SPHARA_InvEuclidean_Mag.txt")); - - IOUtils::read_eigen_matrix(m_matSpharaBabyMEGInnerLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/BabyMEG_SPHARA_InvEuclidean_Inner.txt")); - IOUtils::read_eigen_matrix(m_matSpharaBabyMEGOuterLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/BabyMEG_SPHARA_InvEuclidean_Outer.txt")); - - IOUtils::read_eigen_matrix(m_matSpharaEEGLoaded, QString(QCoreApplication::applicationDirPath() + "/resources/mne_scan/plugins/noisereduction/SPHARA/Current_SPHARA_EEG.txt")); - - //Generate indices used to create the SPHARA operators for VectorView - m_vecIndicesFirstVV.resize(0); - m_vecIndicesSecondVV.resize(0); - - for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { - //Find gardiometers - if(m_pFiffInfo->chs.at(r).chpos.coil_type == 3012) { - m_vecIndicesFirstVV.conservativeResize(m_vecIndicesFirstVV.rows()+1); - m_vecIndicesFirstVV(m_vecIndicesFirstVV.rows()-1) = r; - } - - //Find magnetometers - if(m_pFiffInfo->chs.at(r).chpos.coil_type == 3024) { - m_vecIndicesSecondVV.conservativeResize(m_vecIndicesSecondVV.rows()+1); - m_vecIndicesSecondVV(m_vecIndicesSecondVV.rows()-1) = r; - } - } - - //Generate indices used to create the SPHARA operators for babyMEG - m_vecIndicesFirstBabyMEG.resize(0); - for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { - //Find inner layer - if(m_pFiffInfo->chs.at(r).chpos.coil_type == 7002) { - m_vecIndicesFirstBabyMEG.conservativeResize(m_vecIndicesFirstBabyMEG.rows()+1); - m_vecIndicesFirstBabyMEG(m_vecIndicesFirstBabyMEG.rows()-1) = r; - } - - //TODO: Find outer layer - } - - //Generate indices used to create the SPHARA operators for EEG layouts - m_vecIndicesFirstEEG.resize(0); - for(int r = 0; r < m_pFiffInfo->chs.size(); ++r) { - //Find EEG - if(m_pFiffInfo->chs.at(r).kind == FIFFV_EEG_CH) { - m_vecIndicesFirstEEG.conservativeResize(m_vecIndicesFirstEEG.rows()+1); - m_vecIndicesFirstEEG(m_vecIndicesFirstEEG.rows()-1) = r; - } - } - -// qDebug()<<"NoiseReduction::createSpharaOperator - Read VectorView mag matrix "<chs.size(), m_pFiffInfo->chs.size()); - MatrixXd matSpharaMultSecond = MatrixXd::Identity(m_pFiffInfo->chs.size(), m_pFiffInfo->chs.size()); - - if(m_sCurrentSystem == "VectorView") { - matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaVVGradLoaded, m_vecIndicesFirstVV, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 1); //GRADIOMETERS - matSpharaMultSecond = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaVVMagLoaded, m_vecIndicesSecondVV, m_pFiffInfo->nchan, m_iNBaseFctsSecond, 0); //Magnetometers - } - - if(m_sCurrentSystem == "BabyMEG") { - matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaBabyMEGInnerLoaded, m_vecIndicesFirstBabyMEG, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 0); //InnerLayer - } - - if(m_sCurrentSystem == "EEG") { - matSpharaMultFirst = RTPROCESSINGLIB::makeSpharaProjector(m_matSpharaEEGLoaded, m_vecIndicesFirstEEG, m_pFiffInfo->nchan, m_iNBaseFctsFirst, 0); //InnerLayer - } - - //Write final operator matrices to file -// IOUtils::write_eigen_matrix(matSpharaMultFirst, QString(QCoreApplication::applicationDirPath() + "resources/mne_scan/plugins/noisereduction/SPHARA/matSpharaMultFirst.txt")); -// IOUtils::write_eigen_matrix(matSpharaMultSecond, QString(QCoreApplication::applicationDirPath() + "resources/mne_scan/plugins/noisereduction/SPHARA/matSpharaMultSecond.txt")); - - // - // Make operators sparse - // - qint32 nchan = this->m_pFiffInfo->nchan; - qint32 i, k; - - typedef Eigen::Triplet T; - std::vector tripletList; - tripletList.reserve(nchan); - - //First operator - tripletList.clear(); - tripletList.reserve(matSpharaMultFirst.rows()*matSpharaMultFirst.cols()); - for(i = 0; i < matSpharaMultFirst.rows(); ++i) { - for(k = 0; k < matSpharaMultFirst.cols(); ++k) { - if(matSpharaMultFirst(i,k) != 0) { - tripletList.push_back(T(i, k, matSpharaMultFirst(i,k))); - } - } - } - - SparseMatrix matSparseSpharaMultFirst = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - - if(tripletList.size() > 0) { - matSparseSpharaMultFirst.setFromTriplets(tripletList.begin(), tripletList.end()); - } - - //Second operator - tripletList.clear(); - tripletList.reserve(matSpharaMultSecond.rows()*matSpharaMultSecond.cols()); - - for(i = 0; i < matSpharaMultSecond.rows(); ++i) { - for(k = 0; k < matSpharaMultSecond.cols(); ++k) { - if(matSpharaMultSecond(i,k) != 0) { - tripletList.push_back(T(i, k, matSpharaMultSecond(i,k))); - } - } - } - - SparseMatrixmatSparseSpharaMultSecond = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); - - if(tripletList.size() > 0) { - matSparseSpharaMultSecond.setFromTriplets(tripletList.begin(), tripletList.end()); - } - - //Create full multiplication matrix - m_matSparseSpharaMult = matSparseSpharaMultFirst * matSparseSpharaMultSecond; - - m_matSparseFull = m_matSparseProjMult * m_matSparseCompMult; - - m_mutex.unlock(); -} - -//============================================================================================================= - -QString NoiseReduction::getBuildInfo() -{ - return QString(NOISEREDUCTIONPLUGIN::buildDateTime()) + QString(" - ") + QString(NOISEREDUCTIONPLUGIN::buildHash()); -} - diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency.h b/src/applications/mne_scan/plugins/timefrquency/timefrequency.h deleted file mode 100644 index 42ce52205f0..00000000000 --- a/src/applications/mne_scan/plugins/timefrquency/timefrequency.h +++ /dev/null @@ -1,260 +0,0 @@ -//============================================================================================================= -/** - * @file timefrequency.h - * @author Juan Garcia-Prieto ; - * @since 0.1.0 - * @date March, 2023 - * - * @section LICENSE - * - * Copyright (C) 2023, Juan Garcia-Prieto. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that - * the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of MNE-CPP authors nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @brief Contains the declaration of the TimeFrequency plugin class. - * - */ - -#ifndef TIMEFREQUENCY_PLUGIN_MNESCAN -#define TIMEFREQUENCY_PLUGIN_MNESCAN - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "timefrequency_global.h" -#include - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -//============================================================================================================= -// EIGEN INCLUDES -//============================================================================================================= - - -//============================================================================================================= -// FORWARD DECLARATIONS -//============================================================================================================= - -namespace FIFFLIB{ -class FiffInfo; -} - -namespace RTPROCESSINGLIB{ -class Filter; -} - -namespace SCMEASLIB{ -class RealTimeMultiSampleArray; -} - -//============================================================================================================= -// DEFINE NAMESPACE NOISEREDUCTIONPLUGIN -//============================================================================================================= - -namespace TIMEFREQUENCYPLUGIN -{ - -//============================================================================================================= -// NOISEREDUCTIONPLUGIN FORWARD DECLARATIONS -//============================================================================================================= - -//============================================================================================================= -/** - * DECLARE CLASS NoiseReduction - * - * @brief The NoiseReduction class provides a tools to reduce noise of an incoming data stream. It then forwards the processed data to subsequent plugins. - */ -class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlgorithm -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "scsharedlib/1.0" FILE "timefrequency.json") // New Qt5 Plugin system replaces Q_EXPORT_PLUGIN2 macro - // Use the Q_INTERFACES() macro to tell Qt's meta-object system about the interfaces - Q_INTERFACES(SCSHAREDLIB::AbstractAlgorithm) - -public: - //========================================================================================================= - /** - * Constructs a NoiseReduction. - */ - TimeFrequency(); - - //========================================================================================================= - /** - * Destroys the TimeFrequency. - */ - ~TimeFrequency(); - - //========================================================================================================= - /** - * AbstractAlgorithm functions - */ - virtual QSharedPointer clone() const; - virtual void init(); - virtual void unload(); - virtual bool start(); - virtual bool stop(); - virtual AbstractPlugin::PluginType getType() const; - virtual QString getName() const; - virtual QWidget* setupWidget(); - virtual QString getBuildInfo(); - - //========================================================================================================= - /** - * Udates the pugin with new (incoming) data. - * - * @param[in] pMeasurement The incoming data in form of a generalized Measurement. - */ - // void update(SCMEASLIB::Measurement::SPtr pMeasurement); - - //========================================================================================================= - /** - * Inits widgets which are used to control this plugin, then emits them in form of a QList. - */ - // void initPluginControlWidgets(); - - //========================================================================================================= - /** - * Set the active flag for SPHARA processing. - * - * @param[in] state The new activity flag. - */ - // void setSpharaActive(bool state); - - //========================================================================================================= - /** - * Set the number of base functions and acquisition system for SPHARA processing. - * - * @param[in] sSytemType The acquisition system. - * @param[in] nBaseFctsGrad The number of grad/mag base functions to keep. - * @param[in] nBaseFctsMag The number of grad/mag base functions to keep. - */ - // void setSpharaOptions(const QString& sSytemType, - // int nBaseFctsFirst, - -protected: - //========================================================================================================= - /** - * AbstractAlgorithm function - */ - virtual void run(); - - //========================================================================================================= - /** - * Update the SSP projection - */ - // void updateProjection(const QList& projs); - - //========================================================================================================= - /** - * Update the compensator - * - * @param[in] to Compensator to use in fiff constant format FiffCtfComp.kind (NOT FiffCtfComp.ctfkind). - */ - // void updateCompensator(int to); - - //========================================================================================================= - /** - * Sets the type of channel which are to be filtered - * - * @param[in] sType the channel type which is to be filtered (EEG, MEG, All). - */ - // void setFilterChannelType(QString sType); - - //========================================================================================================= - /** - * Filter parameters changed - * - * @param[in] filterData currently active filter. - */ - // void setFilter(const RTPROCESSINGLIB::FilterKernel& filterData); - - //========================================================================================================= - /** - * Filter avtivated - * - * @param[in] state filter on/off flag. - */ - // void setFilterActive(bool state); - - //========================================================================================================= - /** - * Init the SPHARA method. - */ - // void initSphara(); - - //========================================================================================================= - /** - * Create/Update the SPHARA projection operator. - */ - // void createSpharaOperator(); - -private: - // QMutex m_mutex; /**< The threads mutex.*/ - // - // bool m_bCompActivated; /**< Compensator activated. */ - // bool m_bSpharaActive; /**< Flag whether thread is running.*/ - // bool m_bProjActivated; /**< Projections activated. */ - // bool m_bFilterActivated; /**< Projections activated. */ - // - // int m_iNBaseFctsFirst; /**< The number of grad/inner base functions to use for calculating the sphara opreator.*/ - // int m_iNBaseFctsSecond; /**< The number of grad/outer base functions to use for calculating the sphara opreator.*/ - // int m_iMaxFilterLength; /**< Max order of the current filters. */ - // int m_iMaxFilterTapSize; /**< maximum number of allowed filter taps. This number depends on the size of the receiving blocks. */ - // - // QString m_sCurrentSystem; /**< The current acquisition system (EEG, babyMEG, VectorView).*/ - // QString m_sFilterChannelType; /**< Kind of channel which is to be filtered. */ - // - // RTPROCESSINGLIB::FilterKernel m_filterKernel; /**< The currently active filter. */ - // - // Eigen::VectorXi m_vecIndicesFirstVV; /**< The indices of the channels to pick for the first SPHARA oerpator in case of a VectorView system.*/ - // Eigen::VectorXi m_vecIndicesSecondVV; /**< The indices of the channels to pick for the second SPHARA oerpator in case of a VectorView system.*/ - // Eigen::VectorXi m_vecIndicesFirstBabyMEG; /**< The indices of the channels to pick for the first SPHARA oerpator in case of a BabyMEG system.*/ - // Eigen::VectorXi m_vecIndicesSecondBabyMEG; /**< The indices of the channels to pick for the second SPHARA oerpator in case of a BabyMEG system.*/ - // Eigen::VectorXi m_vecIndicesFirstEEG; /**< The indices of the channels to pick for the second SPHARA operator in case of an EEG system.*/ - // - // Eigen::SparseMatrix m_matSparseSpharaMult; /**< The final sparse SPHARA operator .*/ - // Eigen::SparseMatrix m_matSparseProjCompMult; /**< The final sparse projection + compensator operator.*/ - // Eigen::SparseMatrix m_matSparseProjMult; /**< The final sparse SSP projector. */ - // Eigen::SparseMatrix m_matSparseCompMult; /**< The final sparse compensator matrix. */ - // Eigen::SparseMatrix m_matSparseFull; /**< The final sparse full multiplication matrix . */ - // - // Eigen::MatrixXd m_matSpharaVVGradLoaded; /**< The loaded VectorView gradiometer basis functions.*/ - // Eigen::MatrixXd m_matSpharaVVMagLoaded; /**< The loaded VectorView magnetometer basis functions.*/ - // Eigen::MatrixXd m_matSpharaBabyMEGInnerLoaded; /**< The loaded babyMEG inner layer basis functions.*/ - // Eigen::MatrixXd m_matSpharaBabyMEGOuterLoaded; /**< The loaded babyMEG outer layer basis functions.*/ - // Eigen::MatrixXd m_matSpharaEEGLoaded; /**< The loaded EEG basis functions.*/ - // - // Eigen::RowVectorXi m_lFilterChannelList; /**< The indices of the channels to be filtered.*/ - - QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ - - // QSharedPointer m_pCircularBuffer; /**< Holds incoming raw data. */ - - SCSHAREDLIB::PluginInputData::SPtr m_pNoiseReductionInput; /**< The RealTimeMultiSampleArray of the NoiseReduction input.*/ - // SCSHAREDLIB::PluginOutputData::SPtr m_pNoiseReductionOutput; /**< The RealTimeMultiSampleArray of the NoiseReduction output.*/ - -}; - -} // NAMESPACE - -#endif // TIMEFREQUENCY_PLUGIN_MNESCAN diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp b/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.cpp deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h b/src/applications/mne_scan/plugins/timefrquency/timefrequency_global.h deleted file mode 100644 index e69de29bb2d..00000000000 From 34d44e20064352e26a41e641bb6a9dbd78008701 Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Sat, 4 Mar 2023 11:14:43 -0500 Subject: [PATCH 3/7] add dependencies --- .../plugins/timefrequency/CMakeLists.txt | 8 +- .../plugins/timefrequency/timefrequency.cpp | 182 +----------------- .../plugins/timefrequency/timefrequency.h | 8 +- 3 files changed, 15 insertions(+), 183 deletions(-) diff --git a/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt index fd00b6e862d..d18716fe691 100644 --- a/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt @@ -10,13 +10,13 @@ find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Svg) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Svg) set(SOURCES - timefrequency.cpp + timefrequency.cpp timefrequency_global.cpp ) set(HEADERS - timefrequency_global.h - timefrequency.h + timefrequency_global.h + timefrequency.h ) set(FILE_TO_UPDATE timefrequency_global.cpp) @@ -57,7 +57,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE # mne_mne # mne_fwd # mne_inverse - mne_rtprocessing + # mne_rtprocessing # mne_connectivity # mne_events scDisp diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp index 89e296bba8e..ad218b0d775 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp @@ -36,21 +36,12 @@ // INCLUDES //============================================================================================================= -#include "timefrequency.h" - -// #include -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include -// +#include "timefrequency/timefrequency.h" + #include #include +#include //============================================================================================================= // QT INCLUDES @@ -66,22 +57,14 @@ // USED NAMESPACES //============================================================================================================= -// using namespace SCMEASLIB; -// using namespace UTILSLIB; -// using namespace DISPLIB; -// using namespace RTPROCESSINGLIB; -// using namespace FIFFLIB; -// using namespace SCSHAREDLIB; -// using namespace Eigen; - //============================================================================================================= // DEFINE MEMBER METHODS //============================================================================================================= -namespace TIMEFREQUENCYPLUGIN { +namespace TIMEFREQUENCYPLUGIN { TimeFrequency::TimeFrequency() -: m_pTimeFrequencyIntput(Q_NULLPTR) +: m_pTimeFrequencyInput(Q_NULLPTR) // : m_bCompActivated(false) // , m_bSpharaActive(false) // , m_bProjActivated(false) @@ -120,16 +103,13 @@ void TimeFrequency::init() create(this, "TimeFrequencyIn", "TimeFrequency input data"); m_inputConnectors.append(m_pTimeFrequencyInput); m_pTimeFrequencyInput->measurementData()->setName(this->getName());//Provide name to auto store widget settings - - // Output - // m_pTimeFrequencyOutput = PluginOutputData::create(this, "TimeFrequencyOut", "TimeFrequency output data"); - // m_outputConnectors.append(m_pTimeFrequencyOutput); } //============================================================================================================= void TimeFrequency::unload() { + } //============================================================================================================= @@ -149,8 +129,6 @@ bool TimeFrequency::stop() wait(500); - // m_pTimeFrequencyOutput->measurementData()->clear(); - return true; } @@ -172,156 +150,12 @@ QString TimeFrequency::getName() const QWidget* TimeFrequency::setupWidget() { - // TimeFrequencySetupWidget* setupWidget = new TimeFrequencySetupWidget(this); - // // widget is later distroyed by CentralWidget - so it has to be created everytime new - QLabel* setupWidget("Time Frequency Baby"); + QString* setupWidget("Time Frequency Baby"); return setupWidget; } //============================================================================================================= -// void TimeFrequency::update(SCMEASLIB::Measurement::SPtr pMeasurement) -// { -// if(QSharedPointer pRTMSA = pMeasurement.dynamicCast()) { -// //Check if the fiff info was inititalized -// if(!m_pFiffInfo) { -// m_pFiffInfo = pRTMSA->info(); -// -// //Init the multiplication matrices -// m_matSparseProjMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); -// m_matSparseCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); -// m_matSparseSpharaMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); -// m_matSparseProjCompMult = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); -// m_matSparseFull = SparseMatrix(m_pFiffInfo->chs.size(),m_pFiffInfo->chs.size()); -// -// m_matSparseProjMult.setIdentity(); -// m_matSparseCompMult.setIdentity(); -// m_matSparseSpharaMult.setIdentity(); -// m_matSparseProjCompMult.setIdentity(); -// m_matSparseFull.setIdentity(); -// -// //Init output -// m_pTimeFrequencyOutput->measurementData()->initFromFiffInfo(m_pFiffInfo); -// m_pTimeFrequencyOutput->measurementData()->setMultiArraySize(1); -// } -// -// // Check if data is present -// if(pRTMSA->getMultiSampleArray().size() > 0) { -// //Init widgets -// if(m_iMaxFilterTapSize == -1) { -// m_iMaxFilterTapSize = pRTMSA->getMultiSampleArray().first().cols(); -// initPluginControlWidgets(); -// QThread::start(); -// } -// -// for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) { -// // Please note that we do not need a copy here since this function will block until -// // the buffer accepts new data again. Hence, the data is not deleted in the actual -// // Measurement function after it emitted the notify signal. -// while(!m_pCircularBuffer->push(pRTMSA->getMultiSampleArray()[i])) { -// //Do nothing until the circular buffer is ready to accept new data again -// } -// } -// } -// } -// } -// -// //============================================================================================================= -// -// void TimeFrequency::initPluginControlWidgets() -// { -// if(m_pFiffInfo) { -// QList plControlWidgets; -// -// // Projectors -// ProjectorsView* pProjectorsView = new ProjectorsView(QString("MNESCAN/%1/").arg(this->getName())); -// connect(this, &TimeFrequency::guiModeChanged, -// pProjectorsView, &ProjectorsView::setGuiMode); -// pProjectorsView->setObjectName("group_tab_Settings_SSP"); -// plControlWidgets.append(pProjectorsView); -// -// connect(pProjectorsView, &ProjectorsView::projSelectionChanged, -// this, &TimeFrequency::updateProjection); -// -// pProjectorsView->setProjectors(m_pFiffInfo->projs); -// -// // Compensators -// CompensatorView* pCompensatorView = new CompensatorView(QString("MNESCAN/%1/").arg(this->getName())); -// connect(this, &TimeFrequency::guiModeChanged, -// pCompensatorView, &CompensatorView::setGuiMode); -// pCompensatorView->setObjectName("group_tab_Settings_Comp"); -// plControlWidgets.append(pCompensatorView); -// -// connect(pCompensatorView, &CompensatorView::compSelectionChanged, -// this, &TimeFrequency::updateCompensator); -// -// pCompensatorView->setCompensators(m_pFiffInfo->comps); -// -// // Filter -// FilterSettingsView* pFilterSettingsView = new FilterSettingsView(QString("MNESCAN/%1/").arg(this->getName())); -// connect(this, &TimeFrequency::guiModeChanged, -// pFilterSettingsView, &FilterSettingsView::setGuiMode); -// pFilterSettingsView->setObjectName("group_tab_Settings_Filter"); -// plControlWidgets.append(pFilterSettingsView); -// -// connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChannelTypeChanged, -// this, &TimeFrequency::setFilterChannelType); -// -// connect(pFilterSettingsView->getFilterView().data(), &FilterDesignView::filterChanged, -// this, &TimeFrequency::setFilter); -// -// connect(pFilterSettingsView, &FilterSettingsView::filterActivationChanged, -// this, &TimeFrequency::setFilterActive); -// -// pFilterSettingsView->setSamplingRate(m_pFiffInfo->sfreq); -// pFilterSettingsView->getFilterView()->setMaxAllowedFilterTaps(m_iMaxFilterTapSize); -// -// this->setFilterActive(pFilterSettingsView->getFilterActive()); -// this->setFilterChannelType(pFilterSettingsView->getFilterView()->getChannelType()); -// -// // SPHARA settings -// SpharaSettingsView* pSpharaSettingsView = new SpharaSettingsView(QString("MNESCAN/%1").arg(this->getName())); -// connect(this, &TimeFrequency::guiModeChanged, -// pSpharaSettingsView, &SpharaSettingsView::setGuiMode); -// pSpharaSettingsView->setObjectName("group_tab_Settings_SPHARA"); -// plControlWidgets.append(pSpharaSettingsView); -// -// connect(pSpharaSettingsView, &SpharaSettingsView::spharaActivationChanged, -// this, &TimeFrequency::setSpharaActive); -// -// connect(pSpharaSettingsView, &SpharaSettingsView::spharaOptionsChanged, -// this, &TimeFrequency::setSpharaOptions); -// -// emit pluginControlWidgetsChanged(plControlWidgets, this->getName()); -// } -// } -// -// //============================================================================================================= -// -// void TimeFrequency::setSpharaActive(bool state) -// { -// m_mutex.lock(); -// m_bSpharaActive = state; -// m_mutex.unlock(); -// } -// -// //============================================================================================================= -// -// void TimeFrequency::setSpharaOptions(const QString& sSytemType, -// int nBaseFctsFirst, -// int nBaseFctsSecond) -// { -// m_mutex.lock(); -// m_iNBaseFctsFirst = nBaseFctsFirst; -// m_iNBaseFctsSecond = nBaseFctsSecond; -// m_sCurrentSystem = sSytemType; -// m_mutex.unlock(); -// -// createSpharaOperator(); -// } -// -//============================================================================================================= - void TimeFrequency::run() { // Read and create SPHARA operator for the first time @@ -329,7 +163,7 @@ void TimeFrequency::run() // createSpharaOperator(); // Init - MatrixXd matData; + Eigen::MatrixXd matData; // matData. // QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h index d80e144fd46..57277aca00f 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h @@ -47,6 +47,7 @@ //============================================================================================================= #include +#include //============================================================================================================= // EIGEN INCLUDES @@ -118,7 +119,6 @@ class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlg virtual QString getName() const; virtual QWidget* setupWidget(); virtual QString getBuildInfo(); - protected: virtual void run(); //========================================================================================================= @@ -130,10 +130,8 @@ class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlg */ private: - QSharedPointer - m_pFiffInfo; /**< Fiff measurement info.*/ - SCSHAREDLIB::PluginInputData::SPtr - m_pTimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ + QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + SCSHAREDLIB::PluginInputData::SPtr m_pTimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ }; } // namespace TIMEFREQUENCYPLUGIN From 79272fe1d5322d7913c41602ec5003586032e6eb Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Sat, 4 Mar 2023 11:34:51 -0500 Subject: [PATCH 4/7] fix project dependencies --- .../plugins/timefrequency/CMakeLists.txt | 11 +++++---- .../plugins/timefrequency/timefrequency.cpp | 23 +++++++------------ .../plugins/timefrequency/timefrequency.h | 22 +++++++----------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt index d18716fe691..e02a4df92a5 100644 --- a/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/timefrequency/CMakeLists.txt @@ -6,8 +6,10 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Svg) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Svg) +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS + Core Widgets Network Concurrent) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED + COMPONENTS Core Widgets Network Concurrent) set(SOURCES timefrequency.cpp @@ -25,7 +27,7 @@ set(SOURCE_PATHS ${SOURCES}) list(TRANSFORM SOURCE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") set_source_files_properties(${FILE_TO_UPDATE} PROPERTIES OBJECT_DEPENDS "${SOURCE_PATHS}") -add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${RESOURCES}) +add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS}) set(FFTW_LIBS "") @@ -48,7 +50,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC ../) target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets - Qt${QT_VERSION_MAJOR}::Svg + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Concurrent eigen mne_disp mne_utils diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp index ad218b0d775..5e21f72ca8b 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp @@ -41,13 +41,14 @@ #include #include -#include //============================================================================================================= // QT INCLUDES //============================================================================================================= #include +#include +#include //============================================================================================================= // EIGEN INCLUDES @@ -64,15 +65,7 @@ namespace TIMEFREQUENCYPLUGIN { TimeFrequency::TimeFrequency() -: m_pTimeFrequencyInput(Q_NULLPTR) -// : m_bCompActivated(false) -// , m_bSpharaActive(false) -// , m_bProjActivated(false) -// , m_bFilterActivated(false) -// , m_iMaxFilterLength(1) -// , m_iMaxFilterTapSize(-1) -// , m_sCurrentSystem("VectorView") -// , m_pCircularBuffer(QSharedPointer::create(40)) +: m_pRTMSATimeFrequencyInput(Q_NULLPTR) { qDebug() << "[TimeFrequency::TimeFrequency] Creating Plugin Object."; } @@ -82,7 +75,7 @@ TimeFrequency::TimeFrequency() TimeFrequency::~TimeFrequency() { if(this->isRunning()) { - stop(); + TimeFrequency::stop(); } } @@ -99,10 +92,10 @@ QSharedPointer TimeFrequency::clone() const void TimeFrequency::init() { // Input - m_pTimeFrequencyInput = PluginInputData:: + m_pRTMSATimeFrequencyInput = PluginInputData:: create(this, "TimeFrequencyIn", "TimeFrequency input data"); - m_inputConnectors.append(m_pTimeFrequencyInput); - m_pTimeFrequencyInput->measurementData()->setName(this->getName());//Provide name to auto store widget settings + m_inputConnectors.append(m_pRTMSATimeFrequencyInput); + m_pRTMSATimeFrequencyInput->measurementData()->setName(this->getName());//Provide name to auto store widget settings } //============================================================================================================= @@ -173,7 +166,7 @@ void TimeFrequency::run() msleep(500); // Send the data to the connected plugins and the display if(!isInterruptionRequested()) { - m_pTimeFrequencyInput->measurementData()->setValue(matData); + m_pRTMSATimeFrequencyInput->measurementData()->setValue(matData); } } } diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h index 57277aca00f..70b0303fa28 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h @@ -46,6 +46,7 @@ // QT INCLUDES //============================================================================================================= +#include #include #include @@ -58,24 +59,19 @@ // FORWARD DECLARATIONS //============================================================================================================= -namespace FIFFLIB{ -class FiffInfo; +namespace SCMEASLIB { +class RealTimeMultiSampleArray; } -// namespace RTPROCESSINGLIB{ -// class Filter; -// } - -namespace SCMEASLIB{ -class RealTimeMultiSampleArray; +namespace FIFFLIB { +class FiffInfo; } //============================================================================================================= // DEFINE NAMESPACE TIMEFREQUENCYPLUGIN //============================================================================================================= -namespace TIMEFREQUENCYPLUGIN -{ +namespace TIMEFREQUENCYPLUGIN { //============================================================================================================= // TIMEFREQUENCYPLUGIN FORWARD DECLARATIONS @@ -84,9 +80,7 @@ namespace TIMEFREQUENCYPLUGIN //============================================================================================================= /** * DECLARE CLASS TimeFrequency - * - * @brief The TimeFrequency class provides a tools to compute and show time-frequency maps. - */ + * @brief The TimeFrequency class provides a tools to compute and show time-frequency maps. */ class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlgorithm { Q_OBJECT @@ -130,8 +124,8 @@ class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlg */ private: + QSharedPointer> m_pRTMSATimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ - SCSHAREDLIB::PluginInputData::SPtr m_pTimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ }; } // namespace TIMEFREQUENCYPLUGIN From d11ad176e54d79c7a1d3339a28fc4d6c94c84473 Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Sun, 5 Mar 2023 22:22:57 -0500 Subject: [PATCH 5/7] time_frequency plugin barebones working allright --- .../plugins/timefrequency/timefrequency.cpp | 49 +++++++++++-------- .../plugins/timefrequency/timefrequency.h | 6 ++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp index 5e21f72ca8b..58a0ff42023 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.cpp @@ -65,7 +65,8 @@ namespace TIMEFREQUENCYPLUGIN { TimeFrequency::TimeFrequency() -: m_pRTMSATimeFrequencyInput(Q_NULLPTR) +: m_pRTMSA_In(Q_NULLPTR), + m_pRTMSA_Out(Q_NULLPTR) { qDebug() << "[TimeFrequency::TimeFrequency] Creating Plugin Object."; } @@ -81,7 +82,7 @@ TimeFrequency::~TimeFrequency() //============================================================================================================= -QSharedPointer TimeFrequency::clone() const +QSharedPointer TimeFrequency::clone() const { QSharedPointer pTimeFrequencyClone(new TimeFrequency); return pTimeFrequencyClone; @@ -91,11 +92,20 @@ QSharedPointer TimeFrequency::clone() const void TimeFrequency::init() { - // Input - m_pRTMSATimeFrequencyInput = PluginInputData:: - create(this, "TimeFrequencyIn", "TimeFrequency input data"); - m_inputConnectors.append(m_pRTMSATimeFrequencyInput); - m_pRTMSATimeFrequencyInput->measurementData()->setName(this->getName());//Provide name to auto store widget settings + // Input + m_pRTMSA_In = SCSHAREDLIB::PluginInputData< + SCMEASLIB::RealTimeMultiSampleArray>:: + create(this, "TimeFrequencyIn", "TimeFrequency in data"); + connect(m_pRTMSA_In.data(), &SCSHAREDLIB::PluginInputConnector::notify, + this, &TimeFrequency::update, Qt::DirectConnection); + m_inputConnectors.append(m_pRTMSA_In); + + // Output + m_pRTMSA_Out = SCSHAREDLIB::PluginOutputData< + SCMEASLIB::RealTimeMultiSampleArray>:: + create(this, "TimeFrequencyOut", "TimeFrequencyPluginOutputdata"); + m_pRTMSA_Out->measurementData()->setName(this->getName()); + m_outputConnectors.append(m_pRTMSA_Out); } //============================================================================================================= @@ -110,7 +120,6 @@ void TimeFrequency::unload() bool TimeFrequency::start() { //Start thread as soon as we have received the first data block. See update(). - return true; } @@ -127,7 +136,7 @@ bool TimeFrequency::stop() //============================================================================================================= -AbstractPlugin::PluginType TimeFrequency::getType() const +SCSHAREDLIB::AbstractPlugin::PluginType TimeFrequency::getType() const { return _IAlgorithm; } @@ -143,31 +152,29 @@ QString TimeFrequency::getName() const QWidget* TimeFrequency::setupWidget() { - QString* setupWidget("Time Frequency Baby"); - return setupWidget; + return new QLabel("Time Frequency Baby"); } //============================================================================================================= +void TimeFrequency::update(QSharedPointer pMeasurement) +{ + qDebug() << "new data!"; +} void TimeFrequency::run() { - // Read and create SPHARA operator for the first time - // initSphara(); - // createSpharaOperator(); // Init Eigen::MatrixXd matData; // matData. - // QScopedPointer pRtFilter(new RTPROCESSINGLIB::FilterOverlapAdd()); - while (true) { - // Get the current data msleep(500); - // Send the data to the connected plugins and the display - if(!isInterruptionRequested()) { - m_pRTMSATimeFrequencyInput->measurementData()->setValue(matData); - } + if(isInterruptionRequested()) + break; + qDebug() << "run!!"; + + // m_pRTMSA_Out->measurementData()->setValue(matData); } } diff --git a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h index 70b0303fa28..797cda20f1e 100644 --- a/src/applications/mne_scan/plugins/timefrequency/timefrequency.h +++ b/src/applications/mne_scan/plugins/timefrequency/timefrequency.h @@ -119,13 +119,15 @@ class TIMEFREQUENCYSHARED_EXPORT TimeFrequency : public SCSHAREDLIB::AbstractAlg public: //========================================================================================================= + void update(QSharedPointer pMeasurement); /** * Other methods can go here... */ private: - QSharedPointer> m_pRTMSATimeFrequencyInput; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ - QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + QSharedPointer > m_pRTMSA_In; /**< The RealTimeMultiSampleArray of the TimeFrequency input.*/ + QSharedPointer > m_pRTMSA_Out; /**< The RealTimeMultiSampleArray to provide time-frequency data to other plugins.*/ + //QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ }; } // namespace TIMEFREQUENCYPLUGIN From a8e8c4dbfd0228d2150d15314c2d53af5471614f Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Mon, 6 Mar 2023 00:45:08 -0500 Subject: [PATCH 6/7] add random data simple plugin --- .../plugins/randomdata/CMakeLists.txt | 73 +++++ .../plugins/randomdata/randomdata.cpp | 304 ++++++++++++++++++ .../mne_scan/plugins/randomdata/randomdata.h | 141 ++++++++ .../plugins/randomdata/randomdata.json | 0 .../plugins/randomdata/randomdata_global.cpp | 55 ++++ .../plugins/randomdata/randomdata_global.h | 81 +++++ 6 files changed, 654 insertions(+) create mode 100644 src/applications/mne_scan/plugins/randomdata/CMakeLists.txt create mode 100644 src/applications/mne_scan/plugins/randomdata/randomdata.cpp create mode 100644 src/applications/mne_scan/plugins/randomdata/randomdata.h create mode 100644 src/applications/mne_scan/plugins/randomdata/randomdata.json create mode 100644 src/applications/mne_scan/plugins/randomdata/randomdata_global.cpp create mode 100644 src/applications/mne_scan/plugins/randomdata/randomdata_global.h diff --git a/src/applications/mne_scan/plugins/randomdata/CMakeLists.txt b/src/applications/mne_scan/plugins/randomdata/CMakeLists.txt new file mode 100644 index 00000000000..a76a716e702 --- /dev/null +++ b/src/applications/mne_scan/plugins/randomdata/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.14) +project(scan_randomdata LANGUAGES CXX) + +#Handle qt uic, moc, rrc automatically +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Network Concurrent) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Network Concurrent) + +set(SOURCES + randomdata.cpp + randomdata_global.cpp +) + +set(HEADERS + randomdata.h + randomdata_global.h +) + +set(FILE_TO_UPDATE randomdata_global.cpp) + +set(SOURCE_PATHS ${SOURCES}) +list(TRANSFORM SOURCE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +set_source_files_properties(${FILE_TO_UPDATE} PROPERTIES OBJECT_DEPENDS "${SOURCE_PATHS}") + +add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS}) + +set(FFTW_LIBS "") + +if(USE_FFTW) + if (WIN32) + set(FFTW_LIBS + ${FFTW_DIR_LIBS}/libfftw3-3.dll + ${FFTW_DIR_LIBS}/libfftw3f-3.dll + ${FFTW_DIR_LIBS}/libfftwf3l-3.dll + ) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}) + elseif(UNIX AND NOT APPLE) + set(FFTW_LIBS ${FFTW_DIR_LIBS}/lib/libfftw3.so) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}/api) + endif() +endif() + +target_include_directories(${PROJECT_NAME} PUBLIC ../) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Concurrent + eigen + mne_disp + mne_utils + mne_fiff + # mne_fs + # mne_mne + # mne_fwd + # mne_inverse + # mne_rtprocessing + # mne_connectivity + # mne_events + scDisp + scShared + scMeas + ${FFTW_LIBS}) + +target_compile_definitions(${PROJECT_NAME} PRIVATE SCAN_RANDOMDATA_PLUGIN MNE_GIT_HASH_SHORT="${MNE_GIT_HASH_SHORT}" MNE_GIT_HASH_LONG="${MNE_GIT_HASH_LONG}") + +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_NAME} PRIVATE STATICBUILD QT_STATICPLUGIN) +endif() diff --git a/src/applications/mne_scan/plugins/randomdata/randomdata.cpp b/src/applications/mne_scan/plugins/randomdata/randomdata.cpp new file mode 100644 index 00000000000..7d19cb89500 --- /dev/null +++ b/src/applications/mne_scan/plugins/randomdata/randomdata.cpp @@ -0,0 +1,304 @@ +//============================================================================================================= +/** + * @file randomdata.cpp + * @author Juan GarciaPrieto ; + * Gabriel B Motta ; + * @since 0.1.0 + * @date February, 2023 + * + * @section LICENSE + * + * Copyright (C) 2023, Juan G Prieto, Gabriel B Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the definition of the RandomData class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include + +#include "randomdata/randomdata.h" + +#include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include +#include +#include +#include + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +namespace RANDOMDATAPLUGIN { + +//============================================================================================================= + +// QSharedPointer createFiffInfo(int numChassis, +// int numChannels) { +// QSharedPointer pFiffInfo; +// pFiffInfo->sfreq = 1000.0f; +// pFiffInfo->nchan = numChassis * numChannels; +// pFiffInfo->chs.clear(); +// +// for (int chan_i = 0; chan_i < pFiffInfo->nchan; ++chan_i) { +// FIFFLIB::FiffChInfo channel; +// channel.ch_name = QString("%1:%2").arg(numChannels, 2).arg(chan_i, 2); +// channel.kind = FIFFV_MEG_CH; +// channel.unit = FIFF_UNIT_T; +// channel.unit_mul = FIFF_UNITM_NONE; +// channel.chpos.coil_type = FIFFV_COIL_NONE; +// pFiffInfo->chs.append(channel); +// pFiffInfo->ch_names.append(channel.ch_name); +// } +// } + +// QSharedPointer +// createFiffInfo(std::vector> fl_chassis, float sfreq = 1000.f) { +// QSharedPointer pFiffInfo; +// pFiffInfo->sfreq = sfreq; +// pFiffInfo->chs.clear(); +// +// int total_channels = 0; +// int chassis_num = 0; +// for (auto &chassis : fl_chassis) { +// for (auto &sensor : chassis) { +// FIFFLIB::FiffChInfo channel; +// channel.ch_name = QString("%1:%2").arg(chassis_num, 2).arg(sensor, 2); +// channel.kind = FIFFV_MEG_CH; +// channel.unit = FIFF_UNIT_T; +// channel.unit_mul = FIFF_UNITM_NONE; +// channel.chpos.coil_type = FIFFV_COIL_NONE; +// pFiffInfo->chs.append(channel); +// pFiffInfo->ch_names.append(channel.ch_name); +// ++total_channels; +// } +// } +// pFiffInfo->nchan = total_channels; +// +// return pFiffInfo; +// } +// +// QSharedPointer +// createFiffInfo(int numChassis, int numChannels, float sfreq = 1000.f) { +// std::vector> fl; +// for (int i = 0; i < numChassis; ++i) { +// std::vector ch(numChannels); +// std::iota(ch.begin(), ch.end(), 1); +// fl.push_back(std::move(ch)); +// } +// return createFiffInfo(fl, sfreq); +// } + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +RandomData::RandomData() +: m_pFiffInfo(QSharedPointer(new FIFFLIB::FiffInfo())) +{ + m_pRTMSA_RandomData = SCSHAREDLIB::PluginOutputData< + SCMEASLIB::RealTimeMultiSampleArray>::create(this, "RandomData Out", + "RandomDataPlguin output"); + m_pRTMSA_RandomData->measurementData()->setName(this->getName()); + m_outputConnectors.append(m_pRTMSA_RandomData); +} + +//============================================================================================================= + +RandomData::~RandomData() +{ + if(this->isRunning()) { + RandomData::stop(); + } +} + +//============================================================================================================= + +QSharedPointer RandomData::clone() const +{ + QSharedPointer pRandomDataClone(new RandomData()); + return pRandomDataClone; +} + +//============================================================================================================= + +void RandomData::init() +{ + m_pFiffInfo->sfreq = 1000.0f; + m_pFiffInfo->nchan = 32; + m_pFiffInfo->chs.clear(); + + for (int chan_i = 0; chan_i < m_pFiffInfo->nchan; ++chan_i) { + FIFFLIB::FiffChInfo channel; + channel.ch_name = "Ch. " + QString::number(chan_i); + channel.kind = FIFFV_MEG_CH; + channel.unit = FIFF_UNIT_T; + channel.unit_mul = FIFF_UNITM_NONE; + channel.chpos.coil_type = FIFFV_COIL_NONE; + m_pFiffInfo->chs.append(channel); + m_pFiffInfo->ch_names.append(channel.ch_name); + } + + m_pRTMSA_RandomData->measurementData()->initFromFiffInfo( + m_pFiffInfo); // if(m_pCircularBuffer->pop(matData)) { + m_pRTMSA_RandomData->measurementData()->setMultiArraySize(1); + m_pRTMSA_RandomData->measurementData()->setVisibility(true); + + matData.resize(m_pFiffInfo->nchan, 200); + + qDebug() << " ^^^^^^^^^^^^^^^^^^^^ Init Random Data (....again)"; +} + +//============================================================================================================= + +void RandomData::unload() +{ +} + +//============================================================================================================= + +bool RandomData::start() +{ + // Init circular buffer to transmit data from the producer to this thread + // if(!m_pCircularBuffer) { + // m_pCircularBuffer = QSharedPointer(new + // CircularBuffer_Matrix_double(10)); + // } + // + // //Setup fiff info before setting up the RMTSA because we need it to init + // the RTMSA setUpFiffInfo(); + // + // //Set the channel size of the RMTSA - this needs to be done here and NOT in + // the init() function because the user can change the number of channels + // during runtime + // m_pRMTSA_Natus->measurementData()->initFromFiffInfo(m_pFiffInfo); + // m_pRMTSA_Natus->measurementData()->setMultiArraySize(1); + // + QThread::start(); + // + // // Start the producer + // m_pNatusProducer = + // QSharedPointer::create(m_iSamplesPerBlock, + // m_iNumberChannels); m_pNatusProducer->moveToThread(&m_pProducerThread); + // connect(m_pNatusProducer.data(), &NatusProducer::newDataAvailable, + // this, &RandomData::onNewDataAvailable, Qt::DirectConnection); + // m_pProducerThread.start(); + + return true; +} + +//============================================================================================================= + +bool RandomData::stop() +{ + requestInterruption(); + wait(500); + m_pRTMSA_RandomData->measurementData()->clear(); + + return true; +} + +//============================================================================================================= + +SCSHAREDLIB::AbstractPlugin::PluginType RandomData::getType() const +{ + return SCSHAREDLIB::AbstractPlugin::PluginType::_ISensor; +} + +//============================================================================================================= + +QString RandomData::getName() const +{ + return "Random Data"; +} + +//============================================================================================================= + +QWidget* RandomData::setupWidget() +{ + + // guiWidget = std::make_unique(); + + // NatusSetup* widget = new NatusSetup(this);//widget is later destroyed by + // CentralWidget - so it has to be created everytime new + + // init properties dialog + // widget->initGui(); + + // auto *frame = new QWidget(); + // frame->setLayout(new QHBoxLayout()); + // + // auto *flWidget = new DISPLIB::RandomDataView(2, 16); + // + // frame->layout()->addWidget(flWidget); + // flWidget->setBlinkState(0, 2, true); + // flWidget->setBlinkState(1, 5, true); + + return new QLabel("Random data Baby!"); +} + +//============================================================================================================= + +void RandomData::run() { + + for (;;) { + // gather the data + + matData = Eigen::MatrixXd::Random(m_pFiffInfo->nchan, 200); + matData *= 4e-12; + + msleep(200); + + if (isInterruptionRequested()) + break; + m_pRTMSA_RandomData->measurementData()->setValue(matData); + } +} + +//============================================================================================================= + +QString RandomData::getBuildInfo() { + return QString(buildDateTime()) + QString(" - ") + QString(buildHash()); +} + +} // namespace RANDOMDATAPLUGIN + diff --git a/src/applications/mne_scan/plugins/randomdata/randomdata.h b/src/applications/mne_scan/plugins/randomdata/randomdata.h new file mode 100644 index 00000000000..73d9c044815 --- /dev/null +++ b/src/applications/mne_scan/plugins/randomdata/randomdata.h @@ -0,0 +1,141 @@ +//============================================================================================================= +/** + * @file randomdata.h + * @author Juan GarciaPrieto ; + * Gabriel B Motta ; + * @since 0.1.0 + * @date February, 2023 + * + * @section LICENSE + * + * Copyright (C) 2023, Juan G Prieto, Gabriel B Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the declaration of the Random data plugin class. + * + */ + +#ifndef RANDOMDATA_H +#define RANDOMDATA_H //============================================================================================================= INCLUDES ============================================================================================================= + +#include "randomdata/randomdata_global.h" +// #include "randomdata/randomdata_plugin_gui.h" + +#include +// #include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// FORWARD DECLARATION +//============================================================================================================= + +namespace SCMEASLIB { +class RealTimeMultiSampleArray; +} + +namespace FIFFLIB { +class FiffInfo; +} + + +//============================================================================================================= +// DEFINE NAMESPACE RANDOMDATAPLUGIN +//============================================================================================================= + +namespace RANDOMDATAPLUGIN { + +//============================================================================================================= +// RANDOMDATAPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +//============================================================================================================= +/** + * The RandomData class provides a EEG connector for generating random data. + * + * @brief The RandomData class. + */ +class RANDOMDATASHARED_EXPORT RandomData : public SCSHAREDLIB::AbstractSensor { + Q_OBJECT + Q_PLUGIN_METADATA(IID "scsharedlib/1.0" FILE "randomdata.json") //New Qt5 Plugin system replaces Q_EXPORT_PLUGIN2 macro + // Use the Q_INTERFACES() macro to tell Qt's meta-object system about the interfaces + Q_INTERFACES(SCSHAREDLIB::AbstractSensor) + + public: + //========================================================================================================= + /** + * Constructs RandomData. + */ + RandomData(); + + //========================================================================================================= + /** + * Destroys RandomData. + */ + ~RandomData(); + + //========================================================================================================= + /** + * Virtual Interface + * */ + virtual QSharedPointer clone() const; + virtual void init(); + virtual void unload(); + virtual bool start(); + virtual bool stop(); + virtual AbstractPlugin::PluginType getType() const; + virtual QString getName() const; + virtual QWidget* setupWidget(); + virtual QString getBuildInfo(); + + protected: + //========================================================================================================= + /** + * the starting point for the thread. after calling start(), the newly created thread calls this function. + * returning from this method will end the execution of the thread. + * pure virtual method inherited by qthread. + */ + virtual void run(); + + // std::unique_ptr guiWidget; + + QSharedPointer> m_pRTMSA_RandomData; + QSharedPointer m_pFiffInfo; + Eigen::MatrixXd matData; + +}; // namespace RANDOMDATAPLUGIN + +} + +#endif // RANDOMDATA_H diff --git a/src/applications/mne_scan/plugins/randomdata/randomdata.json b/src/applications/mne_scan/plugins/randomdata/randomdata.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/applications/mne_scan/plugins/randomdata/randomdata_global.cpp b/src/applications/mne_scan/plugins/randomdata/randomdata_global.cpp new file mode 100644 index 00000000000..d009cc09065 --- /dev/null +++ b/src/applications/mne_scan/plugins/randomdata/randomdata_global.cpp @@ -0,0 +1,55 @@ +//============================================================================================================= +/** + * @file randomdata_global.cpp + * @author Juan G Prieto ; + * Gabriel B Motta ; + * @since 0.1.9 + * @date September, 2021 + * + * @section LICENSE + * + * Copyright (C) 2021, Juan G Prieto, Gabriel B Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief randomdata plugin global definitions. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "randomdata_global.h" + +//============================================================================================================= +// DEFINE METHODS +//============================================================================================================= + +const char* RANDOMDATAPLUGIN::buildDateTime(){ return UTILSLIB::dateTimeNow();} + +//============================================================================================================= + +const char* RANDOMDATAPLUGIN::buildHash(){ return UTILSLIB::gitHash();} + +//============================================================================================================= + +const char* RANDOMDATAPLUGIN::buildHashLong(){ return UTILSLIB::gitHashLong();} + diff --git a/src/applications/mne_scan/plugins/randomdata/randomdata_global.h b/src/applications/mne_scan/plugins/randomdata/randomdata_global.h new file mode 100644 index 00000000000..ed025965d3f --- /dev/null +++ b/src/applications/mne_scan/plugins/randomdata/randomdata_global.h @@ -0,0 +1,81 @@ +//============================================================================================================= +/** + * @file randomdata_global.h + * @author Lorenz Esch + * @since 0.1.0 + * @date June, 2018 + * + * @section LICENSE + * + * Copyright (C) 2018, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the Random Data plugin library export/import macros. + * + */ + +#ifndef RANDOMDATA_GLOBAL_H +#define RANDOMDATA_GLOBAL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// PREPROCESSOR DEFINES +//============================================================================================================= + +#if defined(SCAN_RANDOMDATA_PLUGIN) +# define RANDOMDATASHARED_EXPORT Q_DECL_EXPORT /**< Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. */ +#else +# define RANDOMDATASHARED_EXPORT Q_DECL_IMPORT /**< Q_DECL_IMPORT must be added to the declarations of symbols used when compiling a client that uses the shared library. */ +#endif + +namespace RANDOMDATAPLUGIN { + +//============================================================================================================= +/** + * Returns build date and time. + */ +RANDOMDATASHARED_EXPORT const char* buildDateTime(); + +//============================================================================================================= +/** + * Returns abbreviated build git hash. + */ +RANDOMDATASHARED_EXPORT const char* buildHash(); + +//============================================================================================================= +/** + * Returns full build git hash. + */ +RANDOMDATASHARED_EXPORT const char* buildHashLong(); +} // namespace RANDOMDATAPLUGIN + +#endif // RANDOMDATA_GLOBAL_H From b7ba927056302a02f2b67a66666cc9d3dcca9e02 Mon Sep 17 00:00:00 2001 From: JuanGPC Date: Mon, 6 Mar 2023 00:46:14 -0500 Subject: [PATCH 7/7] add random data project to cmake --- src/applications/mne_scan/plugins/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/applications/mne_scan/plugins/CMakeLists.txt b/src/applications/mne_scan/plugins/CMakeLists.txt index 775c74dbf69..18793a941ba 100644 --- a/src/applications/mne_scan/plugins/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(fiffsimulator) add_subdirectory(ftbuffer) add_subdirectory(babymeg) add_subdirectory(natus) +add_subdirectory(randomdata) # Algorithm Plugin add_subdirectory(rtcmne)