Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Maint] Cleanup Hpi refactoring #890

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
102 changes: 52 additions & 50 deletions applications/mne_scan/plugins/hpi/hpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,12 @@ void Hpi::update(SCMEASLIB::Measurement::SPtr pMeasurement)
}
}

if(m_bDoContinousHpi && (m_vCoilFreqs.size() >= 3)) {
m_mutex.lock();
bool bDoContinousHpi = m_bDoContinousHpi;
int iNumberHpiCoils = m_vCoilFreqs.size();
m_mutex.unlock();

if(bDoContinousHpi && (iNumberHpiCoils >= 3)) {
for(unsigned char i = 0; i < pRTMSA->getMultiSampleArray().size(); ++i) {
// Please note that we do not need a copy here since this function will block until
// the buffer accepts new data again. Hence, the data is not deleted in the actual
Expand Down Expand Up @@ -283,14 +288,7 @@ void Hpi::updateDigitizerInfo()

void Hpi::initPluginControlWidgets()
{
bool bFiffInfo = false;
m_mutex.lock();
if(m_pFiffInfo) {
bFiffInfo = true;
}
m_mutex.unlock();

if(bFiffInfo) {
QList<QWidget*> plControlWidgets;

// Projects Settings
Expand Down Expand Up @@ -366,14 +364,19 @@ void Hpi::updateProjections()
}
m_mutex.unlock();

m_mutex.lock();
Eigen::MatrixXd matProjectors = Eigen::MatrixXd::Identity(m_pFiffInfo->chs.size(), m_pFiffInfo->chs.size());
Eigen::MatrixXd matComp = Eigen::MatrixXd::Identity(m_pFiffInfo->chs.size(), m_pFiffInfo->chs.size());

if(m_bUseSSP) {
bool bUseSSP = m_bUseSSP;
m_mutex.unlock();

if(bUseSSP) {
// Use SSP + SGM + calibration
//Do a copy here because we are going to change the activity flags of the SSP's
m_mutex.lock();
FiffInfo infoTemp = *(m_pFiffInfo.data());

m_mutex.unlock();
//Turn on all SSP
for(int i = 0; i < infoTemp.projs.size(); ++i) {
infoTemp.projs[i].active = true;
Expand All @@ -387,13 +390,19 @@ void Hpi::updateProjections()
}
}

if(m_bUseComp) {
m_mutex.lock();
bool bUseComp = m_bUseComp;
m_mutex.unlock();

if(bUseComp) {
// Setup Comps
FiffCtfComp newComp;
//Do this always from 0 since we always read new raw data, we never actually perform a multiplication on already existing data
m_mutex.lock();
if(m_pFiffInfo->make_compensator(0, 101, newComp)) {
matComp = newComp.data->data;
}
m_mutex.unlock();
}

m_mutex.lock();
Expand Down Expand Up @@ -448,7 +457,11 @@ void Hpi::onDigitizersChanged(const QList<FIFFLIB::FiffDigPoint>& lDigitzers,

void Hpi::onDoSingleHpiFit()
{
if(m_vCoilFreqs.size() < 3) {
m_mutex.lock();
int iNumberHpiCoils = m_vCoilFreqs.size();
m_mutex.unlock();

if(iNumberHpiCoils < 3) {
QMessageBox msgBox;
msgBox.setText("Please input HPI coil frequencies first.");
msgBox.exec();
Expand All @@ -464,13 +477,16 @@ void Hpi::onDoSingleHpiFit()

void Hpi::onDoFreqOrder()
{
if(m_vCoilFreqs.size() < 3) {
m_mutex.lock();
int iNumberHpiCoils = m_vCoilFreqs.size();
m_mutex.unlock();

if(iNumberHpiCoils < 3) {
QMessageBox msgBox;
msgBox.setText("Please input HPI coil frequencies first.");
msgBox.exec();
return;
}

m_mutex.lock();
m_bDoFreqOrder = true;
m_mutex.unlock();
Expand All @@ -489,30 +505,31 @@ void Hpi::onCoilFrequenciesChanged(const QVector<int>& vCoilFreqs)

void Hpi::onSspStatusChanged(bool bChecked)
{
m_mutex.lock();
m_bUseSSP = bChecked;
m_mutex.unlock();
updateProjections();
}

//=============================================================================================================

void Hpi::onCompStatusChanged(bool bChecked)
{
m_mutex.lock();
m_bUseComp = bChecked;
m_mutex.unlock();
updateProjections();
}

//=============================================================================================================

void Hpi::onContHpiStatusChanged(bool bChecked)
{
// if(m_vCoilFreqs.size() < 3) {
// QMessageBox msgBox;
// msgBox.setText("Please load a digitizer set with at least 3 HPI coils first.");
// msgBox.exec();
// return;
// }

m_mutex.lock();
m_bDoContinousHpi = bChecked;
m_mutex.unlock();

}

//=============================================================================================================
Expand All @@ -527,44 +544,30 @@ void Hpi::setFittingWindowSize(int winSize)

void Hpi::onDevHeadTransAvailable(const FIFFLIB::FiffCoordTrans& devHeadTrans)
{
m_mutex.lock();
m_pFiffInfo->dev_head_t = devHeadTrans;
m_mutex.unlock();
}

//=============================================================================================================

void Hpi::run()
{
// Wait for fiff info
bool bFiffInfo = false;

while(true) {
m_mutex.lock();
if(m_pFiffInfo) {
bFiffInfo = true;
}
m_mutex.unlock();
if(bFiffInfo) {
break;
}
while(!m_pFiffInfo) {
msleep(100);
}

// init hpi fit
HpiModelParameters hpiModelParameters(m_vCoilFreqs,
m_pFiffInfo->sfreq,
m_pFiffInfo->linefreq,
false);
HpiFitResult fitResult;
fitResult.hpiFreqs = m_vCoilFreqs;
fitResult.errorDistances = QVector<double>(m_vCoilFreqs.size());
fitResult.devHeadTrans = m_pFiffInfo->dev_head_t;
fitResult.devHeadTrans.from = 1;
fitResult.devHeadTrans.to = 4;

m_mutex.lock();
FiffCoordTrans transDevHeadRef = m_pFiffInfo->dev_head_t;

int fittingWindowSize = m_iFittingWindowSize;
MatrixXd matDataMerged(m_pFiffInfo->chs.size(), fittingWindowSize);
HpiDataUpdater hpiDataUpdater = HpiDataUpdater(m_pFiffInfo);
m_mutex.unlock();

HPIFit HPI = HPIFit(hpiDataUpdater.getSensors());
HpiFitResult fitResult;
HpiModelParameters hpiModelParameters;

double dErrorMax = 0.0;
double dMeanErrorDist = 0.0;
Expand All @@ -577,11 +580,7 @@ void Hpi::run()
int iDataIndexCounter = 0;
MatrixXd matData;

m_mutex.lock();
int fittingWindowSize = m_iFittingWindowSize;
m_mutex.unlock();

MatrixXd matDataMerged(m_pFiffInfo->chs.size(), fittingWindowSize);
bool bOrder = false;

while(!isInterruptionRequested()) {
Expand Down Expand Up @@ -616,8 +615,11 @@ void Hpi::run()
m_pFiffInfo->sfreq,
m_pFiffInfo->linefreq,
false);
hpiDataUpdater.checkForUpdate(m_pFiffInfo);
HPI.checkForUpdate(hpiDataUpdater.getSensors());
bool bHasChanged = hpiDataUpdater.checkForUpdate(m_pFiffInfo);

if(bHasChanged) {
HPI.setSensorSet(hpiDataUpdater.getSensors());
}

hpiDataUpdater.prepareDataAndProjectors(matDataMerged,m_matCompProjectors);
bOrder = m_bDoFreqOrder;
Expand Down
3 changes: 2 additions & 1 deletion libraries/inverse/hpiFit/hpidataupdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void HpiDataUpdater::updateHpiDigitizer(const QList<FiffDigPoint>& lDig)

//=============================================================================================================

void HpiDataUpdater::checkForUpdate(const FiffInfo::SPtr pFiffInfo)
bool HpiDataUpdater::checkForUpdate(const FiffInfo::SPtr pFiffInfo)
{
const bool bUpdate = checkIfChanged(pFiffInfo->bads,pFiffInfo->chs);
if(bUpdate)
Expand All @@ -158,6 +158,7 @@ void HpiDataUpdater::checkForUpdate(const FiffInfo::SPtr pFiffInfo)
updateHpiDigitizer(pFiffInfo->dig);
updateSensors(m_lChannels);
}
return bUpdate;
}

//=============================================================================================================
Expand Down
4 changes: 2 additions & 2 deletions libraries/inverse/hpiFit/hpidataupdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ class INVERSESHARED_EXPORT HpiDataUpdater
* Check if information in FiffInfo changed and update if necessary.
*
* @param[in] pFiffInfo The FiffInfo to check for changes.
*
* @return If information in pFiffInfo has changed and data was updated.
*/
void checkForUpdate(const QSharedPointer<FIFFLIB::FiffInfo> pFiffInfo);
bool checkForUpdate(const QSharedPointer<FIFFLIB::FiffInfo> pFiffInfo);

//=========================================================================================================
/**
Expand Down
2 changes: 1 addition & 1 deletion libraries/inverse/hpiFit/hpifit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ HPIFit::HPIFit(const SensorSet& sensorSet)

//=============================================================================================================

void HPIFit::checkForUpdate(const SensorSet &sensorSet)
void HPIFit::setSensorSet(const SensorSet &sensorSet)
{
if(m_sensors != sensorSet) {
m_sensors = sensorSet;
Expand Down
11 changes: 2 additions & 9 deletions libraries/inverse/hpiFit/hpifit.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,6 @@ class INVERSESHARED_EXPORT HPIFit
typedef QSharedPointer<HPIFit> SPtr; /**< Shared pointer type for HPIFit. */
typedef QSharedPointer<const HPIFit> ConstSPtr; /**< Const shared pointer type for HPIFit. */

//=========================================================================================================
/**
* Default constructor.
*
*/
explicit HPIFit();

//=========================================================================================================
/**
* Constructs the HPI from a SensorSet.
Expand All @@ -159,7 +152,7 @@ class INVERSESHARED_EXPORT HPIFit
*
* @param[in] SensorSet The MEG sensorSet used for the hpi fitting.
*/
void checkForUpdate(const SensorSet& sensorSet);
void setSensorSet(const SensorSet& sensorSet);

//=========================================================================================================
/**
Expand All @@ -170,7 +163,7 @@ class INVERSESHARED_EXPORT HPIFit
* @param[in] hpiModelParameters The model parameters to use for the Hpi Fitting, especially to compute the coil amplitudes.
* @param[in] matCoilsHead The hpi coil locations in head space.
* @param[in] bOrderFrequencies Order Hpi coils yes/no.
* @param[out] hpiFitResult The fitting results.
* @param[in,out] hpiFitResult The fitting results.
*/
void fit(const Eigen::MatrixXd& matProjectedData,
const Eigen::MatrixXd& matProjectors,
Expand Down
8 changes: 4 additions & 4 deletions libraries/inverse/hpiFit/hpimodelparameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
*
*/

#ifndef INVERSELIBE_HPIMODELPARAMETERS_H
#define INVERSELIBE_HPIMODELPARAMETERS_H
#ifndef HPIMODELPARAMETERS_H
#define HPIMODELPARAMETERS_H

//=============================================================================================================
// INCLUDES
Expand Down Expand Up @@ -70,9 +70,9 @@ namespace INVERSELIB {

//=============================================================================================================
/**
* Description of what this class is intended to do (in detail).
* HpiModelParamers holds the information to be used for the HpiFit in general, ans especially for extracting the hpi coil amplitudes from the measurement.
*
* @brief Brief description of this class.
* @brief HpiModelParamers holds the information to be used for the HpiFit in general, ans especially for extracting the hpi coil amplitudes from the measurement.
*/
class INVERSESHARED_EXPORT HpiModelParameters
{
Expand Down
2 changes: 1 addition & 1 deletion libraries/inverse/hpiFit/sensorset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void SensorSet::initMatrices(int ncoils, int np)

SensorSetCreator::SensorSetCreator()
{
const QString qPath = QString(QCoreApplication::applicationDirPath() + "/resources/general/coilDefinitions/coil_def.dat");
const QString qPath = QCoreApplication::applicationDirPath() + "/resources/general/coilDefinitions/coil_def.dat";
m_pCoilDefinitions = FwdCoilSet::SPtr(FwdCoilSet::read_coil_defs(qPath));
}

Expand Down
15 changes: 11 additions & 4 deletions libraries/inverse/hpiFit/sensorset.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,14 @@ namespace FIFFLIB{

namespace INVERSELIB
{
enum class Accuracy : int{high = 2, medium = 1, low = 0};
enum class Accuracy : int{low = 0, medium = 1, high = 2};

//=============================================================================================================
/**
* A SensorSet object holds information about the position and orientation of the MEG sensor arrays.
*
* @brief A SensorSet object holds information about the position and orientation of the MEG sensor arrays.
*/

class INVERSESHARED_EXPORT SensorSet {

Expand Down Expand Up @@ -240,9 +247,9 @@ inline bool SensorSet::operator!= (const SensorSet &b) const

//=============================================================================================================
/**
* Create a SensorSet struct from a channel list with specified accuracy.
* Create a SensorSet struct from a channel list with specified accuracy. Reads sensor information from Coil Definition file.
*
* @brief Brief description of this class.
* @brief Create a SensorSet struct from a channel list with specified accuracy. Reads sensor information from Coil Definition file.
*/
class INVERSESHARED_EXPORT SensorSetCreator
{
Expand All @@ -269,7 +276,7 @@ class INVERSESHARED_EXPORT SensorSetCreator
const Accuracy& accuracy);

private:
QSharedPointer<FWDLIB::FwdCoilSet> m_pCoilDefinitions{nullptr}; // the coil definitions as template
QSharedPointer<FWDLIB::FwdCoilSet> m_pCoilDefinitions; // the coil definitions as template
};

//=============================================================================================================
Expand Down
10 changes: 2 additions & 8 deletions libraries/inverse/hpiFit/signalmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ namespace INVERSELIB

//=============================================================================================================
/**
* Description of what this class is intended to do (in detail).
* This class creates and fits a linear model to extract the amplitudes of the hpi coils from measurement data.
*
* @brief Brief description of this class.
* @brief This class creates and fits a linear model to extract the amplitudes of the hpi coils from measurement data..
*/
class INVERSESHARED_EXPORT SignalModel
{
Expand All @@ -78,12 +78,6 @@ class INVERSESHARED_EXPORT SignalModel
typedef QSharedPointer<SignalModel> SPtr; /**< Shared pointer type for SignalModel. */
typedef QSharedPointer<const SignalModel> ConstSPtr; /**< Const shared pointer type for SignalModel. */

//=========================================================================================================
/**
* Constructs a SignalModel object.
*/
explicit SignalModel() = default;

//=========================================================================================================
/**
* Fit the data to the model constructed from given model parameters.
Expand Down
Loading