From ef37e240a1f6b77b84d103bc7bfcac7e5f3fd419 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Mon, 13 Jun 2022 11:43:34 -0400 Subject: [PATCH 01/17] Add skeleton for forward solution plugin --- .../forwardsolution/forwardsolution.cpp | 149 ++++++++++++++++ .../plugins/forwardsolution/forwardsolution.h | 119 +++++++++++++ .../forwardsolution/forwardsolution.json | 0 .../forwardsolution/forwardsolution.pro | 165 ++++++++++++++++++ .../forwardsolution_global.cpp | 54 ++++++ .../forwardsolution/forwardsolution_global.h | 82 +++++++++ applications/mne_analyze/plugins/plugins.pro | 1 + 7 files changed, 570 insertions(+) create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution.h create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution.json create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.cpp create mode 100644 applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.h diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp new file mode 100644 index 00000000000..623f399bd21 --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -0,0 +1,149 @@ +//============================================================================================================= +/** + * @file forwardsolution.cpp + * @author Gabriel Motta ; + * Juan G Prieto + * @since 0.1.9 + * @date June, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel B Motta, Juan G 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 ForwardSolution class defintion. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "forwardsolution.h" + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace FORWARDSOLUTIONPLUGIN; +using namespace ANSHAREDLIB; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +ForwardSolution::ForwardSolution() +: m_pCommu(Q_NULLPTR) +{ +} + +//============================================================================================================= + +ForwardSolution::~ForwardSolution() +{ +} + +//============================================================================================================= + +QSharedPointer ForwardSolution::clone() const +{ + QSharedPointer pForwardSolutionClone(new ForwardSolution); + return pForwardSolutionClone; +} + +//============================================================================================================= + +void ForwardSolution::init() +{ + m_pCommu = new Communicator(this); +} + +//============================================================================================================= + +void ForwardSolution::unload() +{ + +} + +//============================================================================================================= + +QString ForwardSolution::getName() const +{ + return "Source Localization"; +} + +//============================================================================================================= + +QMenu *ForwardSolution::getMenu() +{ + return Q_NULLPTR; +} + +//============================================================================================================= + +QWidget *ForwardSolution::getView() +{ + return Q_NULLPTR; +} + +//============================================================================================================= + +QDockWidget* ForwardSolution::getControl() +{ + //QDockWidget* pControl = new QDockWidget(getName()); + + return Q_NULLPTR; +} + +//============================================================================================================= + +void ForwardSolution::handleEvent(QSharedPointer e) +{ + switch (e->getType()) { + default: + qWarning() << "[ForwardSolution::handleEvent] Received an Event that is not handled by switch cases."; + } +} + +//============================================================================================================= + +QVector ForwardSolution::getEventSubscriptions(void) const +{ + QVector temp; + //temp.push_back(SELECTED_MODEL_CHANGED); + + return temp; +} + +//============================================================================================================= + +QString ForwardSolution::getBuildInfo() +{ + return QString(FORWARDSOLUTIONPLUGIN::buildDateTime()) + QString(" - ") + QString(FORWARDSOLUTIONPLUGIN::buildHash()); +} diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h new file mode 100644 index 00000000000..9ce4ac20399 --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -0,0 +1,119 @@ +//============================================================================================================= +/** + * @file forwardsolution.h + * @author Gabriel Motta + * Juan G Prieto + * @since 0.1.9 + * @date June, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel B Motta, Juan G 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 ForwardSolution class declaration. + * + */ + +#ifndef MNEANALYZE_FORWARDSOLUTION_H +#define MNEANALYZE_FORWARDSOLUTION_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "forwardsolution_global.h" + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace ANSHAREDLIB { + class Communicator; +} + +//============================================================================================================= +// DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN +//============================================================================================================= + +namespace FORWARDSOLUTIONPLUGIN +{ + +//============================================================================================================= +// FORWARDSOLUTIONPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +//============================================================================================================= +/** + * ForwardSolution Plugin + * + * @brief The forwardsolution class provides a plugin for computing averages. + */ +class FORWARDSOLUTIONSHARED_EXPORT ForwardSolution : public ANSHAREDLIB::AbstractPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "ansharedlib/1.0" FILE "forwardsolution.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(ANSHAREDLIB::AbstractPlugin) + +public: + //========================================================================================================= + /** + * Constructs an ForwardSolution object. + */ + ForwardSolution(); + + //========================================================================================================= + /** + * Destroys the ForwardSolution object. + */ + ~ForwardSolution() override; + + // AbstractPlugin functions + virtual QSharedPointer clone() const override; + virtual void init() override; + virtual void unload() override; + virtual QString getName() const override; + + virtual QMenu* getMenu() override; + virtual QDockWidget* getControl() override; + virtual QWidget* getView() override; + virtual QString getBuildInfo() override; + + virtual void handleEvent(QSharedPointer e) override; + virtual QVector getEventSubscriptions() const override; + +private: + QPointer m_pCommu; /**< To broadcst signals. */ +}; + +} // NAMESPACE + +#endif // MNEANALYZE_FORWARDSOLUTION_H diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.json b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro new file mode 100644 index 00000000000..4a34217d380 --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro @@ -0,0 +1,165 @@ +#============================================================================================================== +# +# @file forwardsolution.pro +# @author Gabriel Motta +# Juan G Prieto +# @since 0.1.9 +# @date June, 2022 +# +# @section LICENSE +# +# Copyright (C) 2022, Gabriel B Motta, Juan G 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 This project file generates the makefile for the forwardsolution plugin. +# +#============================================================================================================== + +include(../../../../mne-cpp.pri) + +TEMPLATE = lib + +QT += gui widgets + +CONFIG += skip_target_version_ext plugin + +DEFINES += FORWARDSOLUTION_PLUGIN + +DESTDIR = $${MNE_BINARY_DIR}/mne_analyze_plugins + +contains(MNECPP_CONFIG, wasm) { + DEFINES += WASMBUILD +} + +TARGET = forwardsolution +CONFIG(debug, debug|release) { + TARGET = $$join(TARGET,,,d) +} + +contains(MNECPP_CONFIG, static) { + CONFIG += staticlib + DEFINES += STATICBUILD +} else { + CONFIG += shared +} + +LIBS += -L$${MNE_LIBRARY_DIR} +CONFIG(debug, debug|release) { + LIBS += -lanSharedd \ + -lmnecppDispd \ + -lmnecppEventsd \ + -lmnecppConnectivityd \ + -lmnecppRtProcessingd \ + -lmnecppInversed \ + -lmnecppFwdd \ + -lmnecppMned \ + -lmnecppFiffd \ + -lmnecppFsd \ + -lmnecppUtilsd \ +} else { + LIBS += -lanShared \ + -lmnecppDisp \ + -lmnecppEvents \ + -lmnecppConnectivity \ + -lmnecppRtProcessing \ + -lmnecppInverse \ + -lmnecppFwd \ + -lmnecppMne \ + -lmnecppFiff \ + -lmnecppFs \ + -lmnecppUtils \ +} + +SOURCES += \ + forwardsolution.cpp \ + forwardsolution_global.cpp + +HEADERS += \ + forwardsolution_global.h \ + forwardsolution.h \ + +OTHER_FILES += forwardsolution.json + +clang { + QMAKE_CXXFLAGS += -isystem $${EIGEN_INCLUDE_DIR} +} else { + INCLUDEPATH += $${EIGEN_INCLUDE_DIR} +} +INCLUDEPATH += $${MNE_INCLUDE_DIR} +INCLUDEPATH += $${MNE_ANALYZE_INCLUDE_DIR} + +unix:!macx { + QMAKE_RPATHDIR += $ORIGIN/../../lib +} + +# Activate FFTW backend in Eigen for non-static builds only +contains(MNECPP_CONFIG, useFFTW):!contains(MNECPP_CONFIG, static) { + DEFINES += EIGEN_FFTW_DEFAULT + INCLUDEPATH += $$shell_path($${FFTW_DIR_INCLUDE}) + LIBS += -L$$shell_path($${FFTW_DIR_LIBS}) + + win32 { + # On Windows + LIBS += -llibfftw3-3 \ + -llibfftw3f-3 \ + -llibfftw3l-3 \ + } + + unix:!macx { + # On Linux + LIBS += -lfftw3 \ + -lfftw3_threads \ + } +} + +################################################## BUILD TIMESTAMP/HASH UPDATER ############################################ + +FILE_TO_UPDATE = forwardsolution_global.cpp +win32 { + CONFIG(debug, debug|release) { + OBJ_TARJET = debug\forwardsolution_global.obj + } else { + OBJ_TARJET = release\forwardsolution_global.obj + } +} + +ALL_FILES += $$HEADERS +ALL_FILES += $$SOURCES +ALL_FILES -= $$FILE_TO_UPDATE + +FileUpdater.target = phonyFileUpdater +for (I_FILE, ALL_FILES) { + FileUpdater.depends += $${PWD}/$${I_FILE} +} + +unix|macx { + FileUpdater.commands = touch $${PWD}/$${FILE_TO_UPDATE} ; echo PASTA > phonyFileUpdater +} + +win32 { + FileUpdater.commands = copy /y $$shell_path($${PWD})\\$${FILE_TO_UPDATE} +,, $$shell_path($${PWD})\\$${FILE_TO_UPDATE} & echo PASTA > phonyFileUpdater + OrderForcerTarget.target = $${OBJ_TARJET} + OrderForcerTarget.depends += phonyFileUpdater + QMAKE_EXTRA_TARGETS += OrderForcerTarget +} + +PRE_TARGETDEPS += phonyFileUpdater +QMAKE_EXTRA_TARGETS += FileUpdater diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.cpp new file mode 100644 index 00000000000..19cc687db8b --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.cpp @@ -0,0 +1,54 @@ +//============================================================================================================= +/** + * @file forwardsolution_global.cpp + * @author Gabriel B Motta ; + * Juan G Prieto + * @since 0.1.9 + * @date June, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel B Motta, Juan G 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 forwardsolution plugin global definitions. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "forwardsolution_global.h" + +//============================================================================================================= +// DEFINE METHODS +//============================================================================================================= + +const char* FORWARDSOLUTIONPLUGIN::buildDateTime(){ return UTILSLIB::dateTimeNow();}; + +//============================================================================================================= + +const char* FORWARDSOLUTIONPLUGIN::buildHash(){ return UTILSLIB::gitHash();}; + +//============================================================================================================= + +const char* FORWARDSOLUTIONPLUGIN::buildHashLong(){ return UTILSLIB::gitHashLong();}; diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.h new file mode 100644 index 00000000000..faa0d382e5a --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution_global.h @@ -0,0 +1,82 @@ +//============================================================================================================= +/** + * @file forwardsolution_global.h + * @author Gabriel Motta ; + * Juan G Prieto + * @since 0.1.9 + * @date June, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel B Motta, Juan G 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 MNE Analyze Source Localization Plugin + * + */ + +#ifndef MNEANALYZE_FORWARDSOLUTION_GLOBAL_H +#define MNEANALYZE_FORWARDSOLUTION_GLOBAL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// PREPROCESSOR DEFINES +//============================================================================================================= + +#if defined(FORWARDSOLUTION_PLUGIN) +# define FORWARDSOLUTIONSHARED_EXPORT Q_DECL_EXPORT /**< Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. */ +#else +# define FORWARDSOLUTIONSHARED_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 FORWARDSOLUTIONPLUGIN{ + +//============================================================================================================= +/** + * Returns build date and time. + */ +FORWARDSOLUTIONSHARED_EXPORT const char* buildDateTime(); + +//============================================================================================================= +/** + * Returns abbreviated build git hash. + */ +FORWARDSOLUTIONSHARED_EXPORT const char* buildHash(); + +//============================================================================================================= +/** + * Returns full build git hash. + */ +FORWARDSOLUTIONSHARED_EXPORT const char* buildHashLong(); +} + +#endif // MNEANALYZE_FORWARDSOLUTION_GLOBAL_H diff --git a/applications/mne_analyze/plugins/plugins.pro b/applications/mne_analyze/plugins/plugins.pro index 0d151f6d920..6eb56ded59a 100644 --- a/applications/mne_analyze/plugins/plugins.pro +++ b/applications/mne_analyze/plugins/plugins.pro @@ -49,6 +49,7 @@ SUBDIRS += \ controlmanager \ coregistration \ dipolefit \ + forwardsolution \ # sampleplugin \ # Exclude plugins which rely on the Qt3D module. Note: The Qt3D module is not yet supported by Wasm From 839217169a10d780e27fca0444fe089031f6bd11 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Tue, 14 Jun 2022 10:23:14 -0400 Subject: [PATCH 02/17] Add gui for fwd --- .../forwardsolution/forwardsolution.cpp | 19 ++++++++++++++++--- .../plugins/forwardsolution/forwardsolution.h | 6 ++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 623f399bd21..794cae2ed36 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -41,11 +41,15 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= #include +#include +#include //============================================================================================================= // USED NAMESPACES @@ -95,7 +99,7 @@ void ForwardSolution::unload() QString ForwardSolution::getName() const { - return "Source Localization"; + return "Forward Solution"; } //============================================================================================================= @@ -116,9 +120,18 @@ QWidget *ForwardSolution::getView() QDockWidget* ForwardSolution::getControl() { - //QDockWidget* pControl = new QDockWidget(getName()); + m_pFwdSettingsView = new DISPLIB::FwdSettingsView(); - return Q_NULLPTR; + QVBoxLayout* pControlLayout = new QVBoxLayout(); + pControlLayout->addWidget(m_pFwdSettingsView); + + QScrollArea* pControlScrollArea = new QScrollArea(); + pControlScrollArea->setLayout(pControlLayout); + + QDockWidget* pControlDock = new QDockWidget(this->getName()); + pControlDock->setWidget(pControlScrollArea); + + return pControlDock; } //============================================================================================================= diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index 9ce4ac20399..df07b73e1fe 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -59,6 +59,10 @@ namespace ANSHAREDLIB { class Communicator; } +namespace DISPLIB { + class FwdSettingsView; +} + //============================================================================================================= // DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN //============================================================================================================= @@ -112,6 +116,8 @@ class FORWARDSOLUTIONSHARED_EXPORT ForwardSolution : public ANSHAREDLIB::Abstrac private: QPointer m_pCommu; /**< To broadcst signals. */ + + DISPLIB::FwdSettingsView* m_pFwdSettingsView; }; } // NAMESPACE From 43bd949859e4c26bf0c078305c87b41b47833d0c Mon Sep 17 00:00:00 2001 From: gabrielbmotta Date: Thu, 16 Jun 2022 09:24:37 -0400 Subject: [PATCH 03/17] MAINT: incorporating ui elements to control fwd solution settings --- .../disp/viewers/formfiles/fwdsettingsview.ui | 682 +++++++++++++----- 1 file changed, 506 insertions(+), 176 deletions(-) diff --git a/libraries/disp/viewers/formfiles/fwdsettingsview.ui b/libraries/disp/viewers/formfiles/fwdsettingsview.ui index bc044a84f2a..5e5d8fdf67d 100644 --- a/libraries/disp/viewers/formfiles/fwdsettingsview.ui +++ b/libraries/disp/viewers/formfiles/fwdsettingsview.ui @@ -6,8 +6,8 @@ 0 0 - 333 - 939 + 377 + 1012 @@ -15,186 +15,514 @@ - - - Forward Solution Information + + + 2 - - - - - Source Spaces: - - - - - - - true - - - - - - - Number of Sources: - - - - - - - true - - - - - - - Number of clustered Sources: - - - - - - - - - - true - - - - - - - Source Orientation - - - - - - - - - - true - - - - - - - Number of Channels - - - - - - - - - - true - - - - - - - Coordinate Frame - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - - - - Clustering - - - - - - Brain Atlas Directory - - - - - - - - 140 - 0 - - - - - - - - ... - - - - - - - (lh+rh).aparc.a2009s.annot - - - - - - - QFrame::Panel - - - QFrame::Sunken - - - not loaded - - - - - - - Qt::Horizontal - - - - 142 - 0 - - - - - + + + Info + + + + + + Forward Soluton Information + + + + + + Source Spaces: + + + + + + + true + + + + + + + Number of Sources: + + + + + + + true + + + + + + + Number of clustered Sources: + + + + + + + + + + true + + + + + + + Source Orientation + + + + + + + + + + true + + + + + + + Number of Channels + + + + + + + + + + true + + + + + + + Coordinate Frame + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + + + Clustering + + + + + + Brain Atlas Directory + + + + + + + + 140 + 0 + + + + + + + + ... + + + + + + + (lh+rh).aparc.a2009s.annot + + + + + + + QFrame::Panel + + + QFrame::Sunken + + + not loaded + + + + + + + Qt::Horizontal + + + + 142 + 0 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Files + + + + + + Forward Solution + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + Measurement File (with compensator info) + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + Source Space + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + BEM Model + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + MRI - Head Transformation + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + Output for omitted source space points + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + EEG Model + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + ... + + + + + + + + + + + Settings + + + + + + Compute MEG Solution + + + + + + + Compute EEG Solution + + + + + + + Compute Gradient Solution + + + + + + + Fixed Orientation + + + + + + + Accurate + + + + + + + Compute in MRI Space + + + + + + + Use Threads + + + + + + + Calculate forward solution in all nodes + + + + + + + Identical head- andMRI- space + + + + + + + Filter Source Spaces + + + + + + + Scale Electrode Positions + + + + + + + Use Equivalent source approach for EEG + + + + + - Forward Solution Computation + @@ -259,6 +587,8 @@ + tabWidget + groupBox_recomp From 9dfa1e2b15393cac94936e9f5a50b7252dad5cd6 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Mon, 17 Oct 2022 13:23:20 -0400 Subject: [PATCH 04/17] Adding singla/slot code usedin GUI --- .../forwardsolution/forwardsolution.cpp | 68 +++++++++++++++ .../plugins/forwardsolution/forwardsolution.h | 85 ++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 794cae2ed36..35e58428456 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -131,6 +131,25 @@ QDockWidget* ForwardSolution::getControl() QDockWidget* pControlDock = new QDockWidget(this->getName()); pControlDock->setWidget(pControlScrollArea); + // connect incoming signals + connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::recompStatusChanged, + this, &ForwardSolution::onRecompStatusChanged); + connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::clusteringStatusChanged, + this, &ForwardSolution::onClusteringStatusChanged); + connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::atlasDirChanged, + this, &ForwardSolution::onAtlasDirChanged); + connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::doForwardComputation, + this, &ForwardSolution::onDoForwardComputation); + + // connect outgoing signals + connect(this, &ForwardSolution::statusInformationChanged, + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setRecomputationStatus, Qt::BlockingQueuedConnection); + connect(this, &ForwardSolution::fwdSolutionAvailable, + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setSolutionInformation, Qt::BlockingQueuedConnection); + connect(this, &ForwardSolution::clusteringAvailable, + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setClusteredInformation, Qt::BlockingQueuedConnection); + + return pControlDock; } @@ -160,3 +179,52 @@ QString ForwardSolution::getBuildInfo() { return QString(FORWARDSOLUTIONPLUGIN::buildDateTime()) + QString(" - ") + QString(FORWARDSOLUTIONPLUGIN::buildHash()); } + +//============================================================================================================= + +void ForwardSolution::onDoForwardComputation() +{ + m_mutex.lock(); + m_bDoFwdComputation = true; + m_mutex.unlock(); +} + +//============================================================================================================= + +void ForwardSolution::onRecompStatusChanged(bool bDoRecomputation) +{ + m_mutex.lock(); + if(!m_pHpiInput) { + QMessageBox msgBox; + msgBox.setText("Please connect the Hpi plugin."); + msgBox.exec(); + return; + } + m_bDoRecomputation = bDoRecomputation; + m_mutex.unlock(); +} + +//============================================================================================================= + +void ForwardSolution::onClusteringStatusChanged(bool bDoClustering) +{ + if(m_pAnnotationSet->isEmpty()) { + QMessageBox msgBox; + msgBox.setText("Please load an annotation set befor clustering."); + msgBox.exec(); + return; + } + m_mutex.lock(); + m_bDoClustering = bDoClustering; + m_mutex.unlock(); +} + +//============================================================================================================= + +void ForwardSolution::onAtlasDirChanged(const QString& sDirPath, const FSLIB::AnnotationSet::SPtr pAnnotationSet) +{ + m_mutex.lock(); + m_sAtlasDir = sDirPath; + m_pAnnotationSet = pAnnotationSet; + m_mutex.unlock(); +} diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index df07b73e1fe..44b98713c67 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -44,6 +44,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -63,6 +65,10 @@ namespace DISPLIB { class FwdSettingsView; } +namespace FSLIB{ + class AnnotationSet; +} + //============================================================================================================= // DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN //============================================================================================================= @@ -114,10 +120,87 @@ class FORWARDSOLUTIONSHARED_EXPORT ForwardSolution : public ANSHAREDLIB::Abstrac virtual void handleEvent(QSharedPointer e) override; virtual QVector getEventSubscriptions() const override; -private: +private slots: + //========================================================================================================= + /** + * Call this funciton whenever a forward computation was requested. + */ + void onDoForwardComputation(); + + //========================================================================================================= + /** + * Call this function whenever the recompution status changed. + * + * @param[in] bDoRecomputation If recomputation is activated. + */ + void onRecompStatusChanged(bool bDoRecomputation); + + //========================================================================================================= + /** + * Call this function whenever the clustering status changed. + * + * @param[in] bDoClustering If clustering is activated. + */ + void onClusteringStatusChanged(bool bDoRecomputation); + + //========================================================================================================= + /** + * Call this function whenever the atlas directory is set. + * + * @param[in] sDirPath The path to the atlas directory. + * @param[in] pAnnotationSet The Annotation set. + */ + void onAtlasDirChanged(const QString& sDirPath, + const QSharedPointer pAnnotationSet); + +signals: + //========================================================================================================= + /** + * Emitted when forward solution is available + */ + void fwdSolutionAvailable(FIFFLIB::fiff_int_t iSourceOri, + FIFFLIB::fiff_int_t iCoordFrame, + int iNSource, + int iNChan, + int iNSpaces); + + //========================================================================================================= + /** + * Emitted whenever clustered forward solution is available + */ + void clusteringAvailable(int iNSource); + + //========================================================================================================= + /** + * Emit this signal whenever the clustering status changed + * (0 Initializing, 1 Computing, 2 Recomputing, 3 Clustering, 4 Not Computed, 5 Finished). + * + * @param[in] iStatus status of recomputation. + */ + void statusInformationChanged(int iStatus); + +private: + QPointer m_pCommu; /**< To broadcst signals. */ DISPLIB::FwdSettingsView* m_pFwdSettingsView; + + QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + FIFFLIB::FiffCoordTrans m_transDevHead; /**< Updated meg->head transformation. */ + QSharedPointer m_pAnnotationSet; /**< Annotation set. */ + + QMutex m_mutex; /**< The threads mutex.*/ + + float m_fThreshRot; /**< The allowed rotation in degree.**/ + float m_fThreshMove; /**< The Allowed movement in mm.**/ + bool m_bBusy; /**< Indicates if we have to update headposition.**/ + bool m_bDoRecomputation; /**< If recomputation is activated.**/ + bool m_bDoClustering; /**< If clustering is activated.**/ + bool m_bDoFwdComputation; /**< Do a forward computation. **/ + + QString m_sAtlasDir; /**< File to Atlas. */ + + }; } // NAMESPACE From 10eef1458ec29abc4eb16db5db8e61938204d07d Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Mon, 17 Oct 2022 15:04:28 -0400 Subject: [PATCH 05/17] Port fwd solution computation --- .../forwardsolution/forwardsolution.cpp | 50 ++++++++++++++++--- .../plugins/forwardsolution/forwardsolution.h | 13 +++++ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 35e58428456..5cbe08c7b10 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -43,6 +43,9 @@ #include +#include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -187,6 +190,47 @@ void ForwardSolution::onDoForwardComputation() m_mutex.lock(); m_bDoFwdComputation = true; m_mutex.unlock(); + + m_pFwdSettings->pFiffInfo = m_pFiffInfo; + + emit statusInformationChanged(0); // initializing + FWDLIB::ComputeFwd::SPtr pComputeFwd = FWDLIB::ComputeFwd::SPtr(new FWDLIB::ComputeFwd(m_pFwdSettings)); + + QFile t_fSolution(m_pFwdSettings->solname); + MNELIB::MNEForwardSolution::SPtr pFwdSolution; + MNELIB::MNEForwardSolution::SPtr pClusteredFwd; + + emit statusInformationChanged(4); // not computed + + emit statusInformationChanged(1); // computing + m_mutex.lock(); + m_bBusy = true; + m_mutex.unlock(); + + // compute and store + pComputeFwd->calculateFwd(); + pComputeFwd->storeFwd(); + + // get Mne Forward Solution (in future this is not necessary, ComputeForward will have this as member) + pFwdSolution = MNELIB::MNEForwardSolution::SPtr(new MNELIB::MNEForwardSolution(t_fSolution, false, true)); + + // emit results to control widget + emit fwdSolutionAvailable(pFwdSolution->source_ori, + pFwdSolution->coord_frame, + pFwdSolution->nsource, + pFwdSolution->nchan, + pFwdSolution->src.size()); + + if(m_bDoClustering) { + emit statusInformationChanged(3); // clustering + pClusteredFwd = MNELIB::MNEForwardSolution::SPtr(new MNELIB::MNEForwardSolution(pFwdSolution->cluster_forward_solution(*m_pAnnotationSet.data(), 200))); + emit clusteringAvailable(pClusteredFwd->nsource); + emit statusInformationChanged(5); //finished + m_pFwdSolution = pClusteredFwd; + } else { + emit statusInformationChanged(5); + m_pFwdSolution = pFwdSolution; + } } //============================================================================================================= @@ -194,12 +238,6 @@ void ForwardSolution::onDoForwardComputation() void ForwardSolution::onRecompStatusChanged(bool bDoRecomputation) { m_mutex.lock(); - if(!m_pHpiInput) { - QMessageBox msgBox; - msgBox.setText("Please connect the Hpi plugin."); - msgBox.exec(); - return; - } m_bDoRecomputation = bDoRecomputation; m_mutex.unlock(); } diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index 44b98713c67..d9984490399 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -69,6 +69,15 @@ namespace FSLIB{ class AnnotationSet; } +namespace FWDLIB { + class ComputeFwdSettings; + class ComputeFwd; +} + +namespace MNELIB { + class MNEForwardSolution; +} + //============================================================================================================= // DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN //============================================================================================================= @@ -185,6 +194,10 @@ private slots: DISPLIB::FwdSettingsView* m_pFwdSettingsView; + QSharedPointer m_pFwdSettings; /**< Forward Solution Settings. */ + + QSharedPointer m_pFwdSolution; + QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ FIFFLIB::FiffCoordTrans m_transDevHead; /**< Updated meg->head transformation. */ QSharedPointer m_pAnnotationSet; /**< Annotation set. */ From cbd4c16f00cb00b33299a1d40cfc4f62dc26586f Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Tue, 18 Oct 2022 10:09:05 -0400 Subject: [PATCH 06/17] Add fwd sol model --- .../anShared/Model/forwardsolutionmodel.cpp | 109 +++++++++++ .../anShared/Model/forwardsolutionmodel.h | 174 ++++++++++++++++++ .../mne_analyze/libs/anShared/Utils/types.h | 3 +- .../mne_analyze/libs/anShared/anShared.pro | 2 + 4 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp create mode 100644 applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp new file mode 100644 index 00000000000..cf8d981654d --- /dev/null +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp @@ -0,0 +1,109 @@ +//============================================================================================================= +/** + * @file forwardsolutionmodel.cpp + * @author Gabriel Motta + * @since 0.1.9 + * @date October, 2020 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel 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 Definition of the ForwardSolutionModel Class. + * + */ + + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "forwardsolutionmodel.h" + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// Eigen INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace ANSHAREDLIB; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +ForwardSolutionModel::ForwardSolutionModel(QObject* parent) +:AbstractModel(parent) +{ +} + +//============================================================================================================= + +ForwardSolutionModel::ForwardSolutionModel(QSharedPointer pFwdSolution, + QObject* parent) +: AbstractModel( parent) +{ +} + +//============================================================================================================= + +int ForwardSolutionModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + return 1; +} + +//============================================================================================================= + +int ForwardSolutionModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + return 1; +} + +//============================================================================================================= + +QVariant ForwardSolutionModel::data(const QModelIndex &index, + int role) const +{ + Q_UNUSED(index); + Q_UNUSED(role); + + return QVariant::fromValue(m_pFwdSolution); +} + +//============================================================================================================= + +Qt::ItemFlags ForwardSolutionModel::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); +} diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h new file mode 100644 index 00000000000..90ef29ca07c --- /dev/null +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h @@ -0,0 +1,174 @@ +//============================================================================================================= +/** + * @file forwardsolutionmodel.h + * @author Gabriel Motta + * @since 0.1.9 + * @date October, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel 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 Declaration of the ForwardSolutionModel Class. + * + */ + +#ifndef FORWARDSOLUTIONMODEL_H +#define FORWARDSOLUTIONMODEL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "../anshared_global.h" +#include "../Utils/types.h" +#include "abstractmodel.h" + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace MNELIB { + class MNEForwardSolution; +} + +//============================================================================================================= +// DEFINE NAMESPACE ANSHAREDLIB +//============================================================================================================= + +namespace ANSHAREDLIB { + +//============================================================================================================= +class ANSHAREDSHARED_EXPORT ForwardSolutionModel : public AbstractModel +{ + Q_OBJECT +public: + typedef QSharedPointer SPtr; /**< Shared pointer type for ForwardSolutionModel. */ + typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for ForwardSolutionModel. */ + +public: + //========================================================================================================= + ForwardSolutionModel(QObject* parent = Q_NULLPTR); + + //========================================================================================================= + ForwardSolutionModel(QSharedPointer pFwdSolution, + QObject* parent = Q_NULLPTR); + + //========================================================================================================= + /** + * Returns the number of rows in the model + * + * @param[in] parent The parent index. + */ + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the number of columns in the model + * + * @param[in] parent The parent index. + */ + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the data stored under the given role for the index. + * + * @param[in] index The index that referres to the requested item. + * @param[in] role The requested role. + */ + virtual QVariant data(const QModelIndex &index, + int role = Qt::DisplayRole) const override; + + //========================================================================================================= + /** + * Returns the item flags for the given index. + * + * @param[in] index The index that referres to the requested item. + */ + Qt::ItemFlags flags(const QModelIndex & index) const override; + + //========================================================================================================= + /** + * The type of this model (CovarianceModel) + * + * @return The type of this model (CovarianceModel). + */ + inline MODEL_TYPE getType() const override; + + //========================================================================================================= + /** + * Returns the index for the item in the model specified by the given row, column and parent index. + * Currently only Qt::DisplayRole is supported. + * Index rows reflect channels, first column is channel names, second is raw data. + * + * @param[in] row The specified row. + * @param[in] column The specified column. + * @param[in] parent The parent index. + */ + inline QModelIndex index(int row, + int column, + const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the parent index of the given index. + * In this Model the parent index in always QModelIndex(). + * + * @param[in] index The index that referres to the child. + */ + inline QModelIndex parent(const QModelIndex &index) const override; + +private: + + QSharedPointer m_pFwdSolution; + +}; + +//============================================================================================================= +// INLINE DEFINITIONS +//============================================================================================================= + +inline MODEL_TYPE ForwardSolutionModel::getType() const +{ + return MODEL_TYPE::ANSHAREDLIB_FORWARDSOLUTION_MODEL; +} + +//============================================================================================================= + +QModelIndex ForwardSolutionModel::parent(const QModelIndex &index) const +{ + Q_UNUSED(index); + return QModelIndex(); +} + +//============================================================================================================= + +QModelIndex ForwardSolutionModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return createIndex(row, column); +} + +}//namespace + +#endif // FORWARDSOLUTIONMODEL_H diff --git a/applications/mne_analyze/libs/anShared/Utils/types.h b/applications/mne_analyze/libs/anShared/Utils/types.h index 25623172680..5c9d783699b 100644 --- a/applications/mne_analyze/libs/anShared/Utils/types.h +++ b/applications/mne_analyze/libs/anShared/Utils/types.h @@ -87,7 +87,8 @@ namespace ANSHAREDLIB ANSHAREDLIB_BEMDATA_MODEL, ANSHAREDLIB_NOISE_MODEL, ANSHAREDLIB_MRICOORD_MODEL, - ANSHAREDLIB_DIPOLEFIT_MODEL + ANSHAREDLIB_DIPOLEFIT_MODEL, + ANSHAREDLIB_FORWARDSOLUTION_MODEL }; //========================================================================================================= diff --git a/applications/mne_analyze/libs/anShared/anShared.pro b/applications/mne_analyze/libs/anShared/anShared.pro index 479ff52febf..82859e27790 100644 --- a/applications/mne_analyze/libs/anShared/anShared.pro +++ b/applications/mne_analyze/libs/anShared/anShared.pro @@ -96,12 +96,14 @@ SOURCES += \ Model/fiffrawviewmodel.cpp \ Model/eventmodel.cpp \ Model/averagingdatamodel.cpp \ + Model/forwardsolutionmodel.cpp \ Model/mricoordmodel.cpp \ Model/covariancemodel.cpp \ Plugins/abstractplugin.cpp HEADERS += \ Model/dipolefitmodel.h \ + Model/forwardsolutionmodel.h \ Model/mricoordmodel.h \ Model/covariancemodel.h \ Plugins/abstractplugin.h \ From 019b57b1c856ae709feec9f57d26cdf695ebf003 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Tue, 18 Oct 2022 14:29:44 -0400 Subject: [PATCH 07/17] Add new mne_analyze event types, get relevant data to fwd and source loc plugins --- .../anShared/Model/forwardsolutionmodel.cpp | 3 +- .../anShared/Model/forwardsolutionmodel.h | 2 - .../mne_analyze/libs/anShared/Utils/types.h | 5 +- .../mne_analyze/plugins/events/events.cpp | 4 +- .../forwardsolution/forwardsolution.cpp | 8 ++ .../plugins/forwardsolution/forwardsolution.h | 1 - .../plugins/rawdataviewer/fiffrawview.cpp | 11 +-- .../plugins/rawdataviewer/fiffrawview.h | 8 ++ .../plugins/rawdataviewer/rawdataviewer.cpp | 19 ++++- .../plugins/rawdataviewer/rawdataviewer.h | 10 ++- .../sourcelocalization/sourcelocalization.cpp | 83 ++++++++++++++++++- .../sourcelocalization/sourcelocalization.h | 38 ++++++++- 12 files changed, 171 insertions(+), 21 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp index cf8d981654d..a57f7df9a87 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp @@ -69,6 +69,7 @@ ForwardSolutionModel::ForwardSolutionModel(QObject* parent) ForwardSolutionModel::ForwardSolutionModel(QSharedPointer pFwdSolution, QObject* parent) : AbstractModel( parent) +, m_pFwdSolution(pFwdSolution) { } @@ -93,7 +94,7 @@ int ForwardSolutionModel::columnCount(const QModelIndex &parent) const //============================================================================================================= QVariant ForwardSolutionModel::data(const QModelIndex &index, - int role) const + int role) const { Q_UNUSED(index); Q_UNUSED(role); diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h index 90ef29ca07c..900c0750f0b 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h @@ -139,9 +139,7 @@ class ANSHAREDSHARED_EXPORT ForwardSolutionModel : public AbstractModel inline QModelIndex parent(const QModelIndex &index) const override; private: - QSharedPointer m_pFwdSolution; - }; //============================================================================================================= diff --git a/applications/mne_analyze/libs/anShared/Utils/types.h b/applications/mne_analyze/libs/anShared/Utils/types.h index 5c9d783699b..438107a681e 100644 --- a/applications/mne_analyze/libs/anShared/Utils/types.h +++ b/applications/mne_analyze/libs/anShared/Utils/types.h @@ -101,7 +101,7 @@ namespace ANSHAREDLIB PLUGIN_INIT_FINISHED, ///< [NO DATA] Send when all plugins finished initializing STATUS_BAR_MSG, ///< [QString] Send a message to the status bar (part of gui) SELECTED_MODEL_CHANGED, ///< [QSharedPointer>] Send whenever the selection changes in the datamanager plugin - NEW_EVENT_ADDED, ///< [int] event send whenever the user adds a new event in the rawdataviewer plugin + ADD_NEW_EVENT, ///< [int] event send whenever the user adds a new event in the rawdataviewer plugin EVENTS_UPDATED, ///< [NO DATA] send when events or events-groups have changed TRIGGER_REDRAW, ///< [NO DATA] send when viewer needs to be updated TRIGGER_ACTIVE_CHANGED, ///< [int] send when the trigger active state was toggled @@ -123,7 +123,8 @@ namespace ANSHAREDLIB FIDUCIAL_CHANGED, ///< [int] event send when fiducial was changed SET_DATA3D_TREE_MODEL, ///< [QSharedPointer] send when a new 3D Model is set VIEW3D_SETTINGS_CHANGED, ///< [ANSHAREDLIB::View3DParameters] send to trigger view 3D settings update - MODEL_REMOVED ///< [QSharedPointer>] send to alert plugins when model is being removed + MODEL_REMOVED, ///< [QSharedPointer>] send to alert plugins when model is being removed + SAMPLE_SELECTED }; //========================================================================================================= diff --git a/applications/mne_analyze/plugins/events/events.cpp b/applications/mne_analyze/plugins/events/events.cpp index 4230ec93997..6ee0ba456ac 100644 --- a/applications/mne_analyze/plugins/events/events.cpp +++ b/applications/mne_analyze/plugins/events/events.cpp @@ -172,7 +172,7 @@ QWidget *Events::getView() void Events::handleEvent(QSharedPointer e) { switch (e->getType()) { - case EVENT_TYPE::NEW_EVENT_ADDED: + case EVENT_TYPE::ADD_NEW_EVENT: emit newEventAvailable(e->getData().toInt()); onTriggerRedraw(); break; @@ -192,7 +192,7 @@ void Events::handleEvent(QSharedPointer e) QVector Events::getEventSubscriptions(void) const { QVector temp; - temp.push_back(NEW_EVENT_ADDED); + temp.push_back(ADD_NEW_EVENT); temp.push_back(SELECTED_MODEL_CHANGED); temp.push_back(MODEL_REMOVED); diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 5cbe08c7b10..e6ec6c31b31 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -40,6 +40,9 @@ #include "forwardsolution.h" #include +#include + +#include #include @@ -231,6 +234,11 @@ void ForwardSolution::onDoForwardComputation() emit statusInformationChanged(5); m_pFwdSolution = pFwdSolution; } + + QSharedPointer pFwdSolModel = QSharedPointer(new ANSHAREDLIB::ForwardSolutionModel(m_pFwdSolution)); + + m_pAnalyzeData->addModel(pFwdSolModel, + "Fwd. Sol. - " + QDateTime::currentDateTime().toString()); } //============================================================================================================= diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index d9984490399..349932b4713 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -189,7 +189,6 @@ private slots: void statusInformationChanged(int iStatus); private: - QPointer m_pCommu; /**< To broadcst signals. */ DISPLIB::FwdSettingsView* m_pFwdSettingsView; diff --git a/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.cpp b/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.cpp index 7c21500ee15..b62dbb2a727 100644 --- a/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.cpp +++ b/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.cpp @@ -478,11 +478,12 @@ bool FiffRawView::eventFilter(QObject *object, QEvent *event) switch(mouseEvent->button()){ case Qt::LeftButton:{ if(m_pModel && object == m_pTableView->viewport()){ - QPoint pos = mouseEvent->pos(); - m_pModel->setScrollerSample(static_cast(floor((float)m_pModel->absoluteFirstSample() + //accounting for first sample offset - (m_pTableView->horizontalScrollBar()->value() / m_pModel->pixelDifference()) + //accounting for scroll offset - ((float)pos.x() / m_pModel->pixelDifference())))); //accounting for mouse position offset - m_pTableView->viewport()->repaint(); + QPoint pos = mouseEvent->pos(); + m_pModel->setScrollerSample(static_cast(floor((float)m_pModel->absoluteFirstSample() + //accounting for first sample offset + (m_pTableView->horizontalScrollBar()->value() / m_pModel->pixelDifference()) + //accounting for scroll offset + ((float)pos.x() / m_pModel->pixelDifference())))); //accounting for mouse position offset + m_pTableView->viewport()->repaint(); + emit sendLastClickPos(m_pModel->getScrollerPosition()); } } } diff --git a/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.h b/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.h index 19a13ecc801..2538d04b331 100644 --- a/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.h +++ b/applications/mne_analyze/plugins/rawdataviewer/fiffrawview.h @@ -314,6 +314,14 @@ class RAWDATAVIEWERSHARED_EXPORT FiffRawView : public DISPLIB::AbstractView */ void sendSamplePos(int iSample); + //========================================================================================================= + /** + * Emits sample number where last clicked + * + * @param[in] iSample sample number last clicked. + */ + void sendLastClickPos(int iSample); + private: //========================================================================================================= /** diff --git a/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.cpp b/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.cpp index af2b7c2aba2..5e982d2066b 100644 --- a/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.cpp +++ b/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.cpp @@ -107,7 +107,10 @@ void RawDataViewer::init() m_pFiffRawView->setAttribute(Qt::WA_DeleteOnClose, false); connect(m_pFiffRawView.data(), &FiffRawView::sendSamplePos, - this, &RawDataViewer::onSendSamplePos, Qt::UniqueConnection); + this, &RawDataViewer::sendNewEventSample, Qt::UniqueConnection); + + connect(m_pFiffRawView.data(), &FiffRawView::sendLastClickPos, + this, &RawDataViewer::sendSampleSelected, Qt::UniqueConnection); connect(m_pFiffRawView.data(), &FiffRawView::realtimeDataUpdated, this, &RawDataViewer::onNewRealtimeData, Qt::UniqueConnection); @@ -256,12 +259,22 @@ void RawDataViewer::onModelChanged(QSharedPointer pNewModel) //============================================================================================================= -void RawDataViewer::onSendSamplePos(int iSample) +void RawDataViewer::sendNewEventSample(int iSample) +{ + QVariant data; + data.setValue(iSample); + + m_pCommu->publishEvent(EVENT_TYPE::ADD_NEW_EVENT, data); +} + +//============================================================================================================= + +void RawDataViewer::sendSampleSelected(int iSample) { QVariant data; data.setValue(iSample); - m_pCommu->publishEvent(EVENT_TYPE::NEW_EVENT_ADDED, data); + m_pCommu->publishEvent(EVENT_TYPE::SAMPLE_SELECTED, data); } //============================================================================================================= diff --git a/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.h b/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.h index 7bb97e57b6c..74f1da3f5fb 100644 --- a/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.h +++ b/applications/mne_analyze/plugins/rawdataviewer/rawdataviewer.h @@ -141,7 +141,15 @@ class RAWDATAVIEWERSHARED_EXPORT RawDataViewer : public ANSHAREDLIB::AbstractPlu * * @param[in] iSample The sample to be send. */ - void onSendSamplePos(int iSample); + void sendNewEventSample(int iSample); + + //========================================================================================================= + /** + * Handles if a new sample position should be dispatched + * + * @param[in] iSample The sample to be send. + */ + void sendSampleSelected(int iSample); //========================================================================================================= /** diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index c3677b3a13d..868f11dbd57 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -39,6 +39,9 @@ #include "sourcelocalization.h" #include +#include +#include +#include //============================================================================================================= // QT INCLUDES @@ -59,6 +62,9 @@ using namespace ANSHAREDLIB; SourceLocalization::SourceLocalization() : m_pCommu(Q_NULLPTR) +, m_pFwdSolutionModel(Q_NULLPTR) +, m_pAverageDataModel(Q_NULLPTR) +, m_pRawDataModel(Q_NULLPTR) { } @@ -125,8 +131,14 @@ QDockWidget* SourceLocalization::getControl() void SourceLocalization::handleEvent(QSharedPointer e) { switch (e->getType()) { - default: - qWarning() << "[SourceLocalization::handleEvent] Received an Event that is not handled by switch cases."; + case EVENT_TYPE::SELECTED_MODEL_CHANGED: + onModelChanged(e->getData().value >()); + break; + case EVENT_TYPE::MODEL_REMOVED: + onModelRemoved(e->getData().value>()); + break; + default: + qWarning() << "[Events::handleEvent] Received an Event that is not handled by switch cases."; } } @@ -135,7 +147,9 @@ void SourceLocalization::handleEvent(QSharedPointer e) QVector SourceLocalization::getEventSubscriptions(void) const { QVector temp; - //temp.push_back(SELECTED_MODEL_CHANGED); + temp.push_back(SELECTED_MODEL_CHANGED); + temp.push_back(MODEL_REMOVED); + temp.push_back(SAMPLE_SELECTED); return temp; } @@ -146,3 +160,66 @@ QString SourceLocalization::getBuildInfo() { return QString(SOURCELOCALIZATIONPLUGIN::buildDateTime()) + QString(" - ") + QString(SOURCELOCALIZATIONPLUGIN::buildHash()); } + +//============================================================================================================= + +void SourceLocalization::sourceLocalizationFromAverage() +{ + if(m_sourceLocalizationMode != SOURCE_LOC_FROM_AVG) { + return; + } + + if(!m_pFwdSolutionModel){ + qInfo() << "[SourceLocalization::performSourceLocalization] No forward solution available."; + return; + } + + if(!m_pAverageDataModel){ + qInfo() << "[SourceLocalization::performSourceLocalization] No average model available."; + return; + } +} + +//============================================================================================================= + +void SourceLocalization::sourceLocalizationFromSingleTrial() +{ + if(m_sourceLocalizationMode != SOURCE_LOC_FROM_SINGLE_TRIAL) { + return; + } + + if(!m_pFwdSolutionModel){ + qInfo() << "[SourceLocalization::performSourceLocalization] No forward solution available."; + return; + } + + +} + + +//============================================================================================================= + +void SourceLocalization::onModelChanged(QSharedPointer pNewModel) +{ + switch(pNewModel->getType()){ + case ANSHAREDLIB::ANSHAREDLIB_FIFFRAW_MODEL: + m_pRawDataModel = qSharedPointerCast(pNewModel); + break; + case ANSHAREDLIB::ANSHAREDLIB_AVERAGING_MODEL: + m_pAverageDataModel = qSharedPointerCast(pNewModel); + sourceLocalizationFromAverage(); + break; + case ANSHAREDLIB::ANSHAREDLIB_FORWARDSOLUTION_MODEL: + m_pFwdSolutionModel = qSharedPointerCast(pNewModel); + break; + default: + break; + } +} + +//============================================================================================================= + +void SourceLocalization::onModelRemoved(QSharedPointer pRemovedModel) +{ + +} diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h index 7485a5d1ad4..811042aafed 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h @@ -56,6 +56,10 @@ namespace ANSHAREDLIB { class Communicator; + class AbstractModel; + class FiffRawViewModel; + class AveragingDataModel; + class ForwardSolutionModel; } //============================================================================================================= @@ -109,8 +113,40 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A virtual void handleEvent(QSharedPointer e) override; virtual QVector getEventSubscriptions() const override; -private: +private: + + enum Mode{ + SOURCE_LOC_FROM_AVG, + SOURCE_LOC_FROM_SINGLE_TRIAL + }; + + void sourceLocalizationFromAverage(); + + void sourceLocalizationFromSingleTrial(); + + //========================================================================================================= + /** + * Loads new Fiff model whan current loaded model is changed + * + * @param[in, out] pNewModel pointer to currently loaded FiffRawView Model. + */ + void onModelChanged(QSharedPointer pNewModel); + + //========================================================================================================= + /** + * Handles clearing view if currently used model is being removed + * + * @param[in] pRemovedModel Pointer to model being removed. + */ + void onModelRemoved(QSharedPointer pRemovedModel); + QPointer m_pCommu; /**< To broadcst signals. */ + + QSharedPointer m_pFwdSolutionModel; + QSharedPointer m_pAverageDataModel; + QSharedPointer m_pRawDataModel; + + Mode m_sourceLocalizationMode; }; } // NAMESPACE From 924abced70671b8de61e7caf0e84977ffe38afb6 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Tue, 18 Oct 2022 16:33:55 -0400 Subject: [PATCH 08/17] Check fwd sol files. Get data to where it is needed --- .../anShared/Model/forwardsolutionmodel.cpp | 2 + .../forwardsolution/forwardsolution.cpp | 134 ++++++++++++++++-- .../plugins/forwardsolution/forwardsolution.h | 13 +- .../sourcelocalization/sourcelocalization.cpp | 8 +- .../sourcelocalization/sourcelocalization.h | 2 + libraries/mne/mne_forwardsolution.h | 9 ++ 6 files changed, 153 insertions(+), 15 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp index a57f7df9a87..0abef544856 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp @@ -39,6 +39,8 @@ #include "forwardsolutionmodel.h" +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index e6ec6c31b31..84bd8f4addd 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -42,13 +42,20 @@ #include #include +#include #include +#include +#include #include +#include + #include #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -70,7 +77,28 @@ using namespace ANSHAREDLIB; ForwardSolution::ForwardSolution() : m_pCommu(Q_NULLPTR) +, m_pFwdSettings(new FWDLIB::ComputeFwdSettings) +, m_bBusy(false) +, m_bDoRecomputation(false) +, m_bDoClustering(true) +, m_bDoFwdComputation(false) { + // set init values + m_pFwdSettings->solname = QCoreApplication::applicationDirPath() + "/MNE-sample-data/your-solution-fwd.fif"; + m_pFwdSettings->mriname = QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/all-trans.fif"; + m_pFwdSettings->bemname = QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects/sample/bem/sample-5120-5120-5120-bem.fif"; + m_pFwdSettings->srcname = QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects/sample/bem/sample-oct-6-src.fif"; + m_pFwdSettings->measname = QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw.fif"; + m_pFwdSettings->transname.clear(); + m_pFwdSettings->eeg_model_name = "Default"; + m_pFwdSettings->include_meg = true; + m_pFwdSettings->include_eeg = true; + m_pFwdSettings->accurate = true; + m_pFwdSettings->mindist = 5.0f/1000.0f; + + m_sAtlasDir = QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects/sample/label"; + + m_pAnnotationSet = FSLIB::AnnotationSet::SPtr(new FSLIB::AnnotationSet(m_sAtlasDir+"/lh.aparc.a2009s.annot", m_sAtlasDir+"/rh.aparc.a2009s.annot")); } //============================================================================================================= @@ -164,6 +192,9 @@ QDockWidget* ForwardSolution::getControl() void ForwardSolution::handleEvent(QSharedPointer e) { switch (e->getType()) { + case EVENT_TYPE::SELECTED_MODEL_CHANGED: + onModelChanged(e->getData().value >()); + break; default: qWarning() << "[ForwardSolution::handleEvent] Received an Event that is not handled by switch cases."; } @@ -174,7 +205,7 @@ void ForwardSolution::handleEvent(QSharedPointer e) QVector ForwardSolution::getEventSubscriptions(void) const { QVector temp; - //temp.push_back(SELECTED_MODEL_CHANGED); + temp.push_back(SELECTED_MODEL_CHANGED); return temp; } @@ -190,9 +221,72 @@ QString ForwardSolution::getBuildInfo() void ForwardSolution::onDoForwardComputation() { - m_mutex.lock(); + if(!m_pFiffInfo){ + qInfo() << "No FiffInfo source available for forward solution computation."; + return; + } + + qInfo() << "Performing forward solution computation."; + + QFile t_fBem(m_pFwdSettings->bemname); + FIFFLIB::FiffStream::SPtr stream(new FIFFLIB::FiffStream(&t_fBem)); + if(!stream->open()) { + QMessageBox msgBox; + msgBox.setText("The bem model cannot be opend. Chosse another file."); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); + msgBox.exec(); + stream->close(); + return; + } + stream->close(); + + // Read source space + QFile t_fSource(m_pFwdSettings->srcname); + stream = FIFFLIB::FiffStream::SPtr(new FIFFLIB::FiffStream(&t_fSource)); + if(!stream->open()) { + QMessageBox msgBox; + msgBox.setText("The source space cannot be opend. Chosse another file."); + msgBox.setText(m_pFwdSettings->srcname); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); + msgBox.exec(); + stream->close(); + return; + } + stream->close(); + + // Read MRI transformation + QFile t_fMri(m_pFwdSettings->mriname); + stream = FIFFLIB::FiffStream::SPtr(new FIFFLIB::FiffStream(&t_fMri)); + if(!stream->open()) { + QMessageBox msgBox; + msgBox.setText("The mri - head transformation cannot be opend. Chosse another file."); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); + msgBox.exec(); + stream->close(); + return; + } + stream->close(); + + // Read measurement + QFile t_fMeas(m_pFwdSettings->measname); + stream = FIFFLIB::FiffStream::SPtr(new FIFFLIB::FiffStream(&t_fMri)); + if(!stream->open()) { + QMessageBox msgBox; + msgBox.setText("The meaurement file cannot be opend. Chosse another file."); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setWindowFlags(Qt::WindowStaysOnTopHint); + msgBox.exec(); + stream->close(); + return; + } + stream->close(); + + qInfo() << "Verified source files for forward solution computation."; + m_bDoFwdComputation = true; - m_mutex.unlock(); m_pFwdSettings->pFiffInfo = m_pFiffInfo; @@ -206,9 +300,7 @@ void ForwardSolution::onDoForwardComputation() emit statusInformationChanged(4); // not computed emit statusInformationChanged(1); // computing - m_mutex.lock(); m_bBusy = true; - m_mutex.unlock(); // compute and store pComputeFwd->calculateFwd(); @@ -239,15 +331,15 @@ void ForwardSolution::onDoForwardComputation() m_pAnalyzeData->addModel(pFwdSolModel, "Fwd. Sol. - " + QDateTime::currentDateTime().toString()); + + qInfo() << "New soultion available"; } //============================================================================================================= void ForwardSolution::onRecompStatusChanged(bool bDoRecomputation) { - m_mutex.lock(); m_bDoRecomputation = bDoRecomputation; - m_mutex.unlock(); } //============================================================================================================= @@ -260,17 +352,37 @@ void ForwardSolution::onClusteringStatusChanged(bool bDoClustering) msgBox.exec(); return; } - m_mutex.lock(); m_bDoClustering = bDoClustering; - m_mutex.unlock(); } //============================================================================================================= void ForwardSolution::onAtlasDirChanged(const QString& sDirPath, const FSLIB::AnnotationSet::SPtr pAnnotationSet) { - m_mutex.lock(); m_sAtlasDir = sDirPath; m_pAnnotationSet = pAnnotationSet; - m_mutex.unlock(); +} + +//============================================================================================================= + +void ForwardSolution::onModelChanged(QSharedPointer pNewModel) +{ + switch(pNewModel->getType()){ + case ANSHAREDLIB::ANSHAREDLIB_FIFFRAW_MODEL:{ + auto pRawDataModel = qSharedPointerCast(pNewModel); + if(pRawDataModel){ + m_pFiffInfo = pRawDataModel->getFiffInfo(); + } + break; + } + case ANSHAREDLIB::ANSHAREDLIB_AVERAGING_MODEL:{ + auto pAverageDataModel = qSharedPointerCast(pNewModel); + if(pAverageDataModel){ + m_pFiffInfo = pAverageDataModel->getFiffInfo(); + } + break; + } + default: + break; + } } diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index 349932b4713..256199f4f90 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -59,6 +59,7 @@ namespace ANSHAREDLIB { class Communicator; + class AbstractModel; } namespace DISPLIB { @@ -189,6 +190,16 @@ private slots: void statusInformationChanged(int iStatus); private: + + //========================================================================================================= + /** + * Loads new Fiff model whan current loaded model is changed + * + * @param[in, out] pNewModel pointer to currently loaded FiffRawView Model. + */ + void onModelChanged(QSharedPointer pNewModel); + + QPointer m_pCommu; /**< To broadcst signals. */ DISPLIB::FwdSettingsView* m_pFwdSettingsView; @@ -212,7 +223,7 @@ private slots: QString m_sAtlasDir; /**< File to Atlas. */ - + QString m_sFiffInfoSource; }; } // NAMESPACE diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index 868f11dbd57..6c1541b8ea5 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -39,9 +39,11 @@ #include "sourcelocalization.h" #include + #include #include #include +#include //============================================================================================================= // QT INCLUDES @@ -137,6 +139,9 @@ void SourceLocalization::handleEvent(QSharedPointer e) case EVENT_TYPE::MODEL_REMOVED: onModelRemoved(e->getData().value>()); break; + case EVENT_TYPE::SAMPLE_SELECTED: + m_iSelectedSample = e->getData().value(); + sourceLocalizationFromSingleTrial(); default: qWarning() << "[Events::handleEvent] Received an Event that is not handled by switch cases."; } @@ -192,11 +197,8 @@ void SourceLocalization::sourceLocalizationFromSingleTrial() qInfo() << "[SourceLocalization::performSourceLocalization] No forward solution available."; return; } - - } - //============================================================================================================= void SourceLocalization::onModelChanged(QSharedPointer pNewModel) diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h index 811042aafed..5339c19aadf 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h @@ -146,6 +146,8 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A QSharedPointer m_pAverageDataModel; QSharedPointer m_pRawDataModel; + int m_iSelectedSample; + Mode m_sourceLocalizationMode; }; diff --git a/libraries/mne/mne_forwardsolution.h b/libraries/mne/mne_forwardsolution.h index a6b7bd70b2d..f31bb34478c 100644 --- a/libraries/mne/mne_forwardsolution.h +++ b/libraries/mne/mne_forwardsolution.h @@ -589,4 +589,13 @@ inline bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b } } // NAMESPACE +#ifndef metatype_mneforwardsolution +Q_DECLARE_METATYPE(MNELIB::MNEForwardSolution);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution type. For signal/slot and QVariant usage.*/ +#endif + +#ifndef metatype_mneforwardsolutionsptr +#define metatype_fiffevokedsetsptr +Q_DECLARE_METATYPE(MNELIB::MNEForwardSolution::SPtr);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution::SPtr type. For signal/slot and QVariant usage.*/ +#endif + #endif // MNE_FORWARDSOLUTION_H From 42278d35d384f8faa87a0efc709d08130b397929 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Wed, 19 Oct 2022 11:32:54 -0400 Subject: [PATCH 09/17] huge waste of tiome because qt did no regenerate ui files --- .../FormFiles/fwdsetupwidget.cpp | 343 ++++++++++++ .../FormFiles/fwdsetupwidget.h | 194 +++++++ .../FormFiles/fwdsetupwidget.ui | 496 ++++++++++++++++++ .../forwardsolution/forwardsolution.cpp | 19 +- .../plugins/forwardsolution/forwardsolution.h | 3 + .../forwardsolution/forwardsolution.pro | 7 +- 6 files changed, 1056 insertions(+), 6 deletions(-) create mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp create mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h create mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp new file mode 100644 index 00000000000..3768bd196aa --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp @@ -0,0 +1,343 @@ +//============================================================================================================= +/** + * @file FwdSetupWidget.cpp + * @author Ruben Dörfel + * Gabriel B. Motta + * @since 0.1.9 + * @date October, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Ruben Dörfel, 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 Definition of the FwdSetupWidget class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "fwdsetupwidget.h" + +#include + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using FORWARDSOLUTIONPLUGIN::FwdSetupWidget; +using namespace FIFFLIB; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +FwdSetupWidget::FwdSetupWidget(QSharedPointer settings, QWidget *parent) +: QWidget(parent) +, m_pFwdSettings(settings) +{ + m_ui.setupUi(this); + + // init line edits + m_ui.m_qLineEdit_SolName->setText(m_pFwdSettings->solname); + m_ui.m_qLineEdit_MeasName->setText(m_pFwdSettings->measname); + m_ui.m_qLineEdit_BemName->setText(m_pFwdSettings->bemname); + m_ui.m_qLineEdit_SourceName->setText(m_pFwdSettings->srcname); + m_ui.m_qLineEdit_MriName->setText(m_pFwdSettings->mriname); + m_ui.m_qLineEdit_MinDistName->setText(m_pFwdSettings->mindistoutname); + m_ui.m_qLineEdit_EEGModelFile->setText(m_pFwdSettings->eeg_model_file); + m_ui.m_qLineEdit_EEGModelName->setText(m_pFwdSettings->eeg_model_name); + + // init checkboxes + m_ui.m_check_bDoAll->setChecked(m_pFwdSettings->do_all); + m_ui.m_check_bIncludeEEG->setChecked(m_pFwdSettings->include_eeg); + m_ui.m_check_bIncludeMeg->setChecked(m_pFwdSettings->include_meg); + m_ui.m_check_bComputeGrad->setChecked(m_pFwdSettings->compute_grad); + + if(m_pFwdSettings->coord_frame == FIFFV_COORD_MRI) { + m_ui.m_check_bCoordframe->setChecked(true); + } else { + m_ui.m_check_bCoordframe->setChecked(false); + } + + m_ui.m_check_bAccurate->setChecked(m_pFwdSettings->accurate); + m_ui.m_check_bFixedOri->setChecked(m_pFwdSettings->fixed_ori); + m_ui.m_check_bFilterSpaces->setChecked(m_pFwdSettings->filter_spaces); + m_ui.m_check_bMriHeadIdent->setChecked(m_pFwdSettings->mri_head_ident); + m_ui.m_check_bUseThreads->setChecked(m_pFwdSettings->use_threads); + m_ui.m_check_bUseEquivEeg->setChecked(m_pFwdSettings->use_equiv_eeg); + + // init Spin Boxes + m_ui.m_doubleSpinBox_dMinDist->setValue(m_pFwdSettings->mindist*1000); + m_ui.m_doubleSpinBox_dEegSphereRad->setValue(m_pFwdSettings->eeg_sphere_rad*1000); + m_ui.m_doubleSpinBox_dVecR0x->setValue(m_pFwdSettings->r0.x()*1000); + m_ui.m_doubleSpinBox_dVecR0y->setValue(m_pFwdSettings->r0.y()*1000); + m_ui.m_doubleSpinBox_dVecR0z->setValue(m_pFwdSettings->r0.z()*1000); + + // connect line edits + connect(m_ui.m_qLineEdit_SolName, &QLineEdit::textChanged, this, &FwdSetupWidget::onSolNameChanged); + connect(m_ui.m_qLineEdit_MinDistName, &QLineEdit::textChanged, this, &FwdSetupWidget::onMinDistNameChanged); + + // connect checkboxes + connect(m_ui.m_check_bDoAll, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bAccurate, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bFixedOri, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bCoordframe, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bIncludeEEG, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bIncludeMeg, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bUseThreads, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bComputeGrad, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bScaleEegPos, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bUseEquivEeg, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bFilterSpaces, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + connect(m_ui.m_check_bMriHeadIdent, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); + + // connect spin boxes + connect(m_ui.m_doubleSpinBox_dMinDist,static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onMinDistChanged); + connect(m_ui.m_doubleSpinBox_dEegSphereRad, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereRadChanged); + connect(m_ui.m_doubleSpinBox_dVecR0x, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); + connect(m_ui.m_doubleSpinBox_dVecR0y, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); + connect(m_ui.m_doubleSpinBox_dVecR0z, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); + + // connet push buttons + connect(m_ui.m_qPushButton_SolNameDialog, &QPushButton::released, this, &FwdSetupWidget::showFwdDirDialog); + connect(m_ui.m_qPushButton_BemNameDialog, &QPushButton::released, this, &FwdSetupWidget::showBemFileDialog); + connect(m_ui.m_qPushButton_MeasNameDialog, &QPushButton::released, this, &FwdSetupWidget::showMeasFileDialog); + connect(m_ui.m_qPushButton_SourceNameDialog, &QPushButton::released, this, &FwdSetupWidget::showSourceFileDialog); + connect(m_ui.m_qPushButton_MriNameDialog, &QPushButton::released, this, &FwdSetupWidget::showMriFileDialog); + connect(m_ui.m_qPushButton_MinDistOutDialog, &QPushButton::released, this, &FwdSetupWidget::showMinDistDirDialog); + connect(m_ui.m_qPushButton_EEGModelFileDialog, &QPushButton::released, this, &FwdSetupWidget::showEEGModelFileDialog); +} + +//============================================================================================================= + +void FwdSetupWidget::showFwdDirDialog() +{ + QString t_sSolDir = QFileDialog::getExistingDirectory(this, + tr("Select Directory to store the forward solution"), + QString(), + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + m_ui.m_qLineEdit_SolName->setText(t_sSolDir); +} + +//============================================================================================================= + +void FwdSetupWidget::onSolNameChanged() +{ + QString t_sFileName = m_ui.m_qLineEdit_SolName->text(); + + // check for file endings + if(t_sFileName.contains("-fwd.fif")) { + m_pFwdSettings->solname = t_sFileName; + } else { + qWarning() << "rtFwdSetup: make sure to name solution file correctly: -fwd.fif"; + } +} + +//============================================================================================================= + +void FwdSetupWidget::showMeasFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Measurement File"), + QString(), + tr("Fif Files (*.fif)")); + + m_ui.m_qLineEdit_MeasName->setText(t_sFileName); + + QFile t_fSource(t_sFileName); + if(t_fSource.open(QIODevice::ReadOnly)) { + m_pFwdSettings->measname = t_sFileName; + m_ui.m_qLineEdit_MeasName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Measurement file cannot be opened"; + } + t_fSource.close(); + +} + +//============================================================================================================= + +void FwdSetupWidget::showSourceFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Source Space"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fSource(t_sFileName); + if(t_fSource.open(QIODevice::ReadOnly)) { + m_pFwdSettings->srcname = t_sFileName; + m_ui.m_qLineEdit_SourceName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Source file cannot be opened"; + } + t_fSource.close(); +} + +//============================================================================================================= + +void FwdSetupWidget::showBemFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Bem Model"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fBem(t_sFileName); + if(t_fBem.open(QIODevice::ReadOnly)) { + m_pFwdSettings->bemname = t_sFileName; + m_ui.m_qLineEdit_BemName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Bem file cannot be opened"; + } + t_fBem.close(); +} + +//============================================================================================================= + +void FwdSetupWidget::showMriFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Mri-Head Transformation"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fMri(t_sFileName); + if(t_fMri.open(QIODevice::ReadOnly)) { + m_pFwdSettings->mriname = t_sFileName; + m_ui.m_qLineEdit_MriName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Mri-Head transformation cannot be opened"; + } + t_fMri.close(); +} + +//============================================================================================================= + +void FwdSetupWidget::showEEGModelFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select EEG model"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fEegModel(t_sFileName); + if(t_fEegModel.open(QIODevice::ReadOnly)) { + m_pFwdSettings->eeg_model_file = t_sFileName; + m_ui.m_qLineEdit_EEGModelFile->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Eeg model file cannot be opened"; + } + t_fEegModel.close(); +} + +//============================================================================================================= + +void FwdSetupWidget::onEEGModelNameChanged() +{ + m_pFwdSettings->eeg_model_name = m_ui.m_qLineEdit_EEGModelName->text(); +} + +//============================================================================================================= + +void FwdSetupWidget::showMinDistDirDialog() +{ + QString t_sMinDistDir = QFileDialog::getExistingDirectory(this, + tr("Select output for omitted source space"), + QString(), + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + m_ui.m_qLineEdit_MinDistName->setText(t_sMinDistDir); +} + +//============================================================================================================= + +void FwdSetupWidget::onMinDistNameChanged() +{ + QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text(); + m_pFwdSettings->mindistoutname = t_sFileName; +} + +//============================================================================================================= + +void FwdSetupWidget::onMinDistChanged() +{ + m_pFwdSettings->mindist = m_ui.m_doubleSpinBox_dMinDist->value()/1000; +} +//============================================================================================================= + +void FwdSetupWidget::onEEGSphereRadChanged() +{ + m_pFwdSettings->eeg_sphere_rad = m_ui.m_doubleSpinBox_dEegSphereRad->value()/1000; +} + +//============================================================================================================= + +void FwdSetupWidget::onEEGSphereOriginChanged() +{ + m_pFwdSettings->r0.x() = m_ui.m_doubleSpinBox_dVecR0x->value()/1000; + m_pFwdSettings->r0.y() = m_ui.m_doubleSpinBox_dVecR0y->value()/1000; + m_pFwdSettings->r0.z() = m_ui.m_doubleSpinBox_dVecR0z->value()/1000; +} + +//============================================================================================================= + +void FwdSetupWidget::onCheckStateChanged() +{ + m_pFwdSettings->do_all = m_ui.m_check_bDoAll->isChecked(); + m_pFwdSettings->include_eeg = m_ui.m_check_bIncludeEEG->isChecked(); + m_pFwdSettings->include_meg = m_ui.m_check_bIncludeMeg->isChecked(); + m_pFwdSettings->compute_grad = m_ui.m_check_bComputeGrad->isChecked(); + + if( m_ui.m_check_bCoordframe->isChecked()) { + m_pFwdSettings->coord_frame = FIFFV_COORD_MRI; + } else { + m_pFwdSettings->coord_frame = FIFFV_COORD_HEAD; + } + + m_pFwdSettings->accurate = m_ui.m_check_bAccurate->isChecked(); + m_pFwdSettings->fixed_ori = m_ui.m_check_bFixedOri->isChecked(); + m_pFwdSettings->filter_spaces = m_ui.m_check_bFilterSpaces->isChecked(); + m_pFwdSettings->mri_head_ident = m_ui.m_check_bMriHeadIdent->isChecked(); + m_pFwdSettings->use_threads = m_ui.m_check_bUseThreads->isChecked(); + m_pFwdSettings->use_equiv_eeg = m_ui.m_check_bUseEquivEeg->isChecked(); + m_pFwdSettings->scale_eeg_pos = m_ui.m_check_bScaleEegPos->isChecked(); +} + +//============================================================================================================= + +FwdSetupWidget::~FwdSetupWidget() +{ +} diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h new file mode 100644 index 00000000000..a5e737b0816 --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h @@ -0,0 +1,194 @@ +//============================================================================================================= +/** + * @file rtfwdsetupwidget.h + * @author Ruben Dörfel + * Gabriel B. Motta + * @since 0.1.9 + * @date October, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Ruben Dörfel, 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 RtFwdSetupWidget class. + * + */ + +#ifndef FWDSETUPWIDGET_H +#define FWDSETUPWIDGET_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "ui_fwdsetupwidget.h" + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace Ui { + class FwdSetupWidgetClass; +} + +namespace FWDLIB { + class ComputeFwdSettings; +} + +//============================================================================================================= +// DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN +//============================================================================================================= + +namespace FORWARDSOLUTIONPLUGIN +{ + +//============================================================================================================= +/** + * DECLARE CLASS RtFwdSetupWidget + * + * @brief The RtFwdSetupWidget class provides the RtFwd configuration window. + */ +class FwdSetupWidget : public QWidget +{ + Q_OBJECT + +public: + + //========================================================================================================= + /** + * Constructs a RtFwdSetupWidget which is a child of parent. + * + * @param[in] toolbox a pointer to the corresponding RtFwd. + * @param[in] parent pointer to parent widget; If parent is 0, the new RtFwdSetupWidget becomes a window. If parent is another widget, RtFwdSetupWidget becomes a child window inside parent. RtFwdSetupWidget is deleted when its parent is deleted. + */ + FwdSetupWidget(QSharedPointer settings, QWidget *parent = 0); + + //========================================================================================================= + /** + * Destroys the RtFwdSetupWidget. + * All RtFwdSetupWidget's children are deleted first. The application exits if RtFwdSetupWidget is the main widget. + */ + ~FwdSetupWidget(); + +private: + //========================================================================================================= + /** + * Shows forward solution directory selection dialog + */ + void showFwdDirDialog(); + + //========================================================================================================= + /** + * change name of solution file + */ + void onSolNameChanged(); + + //========================================================================================================= + /** + * Shows measurement selection dialog + */ + void showMeasFileDialog(); + + //========================================================================================================= + /** + * Shows source space selection dialog + */ + void showSourceFileDialog(); + + //========================================================================================================= + /** + * Shows Bem model selection dialog + */ + void showBemFileDialog(); + + //========================================================================================================= + /** + * Shows Mri->Head transformation selection dialog + */ + void showMriFileDialog(); + + //========================================================================================================= + /** + * Shows output file selection dialog + */ + void showMinDistDirDialog(); + + QString m_sMinDistDir; + + //========================================================================================================= + /** + * Change name of MinDistDir output + */ + void onMinDistNameChanged(); + + //========================================================================================================= + /** + * Shows EEG model selection dialog + */ + void showEEGModelFileDialog(); + + //========================================================================================================= + /** + * Shows EEG model name selection selection dialog + */ + void onEEGModelNameChanged(); + + //========================================================================================================= + /** + * Change value of minimum distance skull - source + */ + void onMinDistChanged(); + + //========================================================================================================= + /** + * Change EEG sphere radius + */ + void onEEGSphereRadChanged(); + + //========================================================================================================= + /** + * Change EEG sphere origin + */ + void onEEGSphereOriginChanged(); + + //========================================================================================================= + /** + * Change settings from checkboxes + */ + void onCheckStateChanged(); + + //========================================================================================================= + + + QSharedPointer m_pFwdSettings; /**< Forward Solution Settings. */ + + Ui::FwdSetupWidgetClass m_ui; /**< Holds the user interface for the RtFwdSetupWidget.*/ +}; +} // NAMESPACE + +#endif // FWDSETUPWIDGET_H diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui new file mode 100644 index 00000000000..b50452f07b9 --- /dev/null +++ b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui @@ -0,0 +1,496 @@ + + + FwdSetupWidgetClass + + + + 0 + 0 + 603 + 728 + + + + + 0 + 0 + + + + DummySetupWidget + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + 0 + 0 + + + + <html><head/><body><p>s</p></body></html> + + + 0 + + + + Files + + + + + + Forward Solution + + + false + + + + + + ... + + + + + + + + 140 + 0 + + + + + + + + + + + + + + Measurement File (with compensator inforamtion) + + + false + + + + + + + 140 + 0 + + + + + + + + + + + ... + + + + + + + + + + Source Space + + + false + + + + + + + 140 + 0 + + + + + + + + ... + + + + + + + + + + BEM Model + + + false + + + + + + ... + + + + + + + + 140 + 0 + + + + + + + + + + + MRI - Head Transformation + + + false + + + + + + + 140 + 0 + + + + + + + + ... + + + + + + + + + + Output for omitted source space points + + + false + + + + + + + 140 + 0 + + + + + + + + ... + + + + + + + + + + EEG model + + + false + + + + + + + 140 + 0 + + + + + + + + ... + + + + + + + + + + + Settings + + + + + + Compute MEG Solution + + + + + + + Compute EEG Solution + + + + + + + Compute Gradient Solution + + + + + + + Fixed Orientation + + + + + + + Acurate + + + + + + + Compute in MRI space (else Head space) + + + + + + + Use threads + + + + + + + Calculate forward solution in all nodes + + + + + + + Identical head- and MRI- space + + + + + + + Filter Source Spaces + + + + + + + Scale Electrode Positions + + + + + + + Use equivalent source approach for EEG + + + + + + + Minimum distance skull <-> source [mm] + + + + + + 1 + + + + + + + + + + EEG scalp radius of sphere model [mm] + + + + + + 1 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + + + + Sphere Model Origin (x,y,z) [mm] + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + + + + EEG model name + + + false + + + + + + + 140 + 0 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 84bd8f4addd..e6fae1be07e 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -39,6 +39,8 @@ #include "forwardsolution.h" +#include "FormFiles/fwdsetupwidget.h" + #include #include @@ -155,15 +157,22 @@ QWidget *ForwardSolution::getView() QDockWidget* ForwardSolution::getControl() { m_pFwdSettingsView = new DISPLIB::FwdSettingsView(); +// m_pFwdSetupView = new FwdSetupWidget(m_pFwdSettings); + +// QVBoxLayout* pControlLayout = new QVBoxLayout(); +// pControlLayout->addWidget(m_pFwdSettingsView); +// pControlLayout->addWidget(m_pFwdSetupView); +// pControlLayout->setSpacing(0); - QVBoxLayout* pControlLayout = new QVBoxLayout(); - pControlLayout->addWidget(m_pFwdSettingsView); +// QWidget* containerWidget = new QWidget(); +// containerWidget->setLayout(pControlLayout); - QScrollArea* pControlScrollArea = new QScrollArea(); - pControlScrollArea->setLayout(pControlLayout); +// QScrollArea* pControlScrollArea = new QScrollArea(); +// pControlScrollArea->setWidget(containerWidget); QDockWidget* pControlDock = new QDockWidget(this->getName()); - pControlDock->setWidget(pControlScrollArea); +// pControlDock->setWidget(pControlScrollArea); + pControlDock->setWidget(m_pFwdSettingsView); // connect incoming signals connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::recompStatusChanged, diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index 256199f4f90..b07921df8f9 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -86,6 +86,8 @@ namespace MNELIB { namespace FORWARDSOLUTIONPLUGIN { +class FwdSetupWidget; + //============================================================================================================= // FORWARDSOLUTIONPLUGIN FORWARD DECLARATIONS //============================================================================================================= @@ -203,6 +205,7 @@ private slots: QPointer m_pCommu; /**< To broadcst signals. */ DISPLIB::FwdSettingsView* m_pFwdSettingsView; + FwdSetupWidget* m_pFwdSetupView; QSharedPointer m_pFwdSettings; /**< Forward Solution Settings. */ diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro index 4a34217d380..e45809e11a7 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro @@ -89,13 +89,18 @@ CONFIG(debug, debug|release) { } SOURCES += \ + FormFiles/fwdsetupwidget.cpp \ forwardsolution.cpp \ - forwardsolution_global.cpp + forwardsolution_global.cpp \ HEADERS += \ + FormFiles/fwdsetupwidget.h \ forwardsolution_global.h \ forwardsolution.h \ +FORMS += \ + FormFiles/fwdsetupwidget.ui + OTHER_FILES += forwardsolution.json clang { From 6eeb2013543c251d2c24daf7f139928c76db9fa4 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Wed, 19 Oct 2022 11:37:02 -0400 Subject: [PATCH 10/17] Fix time waste from qt --- .../FormFiles/fwdsetupwidget.cpp | 343 ------------ .../FormFiles/fwdsetupwidget.h | 194 ------- .../FormFiles/fwdsetupwidget.ui | 496 ------------------ .../forwardsolution/forwardsolution.cpp | 20 +- .../plugins/forwardsolution/forwardsolution.h | 3 - .../forwardsolution/forwardsolution.pro | 5 - 6 files changed, 7 insertions(+), 1054 deletions(-) delete mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp delete mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h delete mode 100644 applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp deleted file mode 100644 index 3768bd196aa..00000000000 --- a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.cpp +++ /dev/null @@ -1,343 +0,0 @@ -//============================================================================================================= -/** - * @file FwdSetupWidget.cpp - * @author Ruben Dörfel - * Gabriel B. Motta - * @since 0.1.9 - * @date October, 2022 - * - * @section LICENSE - * - * Copyright (C) 2022, Ruben Dörfel, 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 Definition of the FwdSetupWidget class. - * - */ - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "fwdsetupwidget.h" - -#include - -#include - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -#include - -//============================================================================================================= -// USED NAMESPACES -//============================================================================================================= - -using FORWARDSOLUTIONPLUGIN::FwdSetupWidget; -using namespace FIFFLIB; - -//============================================================================================================= -// DEFINE MEMBER METHODS -//============================================================================================================= - -FwdSetupWidget::FwdSetupWidget(QSharedPointer settings, QWidget *parent) -: QWidget(parent) -, m_pFwdSettings(settings) -{ - m_ui.setupUi(this); - - // init line edits - m_ui.m_qLineEdit_SolName->setText(m_pFwdSettings->solname); - m_ui.m_qLineEdit_MeasName->setText(m_pFwdSettings->measname); - m_ui.m_qLineEdit_BemName->setText(m_pFwdSettings->bemname); - m_ui.m_qLineEdit_SourceName->setText(m_pFwdSettings->srcname); - m_ui.m_qLineEdit_MriName->setText(m_pFwdSettings->mriname); - m_ui.m_qLineEdit_MinDistName->setText(m_pFwdSettings->mindistoutname); - m_ui.m_qLineEdit_EEGModelFile->setText(m_pFwdSettings->eeg_model_file); - m_ui.m_qLineEdit_EEGModelName->setText(m_pFwdSettings->eeg_model_name); - - // init checkboxes - m_ui.m_check_bDoAll->setChecked(m_pFwdSettings->do_all); - m_ui.m_check_bIncludeEEG->setChecked(m_pFwdSettings->include_eeg); - m_ui.m_check_bIncludeMeg->setChecked(m_pFwdSettings->include_meg); - m_ui.m_check_bComputeGrad->setChecked(m_pFwdSettings->compute_grad); - - if(m_pFwdSettings->coord_frame == FIFFV_COORD_MRI) { - m_ui.m_check_bCoordframe->setChecked(true); - } else { - m_ui.m_check_bCoordframe->setChecked(false); - } - - m_ui.m_check_bAccurate->setChecked(m_pFwdSettings->accurate); - m_ui.m_check_bFixedOri->setChecked(m_pFwdSettings->fixed_ori); - m_ui.m_check_bFilterSpaces->setChecked(m_pFwdSettings->filter_spaces); - m_ui.m_check_bMriHeadIdent->setChecked(m_pFwdSettings->mri_head_ident); - m_ui.m_check_bUseThreads->setChecked(m_pFwdSettings->use_threads); - m_ui.m_check_bUseEquivEeg->setChecked(m_pFwdSettings->use_equiv_eeg); - - // init Spin Boxes - m_ui.m_doubleSpinBox_dMinDist->setValue(m_pFwdSettings->mindist*1000); - m_ui.m_doubleSpinBox_dEegSphereRad->setValue(m_pFwdSettings->eeg_sphere_rad*1000); - m_ui.m_doubleSpinBox_dVecR0x->setValue(m_pFwdSettings->r0.x()*1000); - m_ui.m_doubleSpinBox_dVecR0y->setValue(m_pFwdSettings->r0.y()*1000); - m_ui.m_doubleSpinBox_dVecR0z->setValue(m_pFwdSettings->r0.z()*1000); - - // connect line edits - connect(m_ui.m_qLineEdit_SolName, &QLineEdit::textChanged, this, &FwdSetupWidget::onSolNameChanged); - connect(m_ui.m_qLineEdit_MinDistName, &QLineEdit::textChanged, this, &FwdSetupWidget::onMinDistNameChanged); - - // connect checkboxes - connect(m_ui.m_check_bDoAll, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bAccurate, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bFixedOri, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bCoordframe, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bIncludeEEG, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bIncludeMeg, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bUseThreads, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bComputeGrad, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bScaleEegPos, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bUseEquivEeg, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bFilterSpaces, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - connect(m_ui.m_check_bMriHeadIdent, &QCheckBox::stateChanged, this, &FwdSetupWidget::onCheckStateChanged); - - // connect spin boxes - connect(m_ui.m_doubleSpinBox_dMinDist,static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onMinDistChanged); - connect(m_ui.m_doubleSpinBox_dEegSphereRad, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereRadChanged); - connect(m_ui.m_doubleSpinBox_dVecR0x, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); - connect(m_ui.m_doubleSpinBox_dVecR0y, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); - connect(m_ui.m_doubleSpinBox_dVecR0z, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSetupWidget::onEEGSphereOriginChanged); - - // connet push buttons - connect(m_ui.m_qPushButton_SolNameDialog, &QPushButton::released, this, &FwdSetupWidget::showFwdDirDialog); - connect(m_ui.m_qPushButton_BemNameDialog, &QPushButton::released, this, &FwdSetupWidget::showBemFileDialog); - connect(m_ui.m_qPushButton_MeasNameDialog, &QPushButton::released, this, &FwdSetupWidget::showMeasFileDialog); - connect(m_ui.m_qPushButton_SourceNameDialog, &QPushButton::released, this, &FwdSetupWidget::showSourceFileDialog); - connect(m_ui.m_qPushButton_MriNameDialog, &QPushButton::released, this, &FwdSetupWidget::showMriFileDialog); - connect(m_ui.m_qPushButton_MinDistOutDialog, &QPushButton::released, this, &FwdSetupWidget::showMinDistDirDialog); - connect(m_ui.m_qPushButton_EEGModelFileDialog, &QPushButton::released, this, &FwdSetupWidget::showEEGModelFileDialog); -} - -//============================================================================================================= - -void FwdSetupWidget::showFwdDirDialog() -{ - QString t_sSolDir = QFileDialog::getExistingDirectory(this, - tr("Select Directory to store the forward solution"), - QString(), - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - m_ui.m_qLineEdit_SolName->setText(t_sSolDir); -} - -//============================================================================================================= - -void FwdSetupWidget::onSolNameChanged() -{ - QString t_sFileName = m_ui.m_qLineEdit_SolName->text(); - - // check for file endings - if(t_sFileName.contains("-fwd.fif")) { - m_pFwdSettings->solname = t_sFileName; - } else { - qWarning() << "rtFwdSetup: make sure to name solution file correctly: -fwd.fif"; - } -} - -//============================================================================================================= - -void FwdSetupWidget::showMeasFileDialog() -{ - QString t_sFileName = QFileDialog::getOpenFileName(this, - tr("Select Measurement File"), - QString(), - tr("Fif Files (*.fif)")); - - m_ui.m_qLineEdit_MeasName->setText(t_sFileName); - - QFile t_fSource(t_sFileName); - if(t_fSource.open(QIODevice::ReadOnly)) { - m_pFwdSettings->measname = t_sFileName; - m_ui.m_qLineEdit_MeasName->setText(t_sFileName); - } else { - qWarning() << "rtFwdSetup: Measurement file cannot be opened"; - } - t_fSource.close(); - -} - -//============================================================================================================= - -void FwdSetupWidget::showSourceFileDialog() -{ - QString t_sFileName = QFileDialog::getOpenFileName(this, - tr("Select Source Space"), - QString(), - tr("Fif Files (*.fif)")); - - QFile t_fSource(t_sFileName); - if(t_fSource.open(QIODevice::ReadOnly)) { - m_pFwdSettings->srcname = t_sFileName; - m_ui.m_qLineEdit_SourceName->setText(t_sFileName); - } else { - qWarning() << "rtFwdSetup: Source file cannot be opened"; - } - t_fSource.close(); -} - -//============================================================================================================= - -void FwdSetupWidget::showBemFileDialog() -{ - QString t_sFileName = QFileDialog::getOpenFileName(this, - tr("Select Bem Model"), - QString(), - tr("Fif Files (*.fif)")); - - QFile t_fBem(t_sFileName); - if(t_fBem.open(QIODevice::ReadOnly)) { - m_pFwdSettings->bemname = t_sFileName; - m_ui.m_qLineEdit_BemName->setText(t_sFileName); - } else { - qWarning() << "rtFwdSetup: Bem file cannot be opened"; - } - t_fBem.close(); -} - -//============================================================================================================= - -void FwdSetupWidget::showMriFileDialog() -{ - QString t_sFileName = QFileDialog::getOpenFileName(this, - tr("Select Mri-Head Transformation"), - QString(), - tr("Fif Files (*.fif)")); - - QFile t_fMri(t_sFileName); - if(t_fMri.open(QIODevice::ReadOnly)) { - m_pFwdSettings->mriname = t_sFileName; - m_ui.m_qLineEdit_MriName->setText(t_sFileName); - } else { - qWarning() << "rtFwdSetup: Mri-Head transformation cannot be opened"; - } - t_fMri.close(); -} - -//============================================================================================================= - -void FwdSetupWidget::showEEGModelFileDialog() -{ - QString t_sFileName = QFileDialog::getOpenFileName(this, - tr("Select EEG model"), - QString(), - tr("Fif Files (*.fif)")); - - QFile t_fEegModel(t_sFileName); - if(t_fEegModel.open(QIODevice::ReadOnly)) { - m_pFwdSettings->eeg_model_file = t_sFileName; - m_ui.m_qLineEdit_EEGModelFile->setText(t_sFileName); - } else { - qWarning() << "rtFwdSetup: Eeg model file cannot be opened"; - } - t_fEegModel.close(); -} - -//============================================================================================================= - -void FwdSetupWidget::onEEGModelNameChanged() -{ - m_pFwdSettings->eeg_model_name = m_ui.m_qLineEdit_EEGModelName->text(); -} - -//============================================================================================================= - -void FwdSetupWidget::showMinDistDirDialog() -{ - QString t_sMinDistDir = QFileDialog::getExistingDirectory(this, - tr("Select output for omitted source space"), - QString(), - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - m_ui.m_qLineEdit_MinDistName->setText(t_sMinDistDir); -} - -//============================================================================================================= - -void FwdSetupWidget::onMinDistNameChanged() -{ - QString t_sFileName = m_ui.m_qLineEdit_MinDistName->text(); - m_pFwdSettings->mindistoutname = t_sFileName; -} - -//============================================================================================================= - -void FwdSetupWidget::onMinDistChanged() -{ - m_pFwdSettings->mindist = m_ui.m_doubleSpinBox_dMinDist->value()/1000; -} -//============================================================================================================= - -void FwdSetupWidget::onEEGSphereRadChanged() -{ - m_pFwdSettings->eeg_sphere_rad = m_ui.m_doubleSpinBox_dEegSphereRad->value()/1000; -} - -//============================================================================================================= - -void FwdSetupWidget::onEEGSphereOriginChanged() -{ - m_pFwdSettings->r0.x() = m_ui.m_doubleSpinBox_dVecR0x->value()/1000; - m_pFwdSettings->r0.y() = m_ui.m_doubleSpinBox_dVecR0y->value()/1000; - m_pFwdSettings->r0.z() = m_ui.m_doubleSpinBox_dVecR0z->value()/1000; -} - -//============================================================================================================= - -void FwdSetupWidget::onCheckStateChanged() -{ - m_pFwdSettings->do_all = m_ui.m_check_bDoAll->isChecked(); - m_pFwdSettings->include_eeg = m_ui.m_check_bIncludeEEG->isChecked(); - m_pFwdSettings->include_meg = m_ui.m_check_bIncludeMeg->isChecked(); - m_pFwdSettings->compute_grad = m_ui.m_check_bComputeGrad->isChecked(); - - if( m_ui.m_check_bCoordframe->isChecked()) { - m_pFwdSettings->coord_frame = FIFFV_COORD_MRI; - } else { - m_pFwdSettings->coord_frame = FIFFV_COORD_HEAD; - } - - m_pFwdSettings->accurate = m_ui.m_check_bAccurate->isChecked(); - m_pFwdSettings->fixed_ori = m_ui.m_check_bFixedOri->isChecked(); - m_pFwdSettings->filter_spaces = m_ui.m_check_bFilterSpaces->isChecked(); - m_pFwdSettings->mri_head_ident = m_ui.m_check_bMriHeadIdent->isChecked(); - m_pFwdSettings->use_threads = m_ui.m_check_bUseThreads->isChecked(); - m_pFwdSettings->use_equiv_eeg = m_ui.m_check_bUseEquivEeg->isChecked(); - m_pFwdSettings->scale_eeg_pos = m_ui.m_check_bScaleEegPos->isChecked(); -} - -//============================================================================================================= - -FwdSetupWidget::~FwdSetupWidget() -{ -} diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h deleted file mode 100644 index a5e737b0816..00000000000 --- a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.h +++ /dev/null @@ -1,194 +0,0 @@ -//============================================================================================================= -/** - * @file rtfwdsetupwidget.h - * @author Ruben Dörfel - * Gabriel B. Motta - * @since 0.1.9 - * @date October, 2022 - * - * @section LICENSE - * - * Copyright (C) 2022, Ruben Dörfel, 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 RtFwdSetupWidget class. - * - */ - -#ifndef FWDSETUPWIDGET_H -#define FWDSETUPWIDGET_H - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "ui_fwdsetupwidget.h" - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -#include - -//============================================================================================================= -// FORWARD DECLARATIONS -//============================================================================================================= - -namespace Ui { - class FwdSetupWidgetClass; -} - -namespace FWDLIB { - class ComputeFwdSettings; -} - -//============================================================================================================= -// DEFINE NAMESPACE FORWARDSOLUTIONPLUGIN -//============================================================================================================= - -namespace FORWARDSOLUTIONPLUGIN -{ - -//============================================================================================================= -/** - * DECLARE CLASS RtFwdSetupWidget - * - * @brief The RtFwdSetupWidget class provides the RtFwd configuration window. - */ -class FwdSetupWidget : public QWidget -{ - Q_OBJECT - -public: - - //========================================================================================================= - /** - * Constructs a RtFwdSetupWidget which is a child of parent. - * - * @param[in] toolbox a pointer to the corresponding RtFwd. - * @param[in] parent pointer to parent widget; If parent is 0, the new RtFwdSetupWidget becomes a window. If parent is another widget, RtFwdSetupWidget becomes a child window inside parent. RtFwdSetupWidget is deleted when its parent is deleted. - */ - FwdSetupWidget(QSharedPointer settings, QWidget *parent = 0); - - //========================================================================================================= - /** - * Destroys the RtFwdSetupWidget. - * All RtFwdSetupWidget's children are deleted first. The application exits if RtFwdSetupWidget is the main widget. - */ - ~FwdSetupWidget(); - -private: - //========================================================================================================= - /** - * Shows forward solution directory selection dialog - */ - void showFwdDirDialog(); - - //========================================================================================================= - /** - * change name of solution file - */ - void onSolNameChanged(); - - //========================================================================================================= - /** - * Shows measurement selection dialog - */ - void showMeasFileDialog(); - - //========================================================================================================= - /** - * Shows source space selection dialog - */ - void showSourceFileDialog(); - - //========================================================================================================= - /** - * Shows Bem model selection dialog - */ - void showBemFileDialog(); - - //========================================================================================================= - /** - * Shows Mri->Head transformation selection dialog - */ - void showMriFileDialog(); - - //========================================================================================================= - /** - * Shows output file selection dialog - */ - void showMinDistDirDialog(); - - QString m_sMinDistDir; - - //========================================================================================================= - /** - * Change name of MinDistDir output - */ - void onMinDistNameChanged(); - - //========================================================================================================= - /** - * Shows EEG model selection dialog - */ - void showEEGModelFileDialog(); - - //========================================================================================================= - /** - * Shows EEG model name selection selection dialog - */ - void onEEGModelNameChanged(); - - //========================================================================================================= - /** - * Change value of minimum distance skull - source - */ - void onMinDistChanged(); - - //========================================================================================================= - /** - * Change EEG sphere radius - */ - void onEEGSphereRadChanged(); - - //========================================================================================================= - /** - * Change EEG sphere origin - */ - void onEEGSphereOriginChanged(); - - //========================================================================================================= - /** - * Change settings from checkboxes - */ - void onCheckStateChanged(); - - //========================================================================================================= - - - QSharedPointer m_pFwdSettings; /**< Forward Solution Settings. */ - - Ui::FwdSetupWidgetClass m_ui; /**< Holds the user interface for the RtFwdSetupWidget.*/ -}; -} // NAMESPACE - -#endif // FWDSETUPWIDGET_H diff --git a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui b/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui deleted file mode 100644 index b50452f07b9..00000000000 --- a/applications/mne_analyze/plugins/forwardsolution/FormFiles/fwdsetupwidget.ui +++ /dev/null @@ -1,496 +0,0 @@ - - - FwdSetupWidgetClass - - - - 0 - 0 - 603 - 728 - - - - - 0 - 0 - - - - DummySetupWidget - - - - 2 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 0 - 0 - - - - <html><head/><body><p>s</p></body></html> - - - 0 - - - - Files - - - - - - Forward Solution - - - false - - - - - - ... - - - - - - - - 140 - 0 - - - - - - - - - - - - - - Measurement File (with compensator inforamtion) - - - false - - - - - - - 140 - 0 - - - - - - - - - - - ... - - - - - - - - - - Source Space - - - false - - - - - - - 140 - 0 - - - - - - - - ... - - - - - - - - - - BEM Model - - - false - - - - - - ... - - - - - - - - 140 - 0 - - - - - - - - - - - MRI - Head Transformation - - - false - - - - - - - 140 - 0 - - - - - - - - ... - - - - - - - - - - Output for omitted source space points - - - false - - - - - - - 140 - 0 - - - - - - - - ... - - - - - - - - - - EEG model - - - false - - - - - - - 140 - 0 - - - - - - - - ... - - - - - - - - - - - Settings - - - - - - Compute MEG Solution - - - - - - - Compute EEG Solution - - - - - - - Compute Gradient Solution - - - - - - - Fixed Orientation - - - - - - - Acurate - - - - - - - Compute in MRI space (else Head space) - - - - - - - Use threads - - - - - - - Calculate forward solution in all nodes - - - - - - - Identical head- and MRI- space - - - - - - - Filter Source Spaces - - - - - - - Scale Electrode Positions - - - - - - - Use equivalent source approach for EEG - - - - - - - Minimum distance skull <-> source [mm] - - - - - - 1 - - - - - - - - - - EEG scalp radius of sphere model [mm] - - - - - - 1 - - - 500.000000000000000 - - - 1.000000000000000 - - - - - - - - - - Sphere Model Origin (x,y,z) [mm] - - - - - - 1 - - - -500.000000000000000 - - - 500.000000000000000 - - - 1.000000000000000 - - - - - - - 1 - - - -500.000000000000000 - - - 500.000000000000000 - - - 1.000000000000000 - - - - - - - 1 - - - -500.000000000000000 - - - 500.000000000000000 - - - 1.000000000000000 - - - - - - - - - - EEG model name - - - false - - - - - - - 140 - 0 - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index e6fae1be07e..cd4b6bc5a60 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -39,8 +39,6 @@ #include "forwardsolution.h" -#include "FormFiles/fwdsetupwidget.h" - #include #include @@ -157,22 +155,18 @@ QWidget *ForwardSolution::getView() QDockWidget* ForwardSolution::getControl() { m_pFwdSettingsView = new DISPLIB::FwdSettingsView(); -// m_pFwdSetupView = new FwdSetupWidget(m_pFwdSettings); -// QVBoxLayout* pControlLayout = new QVBoxLayout(); -// pControlLayout->addWidget(m_pFwdSettingsView); -// pControlLayout->addWidget(m_pFwdSetupView); -// pControlLayout->setSpacing(0); + QVBoxLayout* pControlLayout = new QVBoxLayout(); + pControlLayout->addWidget(m_pFwdSettingsView); -// QWidget* containerWidget = new QWidget(); -// containerWidget->setLayout(pControlLayout); + QWidget* containerWidget = new QWidget(); + containerWidget->setLayout(pControlLayout); -// QScrollArea* pControlScrollArea = new QScrollArea(); -// pControlScrollArea->setWidget(containerWidget); + QScrollArea* pControlScrollArea = new QScrollArea(); + pControlScrollArea->setWidget(containerWidget); QDockWidget* pControlDock = new QDockWidget(this->getName()); -// pControlDock->setWidget(pControlScrollArea); - pControlDock->setWidget(m_pFwdSettingsView); + pControlDock->setWidget(pControlScrollArea); // connect incoming signals connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::recompStatusChanged, diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h index b07921df8f9..256199f4f90 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.h @@ -86,8 +86,6 @@ namespace MNELIB { namespace FORWARDSOLUTIONPLUGIN { -class FwdSetupWidget; - //============================================================================================================= // FORWARDSOLUTIONPLUGIN FORWARD DECLARATIONS //============================================================================================================= @@ -205,7 +203,6 @@ private slots: QPointer m_pCommu; /**< To broadcst signals. */ DISPLIB::FwdSettingsView* m_pFwdSettingsView; - FwdSetupWidget* m_pFwdSetupView; QSharedPointer m_pFwdSettings; /**< Forward Solution Settings. */ diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro index e45809e11a7..d2a49e4b9b0 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.pro @@ -89,18 +89,13 @@ CONFIG(debug, debug|release) { } SOURCES += \ - FormFiles/fwdsetupwidget.cpp \ forwardsolution.cpp \ forwardsolution_global.cpp \ HEADERS += \ - FormFiles/fwdsetupwidget.h \ forwardsolution_global.h \ forwardsolution.h \ -FORMS += \ - FormFiles/fwdsetupwidget.ui - OTHER_FILES += forwardsolution.json clang { From c3266c4c0c54d1a9684392d41e9615efa04a74cd Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Wed, 19 Oct 2022 13:55:21 -0400 Subject: [PATCH 11/17] Connect code to settings --- .../forwardsolution/forwardsolution.cpp | 1 + .../disp/viewers/formfiles/fwdsettingsview.ui | 429 ++++++++++++------ libraries/disp/viewers/fwdsettingsview.cpp | 212 ++++++++- libraries/disp/viewers/fwdsettingsview.h | 98 +++- 4 files changed, 597 insertions(+), 143 deletions(-) diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index cd4b6bc5a60..280f54f7908 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -155,6 +155,7 @@ QWidget *ForwardSolution::getView() QDockWidget* ForwardSolution::getControl() { m_pFwdSettingsView = new DISPLIB::FwdSettingsView(); + m_pFwdSettingsView->setSettings(m_pFwdSettings); QVBoxLayout* pControlLayout = new QVBoxLayout(); pControlLayout->addWidget(m_pFwdSettingsView); diff --git a/libraries/disp/viewers/formfiles/fwdsettingsview.ui b/libraries/disp/viewers/formfiles/fwdsettingsview.ui index 5e5d8fdf67d..6dcb0bb9f43 100644 --- a/libraries/disp/viewers/formfiles/fwdsettingsview.ui +++ b/libraries/disp/viewers/formfiles/fwdsettingsview.ui @@ -17,9 +17,9 @@ - 2 + 1 - + Info @@ -216,61 +216,67 @@ - + Files - - + + Forward Solution - - - - - - QFrame::StyledPanel - - - QFrame::Raised + + false - - - - - - + + + ... + + + + + 140 + 0 + + + + + + + - - - Measurement File (with compensator info) - - - - - - - QFrame::StyledPanel + + + Measurement File (with compensator inforamtion) - - QFrame::Raised + + false - - - + + + + + + 140 + 0 + + + + + + - - + + ... @@ -280,26 +286,26 @@ - - + + Source Space - - - - - - QFrame::StyledPanel - - - QFrame::Raised + + false - - - + + + + + + 140 + 0 + + + - - + + ... @@ -309,55 +315,55 @@ - - + + BEM Model - - - - - - QFrame::StyledPanel - - - QFrame::Raised + + false - - - - - - + + + ... + + + + + 140 + 0 + + + + - - + + MRI - Head Transformation - - - - - - QFrame::StyledPanel - - - QFrame::Raised + + false - - - + + + + + + 140 + 0 + + + - - + + ... @@ -367,26 +373,26 @@ - - + + Output for omitted source space points - - - - - - QFrame::StyledPanel - - - QFrame::Raised + + false - - - + + + + + + 140 + 0 + + + - - + + ... @@ -396,26 +402,26 @@ - - - EEG Model - - - - - - - QFrame::StyledPanel + + + EEG model - - QFrame::Raised + + false - - - + + + + + + 140 + 0 + + + - - + + ... @@ -424,97 +430,240 @@ + + + + Qt::Vertical + + + + 334 + 118 + + + + - + Settings - + - + Compute MEG Solution - + - Compute EEG Solution + Compute EEG Solution - + Compute Gradient Solution - + Fixed Orientation - + - Accurate + Acurate - + - Compute in MRI Space + Compute in MRI space (else Head space) - + - Use Threads + Use threads - + Calculate forward solution in all nodes - + - Identical head- andMRI- space + Identical head- and MRI- space - + Filter Source Spaces - + Scale Electrode Positions - + - Use Equivalent source approach for EEG + Use equivalent source approach for EEG + + + + + + + Minimum distance skull <-> source [mm] + + + + + + 1 + + + + + + + + + + EEG scalp radius of sphere model [mm] + + + + + + 1 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + + + + Sphere Model Origin (x,y,z) [mm] + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + 1 + + + -500.000000000000000 + + + 500.000000000000000 + + + 1.000000000000000 + + + + + + + + + + EEG model name + + + false + + + + + + 140 + 0 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -587,8 +736,6 @@ - tabWidget - groupBox_recomp diff --git a/libraries/disp/viewers/fwdsettingsview.cpp b/libraries/disp/viewers/fwdsettingsview.cpp index 6d4c3075ef3..d8650341f49 100644 --- a/libraries/disp/viewers/fwdsettingsview.cpp +++ b/libraries/disp/viewers/fwdsettingsview.cpp @@ -2,12 +2,13 @@ /** * @file fwdsettingsview.cpp * @author Ruben Dörfel + * Gabriel B Motta * @since 0.1.1 * @date May, 2020 * * @section LICENSE * - * Copyright (C) 2020, Ruben Dörfel. All rights reserved. + * Copyright (C) 2020, Ruben Dörfel, 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: @@ -40,6 +41,7 @@ #include "ui_fwdsettingsview.h" #include +#include //============================================================================================================= // QT INCLUDES @@ -307,3 +309,211 @@ void FwdSettingsView::clearView() { } + +//============================================================================================================= + +void FwdSettingsView::setSettings(QSharedPointer pSettings) +{ + m_pFwdSettings = pSettings; + + +} + +//============================================================================================================= + +void FwdSettingsView::showFwdDirDialog() +{ + QString t_sSolDir = QFileDialog::getExistingDirectory(this, + tr("Select Directory to store the forward solution"), + QString(), + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + m_pUi->m_qLineEdit_SolName->setText(t_sSolDir); +} + +//============================================================================================================= + +void FwdSettingsView::onSolNameChanged() +{ + QString t_sFileName = m_pUi->m_qLineEdit_SolName->text(); + + // check for file endings + if(t_sFileName.contains("-fwd.fif")) { + m_pFwdSettings->solname = t_sFileName; + } else { + qWarning() << "rtFwdSetup: make sure to name solution file correctly: -fwd.fif"; + } +} + +//============================================================================================================= + +void FwdSettingsView::showMeasFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Measurement File"), + QString(), + tr("Fif Files (*.fif)")); + + m_pUi->m_qLineEdit_MeasName->setText(t_sFileName); + + QFile t_fSource(t_sFileName); + if(t_fSource.open(QIODevice::ReadOnly)) { + m_pFwdSettings->measname = t_sFileName; + m_pUi->m_qLineEdit_MeasName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Measurement file cannot be opened"; + } + t_fSource.close(); + +} + +//============================================================================================================= + +void FwdSettingsView::showSourceFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Source Space"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fSource(t_sFileName); + if(t_fSource.open(QIODevice::ReadOnly)) { + m_pFwdSettings->srcname = t_sFileName; + m_pUi->m_qLineEdit_SourceName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Source file cannot be opened"; + } + t_fSource.close(); +} + +//============================================================================================================= + +void FwdSettingsView::showBemFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Bem Model"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fBem(t_sFileName); + if(t_fBem.open(QIODevice::ReadOnly)) { + m_pFwdSettings->bemname = t_sFileName; + m_pUi->m_qLineEdit_BemName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Bem file cannot be opened"; + } + t_fBem.close(); +} + +//============================================================================================================= + +void FwdSettingsView::showMriFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select Mri-Head Transformation"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fMri(t_sFileName); + if(t_fMri.open(QIODevice::ReadOnly)) { + m_pFwdSettings->mriname = t_sFileName; + m_pUi->m_qLineEdit_MriName->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Mri-Head transformation cannot be opened"; + } + t_fMri.close(); +} + +//============================================================================================================= + +void FwdSettingsView::showEEGModelFileDialog() +{ + QString t_sFileName = QFileDialog::getOpenFileName(this, + tr("Select EEG model"), + QString(), + tr("Fif Files (*.fif)")); + + QFile t_fEegModel(t_sFileName); + if(t_fEegModel.open(QIODevice::ReadOnly)) { + m_pFwdSettings->eeg_model_file = t_sFileName; + m_pUi->m_qLineEdit_EEGModelFile->setText(t_sFileName); + } else { + qWarning() << "rtFwdSetup: Eeg model file cannot be opened"; + } + t_fEegModel.close(); +} + +//============================================================================================================= + +void FwdSettingsView::onEEGModelNameChanged() +{ + m_pFwdSettings->eeg_model_name = m_pUi->m_qLineEdit_EEGModelName->text(); +} + +//============================================================================================================= + +void FwdSettingsView::showMinDistDirDialog() +{ + QString t_sMinDistDir = QFileDialog::getExistingDirectory(this, + tr("Select output for omitted source space"), + QString(), + QFileDialog::ShowDirsOnly + | QFileDialog::DontResolveSymlinks); + + m_pUi->m_qLineEdit_MinDistName->setText(t_sMinDistDir); +} + +//============================================================================================================= + +void FwdSettingsView::onMinDistNameChanged() +{ + QString t_sFileName = m_pUi->m_qLineEdit_MinDistName->text(); + m_pFwdSettings->mindistoutname = t_sFileName; +} + +//============================================================================================================= + +void FwdSettingsView::onMinDistChanged() +{ + m_pFwdSettings->mindist = m_pUi->m_doubleSpinBox_dMinDist->value()/1000; +} +//============================================================================================================= + +void FwdSettingsView::onEEGSphereRadChanged() +{ + m_pFwdSettings->eeg_sphere_rad = m_pUi->m_doubleSpinBox_dEegSphereRad->value()/1000; +} + +//============================================================================================================= + +void FwdSettingsView::onEEGSphereOriginChanged() +{ + m_pFwdSettings->r0.x() = m_pUi->m_doubleSpinBox_dVecR0x->value()/1000; + m_pFwdSettings->r0.y() = m_pUi->m_doubleSpinBox_dVecR0y->value()/1000; + m_pFwdSettings->r0.z() = m_pUi->m_doubleSpinBox_dVecR0z->value()/1000; +} + +//============================================================================================================= + +void FwdSettingsView::onCheckStateChanged() +{ + m_pFwdSettings->do_all = m_pUi->m_check_bDoAll->isChecked(); + m_pFwdSettings->include_eeg = m_pUi->m_check_bIncludeEEG->isChecked(); + m_pFwdSettings->include_meg = m_pUi->m_check_bIncludeMeg->isChecked(); + m_pFwdSettings->compute_grad = m_pUi->m_check_bComputeGrad->isChecked(); + + if( m_pUi->m_check_bCoordframe->isChecked()) { + m_pFwdSettings->coord_frame = FIFFV_COORD_MRI; + } else { + m_pFwdSettings->coord_frame = FIFFV_COORD_HEAD; + } + + m_pFwdSettings->accurate = m_pUi->m_check_bAccurate->isChecked(); + m_pFwdSettings->fixed_ori = m_pUi->m_check_bFixedOri->isChecked(); + m_pFwdSettings->filter_spaces = m_pUi->m_check_bFilterSpaces->isChecked(); + m_pFwdSettings->mri_head_ident = m_pUi->m_check_bMriHeadIdent->isChecked(); + m_pFwdSettings->use_threads = m_pUi->m_check_bUseThreads->isChecked(); + m_pFwdSettings->use_equiv_eeg = m_pUi->m_check_bUseEquivEeg->isChecked(); + m_pFwdSettings->scale_eeg_pos = m_pUi->m_check_bScaleEegPos->isChecked(); +} diff --git a/libraries/disp/viewers/fwdsettingsview.h b/libraries/disp/viewers/fwdsettingsview.h index 6b95374f63a..4c541998efc 100644 --- a/libraries/disp/viewers/fwdsettingsview.h +++ b/libraries/disp/viewers/fwdsettingsview.h @@ -2,12 +2,13 @@ /** * @file fwdsettingsview.h * @author Ruben Dörfel + * Gabriel B Motta * @since 0.1.1 * @date May, 2020 * * @section LICENSE * - * Copyright (C) 2020, Ruben Dörfel. All rights reserved. + * Copyright (C) 2020, Ruben Dörfel, 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: @@ -63,6 +64,10 @@ namespace FSLIB { class AnnotationSet; } +namespace FWDLIB{ + class ComputeFwdSettings; +} + namespace Ui { class FwdSettingsViewWidget; } @@ -179,6 +184,8 @@ class DISPSHARED_EXPORT FwdSettingsView : public AbstractView */ void clearView(); + void setSettings(QSharedPointer pSettings); + protected: //========================================================================================================= /** @@ -202,6 +209,95 @@ class DISPSHARED_EXPORT FwdSettingsView : public AbstractView QString m_sSettingsPath; /**< The settings path to store the GUI settings to. */ + QSharedPointer m_pFwdSettings; + +private: + //========================================================================================================= + /** + * Shows forward solution directory selection dialog + */ + void showFwdDirDialog(); + + //========================================================================================================= + /** + * change name of solution file + */ + void onSolNameChanged(); + + //========================================================================================================= + /** + * Shows measurement selection dialog + */ + void showMeasFileDialog(); + + //========================================================================================================= + /** + * Shows source space selection dialog + */ + void showSourceFileDialog(); + + //========================================================================================================= + /** + * Shows Bem model selection dialog + */ + void showBemFileDialog(); + + //========================================================================================================= + /** + * Shows Mri->Head transformation selection dialog + */ + void showMriFileDialog(); + + //========================================================================================================= + /** + * Shows output file selection dialog + */ + void showMinDistDirDialog(); + + QString m_sMinDistDir; + + //========================================================================================================= + /** + * Change name of MinDistDir output + */ + void onMinDistNameChanged(); + + //========================================================================================================= + /** + * Shows EEG model selection dialog + */ + void showEEGModelFileDialog(); + + //========================================================================================================= + /** + * Shows EEG model name selection selection dialog + */ + void onEEGModelNameChanged(); + + //========================================================================================================= + /** + * Change value of minimum distance skull - source + */ + void onMinDistChanged(); + + //========================================================================================================= + /** + * Change EEG sphere radius + */ + void onEEGSphereRadChanged(); + + //========================================================================================================= + /** + * Change EEG sphere origin + */ + void onEEGSphereOriginChanged(); + + //========================================================================================================= + /** + * Change settings from checkboxes + */ + void onCheckStateChanged(); + signals: //========================================================================================================= /** From eb340bc683a7fa1c48ef3901d1a923facfdc4954 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Wed, 19 Oct 2022 14:52:07 -0400 Subject: [PATCH 12/17] Debug fwd solution --- .../libs/anShared/Management/analyzedata.h | 9 ++- .../forwardsolution/forwardsolution.cpp | 16 ++--- libraries/disp/viewers/fwdsettingsview.cpp | 69 +++++++++++++++++++ .../disp/viewers/helpers/bidsviewmodel.h | 2 +- 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Management/analyzedata.h b/applications/mne_analyze/libs/anShared/Management/analyzedata.h index ca82958f703..260fde6be60 100644 --- a/applications/mne_analyze/libs/anShared/Management/analyzedata.h +++ b/applications/mne_analyze/libs/anShared/Management/analyzedata.h @@ -290,6 +290,13 @@ class ANSHAREDSHARED_EXPORT AnalyzeData : public QObject BIDS_DIPOLE); break; } + case ANSHAREDLIB_FORWARDSOLUTION_MODEL:{ + pItem->setData(data); + m_pData->addToData(pItem, + m_SelectedFunctionalData, + BIDS_UNKNOWN); + break; + } case ANSHAREDLIB_FIFFRAW_MODEL: { pItem->setData(data); QModelIndex index = m_SelectedItem; @@ -299,7 +306,7 @@ class ANSHAREDSHARED_EXPORT AnalyzeData : public QObject break; } default:{ - qWarning() << "[AnalyzeData::addModel] Model type not supported"; + qWarning() << "[AnalyzeData::addModel] Model type not recognized."; break; } } diff --git a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp index 280f54f7908..13cd986d0c8 100644 --- a/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp +++ b/applications/mne_analyze/plugins/forwardsolution/forwardsolution.cpp @@ -171,22 +171,21 @@ QDockWidget* ForwardSolution::getControl() // connect incoming signals connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::recompStatusChanged, - this, &ForwardSolution::onRecompStatusChanged); + this, &ForwardSolution::onRecompStatusChanged, Qt::UniqueConnection); connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::clusteringStatusChanged, - this, &ForwardSolution::onClusteringStatusChanged); + this, &ForwardSolution::onClusteringStatusChanged, Qt::UniqueConnection); connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::atlasDirChanged, - this, &ForwardSolution::onAtlasDirChanged); + this, &ForwardSolution::onAtlasDirChanged, Qt::UniqueConnection); connect(m_pFwdSettingsView, &DISPLIB::FwdSettingsView::doForwardComputation, - this, &ForwardSolution::onDoForwardComputation); + this, &ForwardSolution::onDoForwardComputation, Qt::UniqueConnection); // connect outgoing signals connect(this, &ForwardSolution::statusInformationChanged, - m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setRecomputationStatus, Qt::BlockingQueuedConnection); + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setRecomputationStatus, Qt::UniqueConnection); connect(this, &ForwardSolution::fwdSolutionAvailable, - m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setSolutionInformation, Qt::BlockingQueuedConnection); + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setSolutionInformation, Qt::UniqueConnection); connect(this, &ForwardSolution::clusteringAvailable, - m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setClusteredInformation, Qt::BlockingQueuedConnection); - + m_pFwdSettingsView, &DISPLIB::FwdSettingsView::setClusteredInformation, Qt::UniqueConnection); return pControlDock; } @@ -225,6 +224,7 @@ QString ForwardSolution::getBuildInfo() void ForwardSolution::onDoForwardComputation() { + if(!m_pFiffInfo){ qInfo() << "No FiffInfo source available for forward solution computation."; return; diff --git a/libraries/disp/viewers/fwdsettingsview.cpp b/libraries/disp/viewers/fwdsettingsview.cpp index d8650341f49..57de7956275 100644 --- a/libraries/disp/viewers/fwdsettingsview.cpp +++ b/libraries/disp/viewers/fwdsettingsview.cpp @@ -316,6 +316,75 @@ void FwdSettingsView::setSettings(QSharedPointer pSe { m_pFwdSettings = pSettings; + // init line edits + m_pUi->m_qLineEdit_SolName->setText(m_pFwdSettings->solname); + m_pUi->m_qLineEdit_MeasName->setText(m_pFwdSettings->measname); + m_pUi->m_qLineEdit_BemName->setText(m_pFwdSettings->bemname); + m_pUi->m_qLineEdit_SourceName->setText(m_pFwdSettings->srcname); + m_pUi->m_qLineEdit_MriName->setText(m_pFwdSettings->mriname); + m_pUi->m_qLineEdit_MinDistName->setText(m_pFwdSettings->mindistoutname); + m_pUi->m_qLineEdit_EEGModelFile->setText(m_pFwdSettings->eeg_model_file); + m_pUi->m_qLineEdit_EEGModelName->setText(m_pFwdSettings->eeg_model_name); + + // init checkboxes + m_pUi->m_check_bDoAll->setChecked(m_pFwdSettings->do_all); + m_pUi->m_check_bIncludeEEG->setChecked(m_pFwdSettings->include_eeg); + m_pUi->m_check_bIncludeMeg->setChecked(m_pFwdSettings->include_meg); + m_pUi->m_check_bComputeGrad->setChecked(m_pFwdSettings->compute_grad); + + if(m_pFwdSettings->coord_frame == FIFFV_COORD_MRI) { + m_pUi->m_check_bCoordframe->setChecked(true); + } else { + m_pUi->m_check_bCoordframe->setChecked(false); + } + + m_pUi->m_check_bAccurate->setChecked(m_pFwdSettings->accurate); + m_pUi->m_check_bFixedOri->setChecked(m_pFwdSettings->fixed_ori); + m_pUi->m_check_bFilterSpaces->setChecked(m_pFwdSettings->filter_spaces); + m_pUi->m_check_bMriHeadIdent->setChecked(m_pFwdSettings->mri_head_ident); + m_pUi->m_check_bUseThreads->setChecked(m_pFwdSettings->use_threads); + m_pUi->m_check_bUseEquivEeg->setChecked(m_pFwdSettings->use_equiv_eeg); + + // init Spin Boxes + m_pUi->m_doubleSpinBox_dMinDist->setValue(m_pFwdSettings->mindist*1000); + m_pUi->m_doubleSpinBox_dEegSphereRad->setValue(m_pFwdSettings->eeg_sphere_rad*1000); + m_pUi->m_doubleSpinBox_dVecR0x->setValue(m_pFwdSettings->r0.x()*1000); + m_pUi->m_doubleSpinBox_dVecR0y->setValue(m_pFwdSettings->r0.y()*1000); + m_pUi->m_doubleSpinBox_dVecR0z->setValue(m_pFwdSettings->r0.z()*1000); + + // connect line edits + connect(m_pUi->m_qLineEdit_SolName, &QLineEdit::textChanged, this, &FwdSettingsView::onSolNameChanged); + connect(m_pUi->m_qLineEdit_MinDistName, &QLineEdit::textChanged, this, &FwdSettingsView::onMinDistNameChanged); + + // connect checkboxes + connect(m_pUi->m_check_bDoAll, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bAccurate, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bFixedOri, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bCoordframe, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bIncludeEEG, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bIncludeMeg, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bUseThreads, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bComputeGrad, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bScaleEegPos, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bUseEquivEeg, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bFilterSpaces, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + connect(m_pUi->m_check_bMriHeadIdent, &QCheckBox::stateChanged, this, &FwdSettingsView::onCheckStateChanged); + + // connect spin boxes + connect(m_pUi->m_doubleSpinBox_dMinDist,static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSettingsView::onMinDistChanged); + connect(m_pUi->m_doubleSpinBox_dEegSphereRad, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSettingsView::onEEGSphereRadChanged); + connect(m_pUi->m_doubleSpinBox_dVecR0x, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSettingsView::onEEGSphereOriginChanged); + connect(m_pUi->m_doubleSpinBox_dVecR0y, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSettingsView::onEEGSphereOriginChanged); + connect(m_pUi->m_doubleSpinBox_dVecR0z, static_cast(&QDoubleSpinBox::valueChanged), this, &FwdSettingsView::onEEGSphereOriginChanged); + + // connet push buttons + connect(m_pUi->m_qPushButton_SolNameDialog, &QPushButton::released, this, &FwdSettingsView::showFwdDirDialog); + connect(m_pUi->m_qPushButton_BemNameDialog, &QPushButton::released, this, &FwdSettingsView::showBemFileDialog); + connect(m_pUi->m_qPushButton_MeasNameDialog, &QPushButton::released, this, &FwdSettingsView::showMeasFileDialog); + connect(m_pUi->m_qPushButton_SourceNameDialog, &QPushButton::released, this, &FwdSettingsView::showSourceFileDialog); + connect(m_pUi->m_qPushButton_MriNameDialog, &QPushButton::released, this, &FwdSettingsView::showMriFileDialog); + connect(m_pUi->m_qPushButton_MinDistOutDialog, &QPushButton::released, this, &FwdSettingsView::showMinDistDirDialog); + connect(m_pUi->m_qPushButton_EEGModelFileDialog, &QPushButton::released, this, &FwdSettingsView::showEEGModelFileDialog); } diff --git a/libraries/disp/viewers/helpers/bidsviewmodel.h b/libraries/disp/viewers/helpers/bidsviewmodel.h index 1834849dec8..845575479a6 100644 --- a/libraries/disp/viewers/helpers/bidsviewmodel.h +++ b/libraries/disp/viewers/helpers/bidsviewmodel.h @@ -59,7 +59,7 @@ //SUB-ITEMS #define BIDS_AVERAGE 20 -#define BIDS_EVENT 21 +#define BIDS_EVENT 21 #define BIDS_DIPOLE 22 #define BIDS_UNKNOWN 99 From b1f883b3b8e0ac1832c00e38541bb5f0024ae0fd Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Wed, 19 Oct 2022 15:49:52 -0400 Subject: [PATCH 13/17] Start porting source loc code --- .../sourcelocalization/sourcelocalization.cpp | 22 +++++++++++++++++++ .../sourcelocalization/sourcelocalization.h | 14 +++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index 6c1541b8ea5..13e7ca3339c 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -45,6 +45,8 @@ #include #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -67,6 +69,8 @@ SourceLocalization::SourceLocalization() , m_pFwdSolutionModel(Q_NULLPTR) , m_pAverageDataModel(Q_NULLPTR) , m_pRawDataModel(Q_NULLPTR) +, m_iSelectedSample(-1) +, m_bUpdateMinNorm(false) { } @@ -197,6 +201,23 @@ void SourceLocalization::sourceLocalizationFromSingleTrial() qInfo() << "[SourceLocalization::performSourceLocalization] No forward solution available."; return; } + + if(!m_pRawDataModel){ + qInfo() << "[SourceLocalization::performSourceLocalization] No raw data model available."; + return; + } + + + if(m_bUpdateMinNorm) { + m_pMinimumNorm = INVERSELIB::MinimumNorm::SPtr(new INVERSELIB::MinimumNorm(m_invOp, 1.0f / pow(1.0f, 2), "MNE")); + m_bUpdateMinNorm = false; + + // Set up the inverse according to the parameters. + // Use 1 nave here because in case of evoked data as input the minimum norm will always be updated when the source estimate is calculated (see run method). + m_pMinimumNorm->doInverseSetup(1,true); + } + + } //============================================================================================================= @@ -213,6 +234,7 @@ void SourceLocalization::onModelChanged(QSharedPointer(pNewModel); + break; default: break; diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h index 5339c19aadf..77eff3c0580 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h @@ -43,6 +43,8 @@ #include +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= @@ -62,6 +64,10 @@ namespace ANSHAREDLIB { class ForwardSolutionModel; } +namespace INVERSELIB { + class MinimumNorm; +} + //============================================================================================================= // DEFINE NAMESPACE SOURCELOCALIZATIONPLUGIN //============================================================================================================= @@ -146,7 +152,13 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A QSharedPointer m_pAverageDataModel; QSharedPointer m_pRawDataModel; - int m_iSelectedSample; + QSharedPointer m_pMinimumNorm; + + MNELIB::MNEInverseOperator m_invOp; /**< The inverse operator. */ + + + int m_iSelectedSample; + bool m_bUpdateMinNorm; Mode m_sourceLocalizationMode; }; From 859f7f76c9b0fc0e26609a2ff895902cc058a43a Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Fri, 21 Oct 2022 11:08:49 -0400 Subject: [PATCH 14/17] Port cov, invop, mne, source est code --- .../anShared/Model/forwardsolutionmodel.cpp | 7 + .../anShared/Model/forwardsolutionmodel.h | 2 + .../sourcelocalization/sourcelocalization.cpp | 145 +++++++++++++++++- .../sourcelocalization/sourcelocalization.h | 37 ++++- .../sourcelocalization/sourcelocalization.pro | 2 +- 5 files changed, 182 insertions(+), 11 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp index 0abef544856..aad9489e92e 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp @@ -110,3 +110,10 @@ Qt::ItemFlags ForwardSolutionModel::flags(const QModelIndex &index) const { return QAbstractItemModel::flags(index); } + +//============================================================================================================= + +QSharedPointer ForwardSolutionModel::getFwdSolution() +{ + return m_pFwdSolution; +} diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h index 900c0750f0b..c44192a9f08 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.h @@ -138,6 +138,8 @@ class ANSHAREDSHARED_EXPORT ForwardSolutionModel : public AbstractModel */ inline QModelIndex parent(const QModelIndex &index) const override; + QSharedPointer getFwdSolution(); + private: QSharedPointer m_pFwdSolution; }; diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index 13e7ca3339c..724f84ca30f 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -47,11 +47,18 @@ #include +#include +#include > + +#include + //============================================================================================================= // QT INCLUDES //============================================================================================================= #include +#include +#include //============================================================================================================= // USED NAMESPACES @@ -207,14 +214,60 @@ void SourceLocalization::sourceLocalizationFromSingleTrial() return; } + Eigen::MatrixXd data, times; - if(m_bUpdateMinNorm) { - m_pMinimumNorm = INVERSELIB::MinimumNorm::SPtr(new INVERSELIB::MinimumNorm(m_invOp, 1.0f / pow(1.0f, 2), "MNE")); - m_bUpdateMinNorm = false; + float starting_sec = m_pRawDataModel->getSamplingFrequency() * static_cast(m_iSelectedSample); - // Set up the inverse according to the parameters. - // Use 1 nave here because in case of evoked data as input the minimum norm will always be updated when the source estimate is calculated (see run method). - m_pMinimumNorm->doInverseSetup(1,true); + if(!m_pRawDataModel->getFiffIO()->m_qlistRaw.front()->read_raw_segment_times(data, + times, + starting_sec, + starting_sec + m_pRawDataModel->getSamplingFrequency() + )) + { + qWarning() << "Unable to load raw data for source estimation."; + return; + } + + auto covEstimate = estimateCovariance(data, m_pRawDataModel->getFiffInfo().data()); + + MNELIB::MNEInverseOperator invOp(*m_pRawDataModel->getFiffInfo().data(), + *m_pFwdSolutionModel->getFwdSolution().data(), + covEstimate, + 0.2f, + 0.8f); + + auto pMinimumNorm = INVERSELIB::MinimumNorm::SPtr(new INVERSELIB::MinimumNorm(invOp, 1.0f / pow(1.0f, 2), "MNE")); + + // Set up the inverse according to the parameters. + // Use 1 nave here because in case of evoked data as input the minimum norm will always be updated when the source estimate is calculated (see run method). + pMinimumNorm->doInverseSetup(1,true); + + int iNumberChannels = invOp.noise_cov->names.size(); + float tstep = 1.0f / m_pRawDataModel->getFiffInfo()->sfreq; + auto lChNamesFiffInfo = m_pRawDataModel->getFiffInfo()->ch_names; + auto lChNamesInvOp = invOp.noise_cov->names; + int iTimePointSps = m_pRawDataModel->getFiffInfo()->sfreq * 0.001f; + + MatrixXd matDataResized; + matDataResized.resize(iNumberChannels, data.cols()); + + for(int j = 0; j < iNumberChannels; ++j) { + matDataResized.row(j) = data.row(lChNamesFiffInfo.indexOf(lChNamesInvOp.at(j))); + } + + //TODO: Add picking here. See evoked part as input. + QSharedPointer pSourceEstimate = QSharedPointer(new MNELIB::MNESourceEstimate()); + *pSourceEstimate = pMinimumNorm->calculateInverse(matDataResized, + 0.0f, + tstep, + true); + + if(!pSourceEstimate->isEmpty()) { + if(iTimePointSps < pSourceEstimate->data.cols() && iTimePointSps >= 0) { + *pSourceEstimate = pSourceEstimate->reduce(iTimePointSps,1); + } +// m_pAnalyzeData->addModel(pFwdSolModel, +// "Src. Est. - " + QDateTime::currentDateTime().toString()); } @@ -247,3 +300,83 @@ void SourceLocalization::onModelRemoved(QSharedPointer lData; + lData.push_back(matData); + + int iSamples = matData.cols(); + + QFuture result = QtConcurrent::mappedReduced(lData, + computeCov, + reduceCov); + + result.waitForFinished(); + + CovComputeResult finalResult = result.result(); + + //Final computation + FIFFLIB::FiffCov computedCov; + computedCov.data = finalResult.matData; + + QStringList exclude; + for(int i = 0; ichs.size(); i++) { + if(info->chs.at(i).kind != FIFFV_MEG_CH && + info->chs.at(i).kind != FIFFV_EEG_CH) { + exclude << info->chs.at(i).ch_name; + } + } + bool doProj = true; + + if(iSamples > 0) { + finalResult.mu /= (float)iSamples; + computedCov.data.array() -= iSamples * (finalResult.mu * finalResult.mu.transpose()).array(); + computedCov.data.array() /= (iSamples - 1); + + computedCov.kind = FIFFV_MNE_NOISE_COV; + computedCov.diag = false; + computedCov.dim = computedCov.data.rows(); + + //ToDo do picks + computedCov.names = info->ch_names; + computedCov.projs = info->projs; + computedCov.bads = info->bads; + computedCov.nfree = iSamples; + + // regularize noise covariance + computedCov = computedCov.regularize(*info, 0.05, 0.05, 0.1, doProj, exclude); + + return computedCov; + } else { + qWarning() << "[RtCov::estimateCovariance] Number of samples equals zero. Regularization not possible. Returning empty covariance estimation."; + return FIFFLIB::FiffCov(); + } + +} + +//============================================================================================================= + +SourceLocalization::CovComputeResult SourceLocalization::computeCov(const MatrixXd &matData) +{ + CovComputeResult result; + result.mu = matData.rowwise().sum(); + result.matData = matData * matData.transpose(); + return result; +} + +//============================================================================================================= + +void SourceLocalization::reduceCov(CovComputeResult& finalResult, const CovComputeResult &tempResult) +{ + if(finalResult.matData.size() == 0 || finalResult.mu.size() == 0) { + finalResult.mu = tempResult.mu; + finalResult.matData = tempResult.matData; + } else { + finalResult.mu += tempResult.mu; + finalResult.matData += tempResult.matData; + } +} diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h index 77eff3c0580..aa062dbe775 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h @@ -121,6 +121,11 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A private: + struct CovComputeResult { + Eigen::VectorXd mu; + Eigen::MatrixXd matData; + }; + enum Mode{ SOURCE_LOC_FROM_AVG, SOURCE_LOC_FROM_SINGLE_TRIAL @@ -146,16 +151,40 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A */ void onModelRemoved(QSharedPointer pRemovedModel); + //========================================================================================================= + /** + * Perform actual covariance estimation. + * + * @param[in] inputData Data to estimate the covariance from. + */ + FIFFLIB::FiffCov estimateCovariance(const Eigen::MatrixXd& matData, + FIFFLIB::FiffInfo* info); + + //========================================================================================================= + /** + * Computer multiplication with transposed. + * + * @param[in] matData Data to self multiply with. + * + * @return The multiplication result. + */ + static CovComputeResult computeCov(const Eigen::MatrixXd &matData); + + //========================================================================================================= + /** + * Computer multiplication with transposed. + * + * @param[out] finalResult The final covariance estimation. + * @param[in] tempResult The intermediate result from the compute function. + */ + static void reduceCov(CovComputeResult& finalResult, const CovComputeResult &tempResult); + QPointer m_pCommu; /**< To broadcst signals. */ QSharedPointer m_pFwdSolutionModel; QSharedPointer m_pAverageDataModel; QSharedPointer m_pRawDataModel; - QSharedPointer m_pMinimumNorm; - - MNELIB::MNEInverseOperator m_invOp; /**< The inverse operator. */ - int m_iSelectedSample; bool m_bUpdateMinNorm; diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.pro b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.pro index 3ea7986bf35..4a8763a018e 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.pro +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.pro @@ -36,7 +36,7 @@ include(../../../../mne-cpp.pri) TEMPLATE = lib -QT += gui widgets +QT += gui widgets concurrent CONFIG += skip_target_version_ext plugin From ef1a459e6ac3b2affe80b8bb2b10da1ca162d0b4 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Fri, 21 Oct 2022 11:29:02 -0400 Subject: [PATCH 15/17] Add source_loc_model --- .../libs/anShared/Management/analyzedata.h | 7 + .../anShared/Model/forwardsolutionmodel.cpp | 2 +- .../anShared/Model/sourceestimatemodel.cpp | 130 +++++++++++++ .../libs/anShared/Model/sourceestimatemodel.h | 179 ++++++++++++++++++ .../mne_analyze/libs/anShared/Utils/types.h | 3 +- .../mne_analyze/libs/anShared/anShared.pro | 2 + .../sourcelocalization/sourcelocalization.cpp | 3 +- libraries/mne/mne_forwardsolution.h | 3 +- libraries/mne/mne_sourceestimate.h | 9 + 9 files changed, 334 insertions(+), 4 deletions(-) create mode 100644 applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp create mode 100644 applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h diff --git a/applications/mne_analyze/libs/anShared/Management/analyzedata.h b/applications/mne_analyze/libs/anShared/Management/analyzedata.h index 260fde6be60..7273e8e4806 100644 --- a/applications/mne_analyze/libs/anShared/Management/analyzedata.h +++ b/applications/mne_analyze/libs/anShared/Management/analyzedata.h @@ -297,6 +297,13 @@ class ANSHAREDSHARED_EXPORT AnalyzeData : public QObject BIDS_UNKNOWN); break; } + case ANSHAREDLIB_SOURCEESTIMATE_MODEL:{ + pItem->setData(data); + m_pData->addToData(pItem, + m_SelectedFunctionalData, + BIDS_UNKNOWN); + break; + } case ANSHAREDLIB_FIFFRAW_MODEL: { pItem->setData(data); QModelIndex index = m_SelectedItem; diff --git a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp index aad9489e92e..e31d188c42e 100644 --- a/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/forwardsolutionmodel.cpp @@ -3,7 +3,7 @@ * @file forwardsolutionmodel.cpp * @author Gabriel Motta * @since 0.1.9 - * @date October, 2020 + * @date October, 2022 * * @section LICENSE * diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp new file mode 100644 index 00000000000..9f9f418cb3b --- /dev/null +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp @@ -0,0 +1,130 @@ +//============================================================================================================= +/** + * @file sourceestimatemodel.cpp + * @author Gabriel Motta + * @since 0.1.9 + * @date October, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel 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 Definition of the SourceEstimateModel Class. + * + */ + + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + + +#include "sourceestimatemodel.h" + +#include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// Eigen INCLUDES +//============================================================================================================= + + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace ANSHAREDLIB; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +SourceEstimateModel::SourceEstimateModel(QObject* parent) +:AbstractModel(parent) +{ +} + +//============================================================================================================= + +SourceEstimateModel::SourceEstimateModel(QSharedPointer pSourceEstimate, + QSharedPointer pFwdSolution, + QObject* parent) +: AbstractModel( parent) +, m_pSourceEstimate(pSourceEstimate) +, m_pFwdSolution(pFwdSolution) +{ +} + +//============================================================================================================= + +int SourceEstimateModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + return 1; +} + +//============================================================================================================= + +int SourceEstimateModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + return 1; +} + +//============================================================================================================= + +QVariant SourceEstimateModel::data(const QModelIndex &index, + int role) const +{ + Q_UNUSED(index); + Q_UNUSED(role); + + return QVariant::fromValue(m_pFwdSolution); +} + +//============================================================================================================= + +Qt::ItemFlags SourceEstimateModel::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); +} + +//============================================================================================================= + +QSharedPointer SourceEstimateModel::getFwdSolution() +{ + return m_pFwdSolution; +} + +//============================================================================================================= + +QSharedPointer SourceEstimateModel::getSourceEstimate() +{ + return m_pSourceEstimate; +} diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h new file mode 100644 index 00000000000..9e3df8745ba --- /dev/null +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h @@ -0,0 +1,179 @@ +//============================================================================================================= +/** + * @file sourceestimatemodel.h + * @author Gabriel Motta + * @since 0.1.9 + * @date October, 2022 + * + * @section LICENSE + * + * Copyright (C) 2022, Gabriel 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 Declaration of the SourceEstimateModel Class. + * + */ + +#ifndef SOURCEESTIMATEMODEL_H +#define SOURCEESTIMATEMODEL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "../anshared_global.h" +#include "../Utils/types.h" +#include "abstractmodel.h" + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace MNELIB { + class MNEForwardSolution; + class MNESourceEstimate; +} + +//============================================================================================================= +// DEFINE NAMESPACE ANSHAREDLIB +//============================================================================================================= + +namespace ANSHAREDLIB { + +//============================================================================================================= +class ANSHAREDSHARED_EXPORT SourceEstimateModel : public AbstractModel +{ + Q_OBJECT +public: + typedef QSharedPointer SPtr; /**< Shared pointer type for SourceEstimateModel. */ + typedef QSharedPointer ConstSPtr; /**< Const shared pointer type for SourceEstimateModel. */ + +public: + //========================================================================================================= + SourceEstimateModel(QObject* parent = Q_NULLPTR); + + //========================================================================================================= + SourceEstimateModel(QSharedPointer pSourceEstimate, + QSharedPointer pFwdSolution, + QObject* parent = Q_NULLPTR); + + //========================================================================================================= + /** + * Returns the number of rows in the model + * + * @param[in] parent The parent index. + */ + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the number of columns in the model + * + * @param[in] parent The parent index. + */ + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the data stored under the given role for the index. + * + * @param[in] index The index that referres to the requested item. + * @param[in] role The requested role. + */ + virtual QVariant data(const QModelIndex &index, + int role = Qt::DisplayRole) const override; + + //========================================================================================================= + /** + * Returns the item flags for the given index. + * + * @param[in] index The index that referres to the requested item. + */ + Qt::ItemFlags flags(const QModelIndex & index) const override; + + //========================================================================================================= + /** + * The type of this model (CovarianceModel) + * + * @return The type of this model (CovarianceModel). + */ + inline MODEL_TYPE getType() const override; + + //========================================================================================================= + /** + * Returns the index for the item in the model specified by the given row, column and parent index. + * Currently only Qt::DisplayRole is supported. + * Index rows reflect channels, first column is channel names, second is raw data. + * + * @param[in] row The specified row. + * @param[in] column The specified column. + * @param[in] parent The parent index. + */ + inline QModelIndex index(int row, + int column, + const QModelIndex &parent = QModelIndex()) const override; + + //========================================================================================================= + /** + * Returns the parent index of the given index. + * In this Model the parent index in always QModelIndex(). + * + * @param[in] index The index that referres to the child. + */ + inline QModelIndex parent(const QModelIndex &index) const override; + + QSharedPointer getFwdSolution(); + QSharedPointer getSourceEstimate(); + + +private: + QSharedPointer m_pSourceEstimate; + QSharedPointer m_pFwdSolution; +}; + +//============================================================================================================= +// INLINE DEFINITIONS +//============================================================================================================= + +inline MODEL_TYPE SourceEstimateModel::getType() const +{ + return MODEL_TYPE::ANSHAREDLIB_SOURCEESTIMATE_MODEL; +} + +//============================================================================================================= + +QModelIndex SourceEstimateModel::parent(const QModelIndex &index) const +{ + Q_UNUSED(index); + return QModelIndex(); +} + +//============================================================================================================= + +QModelIndex SourceEstimateModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return createIndex(row, column); +} + +}//namespace + +#endif // SOURCEESTIMATEMODEL_H diff --git a/applications/mne_analyze/libs/anShared/Utils/types.h b/applications/mne_analyze/libs/anShared/Utils/types.h index 438107a681e..611501e3249 100644 --- a/applications/mne_analyze/libs/anShared/Utils/types.h +++ b/applications/mne_analyze/libs/anShared/Utils/types.h @@ -88,7 +88,8 @@ namespace ANSHAREDLIB ANSHAREDLIB_NOISE_MODEL, ANSHAREDLIB_MRICOORD_MODEL, ANSHAREDLIB_DIPOLEFIT_MODEL, - ANSHAREDLIB_FORWARDSOLUTION_MODEL + ANSHAREDLIB_FORWARDSOLUTION_MODEL, + ANSHAREDLIB_SOURCEESTIMATE_MODEL }; //========================================================================================================= diff --git a/applications/mne_analyze/libs/anShared/anShared.pro b/applications/mne_analyze/libs/anShared/anShared.pro index 82859e27790..b69bd63a7b8 100644 --- a/applications/mne_analyze/libs/anShared/anShared.pro +++ b/applications/mne_analyze/libs/anShared/anShared.pro @@ -99,6 +99,7 @@ SOURCES += \ Model/forwardsolutionmodel.cpp \ Model/mricoordmodel.cpp \ Model/covariancemodel.cpp \ + Model/sourceestimatemodel.cpp \ Plugins/abstractplugin.cpp HEADERS += \ @@ -106,6 +107,7 @@ HEADERS += \ Model/forwardsolutionmodel.h \ Model/mricoordmodel.h \ Model/covariancemodel.h \ + Model/sourceestimatemodel.h \ Plugins/abstractplugin.h \ anshared_global.h \ Model/abstractmodel.h \ diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index 724f84ca30f..f82dc6ce8f4 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -136,6 +136,7 @@ QDockWidget* SourceLocalization::getControl() { //QDockWidget* pControl = new QDockWidget(getName()); + return Q_NULLPTR; } @@ -267,7 +268,7 @@ void SourceLocalization::sourceLocalizationFromSingleTrial() *pSourceEstimate = pSourceEstimate->reduce(iTimePointSps,1); } // m_pAnalyzeData->addModel(pFwdSolModel, -// "Src. Est. - " + QDateTime::currentDateTime().toString()); +// "Src. Est. - " + QString::number(m_iSelectedSample)); } diff --git a/libraries/mne/mne_forwardsolution.h b/libraries/mne/mne_forwardsolution.h index f31bb34478c..795512b7484 100644 --- a/libraries/mne/mne_forwardsolution.h +++ b/libraries/mne/mne_forwardsolution.h @@ -590,11 +590,12 @@ inline bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b } // NAMESPACE #ifndef metatype_mneforwardsolution +#define metatype_mneforwardsolution Q_DECLARE_METATYPE(MNELIB::MNEForwardSolution);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution type. For signal/slot and QVariant usage.*/ #endif #ifndef metatype_mneforwardsolutionsptr -#define metatype_fiffevokedsetsptr +#define metatype_mneforwardsolutionsptr Q_DECLARE_METATYPE(MNELIB::MNEForwardSolution::SPtr);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution::SPtr type. For signal/slot and QVariant usage.*/ #endif diff --git a/libraries/mne/mne_sourceestimate.h b/libraries/mne/mne_sourceestimate.h index f63a8c29c87..d464fabdd7d 100644 --- a/libraries/mne/mne_sourceestimate.h +++ b/libraries/mne/mne_sourceestimate.h @@ -221,4 +221,13 @@ inline bool MNESourceEstimate::isEmpty() const } } //NAMESPACE +#ifndef metatype_mnesourceestimate +Q_DECLARE_METATYPE(MNELIB::MNESourceEstimate);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution type. For signal/slot and QVariant usage.*/ +#endif + +#ifndef metatype_mnesourceestimatesptr +#define metatype_mnesourceestimatesptr +Q_DECLARE_METATYPE(MNELIB::MNESourceEstimate::SPtr);/**< Provides QT META type declaration of the MNELIB::MNEForwardSolution::SPtr type. For signal/slot and QVariant usage.*/ +#endif + #endif // MNESOURCEESTIMATE_H From fc26dcfbbd455c91a7d6588c91ba78d6396a528c Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Mon, 24 Oct 2022 09:11:31 -0400 Subject: [PATCH 16/17] Add source loc gui and add get functions to model --- .../anShared/Model/sourceestimatemodel.cpp | 8 ++++---- .../libs/anShared/Model/sourceestimatemodel.h | 19 +++++++++++++++---- .../sourcelocalization/sourcelocalization.cpp | 19 ++++++++++++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp index 9f9f418cb3b..5246c1516e8 100644 --- a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp @@ -117,14 +117,14 @@ Qt::ItemFlags SourceEstimateModel::flags(const QModelIndex &index) const //============================================================================================================= -QSharedPointer SourceEstimateModel::getFwdSolution() +QSharedPointer SourceEstimateModel::getSourceEstimate() { - return m_pFwdSolution; + return m_pSourceEstimate; } //============================================================================================================= -QSharedPointer SourceEstimateModel::getSourceEstimate() +QSharedPointer SourceEstimateModel::getFwdSolution() { - return m_pSourceEstimate; + return m_pFwdSolution; } diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h index 9e3df8745ba..03cc900f7d8 100644 --- a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h @@ -47,6 +47,15 @@ // FORWARD DECLARATIONS //============================================================================================================= +namespace FIFFLIB{ + class FiffCoordTrans; +} + +namespace FSLIB{ + class AnnotationSet; + class SurfaceSet; +} + namespace MNELIB { class MNEForwardSolution; class MNESourceEstimate; @@ -140,13 +149,15 @@ class ANSHAREDSHARED_EXPORT SourceEstimateModel : public AbstractModel */ inline QModelIndex parent(const QModelIndex &index) const override; - QSharedPointer getFwdSolution(); QSharedPointer getSourceEstimate(); - + QSharedPointer getFwdSolution(); private: - QSharedPointer m_pSourceEstimate; - QSharedPointer m_pFwdSolution; + QSharedPointer m_pSourceEstimate; + QSharedPointer m_pFwdSolution; + QSharedPointer m_pCoord; + QSharedPointer m_pAnnotationSet; + QSharedPointer m_pSurfaceSet; }; //============================================================================================================= diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index f82dc6ce8f4..864a62dfe13 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -48,7 +48,9 @@ #include #include -#include > +#include + +#include #include @@ -134,10 +136,21 @@ QWidget *SourceLocalization::getView() QDockWidget* SourceLocalization::getControl() { - //QDockWidget* pControl = new QDockWidget(getName()); + DISPLIB::MinimumNormSettingsView* pMinimumNormSettingsView = new DISPLIB::MinimumNormSettingsView(QString("MNESCAN/%1").arg(this->getName())); + QVBoxLayout* pControlLayout = new QVBoxLayout(); + pControlLayout->addWidget(pMinimumNormSettingsView); - return Q_NULLPTR; + QWidget* containerWidget = new QWidget(); + containerWidget->setLayout(pControlLayout); + + QScrollArea* pControlScrollArea = new QScrollArea(); + pControlScrollArea->setWidget(containerWidget); + + QDockWidget* pControlDock = new QDockWidget(this->getName()); + pControlDock->setWidget(pControlScrollArea); + + return pControlDock; } //============================================================================================================= From 3d0ec9e1ee534ec4332cb384e126f46f2874fe77 Mon Sep 17 00:00:00 2001 From: Gabriel Motta Date: Mon, 24 Oct 2022 14:32:54 -0400 Subject: [PATCH 17/17] Adding get/set functions in SE model. Load data into 3d view. --- .../anShared/Model/sourceestimatemodel.cpp | 72 +++++++++++++++++-- .../libs/anShared/Model/sourceestimatemodel.h | 22 ++++-- .../sourcelocalization/sourcelocalization.cpp | 41 ++++++++++- .../sourcelocalization/sourcelocalization.h | 28 ++++++++ .../mne_analyze/plugins/view3d/view3d.cpp | 56 ++++++++++++++- .../mne_analyze/plugins/view3d/view3d.h | 7 ++ 6 files changed, 212 insertions(+), 14 deletions(-) diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp index 5246c1516e8..48b12db55ef 100644 --- a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.cpp @@ -70,12 +70,18 @@ SourceEstimateModel::SourceEstimateModel(QObject* parent) //============================================================================================================= -SourceEstimateModel::SourceEstimateModel(QSharedPointer pSourceEstimate, - QSharedPointer pFwdSolution, - QObject* parent) +SourceEstimateModel::SourceEstimateModel(QSharedPointer pSourceEstimate, + QSharedPointer pFwdSolution, + QSharedPointer pCoord, + QSharedPointer pAnnotationSet, + QSharedPointer pSurfaceSet, + QObject* parent ) : AbstractModel( parent) , m_pSourceEstimate(pSourceEstimate) , m_pFwdSolution(pFwdSolution) +, m_pCoord(pCoord) +, m_pAnnotationSet(pAnnotationSet) +, m_pSurfaceSet(pSurfaceSet) { } @@ -117,14 +123,70 @@ Qt::ItemFlags SourceEstimateModel::flags(const QModelIndex &index) const //============================================================================================================= -QSharedPointer SourceEstimateModel::getSourceEstimate() +QSharedPointer SourceEstimateModel::getSourceEstimate() const { return m_pSourceEstimate; } //============================================================================================================= -QSharedPointer SourceEstimateModel::getFwdSolution() +QSharedPointer SourceEstimateModel::getFwdSolution() const { return m_pFwdSolution; } + +//============================================================================================================= + +QSharedPointer SourceEstimateModel::getMRIHeadTrans() const +{ + return m_pCoord; +} + +//============================================================================================================= + +QSharedPointer SourceEstimateModel::getAnnotationSet() const +{ + return m_pAnnotationSet; +} + +//============================================================================================================= + +QSharedPointer SourceEstimateModel::getSurfSet() const +{ + return m_pSurfaceSet; +} + +//============================================================================================================= + +void SourceEstimateModel::setSourceEstimate(QSharedPointer pSourceEstimate) +{ + m_pSourceEstimate = pSourceEstimate; +} + +//============================================================================================================= + +void SourceEstimateModel::setFwdSolution(QSharedPointer pFwdSol) +{ + m_pFwdSolution = pFwdSol; +} + +//============================================================================================================= + +void SourceEstimateModel::setMRIHeadTrans( QSharedPointer pCoord) +{ + m_pCoord = pCoord; +} + +//============================================================================================================= + +void SourceEstimateModel::setAnnotationSet(QSharedPointer pAnnot) +{ + m_pAnnotationSet = pAnnot; +} + +//============================================================================================================= + +void SourceEstimateModel::setSurfSet(QSharedPointer pSurfSet) +{ + m_pSurfaceSet = pSurfSet; +} diff --git a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h index 03cc900f7d8..06f58130be5 100644 --- a/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h +++ b/applications/mne_analyze/libs/anShared/Model/sourceestimatemodel.h @@ -80,9 +80,12 @@ class ANSHAREDSHARED_EXPORT SourceEstimateModel : public AbstractModel SourceEstimateModel(QObject* parent = Q_NULLPTR); //========================================================================================================= - SourceEstimateModel(QSharedPointer pSourceEstimate, - QSharedPointer pFwdSolution, - QObject* parent = Q_NULLPTR); + SourceEstimateModel(QSharedPointer pSourceEstimate = Q_NULLPTR, + QSharedPointer pFwdSolution = Q_NULLPTR, + QSharedPointer pCoord = Q_NULLPTR, + QSharedPointer pAnnotationSet = Q_NULLPTR, + QSharedPointer pSurfaceSet = Q_NULLPTR, + QObject* parent = Q_NULLPTR); //========================================================================================================= /** @@ -149,8 +152,17 @@ class ANSHAREDSHARED_EXPORT SourceEstimateModel : public AbstractModel */ inline QModelIndex parent(const QModelIndex &index) const override; - QSharedPointer getSourceEstimate(); - QSharedPointer getFwdSolution(); + QSharedPointer getSourceEstimate() const; + QSharedPointer getFwdSolution() const; + QSharedPointer getMRIHeadTrans() const; + QSharedPointer getAnnotationSet() const; + QSharedPointer getSurfSet() const; + + void setSourceEstimate(QSharedPointer pSourceEstimate); + void setFwdSolution(QSharedPointer pFwdSol); + void setMRIHeadTrans( QSharedPointer pCoord); + void setAnnotationSet(QSharedPointer pAnnot); + void setSurfSet(QSharedPointer pSurfSet); private: QSharedPointer m_pSourceEstimate; diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp index 864a62dfe13..6b079801a0a 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.cpp @@ -138,6 +138,13 @@ QDockWidget* SourceLocalization::getControl() { DISPLIB::MinimumNormSettingsView* pMinimumNormSettingsView = new DISPLIB::MinimumNormSettingsView(QString("MNESCAN/%1").arg(this->getName())); + connect(pMinimumNormSettingsView, &DISPLIB::MinimumNormSettingsView::methodChanged, + this, &SourceLocalization::onMethodChanged); + connect(pMinimumNormSettingsView, &DISPLIB::MinimumNormSettingsView::triggerTypeChanged, + this, &SourceLocalization::onTriggerTypeChanged); + connect(pMinimumNormSettingsView, &DISPLIB::MinimumNormSettingsView::timePointChanged, + this, &SourceLocalization::onTimePointValueChanged); + QVBoxLayout* pControlLayout = new QVBoxLayout(); pControlLayout->addWidget(pMinimumNormSettingsView); @@ -250,7 +257,7 @@ void SourceLocalization::sourceLocalizationFromSingleTrial() 0.2f, 0.8f); - auto pMinimumNorm = INVERSELIB::MinimumNorm::SPtr(new INVERSELIB::MinimumNorm(invOp, 1.0f / pow(1.0f, 2), "MNE")); + auto pMinimumNorm = INVERSELIB::MinimumNorm::SPtr(new INVERSELIB::MinimumNorm(invOp, 1.0f / pow(1.0f, 2), m_sMethod)); // Set up the inverse according to the parameters. // Use 1 nave here because in case of evoked data as input the minimum norm will always be updated when the source estimate is calculated (see run method). @@ -394,3 +401,35 @@ void SourceLocalization::reduceCov(CovComputeResult& finalResult, const CovCompu finalResult.matData += tempResult.matData; } } + +//============================================================================================================= + +void SourceLocalization::onMethodChanged(const QString& method) +{ + m_sMethod = method; +} + +//============================================================================================================= + +void SourceLocalization::onTriggerTypeChanged(const QString& triggerType) +{ + m_sAvrType = triggerType; +} + +//============================================================================================================= + +void SourceLocalization::onTimePointValueChanged(int iTimePointMs) +{ + Q_UNUSED(iTimePointMs); +// if(m_pFiffInfoInput && m_pCircularEvokedBuffer) { +// m_qMutex.lock(); +// m_iTimePointSps = m_pFiffInfoInput->sfreq * (float)iTimePointMs * 0.001f; +// m_qMutex.unlock(); + +// if(this->isRunning()) { +// while(!m_pCircularEvokedBuffer->push(m_currentEvoked)) { +// //Do nothing until the circular buffer is ready to accept new data again +// } +// } +// } +} diff --git a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h index aa062dbe775..ce2a1171a65 100644 --- a/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h +++ b/applications/mne_analyze/plugins/sourcelocalization/sourcelocalization.h @@ -179,6 +179,30 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A */ static void reduceCov(CovComputeResult& finalResult, const CovComputeResult &tempResult); + //========================================================================================================= + /** + * Slot called when the method changed. + * + * @param[in] method The new method. + */ + void onMethodChanged(const QString &method); + + //========================================================================================================= + /** + * Slot called when the trigger type changed. + * + * @param[in] triggerType The new trigger type. + */ + void onTriggerTypeChanged(const QString& triggerType); + + //========================================================================================================= + /** + * Slot called when the time point changes. + * + * @param[in] iTimePointMs The new time point in ms. + */ + void onTimePointValueChanged(int iTimePointMs); + QPointer m_pCommu; /**< To broadcst signals. */ QSharedPointer m_pFwdSolutionModel; @@ -186,6 +210,10 @@ class SOURCELOCALIZATIONSHARED_EXPORT SourceLocalization : public ANSHAREDLIB::A QSharedPointer m_pRawDataModel; + QString m_sAvrType; /**< The average type. */ + QString m_sMethod; /**< The method: "MNE" | "dSPM" | "sLORETA". */ + + int m_iSelectedSample; bool m_bUpdateMinNorm; diff --git a/applications/mne_analyze/plugins/view3d/view3d.cpp b/applications/mne_analyze/plugins/view3d/view3d.cpp index 9ebf722cf4c..1e4a7920d96 100644 --- a/applications/mne_analyze/plugins/view3d/view3d.cpp +++ b/applications/mne_analyze/plugins/view3d/view3d.cpp @@ -43,8 +43,7 @@ #include #include #include - - +#include #include #include @@ -55,6 +54,7 @@ #include #include #include +#include #include @@ -83,6 +83,8 @@ View3D::View3D() : m_pCommu(Q_NULLPTR) , m_pBemTreeCoreg(Q_NULLPTR) , m_pDigitizerCoreg(Q_NULLPTR) + , m_pDipoleFit(Q_NULLPTR) + , m_pRtMNEItem(Q_NULLPTR) , m_pView3D(Q_NULLPTR) , m_bPickingActivated(false) { @@ -361,10 +363,58 @@ void View3D::newDipoleFit(const INVERSELIB::ECDSet &ecdSet) //============================================================================================================= +void View3D::newSourceLoc(QSharedPointer pModel) +{ + auto pSourcEstimate = pModel->getSourceEstimate(); + auto pFwdSolution = pModel->getFwdSolution(); + auto pHeadTrans = pModel->getMRIHeadTrans(); + auto pAnnotationSet = pModel->getAnnotationSet(); + auto pSurfSet = pModel->getSurfSet(); + + if(pSourcEstimate && pFwdSolution && pHeadTrans && pAnnotationSet && pSurfSet){ + if(!m_pRtMNEItem){ + m_pRtMNEItem = m_p3DModel->addSourceData("Subject", "Functional Data", + *pSourcEstimate, + *pFwdSolution, + *pSurfSet, + *pAnnotationSet); + m_pRtMNEItem->setLoopState(false); + m_pRtMNEItem->setTimeInterval(17); + m_pRtMNEItem->setThresholds(QVector3D(0.0,5,10)); + m_pRtMNEItem->setColormapType("Hot"); + m_pRtMNEItem->setVisualizationType("Annotation based"); + m_pRtMNEItem->setNumberAverages(1); // Set to 1 because we want to enable time point picking which only includes one sample + m_pRtMNEItem->setAlpha(1.0); + m_pRtMNEItem->setStreamingState(true); + //m_pRtMNEItem->setSFreq(); + } else { + m_pRtMNEItem->addData(*pSourcEstimate); + } + + } else { + qWarning() << "[View3D::newSourceLoc] Missing data in sourec loc model:"; + if(!pSourcEstimate) qWarning() << "Source Estimate missing."; + if(!pFwdSolution) qWarning() << "Fwd Solution missing."; + if(!pHeadTrans) qWarning() << "MRI Head Trans missing."; + if(!pAnnotationSet) qWarning() << "AnnotationSet missing."; + if(!pSurfSet) qWarning() << "Surface Set missing."; + return; + } +} + +//============================================================================================================= + void View3D::onModelChanged(QSharedPointer pNewModel) { - if(pNewModel->getType() == MODEL_TYPE::ANSHAREDLIB_DIPOLEFIT_MODEL) { + switch(pNewModel->getType()){ + case MODEL_TYPE::ANSHAREDLIB_DIPOLEFIT_MODEL: newDipoleFit(qSharedPointerCast(pNewModel)->data(QModelIndex()).value()); + break; + case MODEL_TYPE::ANSHAREDLIB_SOURCEESTIMATE_MODEL: + newSourceLoc(qSharedPointerCast(pNewModel)); + break; + default: + break; } } diff --git a/applications/mne_analyze/plugins/view3d/view3d.h b/applications/mne_analyze/plugins/view3d/view3d.h index 56597266c0c..3aea03af893 100644 --- a/applications/mne_analyze/plugins/view3d/view3d.h +++ b/applications/mne_analyze/plugins/view3d/view3d.h @@ -62,6 +62,7 @@ namespace ANSHAREDLIB { class BemDataModel; class AbstractModel; class DipoleFitModel; + class SourceEstimateModel; } namespace DISP3DLIB { @@ -70,6 +71,7 @@ namespace DISP3DLIB { class BemTreeItem; class DigitizerSetTreeItem; class EcdDataTreeItem; + class MneDataTreeItem; } namespace DISPLIB { @@ -201,6 +203,9 @@ class VIEW3DSHARED_EXPORT View3D : public ANSHAREDLIB::AbstractPlugin */ void newDipoleFit(const INVERSELIB::ECDSet& ecdSet); + //========================================================================================================= + void newSourceLoc(QSharedPointer pModel); + //========================================================================================================= /** * Loads new model when current loaded model is changed @@ -226,6 +231,8 @@ class VIEW3DSHARED_EXPORT View3D : public ANSHAREDLIB::AbstractPlugin DISP3DLIB::DigitizerSetTreeItem* m_pDigitizerCoreg; /**< The 3D item pointing to the tracked digitizers. */ DISP3DLIB::DigitizerSetTreeItem* m_pMriFidCoreg; /**< The 3D item pointing to the mri fiducials. */ DISP3DLIB::EcdDataTreeItem* m_pDipoleFit; /**< The 3D item pointing to the dipole fit. */ + DISP3DLIB::MneDataTreeItem* m_pRtMNEItem; /**< The Disp3D real time items. */ + DISP3DLIB::View3D* m_pView3D; /**< The Disp3D view. */ DISPLIB::Control3DView* m_pControl3DView; /**< The 3D Control view. */