v2.0.0
Loading...
Searching...
No Matches
hpisettingsview.cpp
Go to the documentation of this file.
1//=============================================================================================================
17
18//=============================================================================================================
19// INCLUDES
20//=============================================================================================================
21
22#include "hpisettingsview.h"
23
24#include "ui_hpisettingsview.h"
25
27#include <fiff/fiff_stream.h>
28#include <iostream>
29
30//=============================================================================================================
31// QT INCLUDES
32//=============================================================================================================
33
34#include <QFileInfo>
35#include <QFileDialog>
36#include <QMessageBox>
37#include <QSettings>
38#include <QJsonObject>
39#include <QJsonArray>
40
41//=============================================================================================================
42// EIGEN INCLUDES
43//=============================================================================================================
44
45//=============================================================================================================
46// USED NAMESPACES
47//=============================================================================================================
48
49using namespace DISPLIB;
50using namespace FIFFLIB;
51
52//=============================================================================================================
53// DEFINE MEMBER METHODS
54//=============================================================================================================
55
56HpiSettingsView::HpiSettingsView(const QString& sSettingsPath,
57 QWidget* parent,
58 Qt::WindowFlags f)
59: AbstractView(parent, f)
60, m_pUi(std::make_unique<Ui::HpiSettingsViewWidget>())
61{
62 m_sSettingsPath = sSettingsPath;
63 m_pUi->setupUi(this);
64
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),
93
94 //Init coil freqs
95 m_vCoilFreqs << 293 << 307 << 314 << 321;
96
98}
99
100//=============================================================================================================
101
106
107//=============================================================================================================
108
109void HpiSettingsView::setErrorLabels(const QVector<double>& vError,
110 const double dMeanErrorDist)
111{
112 //Update eror labels and change from m to mm
113 QString sGof("0mm");
114
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);
119 }
120 }
121
122 m_pUi->m_label_averagedFitError->setText(QString::number(dMeanErrorDist * 1000, 'f', 2) + QString(" mm"));
123
124 //Update good/bad fit label
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;}");
128 } else {
129 m_pUi->m_label_fitFeedback->setText("Last fit: Good");
130 m_pUi->m_label_fitFeedback->setStyleSheet("QLabel { background-color : green;}");
131 }
132}
133
134//=============================================================================================================
135
136void HpiSettingsView::setGoFLabels(const Eigen::VectorXd& vGoF,
137 const double dMeanGof)
138{
139 //Update gof labels and change to %
140 QString sGof("00.00");
141
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);
146 }
147 }
148
149 m_pUi->m_average_gof_set->setText(QString::number(dMeanGof * 100, 'f', 2) + QString(" %"));
150}
151
152//=========================================================================================================
153
155 double dRotation)
156{
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(" °"));
159
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;}");
163 } else {
164 m_pUi->m_label_movementFeedback->setText("Small");
165 m_pUi->m_label_movementFeedback->setStyleSheet("QLabel { background-color : green;}");
166 }
167}
168
169//=============================================================================================================
170
172{
173 return m_pUi->m_checkBox_useSSP->isChecked();
174}
175
176//=============================================================================================================
177
179{
180 return m_pUi->m_checkBox_useComp->isChecked();
181}
182
183//=============================================================================================================
184
186{
187 return m_pUi->m_doubleSpinBox_maxHPIContinousDist->value();
188}
189
190//=============================================================================================================
191
193{
194 return m_pUi->m_doubleSpinBox_moveThreshold->value();
195}
196
197//=============================================================================================================
198
200{
201 return m_pUi->m_doubleSpinBox_rotThreshold->value();
202}
203
204//=============================================================================================================
205
207{
208 return m_pUi->m_checkBox_continousHPI->isChecked();
209}
210
211//=============================================================================================================
212
214{
215 return m_pUi->m_spinBox_samplesToFit->value();
216}
217
218//=============================================================================================================
219
221{
222 if (m_sSettingsPath.isEmpty()) {
223 return;
224 }
225
226 QSettings settings("MNECPP");
227
228 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/coilFreqs"),
229 QVariant::fromValue(m_vCoilFreqs));
230
231 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/useSSP"),
232 QVariant::fromValue(m_pUi->m_checkBox_useSSP->isChecked()));
233
234 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/useCOMP"),
235 QVariant::fromValue(m_pUi->m_checkBox_useComp->isChecked()));
236
237 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/continousHPI"),
238 QVariant::fromValue(m_pUi->m_checkBox_continousHPI->isChecked()));
239
240 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/maxError"),
241 QVariant::fromValue(m_pUi->m_doubleSpinBox_maxHPIContinousDist->value()));
242
243 settings.setValue(m_sSettingsPath + QString("/HpiSettingsView/fittingWindowSize"),
244 QVariant::fromValue(m_pUi->m_spinBox_samplesToFit->value()));
245}
246
247//=============================================================================================================
248
250{
251 if (m_sSettingsPath.isEmpty()) {
252 return;
253 }
254
255 QSettings settings("MNECPP");
256 QVariant defaultData;
257
258 defaultData.setValue(m_vCoilFreqs);
259 m_vCoilFreqs = settings.value(m_sSettingsPath + QString("/HpiSettingsView/coilFreqs"), defaultData).value<QVector<int>>();
261
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());
267}
268
269//=============================================================================================================
270
272{
273 switch (mode) {
275 break;
276 default: // default is research mode
277 break;
278 }
279}
280
281//=============================================================================================================
282
284{
285 switch (mode) {
287 break;
288 default: // default is realtime mode
289 break;
290 }
291}
292
293//=============================================================================================================
294
296{
297 //Get file location
298 QString fileName_HPI = QFileDialog::getOpenFileName(this,
299 tr("Open digitizer file"),
300 "",
301 tr("Fiff file (*.fif)"));
302
303 if (!fileName_HPI.isEmpty()) {
304 m_pUi->m_lineEdit_filePath->setText(fileName_HPI);
305 }
306
307 //Load Polhemus file
308 if (!fileName_HPI.isEmpty()) {
309 fileName_HPI = fileName_HPI.trimmed();
310 QFileInfo checkFile(fileName_HPI);
311
312 const QList<FiffDigPoint> digitizers = checkFile.isFile() ? readDigitizersFromFile(fileName_HPI)
313 : QList<FiffDigPoint>();
314 if (!digitizers.isEmpty()) {
315 // Stop cont HPI first
316 m_pUi->m_checkBox_continousHPI->setChecked(false);
317 emit digitizersChanged(digitizers, fileName_HPI);
318 } else {
319 QMessageBox msgBox;
320 msgBox.setText("File could not be loaded!");
321 msgBox.exec();
322 return;
323 }
324 }
325}
326
327//=============================================================================================================
328
330 int col)
331{
332 if (col != 1 || row >= m_vCoilFreqs.size()) {
333 return;
334 }
335
336 if (QTableWidgetItem* pItem = m_pUi->m_tableWidget_Frequencies->item(row, col)) {
337 if (pItem->text() == "none") {
338 m_vCoilFreqs[row] = -1;
339 } else {
340 m_vCoilFreqs[row] = pItem->text().toInt();
341 }
342
344 }
345}
346
347//=============================================================================================================
348
350{
351 if (m_pUi->m_tableWidget_Frequencies->rowCount() + 1 > m_pUi->m_label_numberLoadedCoils->text().toInt()) {
352 QMessageBox msgBox;
353 msgBox.setText("Cannot add more HPI coils. Not enough digitzed HPI coils loaded.");
354 msgBox.exec();
355 return;
356 }
357
358 // Add column 0 in freq table widget
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,
363 0,
364 pTableItemA);
365
366 // Add column 1 in freq table widget
367 if (m_vCoilFreqs.size() >= m_pUi->m_tableWidget_Frequencies->rowCount()) {
368 m_pUi->m_tableWidget_Frequencies->setItem(m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
369 1,
370 new QTableWidgetItem(QString::number(m_vCoilFreqs.at(m_pUi->m_tableWidget_Frequencies->rowCount() - 1))));
371 } else {
372 m_pUi->m_tableWidget_Frequencies->setItem(m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
373 1,
374 new QTableWidgetItem("none"));
375 m_vCoilFreqs.append(-1);
376 }
377
378 // Add column 0 in error table widget (coil number)
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,
383 0,
384 pTableItemB);
385
386 // Add column 1 in error table widget (error)
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,
390 1,
391 pTableItemC);
392
393 // Add column 2 in error table widget (gof)
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,
397 2,
398 pTableItemD);
399
401}
402
403//=============================================================================================================
404
406{
407 int row = m_pUi->m_tableWidget_Frequencies->currentRow();
408
409 if (row >= 0 && row < m_vCoilFreqs.size()) {
410 m_vCoilFreqs.remove(row);
411 m_pUi->m_tableWidget_Frequencies->removeRow(row);
412
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));
415 }
416
417 m_pUi->m_tableWidget_results->removeRow(row);
418
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));
421 }
422
424 }
425}
426
427//=============================================================================================================
428
429QList<FiffDigPoint> HpiSettingsView::readDigitizersFromFile(const QString& fileName)
430{
431 QFile t_fileDig(fileName);
432 FIFFLIB::FiffStream::SPtr t_pStream(new FIFFLIB::FiffStream(&t_fileDig));
433 FiffDigPointSet t_digSet;
434 if (!FiffDigPointSet::readFromStream(t_pStream, t_digSet) || t_digSet.size() == 0) {
435 return {};
436 }
437
438 clearCoilGUI();
439 updateDigitizerInfoGUI(t_digSet);
440
441 return t_digSet.getList();
442}
443
444//=============================================================================================================
445
446void HpiSettingsView::newDigitizerList(QList<FIFFLIB::FiffDigPoint> pointList)
447{
448 clearCoilGUI();
449
450 FiffDigPointSet t_digSet(pointList);
451 updateDigitizerInfoGUI(t_digSet);
452}
453
454//=============================================================================================================
455
457{
458 qint16 numHPI = 0;
459 qint16 numFiducials = 0;
460 qint16 numEEG = 0;
461 qint16 numAdditional = 0;
462
463 for (int i = 0; i < digSet.size(); ++i) {
464 switch (digSet[i].kind) {
465 case FIFFV_POINT_HPI:
466 if (m_vCoilFreqs.size() <= numHPI) {
467 m_vCoilFreqs.append(-1);
468 }
469 numHPI++;
470 break;
472 numFiducials++;
473 break;
474 case FIFFV_POINT_EEG:
475 numEEG++;
476 break;
478 numAdditional++;
479 break;
480 }
481 }
482
483 //Set loaded number of digitizers
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);
488
489 m_vCoilFreqs.resize(numHPI);
491 setupCoilPresets(numHPI);
492
493 // Make sure that the stored coil freqs always match the number of loaded ones
494 m_vCoilFreqs.resize(numHPI);
496}
497
498//=============================================================================================================
499
501{
502 for (int iCoilFreq : m_vCoilFreqs) {
503 addCoilFreqToGUI(iCoilFreq);
505 }
506}
507
508//=============================================================================================================
509
511{
512 // Add column 0 in freq table widget
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,
517 0,
518 pTableItemA);
519
520 // Add column 1 in freq table widget
521 m_pUi->m_tableWidget_Frequencies->setItem(m_pUi->m_tableWidget_Frequencies->rowCount() - 1,
522 1,
523 new QTableWidgetItem(QString::number(iCoilFreq)));
524}
525
526//=============================================================================================================
527
529{
530 // Add column 0 in error table widget
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,
535 0,
536 pTableItemB);
537
538 // Add column 1 in error table widget
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,
542 1,
543 pTableItemC);
544
545 // Add column 2 in error table widget
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,
549 2,
550 pTableItemD);
551}
552
553//=============================================================================================================
554
556{
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)"));
561
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"));
567}
568
569//=============================================================================================================
570
574
575//==============================================void populateCoilGUI(int iNumCoils);===============================================================
576
577void HpiSettingsView::loadCoilPresets(const QString& sFilePath)
578{
579 QFile inFile(sFilePath);
580 if (inFile.open(QIODevice::ReadOnly)) {
581 QByteArray inArray = inFile.readAll();
582 m_CoilPresets = QJsonDocument::fromJson(inArray);
583 }
584}
585
586//=============================================================================================================
587
589{
590 if (!m_CoilPresets.isNull()) {
591 QJsonArray presetData = m_CoilPresets.object()[QString::number(iNumCoils)].toArray();
592 populatePresetGUI(presetData);
593 }
594}
595
596//=============================================================================================================
597
598void HpiSettingsView::populatePresetGUI(const QJsonArray& presetData)
599{
600 m_pUi->comboBox_coilPreset->clear();
601 m_pUi->comboBox_coilPreset->addItem("Load preset");
602
603 for (const auto& entry : presetData) {
604 QString name = entry.toObject()["name"].toString();
605 QVector<int> vecCoils;
606
607 for (const auto& coil : entry.toObject()["coils"].toArray()) {
608 vecCoils.append(coil.toInt());
609 }
610
611 m_pUi->comboBox_coilPreset->addItem(name, QVariant::fromValue(vecCoils));
612 }
613}
614
615//=============================================================================================================
616
617void HpiSettingsView::selectCoilPreset(int iCoilPresetIndex)
618{
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>>()) {
622 m_vCoilFreqs = coilFreqData.value<QVector<int>>();
623 clearCoilGUI();
625
627 }
628 }
629}
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)
void allowedRotationChanged(double dAllowedRotation)
void updateProcessingMode(ProcessingMode mode)
void sspStatusChanged(bool bChecked)
void updateDigitizerInfoGUI(const FIFFLIB::FiffDigPointSet &digSet)
void fittingWindowSizeChanged(int iFitsPerSecond)
void setMovementResults(double dMovement, double dRotation)
void loadCoilPresets(const QString &sFilePath)
void coilFrequenciesChanged(const QVector< int > &vCoilFreqs)
void newDigitizerList(QList< FIFFLIB::FiffDigPoint > pointList)
void addCoilFreqToGUI(int iCoilFreq)
void updateGuiMode(GuiMode mode)
void populatePresetGUI(const QJsonArray &presetData)
void setGoFLabels(const Eigen::VectorXd &vGoF, const double dMeanGof)
void compStatusChanged(bool bChecked)
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)
QList< FIFFLIB::FiffDigPoint > readDigitizersFromFile(const QString &fileName)
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