From 97ae682c3b49280c76a86986e0e6697f5dbe9353 Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 1 Mar 2023 15:34:17 -0500 Subject: [PATCH 1/4] Add signal gen plugin --- .../mne_scan/plugins/CMakeLists.txt | 1 + .../mne_scan/plugins/signalgen/CMakeLists.txt | 77 +++++ .../signalgen/FormFiles/fiffsimulatorsetup.ui | 289 ++++++++++++++++++ .../FormFiles/fiffsimulatorsetupwidget.cpp | 229 ++++++++++++++ .../FormFiles/fiffsimulatorsetupwidget.h | 130 ++++++++ .../mne_scan/plugins/signalgen/signalgen.cpp | 239 +++++++++++++++ .../mne_scan/plugins/signalgen/signalgen.h | 188 ++++++++++++ .../mne_scan/plugins/signalgen/signalgen.json | 0 .../plugins/signalgen/signalgen_global.cpp | 54 ++++ .../plugins/signalgen/signalgen_global.h | 82 +++++ .../signalgen/signalgensetupwidget.cpp | 14 + .../plugins/signalgen/signalgensetupwidget.h | 22 ++ .../plugins/signalgen/signalgensetupwidget.ui | 32 ++ 13 files changed, 1357 insertions(+) create mode 100644 src/applications/mne_scan/plugins/signalgen/CMakeLists.txt create mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui create mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp create mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgen.cpp create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgen.h create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgen.json create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgen_global.cpp create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgen_global.h create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h create mode 100644 src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui diff --git a/src/applications/mne_scan/plugins/CMakeLists.txt b/src/applications/mne_scan/plugins/CMakeLists.txt index 775c74dbf69..6b4b0745f9c 100644 --- a/src/applications/mne_scan/plugins/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(fiffsimulator) add_subdirectory(ftbuffer) add_subdirectory(babymeg) add_subdirectory(natus) +add_subdirectory(signalgen) # Algorithm Plugin add_subdirectory(rtcmne) diff --git a/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt new file mode 100644 index 00000000000..05596bb7b81 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.14) +project(scan_signalgen LANGUAGES CXX) + +#Handle qt uic, moc, rrc automatically +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Network Concurrent) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Network Concurrent) + +set(SOURCES + signalgen_global.cpp + signalgen.cpp +) + +set(HEADERS + signalgen_global.h + signalgen.h +) + +set(RESOURCES +) + +set(FILE_TO_UPDATE signalgen_global.cpp) + +set(SOURCE_PATHS ${SOURCES}) +list(TRANSFORM SOURCE_PATHS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") +set_source_files_properties(${FILE_TO_UPDATE} PROPERTIES OBJECT_DEPENDS "${SOURCE_PATHS}") + +add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${RESOURCES}) + +set(FFTW_LIBS "") + +if(USE_FFTW) + if (WIN32) + set(FFTW_LIBS + ${FFTW_DIR_LIBS}/libfftw3-3.dll + ${FFTW_DIR_LIBS}/libfftw3f-3.dll + ${FFTW_DIR_LIBS}/libfftwf3l-3.dll + ) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}) + elseif(UNIX AND NOT APPLE) + set(FFTW_LIBS ${FFTW_DIR_LIBS}/lib/libfftw3.so) + target_include_directories(${PROJECT_NAME} PRIVATE ${FFTW_DIR_INCLUDE}/api) + endif() +endif() + +target_include_directories(${PROJECT_NAME} PUBLIC ../) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Network + Qt${QT_VERSION_MAJOR}::Concurrent + eigen + mne_disp + mne_utils + mne_fiff + mne_fs + mne_mne + mne_fwd + mne_inverse + mne_rtprocessing + mne_connectivity + mne_events + mne_communication + scDisp + scShared + scMeas + ${FFTW_LIBS}) + +target_compile_definitions(${PROJECT_NAME} PRIVATE SCAN_signalgen_PLUGIN MNE_GIT_HASH_SHORT="${MNE_GIT_HASH_SHORT}" MNE_GIT_HASH_LONG="${MNE_GIT_HASH_LONG}") + +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_NAME} PRIVATE STATICBUILD QT_STATICPLUGIN) +endif() diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui new file mode 100644 index 00000000000..bfd58a3c543 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui @@ -0,0 +1,289 @@ + + + SignalGenSetupWidgetClass + + + + 0 + 0 + 765 + 640 + + + + RTServerSetupClass + + + + + + + 75 + true + + + + Fiff Simulator Plugin + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + 0 + 0 + + + + 1 + + + + Preferences + + + + + + 3 + + + + + Properties + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + Sampling Rate [sps]: + + + + + + + QFrame::StyledPanel + + + + + + + + + + + + + + + + + Buffer [samples]: + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Description:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This plugin connects to and receives data from the mne_rt_server. It parses the incoming stream and provides it to subsequent connected plugins. For inspection the data stream is visualized in real-time.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to setup this plugin?</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1. Configure bin\resources\mne_rt_server_plugins\FiffSimulation.cfg to point to the file which you want to stream.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2. Start the mne_rt_server.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3. Use the Connection tab in this plugin to check the connection state.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4. Set the desired buffer block size in samples.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to control this plugin during the measurement?</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">All control elements can be found in the QuickControlView's SignalGen tab.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Input data type:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">None</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Output data type:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This plugin streams raw data blocks to subsequent connected plugins.</p></body></html> + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 500 + 20 + + + + + + + + + + + Connection + + + + + + + + Log + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + + + + + + + + 250 + 16777215 + + + + Send Command Line Instruction + + + + + + Instruction: + + + + + + + + + + Send + + + + + + + + + + + 250 + 16777215 + + + + Host (mne_rt_server) Information + + + + + + Connect + + + + + + + Status: + + + + + + + IP Address: + + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + not Connected + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp new file mode 100644 index 00000000000..602871c3d40 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp @@ -0,0 +1,229 @@ +//============================================================================================================= +/** + * @file signalgensetupwidget.cpp + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2013 + * + * @section LICENSE + * + * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Definition of the RTServerSetupWidget class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "signalgensetupwidget.h" + +#include "../signalgen.h" + +#include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include +#include + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace SIGNALGENPLUGIN; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +SignalGenSetupWidget::SignalGenSetupWidget(SignalGen* p_pSignalGen, QWidget* parent) +: QWidget(parent) +, m_pSignalGen(p_pSignalGen) +, m_bIsInit(false) +{ + ui.setupUi(this); + + //rt server connection + this->ui.m_qLineEdit_Ip->setText(m_pSignalGen->m_sSignalGenIP); + + connect(ui.m_qPushButton_Connect, &QPushButton::released, + this, &SignalGenSetupWidget::pressedConnect); + + connect(m_pSignalGen, &SignalGen::cmdConnectionChanged, + this, &SignalGenSetupWidget::cmdConnectionChanged); + + //rt server fiffInfo received + connect(m_pSignalGen, &SignalGen::fiffInfoAvailable, + this, &SignalGenSetupWidget::fiffInfoReceived); + + //Buffer + connect(ui.m_qLineEdit_BufferSize, &QLineEdit::textChanged, + this, &SignalGenSetupWidget::bufferSizeEdited); + + //CLI + connect(ui.m_qPushButton_SendCLI, &QPushButton::released, + this, &SignalGenSetupWidget::pressedSendCLI); + + this->init(); +} + +//============================================================================================================= + +SignalGenSetupWidget::~SignalGenSetupWidget() +{ +} + +//============================================================================================================= + +void SignalGenSetupWidget::init() +{ + cmdConnectionChanged(m_pSignalGen->m_bCmdClientIsConnected); +} + +//============================================================================================================= + +void SignalGenSetupWidget::bufferSizeEdited() +{ + bool t_bSuccess = false; + qint32 t_iBufferSize = ui.m_qLineEdit_BufferSize->text().toInt(&t_bSuccess); + + if(t_bSuccess && t_iBufferSize > 0) + m_pSignalGen->m_iBufferSize = t_iBufferSize; + else + ui.m_qLineEdit_BufferSize->setText(QString("%1").arg(m_pSignalGen->m_iBufferSize)); +} + +//============================================================================================================= + +void SignalGenSetupWidget::pressedConnect() +{ + if(m_pSignalGen->m_bCmdClientIsConnected) + m_pSignalGen->disconnectCmdClient(); + else + { + m_pSignalGen->m_sSignalGenIP = this->ui.m_qLineEdit_Ip->text(); + m_pSignalGen->connectCmdClient(); + } +} + +//============================================================================================================= + +void SignalGenSetupWidget::pressedSendCLI() +{ + if(m_pSignalGen->m_bCmdClientIsConnected) + { + this->printToLog(this->ui.m_qLineEdit_SendCLI->text()); + QString t_sReply = m_pSignalGen->m_pRtCmdClient->sendCLICommand(this->ui.m_qLineEdit_SendCLI->text()); + this->printToLog(t_sReply); + } +} + +//============================================================================================================= + +void SignalGenSetupWidget::printToLog(QString logMsg) +{ + ui.m_qTextBrowser_ServerMessage->insertPlainText(logMsg+"\n"); + //scroll down to the newest entry + QTextCursor c = ui.m_qTextBrowser_ServerMessage->textCursor(); + c.movePosition(QTextCursor::End); + ui.m_qTextBrowser_ServerMessage->setTextCursor(c); +} + +//============================================================================================================= + +void SignalGenSetupWidget::cmdConnectionChanged(bool p_bConnectionStatus) +{ + m_bIsInit = false; + + if(p_bConnectionStatus) + { + // + // set frequency txt + // + if(m_pSignalGen->m_pFiffInfo) + this->ui.m_qLabel_sps->setText(QString("%1").arg(m_pSignalGen->m_pFiffInfo->sfreq)); + + // + // set buffer size txt + // + this->ui.m_qLineEdit_BufferSize->setText(QString("%1").arg(m_pSignalGen->m_iBufferSize)); + + // + // set connectors + // +// QMap::ConstIterator it = m_pSignalGen->m_qMapConnectors.begin(); +// qint32 idx = 0; + +// for(; it != m_pSignalGen->m_qMapConnectors.end(); ++it) +// { +// if(this->ui.m_qComboBox_Connector->findData(it.key()) == -1) +// { +// this->ui.m_qComboBox_Connector->insertItem(idx, it.value(), it.key()); +// ++idx; +// } +// else +// idx = this->ui.m_qComboBox_Connector->findData(it.key()) + 1; +// } +// this->ui.m_qComboBox_Connector->setCurrentIndex(this->ui.m_qComboBox_Connector->findData(m_pSignalGen->m_iActiveConnectorId)); + + //UI enables/disables + this->ui.m_qLabel_ConnectionStatus->setText(QString("Connected")); + this->ui.m_qLineEdit_Ip->setEnabled(false); + this->ui.m_qPushButton_Connect->setText(QString("Disconnect")); + this->ui.m_qLineEdit_SendCLI->setEnabled(true); + this->ui.m_qPushButton_SendCLI->setEnabled(true); + + m_bIsInit = true; + } + else + { + //clear connectors --> ToDO create a clear function + m_pSignalGen->m_qMapConnectors.clear(); +// this->ui.m_qComboBox_Connector->clear(); + m_pSignalGen->m_iBufferSize = -1; + + //UI enables/disables + this->ui.m_qLabel_ConnectionStatus->setText(QString("Not connected")); + this->ui.m_qLineEdit_Ip->setEnabled(true); + this->ui.m_qPushButton_Connect->setText(QString("Connect")); + this->ui.m_qLineEdit_SendCLI->setEnabled(false); + this->ui.m_qPushButton_SendCLI->setEnabled(false); + + this->ui.m_qLineEdit_BufferSize->setText(QString("")); + + } +} + +//============================================================================================================= + +void SignalGenSetupWidget::fiffInfoReceived() +{ + if(m_pSignalGen->m_pFiffInfo) + this->ui.m_qLabel_sps->setText(QString("%1").arg(m_pSignalGen->m_pFiffInfo->sfreq)); +} diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h new file mode 100644 index 00000000000..c6907bedf21 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h @@ -0,0 +1,130 @@ +//============================================================================================================= +/** + * @file signalgensetupwidget.h + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2013 + * + * @section LICENSE + * + * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the declaration of the SignalGenSetupWidget class. + * + */ + +#ifndef SIGNALGENSETUPWIDGET_H +#define SIGNALGENSETUPWIDGET_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "ui_signalgensetup.h" + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +//============================================================================================================= +// DEFINE NAMESPACE SIGNALGENPLUGIN +//============================================================================================================= + +namespace SIGNALGENPLUGIN +{ + +//============================================================================================================= +// SIGNALGENPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +class SignalGen; + +//============================================================================================================= +/** + * DECLARE CLASS SignalGenSetupWidget + * + * @brief The SignalGenSetupWidget class provides the Fiff configuration window. + */ +class SignalGenSetupWidget : public QWidget +{ + Q_OBJECT + +public: + + //========================================================================================================= + /** + * Constructs a SignalGenSetupWidget which is a child of parent. + * + * @param[in] p_pSignalGen a pointer to the corresponding SignalGen. + * @param[in] parent pointer to parent widget; If parent is 0, the new SignalGenSetupWidget becomes a window. If parent is another widget, SignalGenSetupWidget becomes a child window inside parent. SignalGenSetupWidget is deleted when its parent is deleted. + */ + SignalGenSetupWidget(SignalGen* p_pSignalGen, QWidget *parent = 0); + + //========================================================================================================= + /** + * Destroys the SignalGenSetupWidget. + * All SignalGenSetupWidget's children are deleted first. The application exits if SignalGenSetupWidget is the main widget. + */ + ~SignalGenSetupWidget(); + + //========================================================================================================= + /** + * Inits the setup widget + */ + void init(); + +//slots + void bufferSizeEdited(); /**< Buffer size edited and set new buffer size.*/ + + void printToLog(QString message); /**< Implements printing messages to rtproc log.*/ + + void pressedConnect(); /**< Triggers a connection trial to rt_server.*/ + + void pressedSendCLI(); /**< Triggers a send request of a cli command.*/ + + void fiffInfoReceived(); /**< Triggered when new fiff info is recieved by producer and stored intor rt_server. */ + +private: + //========================================================================================================= + /** + * Set command connection status + * + * @param[in] p_bConnectionStatus the connection status. + */ + void cmdConnectionChanged(bool p_bConnectionStatus); + + SignalGen* m_pSignalGen; /**< a pointer to corresponding mne rt client.*/ + + Ui::SignalGenSetupWidgetClass ui; /**< the user interface for the MneRtClientSetupWidget.*/ + + bool m_bIsInit; /**< false when gui is not initialized jet. Prevents gui from already interacting when not initialized. */ +}; +} // NAMESPACE + +#endif // SIGNALGENSETUPWIDGET_H diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.cpp b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp new file mode 100644 index 00000000000..b92b8bbb963 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp @@ -0,0 +1,239 @@ +//============================================================================================================= +/** + * @file signalgen.cpp + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2013 + * + * @section LICENSE + * + * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Definition of the SignalGen class. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "signalgen.h" +#include +#include +#include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include +#include +#include +#include + +#include + +//============================================================================================================= +// USED NAMESPACES +//============================================================================================================= + +using namespace SIGNALGENPLUGIN; +using namespace UTILSLIB; +using namespace SCSHAREDLIB; +using namespace UTILSLIB; +using namespace SCMEASLIB; +using namespace COMMUNICATIONLIB; +using namespace Eigen; + +//============================================================================================================= +// DEFINE MEMBER METHODS +//============================================================================================================= + +SignalGen::SignalGen() +: numChannels(32) +, samplesPerBlock(200) +, sample_freq(1000.f) +, m_mode(Mode::Noise) +{ +} + +//============================================================================================================= + +SignalGen::~SignalGen() +{ + if(this->isRunning()) { + stop(); + } +} + +//============================================================================================================= + +void SignalGen::clear() +{ + QMutexLocker locker(&m_qMutex); + m_pFiffInfo.reset(); +} + +//============================================================================================================= + +QSharedPointer SignalGen::clone() const +{ + QSharedPointer pSignalGenClone(new SignalGen()); + return std::move(pSignalGenClone); +} + +//============================================================================================================= + +void SignalGen::init() +{ + m_pRTMSA_SignalGen = PluginOutputData::create(this, "SignalGen", "Signal Generator Output"); + m_pRTMSA_SignalGen->measurementData()->setName(this->getName());//Provide name to auto store widget settings + m_outputConnectors.append(m_pRTMSA_SignalGen); + + //Try to connect the cmd client on start up using localhost connection + // this->connectCmdClient(); +} + +//============================================================================================================= + +void SignalGen::unload() +{ + qDebug() << "SignalGen::unload()"; +} + +//============================================================================================================= + +bool SignalGen::start() +{ + initOutput(); + QThread::start(); + + return true; +} + +//============================================================================================================= + +bool SignalGen::stop() +{ + // Stop this (consumer) thread first + requestInterruption(); + wait(500); + + m_pRTMSA_SignalGen->measurementData()->clear(); + + return true; +} + +//============================================================================================================= + +AbstractPlugin::PluginType SignalGen::getType() const +{ + return _ISensor; +} + +//============================================================================================================= + +QString SignalGen::getName() const +{ + return "Signal Generator"; +} + +//============================================================================================================= + +QWidget* SignalGen::setupWidget() +{ + //widget is later distroyed by CentralWidget - so it has to be created everytime new + + return new QLabel("Hello"); +// QWidget * pWidget(new SignalGenSetupWidget(this)); +// return pWidget; +} + +//============================================================================================================= + +void SignalGen::run() +{ + MatrixXd matValue; + matValue.resize(numChannels, samplesPerBlock); + + int sleep_time = 1000 * samplesPerBlock / sample_freq; + + while(!isInterruptionRequested()) { + switch(m_mode){ + case Mode::Zero:{ + matValue = MatrixXd::Zero(numChannels, samplesPerBlock); + break; + } + case Mode::Sine: { + break; + } + case Mode::Noise:{ + matValue = MatrixXd::Random(numChannels, samplesPerBlock); + matValue *= 1e-12; + break; + } + } + m_pRTMSA_SignalGen->measurementData()->setValue(matValue); + msleep(sleep_time); + } +} + +//============================================================================================================= + +void SignalGen::initOutput() +{ + QMutexLocker locker (&m_qMutex); + m_pFiffInfo = QSharedPointer(new FIFFLIB::FiffInfo()); + + m_pFiffInfo->sfreq = sample_freq; + m_pFiffInfo->nchan = numChannels; + + m_pFiffInfo->chs.clear(); + + for (int i = 0; i< m_pFiffInfo->nchan; i++){ + FIFFLIB::FiffChInfo channel; + + channel.ch_name = "Ch. " + QString::number(i); + channel.kind = FIFFV_MEG_CH; + channel.unit = FIFF_UNIT_T; + channel.unit_mul = FIFF_UNITM_NONE; + channel.chpos.coil_type = FIFFV_COIL_NONE; + + m_pFiffInfo->chs.append(channel); + + m_pFiffInfo->ch_names.append("Ch. " + QString::number(i)); + } + + m_pRTMSA_SignalGen->measurementData()->initFromFiffInfo(m_pFiffInfo); + m_pRTMSA_SignalGen->measurementData()->setMultiArraySize(1); + m_pRTMSA_SignalGen->measurementData()->setVisibility(true); +} + +//============================================================================================================= + +QString SignalGen::getBuildInfo() +{ + return QString(SIGNALGENPLUGIN::buildDateTime()) + QString(" - ") + QString(SIGNALGENPLUGIN::buildHash()); +} diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.h b/src/applications/mne_scan/plugins/signalgen/signalgen.h new file mode 100644 index 00000000000..a269d849dfc --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgen.h @@ -0,0 +1,188 @@ +//============================================================================================================= +/** + * @file signalgen.h + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2013 + * + * @section LICENSE + * + * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the declaration of the SignalGen class. + * + */ + +#ifndef SIGNALGEN_H +#define SIGNALGEN_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "signalgen_global.h" + +#include +#include +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include +#include +#include + +//============================================================================================================= +// EIGEN INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// FORWARD DECLARATIONS +//============================================================================================================= + +namespace SCMEASLIB { + class RealTimeMultiSampleArray; +} + +namespace FIFFLIB { + class FiffInfo; +} + +//============================================================================================================= +// DEFINE NAMESPACE SIGNALGENPLUGIN +//============================================================================================================= + +namespace SIGNALGENPLUGIN +{ + +//============================================================================================================= +// SIGNALGENPLUGIN FORWARD DECLARATIONS +//============================================================================================================= + +class SignalGenProducer; + +//============================================================================================================= +/** + * DECLARE CLASS SignalGen + * + * @brief The SignalGen class provides a stream of data. + */ +class SIGNALGENSHARED_EXPORT SignalGen : public SCSHAREDLIB::AbstractSensor +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "scsharedlib/1.0" FILE "signalgen.json") //New Qt5 Plugin system replaces Q_EXPORT_PLUGIN2 macro + // Use the Q_INTERFACES() macro to tell Qt's meta-object system about the interfaces + Q_INTERFACES(SCSHAREDLIB::AbstractSensor) + + friend class SignalGenProducer; + friend class SignalGenSetupWidget; + +public: + + enum Mode{ + Zero, + Sine, + Noise + }; + + //========================================================================================================= + /** + * Constructs a SignalGen. + */ + SignalGen(); + + //========================================================================================================= + /** + * Destroys the SignalGen. + */ + virtual ~SignalGen(); + + //========================================================================================================= + /** + * Clears the rt server + */ + void clear(); + + //========================================================================================================= + /** + * Clone the plugin + */ + virtual QSharedPointer clone() const; + + //========================================================================================================= + /** + * Initialise the SignalGen. + */ + virtual void init(); + + //========================================================================================================= + /** + * Is called when plugin is detached of the stage. Can be used to safe settings. + */ + virtual void unload(); + + virtual bool start(); + virtual bool stop(); + + virtual AbstractPlugin::PluginType getType() const; + virtual QString getName() const; + virtual QString getBuildInfo(); + + //========================================================================================================= + /** + * Creates the setup widget. + * + * @return Returns the setup widget. + */ + virtual QWidget* setupWidget(); + +protected: + //========================================================================================================= + /** + * Initialises the output. + */ + void initOutput(); + + virtual void run(); + + SCSHAREDLIB::PluginOutputData::SPtr m_pRTMSA_SignalGen; /**< The RealTimeMultiSampleArray to provide the rt_server Channels.*/ + + QSharedPointer m_pFiffInfo; /**< Fiff measurement info.*/ + + QMutex m_qMutex; /**< The mutex to ensure thread safety.*/ + + int numChannels; + int samplesPerBlock; + + float sample_freq; + + Mode m_mode; + +}; +} // NAMESPACE + +#endif // SIGNALGEN_H diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.json b/src/applications/mne_scan/plugins/signalgen/signalgen.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen_global.cpp b/src/applications/mne_scan/plugins/signalgen/signalgen_global.cpp new file mode 100644 index 00000000000..c3f256cab6b --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgen_global.cpp @@ -0,0 +1,54 @@ +//============================================================================================================= +/** + * @file signalgen_global.cpp + * @author Juan G Prieto ; + * Gabriel B Motta ; + * @since 0.1.9 + * @date September, 2021 + * + * @section LICENSE + * + * Copyright (C) 2021, Juan G Prieto, Gabriel B Motta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief signalgen plugin global definitions. + * + */ + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include "signalgen_global.h" + +//============================================================================================================= +// DEFINE METHODS +//============================================================================================================= + +const char* SIGNALGENPLUGIN::buildDateTime(){ return UTILSLIB::dateTimeNow();} + +//============================================================================================================= + +const char* SIGNALGENPLUGIN::buildHash(){ return UTILSLIB::gitHash();} + +//============================================================================================================= + +const char* SIGNALGENPLUGIN::buildHashLong(){ return UTILSLIB::gitHashLong();} diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen_global.h b/src/applications/mne_scan/plugins/signalgen/signalgen_global.h new file mode 100644 index 00000000000..88da0f1bb8a --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgen_global.h @@ -0,0 +1,82 @@ +//============================================================================================================= +/** + * @file signalgen_global.h + * @author Christoph Dinh ; + * Lorenz Esch + * @since 0.1.0 + * @date February, 2013 + * + * @section LICENSE + * + * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that + * the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of MNE-CPP authors nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * @brief Contains the SignalGen library export/import macros. + * + */ + +#ifndef SIGNALGEN_GLOBAL_H +#define SIGNALGEN_GLOBAL_H + +//============================================================================================================= +// INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// QT INCLUDES +//============================================================================================================= + +#include + +//============================================================================================================= +// PREPROCESSOR DEFINES +//============================================================================================================= + +#if defined(SCAN_SIGNALGEN_PLUGIN) +# define SIGNALGENSHARED_EXPORT Q_DECL_EXPORT /**< Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. */ +#else +# define SIGNALGENSHARED_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 SIGNALGENPLUGIN{ + +//============================================================================================================= +/** + * Returns build date and time. + */ +SIGNALGENSHARED_EXPORT const char* buildDateTime(); + +//============================================================================================================= +/** + * Returns abbreviated build git hash. + */ +SIGNALGENSHARED_EXPORT const char* buildHash(); + +//============================================================================================================= +/** + * Returns full build git hash. + */ +SIGNALGENSHARED_EXPORT const char* buildHashLong(); +} + +#endif // SIGNALGEN_GLOBAL_H diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp new file mode 100644 index 00000000000..ac71a83fdce --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp @@ -0,0 +1,14 @@ +#include "signalgensetupwidget.h" +#include "ui_signalgensetupwidget.h" + +SignalGenSetupWidget::SignalGenSetupWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::SignalGenSetupWidget) +{ + ui->setupUi(this); +} + +SignalGenSetupWidget::~SignalGenSetupWidget() +{ + delete ui; +} diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h new file mode 100644 index 00000000000..b43b79a856d --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h @@ -0,0 +1,22 @@ +#ifndef SIGNALGENSETUPWIDGET_H +#define SIGNALGENSETUPWIDGET_H + +#include + +namespace Ui { +class SignalGenSetupWidget; +} + +class SignalGenSetupWidget : public QWidget +{ + Q_OBJECT + +public: + explicit SignalGenSetupWidget(QWidget *parent = nullptr); + ~SignalGenSetupWidget(); + +private: + Ui::SignalGenSetupWidget *ui; +}; + +#endif // SIGNALGENSETUPWIDGET_H diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui new file mode 100644 index 00000000000..db31e4fb664 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui @@ -0,0 +1,32 @@ + + + SignalGenSetupWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 100 + 40 + 52 + 14 + + + + TextLabel + + + + + + From 96b64639fe96249499b00c8eccb58e2de684f26f Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Wed, 1 Mar 2023 15:51:53 -0500 Subject: [PATCH 2/4] add gui --- .../mne_scan/plugins/signalgen/CMakeLists.txt | 2 + .../signalgen/signalgensetupwidget.cpp | 15 +++ .../plugins/signalgen/signalgensetupwidget.h | 13 +++ .../plugins/signalgen/signalgensetupwidget.ui | 103 +++++++++++++++--- 4 files changed, 120 insertions(+), 13 deletions(-) diff --git a/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt index 05596bb7b81..0f8d276a856 100644 --- a/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt @@ -11,11 +11,13 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Network Conc set(SOURCES signalgen_global.cpp + signalgensetupwidget.cpp signalgen.cpp ) set(HEADERS signalgen_global.h + signalgensetupwidget.h signalgen.h ) diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp index ac71a83fdce..aaa8a43c03c 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp @@ -12,3 +12,18 @@ SignalGenSetupWidget::~SignalGenSetupWidget() { delete ui; } + +void SignalGenSetupWidget::setConfig(const Config& config) +{ + +} + +void SignalGenSetupWidget::numChannelsChanged(int numChannels) +{ + +} + +void SignalGenSetupWidget::sampleFreqChanged(int sampleFreq) +{ + +} diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h index b43b79a856d..61fe7f3f131 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h @@ -12,9 +12,22 @@ class SignalGenSetupWidget : public QWidget Q_OBJECT public: + struct Config{ + int minChannels; + int maxChannels; + int defChannels; + int minSampFreq; + int maxSampFreq; + int defSampFreq; + }; + explicit SignalGenSetupWidget(QWidget *parent = nullptr); ~SignalGenSetupWidget(); + void setConfig(const Config& config); +signals: + void numChannelsChanged(int numChannels); + void sampleFreqChanged(int sampleFreq); private: Ui::SignalGenSetupWidget *ui; }; diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui index db31e4fb664..402521effb5 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui +++ b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui @@ -13,19 +13,96 @@ Form - - - - 100 - 40 - 52 - 14 - - - - TextLabel - - + + + + + + 75 + true + + + + Signal Generator Configuration + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Blocks per second + + + + + + + 1 + + + 999 + + + 32 + + + + + + + 1 + + + 9999 + + + 1000 + + + + + + + 1 + + + 100 + + + 5 + + + + + + + Number of Channels + + + + + + + Sample Frequency + + + + + + + From 890be353c451d44ec4562b434593575a03feaa3c Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Fri, 3 Mar 2023 13:24:39 -0500 Subject: [PATCH 3/4] First working pass of signal gen --- .../mne_scan/plugins/signalgen/CMakeLists.txt | 4 +- .../signalgen/FormFiles/fiffsimulatorsetup.ui | 289 ------------------ .../FormFiles/fiffsimulatorsetupwidget.cpp | 229 -------------- .../FormFiles/fiffsimulatorsetupwidget.h | 130 -------- .../FormFiles/signalgensetupwidget.cpp | 32 ++ .../{ => FormFiles}/signalgensetupwidget.h | 0 .../{ => FormFiles}/signalgensetupwidget.ui | 27 +- .../mne_scan/plugins/signalgen/signalgen.cpp | 16 +- .../signalgen/signalgensetupwidget.cpp | 29 -- 9 files changed, 70 insertions(+), 686 deletions(-) delete mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui delete mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp delete mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h create mode 100644 src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp rename src/applications/mne_scan/plugins/signalgen/{ => FormFiles}/signalgensetupwidget.h (100%) rename src/applications/mne_scan/plugins/signalgen/{ => FormFiles}/signalgensetupwidget.ui (78%) delete mode 100644 src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp diff --git a/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt index 0f8d276a856..145b3bc1719 100644 --- a/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt +++ b/src/applications/mne_scan/plugins/signalgen/CMakeLists.txt @@ -11,13 +11,13 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Network Conc set(SOURCES signalgen_global.cpp - signalgensetupwidget.cpp + FormFiles/signalgensetupwidget.cpp signalgen.cpp ) set(HEADERS signalgen_global.h - signalgensetupwidget.h + FormFiles/signalgensetupwidget.h signalgen.h ) diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui deleted file mode 100644 index bfd58a3c543..00000000000 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetup.ui +++ /dev/null @@ -1,289 +0,0 @@ - - - SignalGenSetupWidgetClass - - - - 0 - 0 - 765 - 640 - - - - RTServerSetupClass - - - - - - - 75 - true - - - - Fiff Simulator Plugin - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - 0 - 0 - - - - 1 - - - - Preferences - - - - - - 3 - - - - - Properties - - - - - - - 0 - 0 - - - - Qt::LeftToRight - - - Sampling Rate [sps]: - - - - - - - QFrame::StyledPanel - - - - - - - - - - - - - - - - - Buffer [samples]: - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Description:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This plugin connects to and receives data from the mne_rt_server. It parses the incoming stream and provides it to subsequent connected plugins. For inspection the data stream is visualized in real-time.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to setup this plugin?</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1. Configure bin\resources\mne_rt_server_plugins\FiffSimulation.cfg to point to the file which you want to stream.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2. Start the mne_rt_server.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3. Use the Connection tab in this plugin to check the connection state.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4. Set the desired buffer block size in samples.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">How to control this plugin during the measurement?</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">All control elements can be found in the QuickControlView's SignalGen tab.</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Input data type:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">None</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Output data type:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This plugin streams raw data blocks to subsequent connected plugins.</p></body></html> - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 500 - 20 - - - - - - - - - - - Connection - - - - - - - - Log - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> - - - - - - - - - - - - - 250 - 16777215 - - - - Send Command Line Instruction - - - - - - Instruction: - - - - - - - - - - Send - - - - - - - - - - - 250 - 16777215 - - - - Host (mne_rt_server) Information - - - - - - Connect - - - - - - - Status: - - - - - - - IP Address: - - - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - not Connected - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp deleted file mode 100644 index 602871c3d40..00000000000 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//============================================================================================================= -/** - * @file signalgensetupwidget.cpp - * @author Christoph Dinh ; - * Lorenz Esch - * @since 0.1.0 - * @date February, 2013 - * - * @section LICENSE - * - * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that - * the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of MNE-CPP authors nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @brief Definition of the RTServerSetupWidget class. - * - */ - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "signalgensetupwidget.h" - -#include "../signalgen.h" - -#include -#include - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -#include -#include -#include - -//============================================================================================================= -// USED NAMESPACES -//============================================================================================================= - -using namespace SIGNALGENPLUGIN; - -//============================================================================================================= -// DEFINE MEMBER METHODS -//============================================================================================================= - -SignalGenSetupWidget::SignalGenSetupWidget(SignalGen* p_pSignalGen, QWidget* parent) -: QWidget(parent) -, m_pSignalGen(p_pSignalGen) -, m_bIsInit(false) -{ - ui.setupUi(this); - - //rt server connection - this->ui.m_qLineEdit_Ip->setText(m_pSignalGen->m_sSignalGenIP); - - connect(ui.m_qPushButton_Connect, &QPushButton::released, - this, &SignalGenSetupWidget::pressedConnect); - - connect(m_pSignalGen, &SignalGen::cmdConnectionChanged, - this, &SignalGenSetupWidget::cmdConnectionChanged); - - //rt server fiffInfo received - connect(m_pSignalGen, &SignalGen::fiffInfoAvailable, - this, &SignalGenSetupWidget::fiffInfoReceived); - - //Buffer - connect(ui.m_qLineEdit_BufferSize, &QLineEdit::textChanged, - this, &SignalGenSetupWidget::bufferSizeEdited); - - //CLI - connect(ui.m_qPushButton_SendCLI, &QPushButton::released, - this, &SignalGenSetupWidget::pressedSendCLI); - - this->init(); -} - -//============================================================================================================= - -SignalGenSetupWidget::~SignalGenSetupWidget() -{ -} - -//============================================================================================================= - -void SignalGenSetupWidget::init() -{ - cmdConnectionChanged(m_pSignalGen->m_bCmdClientIsConnected); -} - -//============================================================================================================= - -void SignalGenSetupWidget::bufferSizeEdited() -{ - bool t_bSuccess = false; - qint32 t_iBufferSize = ui.m_qLineEdit_BufferSize->text().toInt(&t_bSuccess); - - if(t_bSuccess && t_iBufferSize > 0) - m_pSignalGen->m_iBufferSize = t_iBufferSize; - else - ui.m_qLineEdit_BufferSize->setText(QString("%1").arg(m_pSignalGen->m_iBufferSize)); -} - -//============================================================================================================= - -void SignalGenSetupWidget::pressedConnect() -{ - if(m_pSignalGen->m_bCmdClientIsConnected) - m_pSignalGen->disconnectCmdClient(); - else - { - m_pSignalGen->m_sSignalGenIP = this->ui.m_qLineEdit_Ip->text(); - m_pSignalGen->connectCmdClient(); - } -} - -//============================================================================================================= - -void SignalGenSetupWidget::pressedSendCLI() -{ - if(m_pSignalGen->m_bCmdClientIsConnected) - { - this->printToLog(this->ui.m_qLineEdit_SendCLI->text()); - QString t_sReply = m_pSignalGen->m_pRtCmdClient->sendCLICommand(this->ui.m_qLineEdit_SendCLI->text()); - this->printToLog(t_sReply); - } -} - -//============================================================================================================= - -void SignalGenSetupWidget::printToLog(QString logMsg) -{ - ui.m_qTextBrowser_ServerMessage->insertPlainText(logMsg+"\n"); - //scroll down to the newest entry - QTextCursor c = ui.m_qTextBrowser_ServerMessage->textCursor(); - c.movePosition(QTextCursor::End); - ui.m_qTextBrowser_ServerMessage->setTextCursor(c); -} - -//============================================================================================================= - -void SignalGenSetupWidget::cmdConnectionChanged(bool p_bConnectionStatus) -{ - m_bIsInit = false; - - if(p_bConnectionStatus) - { - // - // set frequency txt - // - if(m_pSignalGen->m_pFiffInfo) - this->ui.m_qLabel_sps->setText(QString("%1").arg(m_pSignalGen->m_pFiffInfo->sfreq)); - - // - // set buffer size txt - // - this->ui.m_qLineEdit_BufferSize->setText(QString("%1").arg(m_pSignalGen->m_iBufferSize)); - - // - // set connectors - // -// QMap::ConstIterator it = m_pSignalGen->m_qMapConnectors.begin(); -// qint32 idx = 0; - -// for(; it != m_pSignalGen->m_qMapConnectors.end(); ++it) -// { -// if(this->ui.m_qComboBox_Connector->findData(it.key()) == -1) -// { -// this->ui.m_qComboBox_Connector->insertItem(idx, it.value(), it.key()); -// ++idx; -// } -// else -// idx = this->ui.m_qComboBox_Connector->findData(it.key()) + 1; -// } -// this->ui.m_qComboBox_Connector->setCurrentIndex(this->ui.m_qComboBox_Connector->findData(m_pSignalGen->m_iActiveConnectorId)); - - //UI enables/disables - this->ui.m_qLabel_ConnectionStatus->setText(QString("Connected")); - this->ui.m_qLineEdit_Ip->setEnabled(false); - this->ui.m_qPushButton_Connect->setText(QString("Disconnect")); - this->ui.m_qLineEdit_SendCLI->setEnabled(true); - this->ui.m_qPushButton_SendCLI->setEnabled(true); - - m_bIsInit = true; - } - else - { - //clear connectors --> ToDO create a clear function - m_pSignalGen->m_qMapConnectors.clear(); -// this->ui.m_qComboBox_Connector->clear(); - m_pSignalGen->m_iBufferSize = -1; - - //UI enables/disables - this->ui.m_qLabel_ConnectionStatus->setText(QString("Not connected")); - this->ui.m_qLineEdit_Ip->setEnabled(true); - this->ui.m_qPushButton_Connect->setText(QString("Connect")); - this->ui.m_qLineEdit_SendCLI->setEnabled(false); - this->ui.m_qPushButton_SendCLI->setEnabled(false); - - this->ui.m_qLineEdit_BufferSize->setText(QString("")); - - } -} - -//============================================================================================================= - -void SignalGenSetupWidget::fiffInfoReceived() -{ - if(m_pSignalGen->m_pFiffInfo) - this->ui.m_qLabel_sps->setText(QString("%1").arg(m_pSignalGen->m_pFiffInfo->sfreq)); -} diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h b/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h deleted file mode 100644 index c6907bedf21..00000000000 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/fiffsimulatorsetupwidget.h +++ /dev/null @@ -1,130 +0,0 @@ -//============================================================================================================= -/** - * @file signalgensetupwidget.h - * @author Christoph Dinh ; - * Lorenz Esch - * @since 0.1.0 - * @date February, 2013 - * - * @section LICENSE - * - * Copyright (C) 2013, Christoph Dinh, Lorenz Esch. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that - * the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of MNE-CPP authors nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * - * @brief Contains the declaration of the SignalGenSetupWidget class. - * - */ - -#ifndef SIGNALGENSETUPWIDGET_H -#define SIGNALGENSETUPWIDGET_H - -//============================================================================================================= -// INCLUDES -//============================================================================================================= - -#include "ui_signalgensetup.h" - -//============================================================================================================= -// QT INCLUDES -//============================================================================================================= - -#include - -//============================================================================================================= -// FORWARD DECLARATIONS -//============================================================================================================= - -//============================================================================================================= -// DEFINE NAMESPACE SIGNALGENPLUGIN -//============================================================================================================= - -namespace SIGNALGENPLUGIN -{ - -//============================================================================================================= -// SIGNALGENPLUGIN FORWARD DECLARATIONS -//============================================================================================================= - -class SignalGen; - -//============================================================================================================= -/** - * DECLARE CLASS SignalGenSetupWidget - * - * @brief The SignalGenSetupWidget class provides the Fiff configuration window. - */ -class SignalGenSetupWidget : public QWidget -{ - Q_OBJECT - -public: - - //========================================================================================================= - /** - * Constructs a SignalGenSetupWidget which is a child of parent. - * - * @param[in] p_pSignalGen a pointer to the corresponding SignalGen. - * @param[in] parent pointer to parent widget; If parent is 0, the new SignalGenSetupWidget becomes a window. If parent is another widget, SignalGenSetupWidget becomes a child window inside parent. SignalGenSetupWidget is deleted when its parent is deleted. - */ - SignalGenSetupWidget(SignalGen* p_pSignalGen, QWidget *parent = 0); - - //========================================================================================================= - /** - * Destroys the SignalGenSetupWidget. - * All SignalGenSetupWidget's children are deleted first. The application exits if SignalGenSetupWidget is the main widget. - */ - ~SignalGenSetupWidget(); - - //========================================================================================================= - /** - * Inits the setup widget - */ - void init(); - -//slots - void bufferSizeEdited(); /**< Buffer size edited and set new buffer size.*/ - - void printToLog(QString message); /**< Implements printing messages to rtproc log.*/ - - void pressedConnect(); /**< Triggers a connection trial to rt_server.*/ - - void pressedSendCLI(); /**< Triggers a send request of a cli command.*/ - - void fiffInfoReceived(); /**< Triggered when new fiff info is recieved by producer and stored intor rt_server. */ - -private: - //========================================================================================================= - /** - * Set command connection status - * - * @param[in] p_bConnectionStatus the connection status. - */ - void cmdConnectionChanged(bool p_bConnectionStatus); - - SignalGen* m_pSignalGen; /**< a pointer to corresponding mne rt client.*/ - - Ui::SignalGenSetupWidgetClass ui; /**< the user interface for the MneRtClientSetupWidget.*/ - - bool m_bIsInit; /**< false when gui is not initialized jet. Prevents gui from already interacting when not initialized. */ -}; -} // NAMESPACE - -#endif // SIGNALGENSETUPWIDGET_H diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp new file mode 100644 index 00000000000..9e76d015705 --- /dev/null +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp @@ -0,0 +1,32 @@ +#include "signalgensetupwidget.h" +#include "ui_signalgensetupwidget.h" + +SignalGenSetupWidget::SignalGenSetupWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::SignalGenSetupWidget) +{ + ui->setupUi(this); + + connect(ui->nchannels_spinBox, QOverload::of(&QSpinBox::valueChanged), + this, &SignalGenSetupWidget::numChannelsChanged, Qt::UniqueConnection); + + connect(ui->samplefreq_spinBox, QOverload::of(&QSpinBox::valueChanged), + this, &SignalGenSetupWidget::sampleFreqChanged, Qt::UniqueConnection); +} + +SignalGenSetupWidget::~SignalGenSetupWidget() +{ + delete ui; +} + +void SignalGenSetupWidget::setConfig(const Config& config) +{ + ui->nchannels_spinBox->setMaximum(config.maxChannels); + ui->nchannels_spinBox->setMinimum(config.minChannels); + ui->nchannels_spinBox->setValue(config.defChannels); + + ui->samplefreq_spinBox->setMaximum(config.maxSampFreq); + ui->samplefreq_spinBox->setMinimum(config.minSampFreq); + ui->samplefreq_spinBox->setValue(config.defSampFreq); +} + diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h similarity index 100% rename from src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.h rename to src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui similarity index 78% rename from src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui rename to src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui index 402521effb5..0a20e5cfc70 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.ui +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui @@ -16,6 +16,12 @@ + + + 0 + 0 + + 75 @@ -26,12 +32,18 @@ Signal Generator Configuration - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 0 + 0 + + QFrame::StyledPanel @@ -102,6 +114,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.cpp b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp index b92b8bbb963..1d0aeb9ba35 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgen.cpp +++ b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp @@ -38,6 +38,7 @@ //============================================================================================================= #include "signalgen.h" +#include "FormFiles/signalgensetupwidget.h" #include #include #include @@ -164,11 +165,14 @@ QString SignalGen::getName() const QWidget* SignalGen::setupWidget() { - //widget is later distroyed by CentralWidget - so it has to be created everytime new + auto* widget = new SignalGenSetupWidget(); - return new QLabel("Hello"); -// QWidget * pWidget(new SignalGenSetupWidget(this)); -// return pWidget; + connect(widget, &SignalGenSetupWidget::numChannelsChanged, [this](int nchans){this->numChannels = nchans;}); + connect(widget, &SignalGenSetupWidget::sampleFreqChanged, [this](int freq){this->sample_freq = freq;}); + + widget->setConfig({1, 999, numChannels, 100, 10000, static_cast(sample_freq)}); + + return widget; } //============================================================================================================= @@ -215,7 +219,7 @@ void SignalGen::initOutput() for (int i = 0; i< m_pFiffInfo->nchan; i++){ FIFFLIB::FiffChInfo channel; - channel.ch_name = "Ch. " + QString::number(i); + channel.ch_name = "Ch. " + QString::number(i + 1); channel.kind = FIFFV_MEG_CH; channel.unit = FIFF_UNIT_T; channel.unit_mul = FIFF_UNITM_NONE; @@ -223,7 +227,7 @@ void SignalGen::initOutput() m_pFiffInfo->chs.append(channel); - m_pFiffInfo->ch_names.append("Ch. " + QString::number(i)); + m_pFiffInfo->ch_names.append(m_pFiffInfo->chs[i].ch_name); } m_pRTMSA_SignalGen->measurementData()->initFromFiffInfo(m_pFiffInfo); diff --git a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp deleted file mode 100644 index aaa8a43c03c..00000000000 --- a/src/applications/mne_scan/plugins/signalgen/signalgensetupwidget.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "signalgensetupwidget.h" -#include "ui_signalgensetupwidget.h" - -SignalGenSetupWidget::SignalGenSetupWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::SignalGenSetupWidget) -{ - ui->setupUi(this); -} - -SignalGenSetupWidget::~SignalGenSetupWidget() -{ - delete ui; -} - -void SignalGenSetupWidget::setConfig(const Config& config) -{ - -} - -void SignalGenSetupWidget::numChannelsChanged(int numChannels) -{ - -} - -void SignalGenSetupWidget::sampleFreqChanged(int sampleFreq) -{ - -} From d2b9ef8e58240688314415e96f71c0f3652ca57e Mon Sep 17 00:00:00 2001 From: Gabriel B Motta Date: Mon, 6 Mar 2023 12:07:18 -0500 Subject: [PATCH 4/4] Add mode switching and controls --- .../FormFiles/signalgensetupwidget.cpp | 82 ++++++++++++++-- .../FormFiles/signalgensetupwidget.h | 24 +++-- .../FormFiles/signalgensetupwidget.ui | 97 ++++++++++++++----- .../mne_scan/plugins/signalgen/signalgen.cpp | 34 ++++++- .../mne_scan/plugins/signalgen/signalgen.h | 6 +- 5 files changed, 197 insertions(+), 46 deletions(-) diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp index 9e76d015705..d46cbfdd95c 100644 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.cpp @@ -12,6 +12,23 @@ SignalGenSetupWidget::SignalGenSetupWidget(QWidget *parent) : connect(ui->samplefreq_spinBox, QOverload::of(&QSpinBox::valueChanged), this, &SignalGenSetupWidget::sampleFreqChanged, Qt::UniqueConnection); + + connect(ui->blockpersecond_spinBox, QOverload::of(&QSpinBox::valueChanged), + this, &SignalGenSetupWidget::blocksPerSecondChanged, Qt::UniqueConnection); + + connect(ui->checkBox_random, &QCheckBox::stateChanged, + [this](int state){if(state == Qt::Checked) this->emit modeChanged(SIGNALGENPLUGIN::SignalGen::Mode::Noise); this->updateUiState();}); + + connect(ui->checkBox_wave, &QCheckBox::stateChanged, + [this](int state){if(state == Qt::Checked) this->emit modeChanged(SIGNALGENPLUGIN::SignalGen::Mode::Wave); this->updateUiState();}); + + connect(ui->checkBox_zero, &QCheckBox::stateChanged, + [this](int state){if(state == Qt::Checked) this->emit modeChanged(SIGNALGENPLUGIN::SignalGen::Mode::Zero); this->updateUiState();}); + + connect(ui->spinBox_gen_frq, QOverload::of(&QSpinBox::valueChanged), + this, &SignalGenSetupWidget::genFreqChanged, Qt::UniqueConnection); + + updateUiState(); } SignalGenSetupWidget::~SignalGenSetupWidget() @@ -19,14 +36,65 @@ SignalGenSetupWidget::~SignalGenSetupWidget() delete ui; } -void SignalGenSetupWidget::setConfig(const Config& config) +void SignalGenSetupWidget::defineChannelSettings(int min, int max, int def) { - ui->nchannels_spinBox->setMaximum(config.maxChannels); - ui->nchannels_spinBox->setMinimum(config.minChannels); - ui->nchannels_spinBox->setValue(config.defChannels); + ui->nchannels_spinBox->setMinimum(min); + ui->nchannels_spinBox->setMaximum(max); + ui->nchannels_spinBox->setValue(def); +} - ui->samplefreq_spinBox->setMaximum(config.maxSampFreq); - ui->samplefreq_spinBox->setMinimum(config.minSampFreq); - ui->samplefreq_spinBox->setValue(config.defSampFreq); +void SignalGenSetupWidget::defineSampleFreqSettings(int min, int max, int def) +{ + ui->samplefreq_spinBox->setMinimum(min); + ui->samplefreq_spinBox->setMaximum(max); + ui->samplefreq_spinBox->setValue(def); +} + +void SignalGenSetupWidget::defineBlockSettings(int min, int max, int def) +{ + ui->blockpersecond_spinBox->setMinimum(min); + ui->blockpersecond_spinBox->setMaximum(max); + ui->blockpersecond_spinBox->setValue(def); } +void SignalGenSetupWidget::defineGeneratedFreqSettings(int min, int max, int def) +{ + ui->spinBox_gen_frq->setMinimum(min); + ui->spinBox_gen_frq->setMaximum(max); + ui->spinBox_gen_frq->setValue(def); +} + +void SignalGenSetupWidget::defineMode(SIGNALGENPLUGIN::SignalGen::Mode mode) +{ + switch (mode){ + case SIGNALGENPLUGIN::SignalGen::Mode::Noise: + { + ui->checkBox_random->setChecked(true); + break; + } + case SIGNALGENPLUGIN::SignalGen::Mode::Wave: + { + ui->checkBox_wave->setChecked(true); + break; + } + case SIGNALGENPLUGIN::SignalGen::Mode::Zero: + { + ui->checkBox_zero->setChecked(true); + break; + } + } + + updateUiState(); +} + + +void SignalGenSetupWidget::updateUiState() +{ + if(ui->checkBox_wave->isChecked()){ + ui->label_gen_freq->show(); + ui->spinBox_gen_frq->show(); + } else { + ui->label_gen_freq->hide(); + ui->spinBox_gen_frq->hide(); + } +} diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h index 61fe7f3f131..1e15e51842e 100644 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.h @@ -3,6 +3,8 @@ #include +#include "../signalgen.h" + namespace Ui { class SignalGenSetupWidget; } @@ -12,23 +14,25 @@ class SignalGenSetupWidget : public QWidget Q_OBJECT public: - struct Config{ - int minChannels; - int maxChannels; - int defChannels; - int minSampFreq; - int maxSampFreq; - int defSampFreq; - }; - explicit SignalGenSetupWidget(QWidget *parent = nullptr); ~SignalGenSetupWidget(); - void setConfig(const Config& config); + void defineChannelSettings(int min, int max, int def); + void defineSampleFreqSettings(int min, int max, int def); + void defineBlockSettings(int min, int max, int def); + void defineGeneratedFreqSettings(int min, int max, int def); + void defineMode(SIGNALGENPLUGIN::SignalGen::Mode mode); + signals: void numChannelsChanged(int numChannels); void sampleFreqChanged(int sampleFreq); + void blocksPerSecondChanged(int blocksPerSecond); + void genFreqChanged(int genFreq); + void modeChanged(SIGNALGENPLUGIN::SignalGen::Mode mode); private: + + void updateUiState(); + Ui::SignalGenSetupWidget *ui; }; diff --git a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui index 0a20e5cfc70..efe6808596b 100644 --- a/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui +++ b/src/applications/mne_scan/plugins/signalgen/FormFiles/signalgensetupwidget.ui @@ -51,6 +51,20 @@ QFrame::Raised + + + + Number of Channels + + + + + + + Mode + + + @@ -58,7 +72,54 @@ - + + + + Generated Frequency + + + + + + + Random + + + true + + + checkGroup + + + + + + + Zero + + + checkGroup + + + + + + + Sample Frequency + + + + + + + Wave + + + checkGroup + + + + 1 @@ -71,45 +132,34 @@ - - + + 1 - 9999 + 100 - 1000 + 5 - - + + 1 - 100 + 9999 - 5 - - - - - - - Number of Channels + 1000 - - - - Sample Frequency - - + + @@ -131,4 +181,7 @@ + + + diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.cpp b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp index 1d0aeb9ba35..61ff28bf965 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgen.cpp +++ b/src/applications/mne_scan/plugins/signalgen/signalgen.cpp @@ -43,6 +43,7 @@ #include #include #include +#include //============================================================================================================= // QT INCLUDES @@ -74,8 +75,9 @@ using namespace Eigen; SignalGen::SignalGen() : numChannels(32) -, samplesPerBlock(200) +, numBlocksPerSecond(5) , sample_freq(1000.f) +, gen_freq(3) , m_mode(Mode::Noise) { } @@ -169,8 +171,17 @@ QWidget* SignalGen::setupWidget() connect(widget, &SignalGenSetupWidget::numChannelsChanged, [this](int nchans){this->numChannels = nchans;}); connect(widget, &SignalGenSetupWidget::sampleFreqChanged, [this](int freq){this->sample_freq = freq;}); + connect(widget, &SignalGenSetupWidget::blocksPerSecondChanged, [this](int bps){this->numBlocksPerSecond = bps;}); + connect(widget, &SignalGenSetupWidget::genFreqChanged, [this](int freq){this->gen_freq = freq;}); - widget->setConfig({1, 999, numChannels, 100, 10000, static_cast(sample_freq)}); + connect(widget, &SignalGenSetupWidget::modeChanged, [this](Mode m){this->m_mode = m;}); + + widget->defineChannelSettings(1, 999, numChannels); + widget->defineSampleFreqSettings(100, 10000, static_cast(sample_freq)); + widget->defineBlockSettings(1, 100, numBlocksPerSecond); + widget->defineGeneratedFreqSettings(1,999, gen_freq); + + widget->defineMode(m_mode); return widget; } @@ -180,9 +191,14 @@ QWidget* SignalGen::setupWidget() void SignalGen::run() { MatrixXd matValue; + int samplesPerBlock = sample_freq / numBlocksPerSecond; + matValue.resize(numChannels, samplesPerBlock); - int sleep_time = 1000 * samplesPerBlock / sample_freq; + int sleep_time_ms = 1000 * samplesPerBlock / sample_freq; + + double time = 0; + double pi = 2*acos(0.0); while(!isInterruptionRequested()) { switch(m_mode){ @@ -190,7 +206,15 @@ void SignalGen::run() matValue = MatrixXd::Zero(numChannels, samplesPerBlock); break; } - case Mode::Sine: { + case Mode::Wave: { + for(auto i = 0; i < matValue.cols(); ++i){ + time += 1/sample_freq; + auto value = sin(2 * pi * gen_freq * time); + for (auto& val : matValue.col(i)){ + val = value; + } + } + matValue *= 1e-12; break; } case Mode::Noise:{ @@ -200,7 +224,7 @@ void SignalGen::run() } } m_pRTMSA_SignalGen->measurementData()->setValue(matValue); - msleep(sleep_time); + msleep(sleep_time_ms); } } diff --git a/src/applications/mne_scan/plugins/signalgen/signalgen.h b/src/applications/mne_scan/plugins/signalgen/signalgen.h index a269d849dfc..770b60d9192 100644 --- a/src/applications/mne_scan/plugins/signalgen/signalgen.h +++ b/src/applications/mne_scan/plugins/signalgen/signalgen.h @@ -105,7 +105,7 @@ class SIGNALGENSHARED_EXPORT SignalGen : public SCSHAREDLIB::AbstractSensor enum Mode{ Zero, - Sine, + Wave, Noise }; @@ -176,10 +176,12 @@ class SIGNALGENSHARED_EXPORT SignalGen : public SCSHAREDLIB::AbstractSensor QMutex m_qMutex; /**< The mutex to ensure thread safety.*/ int numChannels; - int samplesPerBlock; + int numBlocksPerSecond; float sample_freq; + float gen_freq; + Mode m_mode; };