24#include "ui_hpisettingsview.h"
60,
m_pUi(std::make_unique<Ui::HpiSettingsViewWidget>())
65 connect(
m_pUi->m_pushButton_loadDigitizers, &QPushButton::released,
67 connect(
m_pUi->m_pushButton_doFreqOrder, &QPushButton::clicked,
69 connect(
m_pUi->m_pushButton_doSingleFit, &QPushButton::clicked,
71 connect(
m_pUi->m_tableWidget_Frequencies, &QTableWidget::cellChanged,
73 connect(
m_pUi->m_pushButton_addCoil, &QPushButton::clicked,
75 connect(
m_pUi->m_pushButton_removeCoil, &QPushButton::clicked,
77 connect(
m_pUi->m_checkBox_useSSP, &QCheckBox::clicked,
79 connect(
m_pUi->m_checkBox_useComp, &QCheckBox::clicked,
81 connect(
m_pUi->m_checkBox_continousHPI, &QCheckBox::clicked,
83 connect(
m_pUi->m_spinBox_samplesToFit, QOverload<int>::of(&QSpinBox::valueChanged),
85 connect(
m_pUi->m_doubleSpinBox_maxHPIContinousDist,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
87 connect(
m_pUi->m_doubleSpinBox_moveThreshold,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
89 connect(
m_pUi->m_doubleSpinBox_rotThreshold,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
91 connect(
m_pUi->comboBox_coilPreset,
static_cast<void (QComboBox::*)(
int)
>(&QComboBox::currentIndexChanged),
110 const double dMeanErrorDist)
115 for (
int i = 0; i < vError.size(); ++i) {
116 if (i < m_pUi->m_tableWidget_results->rowCount()) {
117 sGof = QString::number(vError[i] * 1000,
'f', 2) + QString(
" mm");
118 m_pUi->m_tableWidget_results->item(i, 1)->setText(sGof);
122 m_pUi->m_label_averagedFitError->setText(QString::number(dMeanErrorDist * 1000,
'f', 2) + QString(
" mm"));
125 if (dMeanErrorDist * 1000 >
m_pUi->m_doubleSpinBox_maxHPIContinousDist->value()) {
126 m_pUi->m_label_fitFeedback->setText(
"Last fit: Bad");
127 m_pUi->m_label_fitFeedback->setStyleSheet(
"QLabel { background-color : red;}");
129 m_pUi->m_label_fitFeedback->setText(
"Last fit: Good");
130 m_pUi->m_label_fitFeedback->setStyleSheet(
"QLabel { background-color : green;}");
137 const double dMeanGof)
140 QString sGof(
"00.00");
142 for (
int i = 0; i < vGoF.size(); ++i) {
143 if (i < m_pUi->m_tableWidget_results->rowCount()) {
144 sGof = QString::number(vGoF[i] * 100,
'f', 2) + QString(
" %");
145 m_pUi->m_tableWidget_results->item(i, 2)->setText(sGof);
149 m_pUi->m_average_gof_set->setText(QString::number(dMeanGof * 100,
'f', 2) + QString(
" %"));
157 m_pUi->m_qLineEdit_moveResult->setText(QString::number(dMovement * 1000,
'f', 2) + QString(
" mm"));
158 m_pUi->m_qLineEdit_rotResult->setText(QString::number(dRotation,
'f', 2) + QString(
" °"));
160 if (dMovement * 1000 >
m_pUi->m_doubleSpinBox_moveThreshold->value() || dRotation >
m_pUi->m_doubleSpinBox_rotThreshold->value()) {
161 m_pUi->m_label_movementFeedback->setText(
"Big");
162 m_pUi->m_label_movementFeedback->setStyleSheet(
"QLabel { background-color : red;}");
164 m_pUi->m_label_movementFeedback->setText(
"Small");
165 m_pUi->m_label_movementFeedback->setStyleSheet(
"QLabel { background-color : green;}");
173 return m_pUi->m_checkBox_useSSP->isChecked();
180 return m_pUi->m_checkBox_useComp->isChecked();
187 return m_pUi->m_doubleSpinBox_maxHPIContinousDist->value();
194 return m_pUi->m_doubleSpinBox_moveThreshold->value();
201 return m_pUi->m_doubleSpinBox_rotThreshold->value();
208 return m_pUi->m_checkBox_continousHPI->isChecked();
215 return m_pUi->m_spinBox_samplesToFit->value();
226 QSettings settings(
"MNECPP");
228 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/coilFreqs"),
231 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/useSSP"),
232 QVariant::fromValue(
m_pUi->m_checkBox_useSSP->isChecked()));
234 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/useCOMP"),
235 QVariant::fromValue(
m_pUi->m_checkBox_useComp->isChecked()));
237 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/continousHPI"),
238 QVariant::fromValue(
m_pUi->m_checkBox_continousHPI->isChecked()));
240 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/maxError"),
241 QVariant::fromValue(
m_pUi->m_doubleSpinBox_maxHPIContinousDist->value()));
243 settings.setValue(
m_sSettingsPath + QString(
"/HpiSettingsView/fittingWindowSize"),
244 QVariant::fromValue(
m_pUi->m_spinBox_samplesToFit->value()));
255 QSettings settings(
"MNECPP");
256 QVariant defaultData;
262 m_pUi->m_checkBox_useSSP->setChecked(settings.value(
m_sSettingsPath + QString(
"/HpiSettingsView/useSSP"),
false).toBool());
263 m_pUi->m_checkBox_useComp->setChecked(settings.value(
m_sSettingsPath + QString(
"/HpiSettingsView/useCOMP"),
false).toBool());
264 m_pUi->m_checkBox_continousHPI->setChecked(settings.value(
m_sSettingsPath + QString(
"/HpiSettingsView/continousHPI"),
false).toBool());
265 m_pUi->m_doubleSpinBox_maxHPIContinousDist->setValue(settings.value(
m_sSettingsPath + QString(
"/HpiSettingsView/maxError"), 10.0).toDouble());
266 m_pUi->m_spinBox_samplesToFit->setValue(settings.value(
m_sSettingsPath + QString(
"/HpiSettingsView/fittingWindowSize"), 300).toInt());
298 QString fileName_HPI = QFileDialog::getOpenFileName(
this,
299 tr(
"Open digitizer file"),
301 tr(
"Fiff file (*.fif)"));
303 if (!fileName_HPI.isEmpty()) {
304 m_pUi->m_lineEdit_filePath->setText(fileName_HPI);
308 if (!fileName_HPI.isEmpty()) {
309 fileName_HPI = fileName_HPI.trimmed();
310 QFileInfo checkFile(fileName_HPI);
313 : QList<FiffDigPoint>();
314 if (!digitizers.isEmpty()) {
316 m_pUi->m_checkBox_continousHPI->setChecked(
false);
320 msgBox.setText(
"File could not be loaded!");
336 if (QTableWidgetItem* pItem =
m_pUi->m_tableWidget_Frequencies->item(row, col)) {
337 if (pItem->text() ==
"none") {
351 if (
m_pUi->m_tableWidget_Frequencies->rowCount() + 1 >
m_pUi->m_label_numberLoadedCoils->text().toInt()) {
353 msgBox.setText(
"Cannot add more HPI coils. Not enough digitzed HPI coils loaded.");
359 m_pUi->m_tableWidget_Frequencies->insertRow(
m_pUi->m_tableWidget_Frequencies->rowCount());
360 QTableWidgetItem* pTableItemA =
new QTableWidgetItem(QString::number(
m_pUi->m_tableWidget_Frequencies->rowCount()));
361 pTableItemA->setFlags(Qt::ItemIsEnabled);
362 m_pUi->m_tableWidget_Frequencies->setItem(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
368 m_pUi->m_tableWidget_Frequencies->setItem(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
370 new QTableWidgetItem(QString::number(
m_vCoilFreqs.at(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1))));
372 m_pUi->m_tableWidget_Frequencies->setItem(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
374 new QTableWidgetItem(
"none"));
379 m_pUi->m_tableWidget_results->insertRow(
m_pUi->m_tableWidget_results->rowCount());
380 QTableWidgetItem* pTableItemB =
new QTableWidgetItem(QString::number(
m_pUi->m_tableWidget_Frequencies->rowCount()));
381 pTableItemB->setFlags(Qt::ItemIsEnabled);
382 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
387 QTableWidgetItem* pTableItemC =
new QTableWidgetItem(
"0mm");
388 pTableItemC->setFlags(Qt::ItemIsEnabled);
389 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
394 QTableWidgetItem* pTableItemD =
new QTableWidgetItem(
"00.00");
395 pTableItemD->setFlags(Qt::ItemIsEnabled);
396 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
407 int row =
m_pUi->m_tableWidget_Frequencies->currentRow();
411 m_pUi->m_tableWidget_Frequencies->removeRow(row);
413 for (
int i = 0; i <
m_pUi->m_tableWidget_Frequencies->rowCount(); ++i) {
414 m_pUi->m_tableWidget_Frequencies->item(i, 0)->setText(QString::number(i + 1));
417 m_pUi->m_tableWidget_results->removeRow(row);
419 for (
int i = 0; i <
m_pUi->m_tableWidget_results->rowCount(); ++i) {
420 m_pUi->m_tableWidget_results->item(i, 0)->setText(QString::number(i + 1));
431 QFile t_fileDig(fileName);
459 qint16 numFiducials = 0;
461 qint16 numAdditional = 0;
463 for (
int i = 0; i < digSet.
size(); ++i) {
464 switch (digSet[i].kind) {
484 m_pUi->m_label_numberLoadedCoils->setNum(numHPI);
485 m_pUi->m_label_numberLoadedFiducials->setNum(numFiducials);
486 m_pUi->m_label_numberLoadedEEG->setNum(numEEG);
487 m_pUi->m_label_numberLoadedAdditional->setNum(numAdditional);
513 m_pUi->m_tableWidget_Frequencies->insertRow(
m_pUi->m_tableWidget_Frequencies->rowCount());
514 QTableWidgetItem* pTableItemA =
new QTableWidgetItem(QString::number(
m_pUi->m_tableWidget_Frequencies->rowCount()));
515 pTableItemA->setFlags(Qt::ItemIsEnabled);
516 m_pUi->m_tableWidget_Frequencies->setItem(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
521 m_pUi->m_tableWidget_Frequencies->setItem(
m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
523 new QTableWidgetItem(QString::number(iCoilFreq)));
531 m_pUi->m_tableWidget_results->insertRow(
m_pUi->m_tableWidget_results->rowCount());
532 QTableWidgetItem* pTableItemB =
new QTableWidgetItem(QString::number(
m_pUi->m_tableWidget_Frequencies->rowCount()));
533 pTableItemB->setFlags(Qt::ItemIsEnabled);
534 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
539 QTableWidgetItem* pTableItemC =
new QTableWidgetItem(
"0mm");
540 pTableItemC->setFlags(Qt::ItemIsEnabled);
541 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
546 QTableWidgetItem* pTableItemD =
new QTableWidgetItem(
"00.00%");
547 pTableItemD->setFlags(Qt::ItemIsEnabled);
548 m_pUi->m_tableWidget_results->setItem(
m_pUi->m_tableWidget_results->rowCount() - 1,
557 m_pUi->m_tableWidget_Frequencies->clear();
558 m_pUi->m_tableWidget_Frequencies->setRowCount(0);
559 m_pUi->m_tableWidget_Frequencies->setHorizontalHeaderItem(0,
new QTableWidgetItem(
"#Coil"));
560 m_pUi->m_tableWidget_Frequencies->setHorizontalHeaderItem(1,
new QTableWidgetItem(
"Frequency (Hz)"));
562 m_pUi->m_tableWidget_results->clear();
563 m_pUi->m_tableWidget_results->setRowCount(0);
564 m_pUi->m_tableWidget_results->setHorizontalHeaderItem(0,
new QTableWidgetItem(
"#Coil"));
565 m_pUi->m_tableWidget_results->setHorizontalHeaderItem(1,
new QTableWidgetItem(
"Error"));
566 m_pUi->m_tableWidget_results->setHorizontalHeaderItem(2,
new QTableWidgetItem(
"GoF"));
579 QFile inFile(sFilePath);
580 if (inFile.open(QIODevice::ReadOnly)) {
581 QByteArray inArray = inFile.readAll();
591 QJsonArray presetData =
m_CoilPresets.object()[QString::number(iNumCoils)].toArray();
600 m_pUi->comboBox_coilPreset->clear();
601 m_pUi->comboBox_coilPreset->addItem(
"Load preset");
603 for (
const auto& entry : presetData) {
604 QString name = entry.toObject()[
"name"].toString();
605 QVector<int> vecCoils;
607 for (
const auto& coil : entry.toObject()[
"coils"].toArray()) {
608 vecCoils.append(coil.toInt());
611 m_pUi->comboBox_coilPreset->addItem(name, QVariant::fromValue(vecCoils));
619 if (iCoilPresetIndex < (
m_pUi->comboBox_coilPreset->count())) {
620 auto coilFreqData =
m_pUi->comboBox_coilPreset->itemData(iCoilPresetIndex);
621 if (!coilFreqData.isNull() && coilFreqData.canConvert<QVector<int>>()) {
constexpr auto FIFFV_POINT_EXTRA
constexpr auto FIFFV_POINT_CARDINAL
constexpr auto FIFFV_POINT_HPI
constexpr auto FIFFV_POINT_EEG
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
Container for the FIFF_DIG_POINT records of a measurement (a parsed FIFFB_ISOTRAK block).
Continuous HPI head-position-indicator configuration panel.
FIFF file I/O, in-memory data structures and high-level readers/writers.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
AbstractView(QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
QVector< int > m_vCoilFreqs
void allowedRotationChanged(double dAllowedRotation)
void updateProcessingMode(ProcessingMode mode)
void sspStatusChanged(bool bChecked)
void updateDigitizerInfoGUI(const FIFFLIB::FiffDigPointSet &digSet)
bool getCompStatusChanged()
void fittingWindowSizeChanged(int iFitsPerSecond)
QJsonDocument m_CoilPresets
void setMovementResults(double dMovement, double dRotation)
void loadCoilPresets(const QString &sFilePath)
void coilFrequenciesChanged(const QVector< int > &vCoilFreqs)
bool continuousHPIChecked()
double getAllowedRotationChanged()
void newDigitizerList(QList< FIFFLIB::FiffDigPoint > pointList)
void addCoilFreqToGUI(int iCoilFreq)
void updateGuiMode(GuiMode mode)
void populatePresetGUI(const QJsonArray &presetData)
double getAllowedMovementChanged()
void setGoFLabels(const Eigen::VectorXd &vGoF, const double dMeanGof)
void compStatusChanged(bool bChecked)
bool getSspStatusChanged()
void setupCoilPresets(int iNumCoils)
void onFrequencyCellChanged(int row, int col)
void setErrorLabels(const QVector< double > &vError, const double dMeanErrorDist)
void addCoilErrorToGUI()
addCoilErrorToGUI
HpiSettingsView(const QString &sSettingsPath="", QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
void allowedMovementChanged(double dAllowedMovement)
void allowedMeanErrorDistChanged(double dAllowedMeanErrorDist)
void selectCoilPreset(int iCoilPresetIndex)
int getFittingWindowSize()
QList< FIFFLIB::FiffDigPoint > readDigitizersFromFile(const QString &fileName)
double getAllowedMeanErrorDistChanged()
std::unique_ptr< Ui::HpiSettingsViewWidget > m_pUi
void digitizersChanged(const QList< FIFFLIB::FiffDigPoint > &lDigitzers, const QString &sFilePath)
void contHpiStatusChanged(bool bChecked)
Collection of FiffDigPoint records as parsed from a FIFFB_ISOTRAK block.
static bool readFromStream(FiffStream::SPtr &p_Stream, FiffDigPointSet &p_Dig)
QList< FiffDigPoint > getList()
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
QSharedPointer< FiffStream > SPtr