From d3088589f8bb7cbbbce6aa621c7d973e7d6d7c79 Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Sat, 5 Mar 2022 19:15:05 +0100 Subject: [PATCH 1/6] Fix: disable window size change during runtime for now. --- libraries/disp/viewers/formfiles/hpisettingsview.ui | 4 ++-- libraries/disp/viewers/hpisettingsview.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/disp/viewers/formfiles/hpisettingsview.ui b/libraries/disp/viewers/formfiles/hpisettingsview.ui index c588529c29f..1375a428883 100644 --- a/libraries/disp/viewers/formfiles/hpisettingsview.ui +++ b/libraries/disp/viewers/formfiles/hpisettingsview.ui @@ -17,7 +17,7 @@ - 0 + 1 @@ -327,7 +327,7 @@ - + 61 diff --git a/libraries/disp/viewers/hpisettingsview.cpp b/libraries/disp/viewers/hpisettingsview.cpp index 2f83f4a1974..9d8bdb3a78d 100644 --- a/libraries/disp/viewers/hpisettingsview.cpp +++ b/libraries/disp/viewers/hpisettingsview.cpp @@ -80,6 +80,12 @@ HpiSettingsView::HpiSettingsView(const QString& sSettingsPath, m_sSettingsPath = sSettingsPath; m_pUi->setupUi(this); + // Disable change of window size for now + bool bWindowsize = false; + m_pUi->frame_samplesToFit->setVisible(bWindowsize); + m_pUi->label_3->setVisible(bWindowsize); + m_pUi->m_spinBox_samplesToFit->setVisible(bWindowsize); + connect(m_pUi->m_pushButton_loadDigitizers, &QPushButton::released, this, &HpiSettingsView::onLoadDigitizers); connect(m_pUi->m_pushButton_doFreqOrder, &QPushButton::clicked, From 6eb150a07877d6a3da64edfd4f34aab09d015cc3 Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Sun, 24 Apr 2022 16:42:17 +0200 Subject: [PATCH 2/6] Enh: add function to compute minimal window size --- applications/mne_scan/plugins/hpi/hpi.cpp | 67 ++++++++++++++++++++--- applications/mne_scan/plugins/hpi/hpi.h | 23 ++++++-- 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/applications/mne_scan/plugins/hpi/hpi.cpp b/applications/mne_scan/plugins/hpi/hpi.cpp index 3eed247158e..c4156e071c3 100644 --- a/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/applications/mne_scan/plugins/hpi/hpi.cpp @@ -87,7 +87,7 @@ constexpr const int defaultFittingWindowSize(300); Hpi::Hpi() : m_iNumberBadChannels(0) -, m_iFittingWindowSize(defaultFittingWindowSize) +, m_iRepetitionWindowSize(defaultFittingWindowSize) , m_dAllowedMeanErrorDist(10) , m_dAllowedMovement(3) , m_dAllowedRotation(5) @@ -322,7 +322,7 @@ void Hpi::initPluginControlWidgets() this, &Hpi::onAllowedMovementChanged); connect(pHpiSettingsView, &HpiSettingsView::allowedRotationChanged, this, &Hpi::onAllowedRotationChanged); - connect(pHpiSettingsView, &HpiSettingsView::fittingWindowSizeChanged, + connect(pHpiSettingsView, &HpiSettingsView::fittingRepetitionTimeChanged, this, &Hpi::setFittingWindowSize); connect(this, &Hpi::errorsChanged, pHpiSettingsView, &HpiSettingsView::setErrorLabels, Qt::BlockingQueuedConnection); @@ -337,7 +337,7 @@ void Hpi::initPluginControlWidgets() onAllowedMeanErrorDistChanged(pHpiSettingsView->getAllowedMeanErrorDistChanged()); onAllowedMovementChanged(pHpiSettingsView->getAllowedMovementChanged()); onAllowedRotationChanged(pHpiSettingsView->getAllowedRotationChanged()); - setFittingWindowSize(pHpiSettingsView->getFittingWindowSize()); + setFittingWindowSize(pHpiSettingsView->getFittingRepetitionTime()); onContHpiStatusChanged(pHpiSettingsView->continuousHPIChecked()); plControlWidgets.append(pHpiSettingsView); @@ -481,6 +481,12 @@ void Hpi::onCoilFrequenciesChanged(const QVector& vCoilFreqs) m_mutex.lock(); m_vCoilFreqs = vCoilFreqs; m_mutex.unlock(); + + int iMinimalWindowSize = computeMinimalWindowsize(); + + m_mutex.lock(); + m_iFittingWindowSize = iMinimalWindowSize; + m_mutex.unlock(); } //============================================================================================================= @@ -515,10 +521,10 @@ void Hpi::onContHpiStatusChanged(bool bChecked) //============================================================================================================= -void Hpi::setFittingWindowSize(int winSize) +void Hpi::setFittingWindowSize(double dRepetitionTime) { QMutexLocker locker(&m_mutex); - m_iFittingWindowSize = winSize; + m_iRepetitionWindowSize = dRepetitionTime * m_pFiffInfo->sfreq; } //============================================================================================================= @@ -530,6 +536,42 @@ void Hpi::onDevHeadTransAvailable(const FIFFLIB::FiffCoordTrans& devHeadTrans) //============================================================================================================= +int Hpi::computeMinimalWindowsize() +{ + m_mutex.lock(); + double dSFreq = m_pFiffInfo->sfreq; + double dLineFreq = m_pFiffInfo->linefreq; + QVector vecFreqs = m_vCoilFreqs; + m_mutex.unlock(); + + // get number of harmonics to take into account + int iMaxHpiFreq = *std::max_element(vecFreqs.constBegin(), vecFreqs.constEnd()); + int nHarmonics = ceil(iMaxHpiFreq/dLineFreq); + + // append frequency vector + for(int i = 1; i <= nHarmonics; i++) { + vecFreqs << dLineFreq * i; + } + + // sort vector in increasing order + std::sort(vecFreqs.constBegin(), vecFreqs.constEnd()); + + // get minimimal required frequency difference + int iMinDeltaF = dSFreq; + + for(int i = 0; i < vecFreqs.size() - 1; i++) { + int iSubsequentDeltaF = vecFreqs[i+1] - vecFreqs[i]; + if(iSubsequentDeltaF< iMinDeltaF) { + iMinDeltaF = iSubsequentDeltaF; + } + } + + // compute buffersize needed to provide this resolution in frequency space N = FS/df + return ceil(dSFreq/iMinDeltaF); +} + +//============================================================================================================= + void Hpi::run() { // Wait for fiff info @@ -575,28 +617,35 @@ void Hpi::run() MatrixXd matData; m_mutex.lock(); - int fittingWindowSize = m_iFittingWindowSize; + int fittingWindowSize = m_iRepetitionWindowSize; m_mutex.unlock(); MatrixXd matDataMerged(m_pFiffInfo->chs.size(), fittingWindowSize); bool bOrder = false; + QElapsedTimer timer; + timer.start(); while(!isInterruptionRequested()) { m_mutex.lock(); - if(fittingWindowSize != m_iFittingWindowSize) { - fittingWindowSize = m_iFittingWindowSize; + if(fittingWindowSize != m_iRepetitionWindowSize) { + fittingWindowSize = m_iRepetitionWindowSize; std::cout << "Fitting window size: " << fittingWindowSize << "\n"; matDataMerged.resize(m_pFiffInfo->chs.size(), fittingWindowSize); iDataIndexCounter = 0; } m_mutex.unlock(); - //pop matrix if(m_pCircularBuffer->pop(matData)) { if(iDataIndexCounter + matData.cols() < matDataMerged.cols()) { matDataMerged.block(0, iDataIndexCounter, matData.rows(), matData.cols()) = matData; iDataIndexCounter += matData.cols(); + qDebug() << "Data im counter:" << iDataIndexCounter; + } else { + qDebug() << "Time elapsed:" << timer.restart(); + qDebug() << "matDataMerged samples:" << matDataMerged.cols(); + qDebug() << "fittingWindowSize:" << fittingWindowSize; + m_mutex.lock(); if(m_bDoSingleHpi) { m_bDoSingleHpi = false; diff --git a/applications/mne_scan/plugins/hpi/hpi.h b/applications/mne_scan/plugins/hpi/hpi.h index 30f9e390bb0..17d57e98cd9 100644 --- a/applications/mne_scan/plugins/hpi/hpi.h +++ b/applications/mne_scan/plugins/hpi/hpi.h @@ -241,11 +241,11 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm //========================================================================================================= /** - * Set fitting window size when doing continuous hpi. + * Set fitting window size when doing continuous hpi using the repetition time as measure. * - * @param[in] winSize window size in samples + * @param[in] dRepetitionTime Repetition time in seconds */ - void setFittingWindowSize(int winSize); + void setFittingWindowSize(double dRepetitionTime); //========================================================================================================= /** @@ -289,6 +289,19 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm */ void updateDigitizerInfo(); + //========================================================================================================= + /** + * Returns the optimal window size for hpi computation + * + * Compute the optimal window size based on minimal detectable frequency difference between HPI + * freqeuencies and line frequency (+ harmonics). + * + * @return optimal Windowsize + */ + int computeOptimalWindowsize(); + + + void resetState(); QMutex m_mutex; /**< The threads mutex.*/ @@ -298,8 +311,8 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm QString m_sFilePathDigitzers; /**< The file path to the current digitzers. */ qint16 m_iNumberBadChannels; /**< The number of bad channels.*/ - qint16 m_iFittingWindowSize; /**< The number of samples in each fitting window.*/ - + qint16 m_iRepetitionWindowSize; /**< The number of samples to wait between fits.*/ + int m_iFittingWindowSize; /**< The number of samples in each fitting window.*/ double m_dAllowedMeanErrorDist; /**< The allowed error distance in order for the last fit to be counted as a good fit.*/ double m_dAllowedMovement; /**< The allowed head movement regarding reference head position.*/ double m_dAllowedRotation; /**< The allowed head rotation regarding reference head position in degree.*/ From de0f94950f0682b8c94e5e9e0a71fd71e913f4ce Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Sun, 24 Apr 2022 17:18:20 +0200 Subject: [PATCH 3/6] enh: implement variable fitting window size as well --- applications/mne_scan/plugins/hpi/hpi.cpp | 44 ++++++++++++++++------- applications/mne_scan/plugins/hpi/hpi.h | 4 +-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/applications/mne_scan/plugins/hpi/hpi.cpp b/applications/mne_scan/plugins/hpi/hpi.cpp index c4156e071c3..41fbafd5664 100644 --- a/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/applications/mne_scan/plugins/hpi/hpi.cpp @@ -87,7 +87,7 @@ constexpr const int defaultFittingWindowSize(300); Hpi::Hpi() : m_iNumberBadChannels(0) -, m_iRepetitionWindowSize(defaultFittingWindowSize) +, m_iRepetitionTimeInSamples(defaultFittingWindowSize) , m_dAllowedMeanErrorDist(10) , m_dAllowedMovement(3) , m_dAllowedRotation(5) @@ -524,7 +524,7 @@ void Hpi::onContHpiStatusChanged(bool bChecked) void Hpi::setFittingWindowSize(double dRepetitionTime) { QMutexLocker locker(&m_mutex); - m_iRepetitionWindowSize = dRepetitionTime * m_pFiffInfo->sfreq; + m_iRepetitionTimeInSamples = dRepetitionTime * m_pFiffInfo->sfreq; } //============================================================================================================= @@ -554,7 +554,7 @@ int Hpi::computeMinimalWindowsize() } // sort vector in increasing order - std::sort(vecFreqs.constBegin(), vecFreqs.constEnd()); + std::sort(vecFreqs.begin(), vecFreqs.end()); // get minimimal required frequency difference int iMinDeltaF = dSFreq; @@ -613,38 +613,55 @@ void Hpi::run() double dMovement = 0.0; double dRotation = 0.0; + int iRepetitionIndexCounter = 0; int iDataIndexCounter = 0; MatrixXd matData; m_mutex.lock(); - int fittingWindowSize = m_iRepetitionWindowSize; + int iFittingWindowSize = m_iFittingWindowSize; + int iRepetitionTimeInSamples = m_iRepetitionTimeInSamples; + m_mutex.unlock(); - MatrixXd matDataMerged(m_pFiffInfo->chs.size(), fittingWindowSize); + MatrixXd matDataMerged(m_pFiffInfo->chs.size(), iFittingWindowSize); bool bOrder = false; QElapsedTimer timer; timer.start(); while(!isInterruptionRequested()) { m_mutex.lock(); - if(fittingWindowSize != m_iRepetitionWindowSize) { - fittingWindowSize = m_iRepetitionWindowSize; - std::cout << "Fitting window size: " << fittingWindowSize << "\n"; - matDataMerged.resize(m_pFiffInfo->chs.size(), fittingWindowSize); - iDataIndexCounter = 0; + // check if fitting window size has changed and resize matData if necessary + if(iFittingWindowSize != m_iFittingWindowSize) { + iFittingWindowSize = m_iFittingWindowSize; + std::cout << "Fitting window size: " << iFittingWindowSize << "\n"; + matDataMerged.resize(m_pFiffInfo->chs.size(), iFittingWindowSize); + iRepetitionIndexCounter = 0; + } + + // check if time between fits has changed + if(iRepetitionTimeInSamples != m_iRepetitionTimeInSamples) { + iRepetitionTimeInSamples = m_iRepetitionTimeInSamples; + std::cout << "Repetition time in samples: " << iRepetitionTimeInSamples << "\n"; + iRepetitionIndexCounter = 0; } m_mutex.unlock(); + //pop matrix if(m_pCircularBuffer->pop(matData)) { - if(iDataIndexCounter + matData.cols() < matDataMerged.cols()) { + if(iRepetitionIndexCounter + matData.cols() < iRepetitionTimeInSamples) { + iRepetitionIndexCounter += matData.cols(); + qDebug() << "Samples im repetition counter:" << iRepetitionIndexCounter << "From: " << iRepetitionTimeInSamples; + + } else if(iDataIndexCounter + matData.cols() < iFittingWindowSize) { matDataMerged.block(0, iDataIndexCounter, matData.rows(), matData.cols()) = matData; iDataIndexCounter += matData.cols(); - qDebug() << "Data im counter:" << iDataIndexCounter; + qDebug() << "Samples im data counter:" << iDataIndexCounter << "From: " << iFittingWindowSize; } else { qDebug() << "Time elapsed:" << timer.restart(); qDebug() << "matDataMerged samples:" << matDataMerged.cols(); - qDebug() << "fittingWindowSize:" << fittingWindowSize; + qDebug() << "fittingWindowSize:" << iFittingWindowSize; + qDebug() << "repetition time in samples:" << iRepetitionTimeInSamples; m_mutex.lock(); if(m_bDoSingleHpi) { @@ -720,6 +737,7 @@ void Hpi::run() } } + iRepetitionIndexCounter = 0; iDataIndexCounter = 0; } } diff --git a/applications/mne_scan/plugins/hpi/hpi.h b/applications/mne_scan/plugins/hpi/hpi.h index 17d57e98cd9..864f76d76cc 100644 --- a/applications/mne_scan/plugins/hpi/hpi.h +++ b/applications/mne_scan/plugins/hpi/hpi.h @@ -298,7 +298,7 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm * * @return optimal Windowsize */ - int computeOptimalWindowsize(); + int computeMinimalWindowsize(); @@ -311,7 +311,7 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm QString m_sFilePathDigitzers; /**< The file path to the current digitzers. */ qint16 m_iNumberBadChannels; /**< The number of bad channels.*/ - qint16 m_iRepetitionWindowSize; /**< The number of samples to wait between fits.*/ + qint16 m_iRepetitionTimeInSamples; /**< The number of samples to wait between fits.*/ int m_iFittingWindowSize; /**< The number of samples in each fitting window.*/ double m_dAllowedMeanErrorDist; /**< The allowed error distance in order for the last fit to be counted as a good fit.*/ double m_dAllowedMovement; /**< The allowed head movement regarding reference head position.*/ From d3e2c9e8d8cb3bbed447c3f822de82278495a407 Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Sun, 24 Apr 2022 18:16:42 +0200 Subject: [PATCH 4/6] Enh: add control for window size to gui --- applications/mne_scan/plugins/hpi/hpi.cpp | 22 +++++- applications/mne_scan/plugins/hpi/hpi.h | 15 +++- .../disp/viewers/formfiles/hpisettingsview.ui | 77 +++++++++++++++---- libraries/disp/viewers/hpisettingsview.cpp | 31 +++++--- libraries/disp/viewers/hpisettingsview.h | 28 +++++-- 5 files changed, 134 insertions(+), 39 deletions(-) diff --git a/applications/mne_scan/plugins/hpi/hpi.cpp b/applications/mne_scan/plugins/hpi/hpi.cpp index 41fbafd5664..7cd11f9a430 100644 --- a/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/applications/mne_scan/plugins/hpi/hpi.cpp @@ -322,7 +322,9 @@ void Hpi::initPluginControlWidgets() this, &Hpi::onAllowedMovementChanged); connect(pHpiSettingsView, &HpiSettingsView::allowedRotationChanged, this, &Hpi::onAllowedRotationChanged); - connect(pHpiSettingsView, &HpiSettingsView::fittingRepetitionTimeChanged, + connect(pHpiSettingsView, &HpiSettingsView::repetitionTimeChanged, + this, &Hpi::setTimeBetweenFits); + connect(pHpiSettingsView, &HpiSettingsView::fittingWindowTimeChanged, this, &Hpi::setFittingWindowSize); connect(this, &Hpi::errorsChanged, pHpiSettingsView, &HpiSettingsView::setErrorLabels, Qt::BlockingQueuedConnection); @@ -330,7 +332,8 @@ void Hpi::initPluginControlWidgets() pHpiSettingsView, &HpiSettingsView::setMovementResults, Qt::BlockingQueuedConnection); connect(this, &Hpi::newDigitizerList, pHpiSettingsView, &HpiSettingsView::newDigitizerList); - + connect(this, &Hpi::minimumWindowSizeChanged, + pHpiSettingsView, &HpiSettingsView::setMinimumWindowSize); onSspStatusChanged(pHpiSettingsView->getSspStatusChanged()); onCompStatusChanged(pHpiSettingsView->getCompStatusChanged()); @@ -521,7 +524,7 @@ void Hpi::onContHpiStatusChanged(bool bChecked) //============================================================================================================= -void Hpi::setFittingWindowSize(double dRepetitionTime) +void Hpi::setTimeBetweenFits(double dRepetitionTime) { QMutexLocker locker(&m_mutex); m_iRepetitionTimeInSamples = dRepetitionTime * m_pFiffInfo->sfreq; @@ -529,6 +532,14 @@ void Hpi::setFittingWindowSize(double dRepetitionTime) //============================================================================================================= +void Hpi::setFittingWindowSize(double dFittingWindowSizeInMillisecons) +{ + QMutexLocker locker(&m_mutex); + m_iFittingWindowSize = dFittingWindowSizeInMillisecons / 1000.0 * m_pFiffInfo->sfreq; +} + +//============================================================================================================= + void Hpi::onDevHeadTransAvailable(const FIFFLIB::FiffCoordTrans& devHeadTrans) { m_pFiffInfo->dev_head_t = devHeadTrans; @@ -567,7 +578,10 @@ int Hpi::computeMinimalWindowsize() } // compute buffersize needed to provide this resolution in frequency space N = FS/df - return ceil(dSFreq/iMinDeltaF); + int iWindowSize = ceil(dSFreq/iMinDeltaF); + minimumWindowSizeChanged(iWindowSize/dSFreq); + + return iWindowSize; } //============================================================================================================= diff --git a/applications/mne_scan/plugins/hpi/hpi.h b/applications/mne_scan/plugins/hpi/hpi.h index 864f76d76cc..089a4f6a60b 100644 --- a/applications/mne_scan/plugins/hpi/hpi.h +++ b/applications/mne_scan/plugins/hpi/hpi.h @@ -239,13 +239,22 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm */ void onDevHeadTransAvailable(const FIFFLIB::FiffCoordTrans& devHeadTrans); + //========================================================================================================= /** - * Set fitting window size when doing continuous hpi using the repetition time as measure. + * Set repetition time between hpi fits. * * @param[in] dRepetitionTime Repetition time in seconds */ - void setFittingWindowSize(double dRepetitionTime); + void setTimeBetweenFits(double dRepetitionTimeInSeconds); + + //========================================================================================================= + /** + * Set hpi fitting window size. + * + * @param[in] dFittingWindowSizeInSeconds Fitting window size in seconds + */ + void setFittingWindowSize(double dFittingWindowSizeInSeconds); //========================================================================================================= /** @@ -334,6 +343,8 @@ class HPISHARED_EXPORT Hpi : public SCSHAREDLIB::AbstractAlgorithm SCSHAREDLIB::PluginOutputData::SPtr m_pHpiOutput; /**< The RealTimeHpiResult of the Hpi output.*/ signals: + void minimumWindowSizeChanged(const double dWindowSizeInSeconds); + void errorsChanged(const QVector& vErrors, double dMeanErrorDist); void movementResultsChanged(double dMovement, diff --git a/libraries/disp/viewers/formfiles/hpisettingsview.ui b/libraries/disp/viewers/formfiles/hpisettingsview.ui index 1375a428883..fdb3795467c 100644 --- a/libraries/disp/viewers/formfiles/hpisettingsview.ui +++ b/libraries/disp/viewers/formfiles/hpisettingsview.ui @@ -17,7 +17,7 @@ - 1 + 0 @@ -319,7 +319,7 @@ - Do continous HPI fitting at + Do continous HPI fitting @@ -328,6 +328,12 @@ + + + 0 + 0 + + 61 @@ -340,36 +346,77 @@ QFrame::Raised - - - 4 - - - 4 - - - + + + + + + 0 + 0 + + 70 16777215 + + 2 + - 10 + 0.200000000000000 - 1000000 + 30.000000000000000 + + + 0.500000000000000 + 1.000000000000000 + + + + + + + + 0 + 0 + + + + + 70 + 16777215 + + + + 50 + + + 1000 + + 10 + + 200 + - + - Win Size [Samples] + Time between fits [Seconds] + + + + + + + Window Size [Milliseconds] diff --git a/libraries/disp/viewers/hpisettingsview.cpp b/libraries/disp/viewers/hpisettingsview.cpp index 9d8bdb3a78d..615353dad88 100644 --- a/libraries/disp/viewers/hpisettingsview.cpp +++ b/libraries/disp/viewers/hpisettingsview.cpp @@ -80,12 +80,6 @@ HpiSettingsView::HpiSettingsView(const QString& sSettingsPath, m_sSettingsPath = sSettingsPath; m_pUi->setupUi(this); - // Disable change of window size for now - bool bWindowsize = false; - m_pUi->frame_samplesToFit->setVisible(bWindowsize); - m_pUi->label_3->setVisible(bWindowsize); - m_pUi->m_spinBox_samplesToFit->setVisible(bWindowsize); - connect(m_pUi->m_pushButton_loadDigitizers, &QPushButton::released, this, &HpiSettingsView::onLoadDigitizers); connect(m_pUi->m_pushButton_doFreqOrder, &QPushButton::clicked, @@ -104,8 +98,10 @@ HpiSettingsView::HpiSettingsView(const QString& sSettingsPath, this, &HpiSettingsView::compStatusChanged); connect(m_pUi->m_checkBox_continousHPI, &QCheckBox::clicked, this, &HpiSettingsView::contHpiStatusChanged); - connect(m_pUi->m_spinBox_samplesToFit, QOverload::of(&QSpinBox::valueChanged), - this, &HpiSettingsView::fittingWindowSizeChanged); + connect(m_pUi->m_doubleSpinBox_fittingRepetitionTime, static_cast(&QDoubleSpinBox::valueChanged), + this, &HpiSettingsView::repetitionTimeChanged); + connect(m_pUi->m_spinBox_windowSize, QOverload::of(&QSpinBox::valueChanged), + this, &HpiSettingsView::fittingWindowTimeChanged); connect(m_pUi->m_doubleSpinBox_maxHPIContinousDist, static_cast(&QDoubleSpinBox::valueChanged), this, &HpiSettingsView::allowedMeanErrorDistChanged); connect(m_pUi->m_doubleSpinBox_moveThreshold, static_cast(&QDoubleSpinBox::valueChanged), @@ -177,6 +173,17 @@ void HpiSettingsView::setMovementResults(double dMovement, //============================================================================================================= +void HpiSettingsView::setMinimumWindowSize(double dWindowSize) +{ + int iMinimumInMs = ceil(dWindowSize*1000); + m_pUi->m_spinBox_windowSize->setMinimum(iMinimumInMs); + if(m_pUi->m_spinBox_windowSize->value() < iMinimumInMs) { + m_pUi->m_spinBox_windowSize->setValue(iMinimumInMs); + } +} + +//============================================================================================================= + bool HpiSettingsView::getSspStatusChanged() { return m_pUi->m_checkBox_useSSP->isChecked(); @@ -220,9 +227,9 @@ bool HpiSettingsView::continuousHPIChecked() //============================================================================================================= -int HpiSettingsView::getFittingWindowSize() +double HpiSettingsView::getFittingRepetitionTime() { - return m_pUi->m_spinBox_samplesToFit->value(); + return m_pUi->m_doubleSpinBox_fittingRepetitionTime->value(); } //============================================================================================================= @@ -251,7 +258,7 @@ void HpiSettingsView::saveSettings() QVariant::fromValue(m_pUi->m_doubleSpinBox_maxHPIContinousDist->value())); settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), - QVariant::fromValue(m_pUi->m_spinBox_samplesToFit->value())); + QVariant::fromValue(m_pUi->m_doubleSpinBox_fittingRepetitionTime->value())); } //============================================================================================================= @@ -273,7 +280,7 @@ void HpiSettingsView::loadSettings() m_pUi->m_checkBox_useComp->setChecked(settings.value(m_sSettingsPath + QString("/HpiSettingsView/useCOMP"), false).toBool()); m_pUi->m_checkBox_continousHPI->setChecked(settings.value(m_sSettingsPath + QString("/HpiSettingsView/continousHPI"), false).toBool()); m_pUi->m_doubleSpinBox_maxHPIContinousDist->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/maxError"), 10.0).toDouble()); - m_pUi->m_spinBox_samplesToFit->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), 300).toInt()); + m_pUi->m_doubleSpinBox_fittingRepetitionTime->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), 300).toInt()); } //============================================================================================================= diff --git a/libraries/disp/viewers/hpisettingsview.h b/libraries/disp/viewers/hpisettingsview.h index ffaafb58ac9..4f7eaecdc49 100644 --- a/libraries/disp/viewers/hpisettingsview.h +++ b/libraries/disp/viewers/hpisettingsview.h @@ -117,6 +117,14 @@ class DISPSHARED_EXPORT HpiSettingsView : public AbstractView void setMovementResults(double dMovement, double dRotation); + //========================================================================================================= + /** + * Updates the minimal window time for hpi fits. + * + * @param[in] dMinimumWindowTime in seconds. + */ + void setMinimumWindowSize(double dMinimumWindowTime); + //========================================================================================================= /** * Get the SSP checked status. @@ -167,11 +175,11 @@ class DISPSHARED_EXPORT HpiSettingsView : public AbstractView //========================================================================================================= /** - * Get number of fits per second to do when performing continuous hpi + * Get the time between hpi fits in seconds. * - * @return Number of fits per second + * @return Repetition time between fits in seconds. */ - int getFittingWindowSize(); + double getFittingRepetitionTime(); //========================================================================================================= /** @@ -382,11 +390,19 @@ class DISPSHARED_EXPORT HpiSettingsView : public AbstractView //========================================================================================================= /** - * Emit this signal when 'fits per second' control gets updated. + * Emit this signal when 'Time between fits' control gets updated. + * + * @param[in] dTimeBetweenFitsInSecs The time between fits in seconds. + */ + void repetitionTimeChanged(double dTimeBetweenFitsInSecs); + + //========================================================================================================= + /** + * Emit this signal when 'Time between fits' control gets updated. * - * @param[in] iFitsPerSecond How many fits per second we should do. + * @param[in] dWindowSizeInSeconds The window size to use for hpi fits in seconds. */ - void fittingWindowSizeChanged(int iFitsPerSecond); + void fittingWindowTimeChanged(double dWindowSizeInSeconds); //========================================================================================================= /** From 18bb0d57b1bbb878059b217ec715a0c39edd0a93 Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Sun, 24 Apr 2022 18:20:55 +0200 Subject: [PATCH 5/6] maint: remove prints to console --- applications/mne_scan/plugins/hpi/hpi.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/applications/mne_scan/plugins/hpi/hpi.cpp b/applications/mne_scan/plugins/hpi/hpi.cpp index 7cd11f9a430..4df9369f8bc 100644 --- a/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/applications/mne_scan/plugins/hpi/hpi.cpp @@ -647,7 +647,6 @@ void Hpi::run() // check if fitting window size has changed and resize matData if necessary if(iFittingWindowSize != m_iFittingWindowSize) { iFittingWindowSize = m_iFittingWindowSize; - std::cout << "Fitting window size: " << iFittingWindowSize << "\n"; matDataMerged.resize(m_pFiffInfo->chs.size(), iFittingWindowSize); iRepetitionIndexCounter = 0; } @@ -655,7 +654,6 @@ void Hpi::run() // check if time between fits has changed if(iRepetitionTimeInSamples != m_iRepetitionTimeInSamples) { iRepetitionTimeInSamples = m_iRepetitionTimeInSamples; - std::cout << "Repetition time in samples: " << iRepetitionTimeInSamples << "\n"; iRepetitionIndexCounter = 0; } m_mutex.unlock(); @@ -664,19 +662,12 @@ void Hpi::run() if(m_pCircularBuffer->pop(matData)) { if(iRepetitionIndexCounter + matData.cols() < iRepetitionTimeInSamples) { iRepetitionIndexCounter += matData.cols(); - qDebug() << "Samples im repetition counter:" << iRepetitionIndexCounter << "From: " << iRepetitionTimeInSamples; } else if(iDataIndexCounter + matData.cols() < iFittingWindowSize) { matDataMerged.block(0, iDataIndexCounter, matData.rows(), matData.cols()) = matData; iDataIndexCounter += matData.cols(); - qDebug() << "Samples im data counter:" << iDataIndexCounter << "From: " << iFittingWindowSize; } else { - qDebug() << "Time elapsed:" << timer.restart(); - qDebug() << "matDataMerged samples:" << matDataMerged.cols(); - qDebug() << "fittingWindowSize:" << iFittingWindowSize; - qDebug() << "repetition time in samples:" << iRepetitionTimeInSamples; - m_mutex.lock(); if(m_bDoSingleHpi) { m_bDoSingleHpi = false; From 6e751f71004319d10de29d9ff611d8a344a32402 Mon Sep 17 00:00:00 2001 From: RDoerfel Date: Fri, 13 May 2022 18:52:48 +0200 Subject: [PATCH 6/6] maint: make new spin box to avoid shadowing from old names --- applications/mne_scan/plugins/hpi/hpi.cpp | 6 +- .../disp/viewers/formfiles/hpisettingsview.ui | 101 ++++++++---------- libraries/disp/viewers/hpisettingsview.cpp | 22 ++-- 3 files changed, 63 insertions(+), 66 deletions(-) diff --git a/applications/mne_scan/plugins/hpi/hpi.cpp b/applications/mne_scan/plugins/hpi/hpi.cpp index 4df9369f8bc..60842226a16 100644 --- a/applications/mne_scan/plugins/hpi/hpi.cpp +++ b/applications/mne_scan/plugins/hpi/hpi.cpp @@ -79,7 +79,7 @@ using namespace INVERSELIB; // DEFINE LOCAL CONSTANTS //============================================================================================================= -constexpr const int defaultFittingWindowSize(300); +constexpr const int defaultFittingWindowSize(2000); //============================================================================================================= // DEFINE MEMBER METHODS @@ -485,7 +485,7 @@ void Hpi::onCoilFrequenciesChanged(const QVector& vCoilFreqs) m_vCoilFreqs = vCoilFreqs; m_mutex.unlock(); - int iMinimalWindowSize = computeMinimalWindowsize(); + const int iMinimalWindowSize = computeMinimalWindowsize(); m_mutex.lock(); m_iFittingWindowSize = iMinimalWindowSize; @@ -579,7 +579,7 @@ int Hpi::computeMinimalWindowsize() // compute buffersize needed to provide this resolution in frequency space N = FS/df int iWindowSize = ceil(dSFreq/iMinDeltaF); - minimumWindowSizeChanged(iWindowSize/dSFreq); + emit minimumWindowSizeChanged(iWindowSize/dSFreq); return iWindowSize; } diff --git a/libraries/disp/viewers/formfiles/hpisettingsview.ui b/libraries/disp/viewers/formfiles/hpisettingsview.ui index fdb3795467c..87e096fb94d 100644 --- a/libraries/disp/viewers/formfiles/hpisettingsview.ui +++ b/libraries/disp/viewers/formfiles/hpisettingsview.ui @@ -327,96 +327,63 @@ - + - + 0 0 - - - 61 - 35 - - - - QFrame::StyledPanel - - - QFrame::Raised + + - - - - - 0 - 0 - - - - - 70 - 16777215 - - - - 2 - + + - 0.200000000000000 + 200 - 30.000000000000000 + 1000 - 0.500000000000000 + 100 - 1.000000000000000 + 333 - - - - - 0 - 0 - - - - - 70 - 16777215 - + + + + 1 - 50 + 0.200000000000000 - 1000 + 30.000000000000000 - 10 + 0.100000000000000 - 200 + 2.000000000000000 - + - Time between fits [Seconds] + Time between fits [seconds] - + - Window Size [Milliseconds] + Window size [ms] @@ -603,6 +570,12 @@ + + + 0 + 0 + + mm @@ -623,6 +596,12 @@ + + + 0 + 0 + + ° @@ -652,6 +631,12 @@ + + + 0 + 0 + + true @@ -666,6 +651,12 @@ + + + 0 + 0 + + true diff --git a/libraries/disp/viewers/hpisettingsview.cpp b/libraries/disp/viewers/hpisettingsview.cpp index 615353dad88..aa42895931a 100644 --- a/libraries/disp/viewers/hpisettingsview.cpp +++ b/libraries/disp/viewers/hpisettingsview.cpp @@ -98,7 +98,7 @@ HpiSettingsView::HpiSettingsView(const QString& sSettingsPath, this, &HpiSettingsView::compStatusChanged); connect(m_pUi->m_checkBox_continousHPI, &QCheckBox::clicked, this, &HpiSettingsView::contHpiStatusChanged); - connect(m_pUi->m_doubleSpinBox_fittingRepetitionTime, static_cast(&QDoubleSpinBox::valueChanged), + connect(m_pUi->m_doubleSpinBox_repTime, static_cast(&QDoubleSpinBox::valueChanged), this, &HpiSettingsView::repetitionTimeChanged); connect(m_pUi->m_spinBox_windowSize, QOverload::of(&QSpinBox::valueChanged), this, &HpiSettingsView::fittingWindowTimeChanged); @@ -175,11 +175,21 @@ void HpiSettingsView::setMovementResults(double dMovement, void HpiSettingsView::setMinimumWindowSize(double dWindowSize) { + QSignalBlocker blockeWindowr(m_pUi->m_spinBox_windowSize); + QSignalBlocker blockerTime(m_pUi->m_doubleSpinBox_repTime); + int iMinimumInMs = ceil(dWindowSize*1000); m_pUi->m_spinBox_windowSize->setMinimum(iMinimumInMs); + m_pUi->m_doubleSpinBox_repTime->setMinimum(dWindowSize); + if(m_pUi->m_spinBox_windowSize->value() < iMinimumInMs) { m_pUi->m_spinBox_windowSize->setValue(iMinimumInMs); } + + if(m_pUi->m_doubleSpinBox_repTime->value() < dWindowSize) { + m_pUi->m_doubleSpinBox_repTime->setValue(dWindowSize); + } + } //============================================================================================================= @@ -229,7 +239,7 @@ bool HpiSettingsView::continuousHPIChecked() double HpiSettingsView::getFittingRepetitionTime() { - return m_pUi->m_doubleSpinBox_fittingRepetitionTime->value(); + return m_pUi->m_doubleSpinBox_repTime->value(); } //============================================================================================================= @@ -251,14 +261,11 @@ void HpiSettingsView::saveSettings() settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/useCOMP"), QVariant::fromValue(m_pUi->m_checkBox_useComp->isChecked())); - settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/continousHPI"),\ - QVariant::fromValue(m_pUi->m_checkBox_continousHPI->isChecked())); - settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/maxError"), QVariant::fromValue(m_pUi->m_doubleSpinBox_maxHPIContinousDist->value())); settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), - QVariant::fromValue(m_pUi->m_doubleSpinBox_fittingRepetitionTime->value())); + QVariant::fromValue(m_pUi->m_doubleSpinBox_repTime->value())); } //============================================================================================================= @@ -278,9 +285,8 @@ void HpiSettingsView::loadSettings() m_pUi->m_checkBox_useSSP->setChecked(settings.value(m_sSettingsPath + QString("/HpiSettingsView/useSSP"), false).toBool()); m_pUi->m_checkBox_useComp->setChecked(settings.value(m_sSettingsPath + QString("/HpiSettingsView/useCOMP"), false).toBool()); - m_pUi->m_checkBox_continousHPI->setChecked(settings.value(m_sSettingsPath + QString("/HpiSettingsView/continousHPI"), false).toBool()); m_pUi->m_doubleSpinBox_maxHPIContinousDist->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/maxError"), 10.0).toDouble()); - m_pUi->m_doubleSpinBox_fittingRepetitionTime->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), 300).toInt()); + m_pUi->m_doubleSpinBox_repTime->setValue(settings.value(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"), 300).toInt()); } //=============================================================================================================