20#include "ui_coregsettingsview.h"
42#include <Eigen/Geometry>
64, m_pUi(std::make_unique<Ui::CoregSettingsViewWidget>())
66 m_sSettingsPath = sSettingsPath;
72 connect(m_pUi->m_qPushButton_LoadFid, &QPushButton::released,
73 this, &CoregSettingsView::onLoadFidFile);
74 connect(m_pUi->m_qPushButton_StoreFid, &QPushButton::released,
75 this, &CoregSettingsView::onStoreFidFile);
76 connect(m_pUi->m_qPushButton_LoadDig, &QPushButton::released,
77 this, &CoregSettingsView::onLoadDigFile);
78 connect(m_pUi->m_qPushButton_LoadTrans, &QPushButton::released,
79 this, &CoregSettingsView::onLoadTrans);
80 connect(m_pUi->m_qPushButton_StoreTrans, &QPushButton::released,
81 this, &CoregSettingsView::onStoreTrans);
82 connect(m_pUi->m_qComboBox_BemItems, &QComboBox::currentTextChanged,
85 connect(m_pUi->m_qComboBox_BemItems, &QComboBox::currentTextChanged,
87 connect(m_pUi->m_qComboBox_BemItems, &QComboBox::currentTextChanged,
91 connect(m_pUi->m_qCheckBox_PickFiducials, &QCheckBox::checkStateChanged,
92 this, &CoregSettingsView::onPickingStatus);
93 connect(m_pUi->m_qRadioButton_LPA, &QCheckBox::toggled,
94 this, &CoregSettingsView::onFiducialChanged);
95 connect(m_pUi->m_qRadioButton_NAS, &QCheckBox::toggled,
96 this, &CoregSettingsView::onFiducialChanged);
97 connect(m_pUi->m_qRadioButton_RPA, &QCheckBox::toggled,
98 this, &CoregSettingsView::onFiducialChanged);
102 connect(m_pUi->m_qPushButton_FitFiducials, &QPushButton::released,
103 this, &CoregSettingsView::onFitFiducials);
104 connect(m_pUi->m_qPushButton_FitICP, &QPushButton::released,
105 this, &CoregSettingsView::onFitICP);
108 connect(m_pUi->m_qDoubleSpinBox_ScalingX,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
110 connect(m_pUi->m_qDoubleSpinBox_ScalingY,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
112 connect(m_pUi->m_qDoubleSpinBox_ScalingZ,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
114 connect(m_pUi->m_qDoubleSpinBox_RotX,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
116 connect(m_pUi->m_qDoubleSpinBox_RotY,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
118 connect(m_pUi->m_qDoubleSpinBox_RotZ,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
120 connect(m_pUi->m_qDoubleSpinBox_TransX,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
122 connect(m_pUi->m_qDoubleSpinBox_TransY,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
124 connect(m_pUi->m_qDoubleSpinBox_TransZ,
static_cast<void (QDoubleSpinBox::*)(
double)
>(&QDoubleSpinBox::valueChanged),
126 connect(m_pUi->m_qComboBox_ScalingMode, &QComboBox::currentTextChanged,
127 this, &CoregSettingsView::onScalingModeChanges, Qt::UniqueConnection);
128 onScalingModeChanges();
145 if (m_sSettingsPath.isEmpty()) {
150 QSettings settings(
"MNECPP");
157 if (m_sSettingsPath.isEmpty()) {
162 QSettings settings(
"MNECPP");
191void CoregSettingsView::setToolTipInfo()
193 m_pUi->m_qComboBox_BemItems->setToolTip(
"Select the Bem to use for coregistration. Load the Bem via: File->Open");
194 m_pUi->m_qPushButton_LoadFid->setToolTip(
"Optional. Load the fiducials from file.");
195 m_pUi->m_qPushButton_StoreFid->setToolTip(
"Store the fiducials to file.");
196 m_pUi->m_qPushButton_LoadDig->setToolTip(
"Load the digitizers from file.");
197 m_pUi->m_qPushButton_LoadTrans->setToolTip(
"Optional. Load the coordinate transformation from file.");
198 m_pUi->m_qPushButton_StoreTrans->setToolTip(
"Store the coordinate transformation to file.");
200 m_pUi->m_qDoubleSpinBox_WeightRpa->setToolTip(
"The weight for the RPA.");
201 m_pUi->m_qDoubleSpinBox_WeightLpa->setToolTip(
"The weight for the LPA.");
202 m_pUi->m_qDoubleSpinBox_WeightNas->setToolTip(
"The weight for the Nasion.");
203 m_pUi->m_qDoubleSpinBox_WeightEEG->setToolTip(
"The weight for the EEG points.");
204 m_pUi->m_qDoubleSpinBox_WeightHPI->setToolTip(
"The weight for the HPI points.");
205 m_pUi->m_qDoubleSpinBox_WeightHSP->setToolTip(
"The weight for the HSP points. HSP = Head Shape Points");
206 m_pUi->m_qCheckBox_HSP->setToolTip(
"Wheater to use the HSP points for the Coregistration. HSP = Head Shape Points");
207 m_pUi->m_qCheckBox_EEG->setToolTip(
"Wheater to use the EEG points for the Coregistration.");
208 m_pUi->m_qCheckBox_HPI->setToolTip(
"Wheater to use the HPI points for the Coregistration.");
209 m_pUi->m_qSpinBox_MaxDist->setToolTip(
"The maximum allowed distace between head surface and digitizer cloud. This is used to discard outliers.");
211 m_pUi->m_qCheckBox_AutoScale->setToolTip(
"Wheater to use automatic scaling for the fiducial alignment.");
212 m_pUi->m_qDoubleSpinBox_Converge->setToolTip(
"The convergence limit for the ICP algorithm.");
213 m_pUi->m_qSpinBox_MaxIter->setToolTip(
"The maximum number of iterations for the ICP algorithm.");
214 m_pUi->m_qPushButton_FitFiducials->setToolTip(
"Fiducial alignment. Apply this step before using the ICP algorithm to get a better first guess.");
215 m_pUi->m_qPushButton_FitICP->setToolTip(
"Co-Registration with the ICP algorithm.");
216 m_pUi->m_qLabel_RMSE->setToolTip(
"The Root-Mean-Square-Error of the distance between closest point and digigizer in mm");
217 m_pUi->m_qComboBox_ScalingMode->setToolTip(
"The scaling Mode. None - No scaling is applied; Uniform - same scaling for x,y,z-axis; 3-Axis - scaling on each axis.");
218 m_pUi->m_qDoubleSpinBox_ScalingX->setToolTip(
"Scaling to apply in x-direction.");
219 m_pUi->m_qDoubleSpinBox_ScalingY->setToolTip(
"Scaling to apply in y-direction.");
220 m_pUi->m_qDoubleSpinBox_ScalingZ->setToolTip(
"Scaling to apply in z-direction.");
222 m_pUi->m_qDoubleSpinBox_RotX->setToolTip(
"Rotation arround x-axis.");
223 m_pUi->m_qDoubleSpinBox_RotY->setToolTip(
"Rotation arround y-axis.");
224 m_pUi->m_qDoubleSpinBox_RotZ->setToolTip(
"Rotation arround z-axis.");
226 m_pUi->m_qDoubleSpinBox_TransX->setToolTip(
"Translation to apply in x-direction.");
227 m_pUi->m_qDoubleSpinBox_TransY->setToolTip(
"Translation to apply in y-direction.");
228 m_pUi->m_qDoubleSpinBox_TransZ->setToolTip(
"Translation to apply in z-direction.");
233void CoregSettingsView::onLoadFidFile()
235 QString sFileName = QFileDialog::getOpenFileName(
this,
236 tr(
"Select fiducials"),
238 tr(
"Fif Files (*.fif)"));
240 if (sFileName.isEmpty()) {
249void CoregSettingsView::onPickingStatus()
251 bool bState = m_pUi->m_qCheckBox_PickFiducials->isChecked();
253 m_pUi->m_qWidget_ResultFiducials->setEnabled(
true);
256 m_pUi->m_qWidget_ResultFiducials->setEnabled(
false);
268 if (m_pUi->m_qRadioButton_LPA->isChecked()) {
269 m_vecLPA = vecPosition;
272 m_pUi->m_qRadioButton_NAS->setChecked(
true);
275 }
else if (m_pUi->m_qRadioButton_NAS->isChecked()) {
276 m_vecNAS = vecPosition;
279 m_pUi->m_qRadioButton_RPA->setChecked(
true);
283 m_vecRPA = vecPosition;
286 m_pUi->m_qRadioButton_LPA->setChecked(
true);
292 m_pUi->m_qLineEdit_FidX->setText(QString::number(floor(vecTemp[0] * 100) / 100 * 1000) +
" mm");
293 m_pUi->m_qLineEdit_FidY->setText(QString::number(floor(vecTemp[1] * 100) / 100 * 1000) +
" mm");
294 m_pUi->m_qLineEdit_FidZ->setText(QString::number(floor(vecTemp[2] * 100) / 100 * 1000) +
" mm");
300void CoregSettingsView::onFiducialChanged()
303 if (m_pUi->m_qRadioButton_LPA->isChecked()) {
306 }
else if (m_pUi->m_qRadioButton_NAS->isChecked()) {
315 m_pUi->m_qLineEdit_FidX->setText(QString::number(floor(vecTemp[0] * 100) / 100 * 1000) +
" mm");
316 m_pUi->m_qLineEdit_FidY->setText(QString::number(floor(vecTemp[1] * 100) / 100 * 1000) +
" mm");
317 m_pUi->m_qLineEdit_FidZ->setText(QString::number(floor(vecTemp[2] * 100) / 100 * 1000) +
" mm");
323void CoregSettingsView::onStoreFidFile()
325 QString sFileName = QFileDialog::getSaveFileName(
nullptr,
326 tr(
"Save Fiducials"),
"",
327 tr(
"Fif file (*fiducials.fif)"));
329 if (sFileName.isEmpty()) {
338void CoregSettingsView::onLoadDigFile()
340 QString sFileName = QFileDialog::getOpenFileName(
this,
341 tr(
"Select digitizer file"),
343 tr(
"Fif Files (*.fif)"));
345 if (sFileName.isEmpty()) {
354void CoregSettingsView::onLoadTrans()
356 QString sFileName = QFileDialog::getOpenFileName(
this,
357 tr(
"Select Transformation"),
359 tr(
"Fif Files (*-trans.fif)"));
361 if (sFileName.isEmpty()) {
370void CoregSettingsView::onStoreTrans()
372 QString sFileName = QFileDialog::getSaveFileName(
nullptr,
373 tr(
"Save Transformation"),
"",
374 tr(
"Fif file (*-trans.fif)"));
376 if (sFileName.isEmpty()) {
388 if (m_pUi->m_qRadioButton_LPA->isChecked()) {
390 }
else if (m_pUi->m_qRadioButton_NAS->isChecked()) {
392 }
else if (m_pUi->m_qRadioButton_RPA->isChecked()) {
402 return m_pUi->m_qSpinBox_MaxIter->value();
409 return m_pUi->m_qDoubleSpinBox_Converge->value() / 1000;
416 return m_pUi->m_qCheckBox_AutoScale->isChecked();
423 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightLpa->value());
430 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightRpa->value());
437 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightNas->value());
444 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightEEG->value());
451 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightHPI->value());
458 return static_cast<float>(m_pUi->m_qDoubleSpinBox_WeightHSP->value());
465 return static_cast<float>(m_pUi->m_qSpinBox_MaxDist->value()) / 1000.0;
476 if (m_pUi->m_qCheckBox_EEG->isChecked()) {
479 if (m_pUi->m_qCheckBox_HPI->isChecked()) {
482 if (m_pUi->m_qCheckBox_HSP->isChecked()) {
493 QSignalBlocker blockerComboBox(m_pUi->m_qComboBox_BemItems);
494 m_pUi->m_qComboBox_BemItems->clear();
501 m_pUi->m_qComboBox_BemItems->addItem(sBemName);
508 return m_pUi->m_qComboBox_BemItems->currentText();
515 m_pUi->m_qLabel_NOmitted->setText(QString::number(iN));
522 m_pUi->m_qLabel_RMSE->setText(QString::number(fRMSE * 1000) +
" mm");
528 const Vector3f& vecRot,
529 const Vector3f& vecScale)
532 QSignalBlocker blockerTransX(m_pUi->m_qDoubleSpinBox_TransX);
533 QSignalBlocker blockerTransY(m_pUi->m_qDoubleSpinBox_TransY);
534 QSignalBlocker blockerTransZ(m_pUi->m_qDoubleSpinBox_TransZ);
535 QSignalBlocker blockerRotX(m_pUi->m_qDoubleSpinBox_RotX);
536 QSignalBlocker blockerRotY(m_pUi->m_qDoubleSpinBox_RotY);
537 QSignalBlocker blockerRotZ(m_pUi->m_qDoubleSpinBox_RotZ);
538 QSignalBlocker blockerScaleX(m_pUi->m_qDoubleSpinBox_ScalingX);
539 QSignalBlocker blockerScaleY(m_pUi->m_qDoubleSpinBox_ScalingY);
540 QSignalBlocker blockerScaleZ(m_pUi->m_qDoubleSpinBox_ScalingZ);
542 m_pUi->m_qDoubleSpinBox_TransX->setValue(vecTrans(0) * 1000);
543 m_pUi->m_qDoubleSpinBox_TransY->setValue(vecTrans(1) * 1000);
544 m_pUi->m_qDoubleSpinBox_TransZ->setValue(vecTrans(2) * 1000);
547 m_pUi->m_qDoubleSpinBox_RotX->setValue(vecRot(2) * 180 / std::numbers::pi);
548 m_pUi->m_qDoubleSpinBox_RotY->setValue(vecRot(1) * 180 / std::numbers::pi);
549 m_pUi->m_qDoubleSpinBox_RotZ->setValue(vecRot(0) * 180 / std::numbers::pi);
551 m_pUi->m_qDoubleSpinBox_ScalingX->setValue(vecScale(0));
552 m_pUi->m_qDoubleSpinBox_ScalingY->setValue(vecScale(1));
553 m_pUi->m_qDoubleSpinBox_ScalingZ->setValue(vecScale(2));
562 vecTrans(0) = m_pUi->m_qDoubleSpinBox_TransX->value() / 1000.0;
563 vecTrans(1) = m_pUi->m_qDoubleSpinBox_TransY->value() / 1000.0;
564 vecTrans(2) = m_pUi->m_qDoubleSpinBox_TransZ->value() / 1000.0;
567 vecRot(2) = m_pUi->m_qDoubleSpinBox_RotX->value() * std::numbers::pi / 180.0;
568 vecRot(1) = m_pUi->m_qDoubleSpinBox_RotY->value() * std::numbers::pi / 180.0;
569 vecRot(0) = m_pUi->m_qDoubleSpinBox_RotZ->value() * std::numbers::pi / 180.0;
572 if (m_pUi->m_qComboBox_ScalingMode->currentText() ==
"Uniform") {
573 vecScale.fill(m_pUi->m_qDoubleSpinBox_ScalingX->value());
574 }
else if (m_pUi->m_qComboBox_ScalingMode->currentText() ==
"3-Axis") {
575 vecScale(0) = m_pUi->m_qDoubleSpinBox_ScalingX->value();
576 vecScale(1) = m_pUi->m_qDoubleSpinBox_ScalingY->value();
577 vecScale(2) = m_pUi->m_qDoubleSpinBox_ScalingZ->value();
587void CoregSettingsView::onScalingModeChanges()
590 if (m_pUi->m_qComboBox_ScalingMode->currentText() ==
"Uniform") {
591 m_pUi->m_qDoubleSpinBox_ScalingX->setEnabled(
true);
592 m_pUi->m_qDoubleSpinBox_ScalingY->setEnabled(
false);
593 m_pUi->m_qDoubleSpinBox_ScalingZ->setEnabled(
false);
594 }
else if (m_pUi->m_qComboBox_ScalingMode->currentText() ==
"3-Axis") {
595 m_pUi->m_qDoubleSpinBox_ScalingX->setEnabled(
true);
596 m_pUi->m_qDoubleSpinBox_ScalingY->setEnabled(
true);
597 m_pUi->m_qDoubleSpinBox_ScalingZ->setEnabled(
true);
599 m_pUi->m_qDoubleSpinBox_ScalingX->setEnabled(
false);
600 m_pUi->m_qDoubleSpinBox_ScalingY->setEnabled(
false);
601 m_pUi->m_qDoubleSpinBox_ScalingZ->setEnabled(
false);
608void CoregSettingsView::onFitFiducials()
610 m_pUi->m_qCheckBox_PickFiducials->setChecked(
false);
616void CoregSettingsView::onFitICP()
618 m_pUi->m_qCheckBox_PickFiducials->setChecked(
false);
constexpr auto FIFFV_POINT_EXTRA
constexpr auto FIFFV_POINT_CARDINAL
constexpr auto FIFFV_POINT_HPI
constexpr auto FIFFV_POINT_EEG
constexpr auto FIFFV_POINT_LPA
constexpr auto FIFFV_POINT_NASION
constexpr auto FIFFV_POINT_RPA
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
Co-registration parameter panel driving the MRI ↔ head fiducial alignment dialog.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
AbstractView(QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
void fidFileChanged(const QString &sFilePath)
void setRMSE(const float fRMSE)
void addSelectionBem(const QString &sBemName)
void updateProcessingMode(ProcessingMode mode)
void changeSelectedBem(const QString &sText)
void setOmittedPoints(const int iN)
void updateGuiMode(GuiMode mode)
void pickFiducials(bool bActivatePicking)
QString getCurrentSelectedBem()
void loadTrans(const QString &sFilePath)
void setTransParams(const Eigen::Vector3f &vecTrans, const Eigen::Vector3f &vecRot, const Eigen::Vector3f &vecScale)
QList< int > getDigitizerCheckState()
void fidStoreFileChanged(const QString &sFilePath)
void setFiducials(const QVector3D vecAxialPosition)
void digFileChanged(const QString &sFilePath)
void getTransParams(Eigen::Vector3f &vecRot, Eigen::Vector3f &vecTrans, Eigen::Vector3f &vecScale)
void storeTrans(const QString &sFilePath)
void fiducialChanged(const int iFiducial)
CoregSettingsView(const QString &sSettingsPath="", QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)