MNE-CPP  beta 1.0
tmsiimpedancewidget.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "tmsiimpedancewidget.h"
43 #include "ui_tmsiimpedancewidget.h"
44 
45 #include "../tmsi.h"
46 
47 
48 //*************************************************************************************************************
49 //=============================================================================================================
50 // QT INCLUDES
51 //=============================================================================================================
52 
53 #include <QFileDialog>
54 #include <QString>
55 
56 
57 //*************************************************************************************************************
58 //=============================================================================================================
59 // USED NAMESPACES
60 //=============================================================================================================
61 
62 using namespace TMSIPlugin;
63 
64 
65 //*************************************************************************************************************
66 //=============================================================================================================
67 // DEFINE MEMBER METHODS
68 //=============================================================================================================
69 
70 TMSIImpedanceWidget::TMSIImpedanceWidget(TMSI* pTMSI, QWidget *parent)
71 : m_pTMSI(pTMSI)
72 , QWidget(parent)
73 , ui(new Ui::TMSIImpedanceWidget)
74 , m_dMaxImpedance(200000)
75 {
76  ui->setupUi(this);
77 
78  // Init colormap object
79  m_cbColorMap = QSharedPointer<ColorMap>(new ColorMap());
80 
81  // Init GUI stuff
82  m_qGScene = new TMSIImpedanceScene(ui->m_graphicsView_impedanceView);
83  ui->m_graphicsView_impedanceView->setScene(m_qGScene);
84  ui->m_graphicsView_impedanceView->show();
85 
86  ui->m_pushButton_stop->setEnabled(false);
87 
88  // Connects of this widget
89  connect(ui->m_pushButton_stop, &QPushButton::released, this, &TMSIImpedanceWidget::stopImpedanceMeasurement);
90  connect(ui->m_pushButton_start, &QPushButton::released, this, &TMSIImpedanceWidget::startImpedanceMeasurement);
91  connect(ui->m_pushButton_takeScreenshot, &QPushButton::released, this, &TMSIImpedanceWidget::takeScreenshot);
92  connect(ui->m_pushButton_loadLayout, &QPushButton::released, this, &TMSIImpedanceWidget::loadLayout);
93  connect(ui->m_pushButton_saveValues, &QPushButton::released, this, &TMSIImpedanceWidget::saveToFile);
94  connect(ui->m_pushButton_Help, &QPushButton::released, this, &TMSIImpedanceWidget::helpDialog);
95  //connect(ui->m_verticalSlider_manualImpedanceValue, &QSlider::valueChanged, this, &TMSIImpedanceWidget::setIm);
96 
97 }
98 
99 //*************************************************************************************************************
100 
101 TMSIImpedanceWidget::~TMSIImpedanceWidget()
102 {
103  delete ui;
104 }
105 
106 //*************************************************************************************************************
107 
109 {
110  // Get scene items
111  QList<QGraphicsItem *> itemList = m_qGScene->items();
112 
113  // Update color and impedance values for each electrode item
114  int matIndex = 0;
115  double impedanceValue = 0.0;
116  int numberItems = itemList.size();
117 
118  if(itemList.size()>matValue.rows())
119  {
120  qDebug()<<"TMSIImpedanceWidget - ERROR - There were more items in the scene than samples received from the device - Check the current layout! Only available channels will be displayed!"<<endl;
121  numberItems = matValue.rows();
122  return;
123  }
124 
125  for(int i = 0; i<numberItems; i++)
126  {
127  TMSIElectrodeItem *item = (TMSIElectrodeItem *) itemList.at(i);
128 
129  // find matrix index for given electrode name
130  matIndex = m_qmElectrodeNameIndex[item->getElectrodeName()];
131  impedanceValue = matValue[matIndex];
132 
133  // set new color and impedance value. Clip received impedance value if > predefined max impedance value
134 // if(impedanceValue>m_dMaxImpedance || impedanceValue<0)
135 // impedanceValue = m_dMaxImpedance;
136 
137  // For testing purposes only!
138  //impedanceValue = ui->m_verticalSlider_manualImpedanceValue->value();
139 
140  double scale = ui->m_doubleSpinBox_manualImpedanceValueScale->value();
141  //double scale = 0.000053;
142  //cout << scale <<endl;
143  double valueScaledNormalized = (scale*impedanceValue)/(scale*impedanceValue+1);
144 
145  item->setColor(m_cbColorMap->valueToJet(valueScaledNormalized));
146  item->setImpedanceValue(impedanceValue);
147  }
148 
149  m_qGScene->update(m_qGScene->itemsBoundingRect());
150 }
151 
152 //*************************************************************************************************************
153 
155 {
156  // Clear all items from scene
157  m_qGScene->clear();
158 
159  // Load standard layout file
160  LayoutLoader *asaObject = new LayoutLoader();
161  QVector< QVector<double> > elcLocation3D;
162  QVector< QVector<double> > elcLocation2D;
163  QString unit;
164  QStringList elcChannelNames;
165  QString sElcFilePath = QString("./mne_x_plugins/resources/tmsi/loc_files/standard_waveguard128.elc");
166 
167  if(!asaObject->readAsaElcFile(sElcFilePath, elcChannelNames, elcLocation3D, elcLocation2D, unit))
168  {
169  qDebug() << "Error: Reading elc file.";
170  return;
171  }
172 
173  // Generate lookup table for channel names to corresponding matrix/vector index
174  for(int i = 0; i<elcLocation2D.size(); i++)
175  m_qmElectrodeNameIndex.insert(elcChannelNames.at(i), i);
176 
177  // Add electrodes to scene
178  for(int i = 0; i<elcLocation2D.size(); i++)
179  {
180  QVector2D position(elcLocation2D[i][1]*-4.5,elcLocation2D[i][0]*-4.5); // swap x y to rotate 90°, multiply to mirror by x and y axis, multiply by to scale
181  addElectrodeItem(elcChannelNames.at(i), position);
182  }
183 
184  ui->m_graphicsView_impedanceView->fitInView(m_qGScene->itemsBoundingRect(), Qt::KeepAspectRatio);
185 }
186 
187 //*************************************************************************************************************
188 
189 void TMSIImpedanceWidget::addElectrodeItem(QString electrodeName, QVector2D position)
190 {
191  TMSIElectrodeItem *item = new TMSIElectrodeItem(electrodeName, QPointF(position.x(), position.y()), QColor(m_cbColorMap->valueToJet(1)), m_qmElectrodeNameIndex[electrodeName]);
192  item->setPos(QPointF(position.x(), position.y()));
193  m_qGScene->addItem(item);
194 }
195 
196 //*************************************************************************************************************
197 
198 void TMSIImpedanceWidget::startImpedanceMeasurement()
199 {
200  m_pTMSI->m_bCheckImpedances = true;
201 
202  if(m_pTMSI->start())
203  {
204  ui->m_pushButton_stop->setEnabled(true);
205  ui->m_pushButton_start->setEnabled(false);
206  }
207  else
208  m_pTMSI->m_bCheckImpedances = false;
209 }
210 
211 //*************************************************************************************************************
212 
213 void TMSIImpedanceWidget::stopImpedanceMeasurement()
214 {
215  m_pTMSI->m_bCheckImpedances = false;
216 
217  if(m_pTMSI->stop())
218  {
219  ui->m_pushButton_stop->setEnabled(false);
220  ui->m_pushButton_start->setEnabled(true);
221  }
222  else
223  m_pTMSI->m_bCheckImpedances = true;
224 }
225 
226 //*************************************************************************************************************
227 
228 void TMSIImpedanceWidget::takeScreenshot()
229 {
230  // Open file dialog
231  QDate date;
232  QString fileName = QFileDialog::getSaveFileName(this,
233  "Save Screenshot",
234  QString("%1/%2_%3_%4_Impedances").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
235  tr("Vector graphic(*.svg);;Images (*.png)"));
236 
237  if(!fileName.isEmpty())
238  {
239  // Generate screenshot
240  if(fileName.contains(".svg"))
241  {
242  QSvgGenerator svgGen;
243 
244  svgGen.setFileName(fileName);
245  QRectF rect = m_qGScene->itemsBoundingRect();
246  svgGen.setSize(QSize(rect.width(), rect.height()));
247  //svgGen.setViewBox(QRect(0, 0, rect.width(), rect.height()));
248 
249  QPainter painter(&svgGen);
250  m_qGScene->render(&painter);
251  }
252 
253  if(fileName.contains(".png"))
254  {
255  m_qGScene->setSceneRect(m_qGScene->itemsBoundingRect()); // Re-shrink the scene to it's bounding contents
256  QImage image(m_qGScene->sceneRect().size().toSize(), QImage::Format_ARGB32); // Create the image with the exact size of the shrunk scene
257  image.fill(Qt::transparent); // Start all pixels transparent
258 
259  QPainter painter(&image);
260  m_qGScene->render(&painter);
261  image.save(fileName);
262  }
263  }
264 }
265 
266 //*************************************************************************************************************
267 
268 void TMSIImpedanceWidget::loadLayout()
269 {
270  QString sElcFilePath = QFileDialog::getOpenFileName(this,
271  tr("Open Layout"),
272  "./mne_x_plugins/resources/tmsi/loc_files/",
273  tr("ELC layout file (*.elc)"));
274 
275  // Load standard layout file
276  LayoutLoader *asaObject = new LayoutLoader();
277  QVector< QVector<double> > elcLocation3D;
278  QVector< QVector<double> > elcLocation2D;
279  QString unit;
280  QStringList elcChannelNames;
281 
282  if(!asaObject->readAsaElcFile(sElcFilePath, elcChannelNames, elcLocation3D, elcLocation2D, unit))
283  qDebug() << "Error: Reading elc file.";
284  else
285  m_qGScene->clear();
286 
287  // Clean old map -> Generate lookup table for channel names and corresponding index
288  m_qmElectrodeNameIndex.clear();
289 
290  for(int i = 0; i<elcLocation2D.size(); i++)
291  m_qmElectrodeNameIndex.insert(elcChannelNames.at(i), i);
292 
293  // Add electrodes to scene
294  for(int i = 0; i<elcLocation2D.size(); i++)
295  {
296  QVector2D position(elcLocation2D[i][1]*-4.5,elcLocation2D[i][0]*-4.5); // swap x y to rotate 90°, multiply to mirror by x and y axis, multiply by to scale
297 
298  addElectrodeItem(elcChannelNames.at(i), position);
299  }
300 
301  ui->m_graphicsView_impedanceView->fitInView(m_qGScene->itemsBoundingRect(), Qt::KeepAspectRatio);
302 }
303 
304 //*************************************************************************************************************
305 
306 void TMSIImpedanceWidget::closeEvent(QCloseEvent *event)
307 {
308  Q_UNUSED(event);
309 
310  // On window close event -> stop impedance measurement
311  if(m_pTMSI->m_bIsRunning)
312  stopImpedanceMeasurement();
313 }
314 
315 //*************************************************************************************************************
316 
317 // This function is needed to sort the QList
318 bool compareChannelIndex(TMSIElectrodeItem* a, TMSIElectrodeItem* b)
319 {
320  return a->getChannelIndex() < b->getChannelIndex();
321 }
322 
323 void TMSIImpedanceWidget::saveToFile()
324 {
325  // Open file dialog
326  QDate date;
327  QString fileName = QFileDialog::getSaveFileName(this,
328  "Save impedance values",
329  QString("%1/%2_%3_%4_Impedances").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
330  tr("Text file (*.txt)"));
331 
332  ofstream outputFileStream;
333  outputFileStream.open(fileName.toStdString(), ios::trunc); //ios::trunc deletes old file data
334 
335  QList<QGraphicsItem *> itemList = m_qGScene->items();
336 
337  // Convert to QList with TMSIElectrodeItem's
338  QList<TMSIElectrodeItem *> itemListNew;
339  for(int i = 0; i<itemList.size(); i++)
340  itemListNew.append((TMSIElectrodeItem *)itemList.at(i));
341 
342  // Sort list corresponding to the channelIndex
343  sort(itemListNew.begin(), itemListNew.end(), compareChannelIndex);
344 
345  // Update position
346  for(int i = 0; i<itemListNew.size(); i++)
347  {
348  TMSIElectrodeItem *item = itemListNew.at(i);
349  outputFileStream << i << " " << item->getElectrodeName().toStdString() << " " << item->getImpedanceValue() << endl;
350  }
351 
352  outputFileStream.close();
353 }
354 
355 //*************************************************************************************************************
356 
357 void TMSIImpedanceWidget::helpDialog()
358 {
359  QMessageBox msgBox;
360  msgBox.setText("- Use mouse wheel to zoom.\n- Hold and move right mouse button to scale the electrode positions in the scene.\n- Double click to fit the scene into the view.");
361  msgBox.exec();
362 }
virtual bool start()
Definition: tmsi.cpp:490
Color map RGB transformations.
Definition: colormap.h:82
Definition: aboutwindow.h:52
virtual bool stop()
Definition: tmsi.cpp:546
The TMSIImpedanceScene class provides a reimplemented QGraphicsScene.
void updateGraphicScene(VectorXd matValue)
The TMSIElectrodeItem class provides a new data structure for impedance values.
static bool readAsaElcFile(QString path, QStringList &channelNames, QVector< QVector< double > > &location3D, QVector< QVector< double > > &location2D, QString &unit)
Contains the declaration of the TmsiImpedanceWidget class.
Processes AsA .elc files which contain the electrode positions of a EEG hat.
Definition: layoutloader.h:101
The TMSI class provides a EEG connector. In order for this plugin to work properly the driver dll "RT...
Definition: tmsi.h:122
The TMSIImpedanceWidget class provides the TMSIImpedanceWidget configuration window.
void setImpedanceValue(double impedanceValue)
void setColor(QColor electrodeColor)