MNE-CPP  beta 1.0
eegosports.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "eegosports.h"
43 #include "eegosportsproducer.h"
44 
45 
46 //*************************************************************************************************************
47 //=============================================================================================================
48 // QT INCLUDES
49 //=============================================================================================================
50 
51 #include <QtCore/QtPlugin>
52 #include <QtCore/QTextStream>
53 #include <QDebug>
54 
55 
56 //*************************************************************************************************************
57 //=============================================================================================================
58 // USED NAMESPACES
59 //=============================================================================================================
60 
61 using namespace EEGoSportsPlugin;
62 
63 
64 //*************************************************************************************************************
65 //=============================================================================================================
66 // DEFINE MEMBER METHODS
67 //=============================================================================================================
68 
70 : m_pRMTSA_EEGoSports(0)
71 , m_qStringResourcePath(qApp->applicationDirPath()+"/mne_x_plugins/resources/eegosports/")
72 , m_pRawMatrixBuffer_In(0)
73 , m_pEEGoSportsProducer(new EEGoSportsProducer(this))
74 {
75  // Create record file option action bar item/button
76  m_pActionSetupProject = new QAction(QIcon(":/images/database.png"), tr("Setup project"), this);
77  m_pActionSetupProject->setStatusTip(tr("Setup project"));
78  connect(m_pActionSetupProject, &QAction::triggered, this, &EEGoSports::showSetupProjectDialog);
79  addPluginAction(m_pActionSetupProject);
80 
81  // Create start recordin action bar item/button
82  m_pActionStartRecording = new QAction(QIcon(":/images/record.png"), tr("Start recording data to fif file"), this);
83  m_pActionStartRecording->setStatusTip(tr("Start recording data to fif file"));
84  connect(m_pActionStartRecording, &QAction::triggered, this, &EEGoSports::showStartRecording);
85  addPluginAction(m_pActionStartRecording);
86 }
87 
88 
89 //*************************************************************************************************************
90 
92 {
93  //std::cout << "EEGoSports::~EEGoSports() " << std::endl;
94 
95  //If the program is closed while the sampling is in process
96  if(this->isRunning())
97  this->stop();
98 }
99 
100 
101 //*************************************************************************************************************
102 
103 QSharedPointer<IPlugin> EEGoSports::clone() const
104 {
105  QSharedPointer<EEGoSports> pEEGoSportsClone(new EEGoSports());
106  return pEEGoSportsClone;
107 }
108 
109 
110 //*************************************************************************************************************
111 
113 {
114  m_pRMTSA_EEGoSports = PluginOutputData<NewRealTimeMultiSampleArray>::create(this, "EEGoSports", "EEG output data");
115 
116  m_outputConnectors.append(m_pRMTSA_EEGoSports);
117 
118  //default values used by the setupGUI class must be set here
119  m_iSamplingFreq = 1024;
120  m_iNumberOfChannels = 64;
121  m_iSamplesPerBlock = 16;
122  m_iTriggerInterval = 5000;
123  m_bUseChExponent = true;
124  m_bWriteToFile = false;
125  m_bWriteDriverDebugToFile = false;
126  m_bUseFiltering = false;
127  m_bIsRunning = false;
128  m_bBeepTrigger = false;
129  m_bCheckImpedances = false;
130 
131  QDate date;
132  m_sOutputFilePath = QString ("%1Sequence_01/Subject_01/%2_%3_%4_EEG_001_raw.fif").arg(m_qStringResourcePath).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day());
133 
134  m_sElcFilePath = QString("./mne_x_plugins/resources/eegosports/loc_files/standard_waveguard64.elc");
135 
136  m_pFiffInfo = QSharedPointer<FiffInfo>(new FiffInfo());
137 
138  //Initialise matrix used to perform a very simple high pass filter operation
139  //m_matOldMatrix = MatrixXf::Zero(m_iNumberOfChannels, m_iSamplesPerBlock);
140 }
141 
142 
143 //*************************************************************************************************************
144 
146 {
147 
148 }
149 
150 
151 //*************************************************************************************************************
152 
154 {
155  //
156  //Clear old fiff info data
157  //
158  m_pFiffInfo->clear();
159 
160  //
161  //Set number of channels, sampling frequency and high/-lowpass
162  //
163  m_pFiffInfo->nchan = m_iNumberOfChannels;
164  m_pFiffInfo->sfreq = m_iSamplingFreq;
165  m_pFiffInfo->highpass = (float)0.001;
166  m_pFiffInfo->lowpass = m_iSamplingFreq/2;
167 
168  //
169  //Read electrode positions from .elc file
170  //
171  QVector< QVector<double> > elcLocation3D;
172  QVector< QVector<double> > elcLocation2D;
173  QString unit;
174  QStringList elcChannelNames;
175 
176  if(!LayoutLoader::readAsaElcFile(m_sElcFilePath, elcChannelNames, elcLocation3D, elcLocation2D, unit))
177  qDebug() << "Error: Reading elc file.";
178 
179  //qDebug() << elcLocation3D;
180  //qDebug() << elcLocation2D;
181  //qDebug() << elcChannelNames;
182 
183  //The positions read from the asa elc file do not correspond to a RAS coordinate system - use a simple 90° z transformation to fix this
184  Matrix3f rotation_z;
185  rotation_z = AngleAxisf((float)M_PI/2, Vector3f::UnitZ()); //M_PI/2 = 90°
186  QVector3D center_pos;
187 
188  for(int i = 0; i<elcLocation3D.size(); i++)
189  {
190  Vector3f point;
191  point << elcLocation3D[i][0], elcLocation3D[i][1] , elcLocation3D[i][2];
192  Vector3f point_rot = rotation_z * point;
193 // cout<<"point: "<<endl<<point<<endl<<endl;
194 // cout<<"matrix: "<<endl<<rotation_z<<endl<<endl;
195 // cout<<"point_rot: "<<endl<<point_rot<<endl<<endl;
196 // cout<<"-----------------------------"<<endl;
197  elcLocation3D[i][0] = point_rot[0];
198  elcLocation3D[i][1] = point_rot[1];
199  elcLocation3D[i][2] = point_rot[2];
200 
201  //Also calculate the center position of the electrode positions in this for routine
202  center_pos.setX(center_pos.x() + elcLocation3D[i][0]);
203  center_pos.setY(center_pos.y() + elcLocation3D[i][1]);
204  center_pos.setZ(center_pos.z() + elcLocation3D[i][2]);
205  }
206 
207  center_pos.setX(center_pos.x()/elcLocation3D.size());
208  center_pos.setY(center_pos.y()/elcLocation3D.size());
209  center_pos.setZ(center_pos.z()/elcLocation3D.size());
210 
211  //
212  //Write electrode positions to the digitizer info in the fiffinfo
213  //
214  QList<FiffDigPoint> digitizerInfo;
215 
216  //Only write the EEG channel positions to the fiff info. The Refa devices have next to the EEG input channels 10 other input channels (Bipolar, Auxilary, Digital, Test)
217  int numberEEGCh;
218  if(m_iNumberOfChannels>128)
219  numberEEGCh = 138 - (m_iNumberOfChannels-128);
220  else
221  numberEEGCh = m_iNumberOfChannels;
222 
223  //Check if channel size by user corresponds with read channel informations from the elc file. If not append zeros and string 'unknown' until the size matches.
224  if(numberEEGCh > elcLocation3D.size())
225  {
226  qDebug()<<"Warning: setUpFiffInfo() - Not enough positions read from the elc file. Filling missing channel names and positions with zeroes and 'unknown' strings.";
227  QVector<double> tempA(3, 0.0);
228  QVector<double> tempB(2, 0.0);
229  int size = numberEEGCh-elcLocation3D.size();
230  for(int i = 0; i<size; i++)
231  {
232  elcLocation3D.push_back(tempA);
233  elcLocation2D.push_back(tempB);
234  elcChannelNames.append(QString("Unknown"));
235  }
236  }
237 
238  //Append LAP value to digitizer data. Take location of LE2 electrode minus 1 cm as approximation.
239  FiffDigPoint digPoint;
240  int indexLE2 = elcChannelNames.indexOf("LE2");
241  digPoint.kind = FIFFV_POINT_CARDINAL;
242  digPoint.ident = FIFFV_POINT_LPA;//digitizerInfo.size();
243 
244  //Set EEG electrode location - Convert from mm to m
245  if(indexLE2!=-1)
246  {
247  digPoint.r[0] = elcLocation3D[indexLE2][0]*0.001;
248  digPoint.r[1] = elcLocation3D[indexLE2][1]*0.001;
249  digPoint.r[2] = (elcLocation3D[indexLE2][2]-10)*0.001;
250  digitizerInfo.push_back(digPoint);
251  }
252  else
253  cout<<"Plugin TMSI - ERROR - LE2 not found. Check loaded layout."<<endl;
254 
255  //Append nasion value to digitizer data. Take location of Z1 electrode minus 6 cm as approximation.
256  int indexZ1 = elcChannelNames.indexOf("Z1");
257  digPoint.kind = FIFFV_POINT_CARDINAL;//FIFFV_POINT_NASION;
258  digPoint.ident = FIFFV_POINT_NASION;//digitizerInfo.size();
259 
260  //Set EEG electrode location - Convert from mm to m
261  if(indexZ1!=-1)
262  {
263  digPoint.r[0] = elcLocation3D[indexZ1][0]*0.001;
264  digPoint.r[1] = elcLocation3D[indexZ1][1]*0.001;
265  digPoint.r[2] = (elcLocation3D[indexZ1][2]-60)*0.001;
266  digitizerInfo.push_back(digPoint);
267  }
268  else
269  cout<<"Plugin TMSI - ERROR - Z1 not found. Check loaded layout."<<endl;
270 
271  //Append RAP value to digitizer data. Take location of RE2 electrode minus 1 cm as approximation.
272  int indexRE2 = elcChannelNames.indexOf("RE2");
273  digPoint.kind = FIFFV_POINT_CARDINAL;
274  digPoint.ident = FIFFV_POINT_RPA;//digitizerInfo.size();
275 
276  //Set EEG electrode location - Convert from mm to m
277  if(indexRE2!=-1)
278  {
279  digPoint.r[0] = elcLocation3D[indexRE2][0]*0.001;
280  digPoint.r[1] = elcLocation3D[indexRE2][1]*0.001;
281  digPoint.r[2] = (elcLocation3D[indexRE2][2]-10)*0.001;
282  digitizerInfo.push_back(digPoint);
283  }
284  else
285  cout<<"Plugin TMSI - ERROR - RE2 not found. Check loaded layout."<<endl;
286 
287  //Add EEG electrode positions as digitizers
288  for(int i=0; i<numberEEGCh; i++)
289  {
290  FiffDigPoint digPoint;
291  digPoint.kind = FIFFV_POINT_EEG;
292  digPoint.ident = i;
293 
294  //Set EEG electrode location - Convert from mm to m
295  digPoint.r[0] = elcLocation3D[i][0]*0.001;
296  digPoint.r[1] = elcLocation3D[i][1]*0.001;
297  digPoint.r[2] = elcLocation3D[i][2]*0.001;
298  digitizerInfo.push_back(digPoint);
299  }
300 
301  //Set the final digitizer values to the fiff info
302  m_pFiffInfo->dig = digitizerInfo;
303 
304  //
305  //Set up the channel info
306  //
307  QStringList QSLChNames;
308  m_pFiffInfo->chs.clear();
309 
310  for(int i=0; i<m_iNumberOfChannels; i++)
311  {
312  //Create information for each channel
313  QString sChType;
314  FiffChInfo fChInfo;
315 
316  //EEG Channels
317  if(i<=numberEEGCh-1)
318  {
319  //Set channel name
320  //fChInfo.ch_name = elcChannelNames.at(i);
321  sChType = QString("EEG ");
322  if(i<10)
323  sChType.append("00");
324 
325  if(i>=10 && i<100)
326  sChType.append("0");
327 
328  fChInfo.ch_name = sChType.append(sChType.number(i));
329 
330  //Set channel type
331  fChInfo.kind = FIFFV_EEG_CH;
332 
333  //Set coil type
334  fChInfo.coil_type = FIFFV_COIL_EEG;
335 
336  //Set logno
337  fChInfo.logno = i;
338 
339  //Set coord frame
340  fChInfo.coord_frame = FIFFV_COORD_HEAD;
341 
342  //Set unit
343  fChInfo.unit = FIFF_UNIT_V;
344  fChInfo.unit_mul = 0;
345 
346  //Set EEG electrode location - Convert from mm to m
347  fChInfo.eeg_loc(0,0) = elcLocation3D[i][0]*0.001;
348  fChInfo.eeg_loc(1,0) = elcLocation3D[i][1]*0.001;
349  fChInfo.eeg_loc(2,0) = elcLocation3D[i][2]*0.001;
350 
351  //Set EEG electrode direction - Convert from mm to m
352  fChInfo.eeg_loc(0,1) = center_pos.x()*0.001;
353  fChInfo.eeg_loc(1,1) = center_pos.y()*0.001;
354  fChInfo.eeg_loc(2,1) = center_pos.z()*0.001;
355 
356  //Also write the eeg electrode locations into the meg loc variable (mne_ex_read_raw() matlab function wants this)
357  fChInfo.loc(0,0) = elcLocation3D[i][0]*0.001;
358  fChInfo.loc(1,0) = elcLocation3D[i][1]*0.001;
359  fChInfo.loc(2,0) = elcLocation3D[i][2]*0.001;
360 
361  fChInfo.loc(3,0) = center_pos.x()*0.001;
362  fChInfo.loc(4,0) = center_pos.y()*0.001;
363  fChInfo.loc(5,0) = center_pos.z()*0.001;
364 
365  fChInfo.loc(6,0) = 0;
366  fChInfo.loc(7,0) = 1;
367  fChInfo.loc(8,0) = 0;
368 
369  fChInfo.loc(9,0) = 0;
370  fChInfo.loc(10,0) = 0;
371  fChInfo.loc(11,0) = 1;
372 
373  //cout<<i<<endl<<fChInfo.eeg_loc<<endl;
374  }
375 
376  QSLChNames << sChType;
377 
378  m_pFiffInfo->chs.append(fChInfo);
379  }
380 
381  //Set channel names in fiff_info_base
382  m_pFiffInfo->ch_names = QSLChNames;
383 
384  //
385  //Set head projection
386  //
387  m_pFiffInfo->dev_head_t.from = FIFFV_COORD_DEVICE;
388  m_pFiffInfo->dev_head_t.to = FIFFV_COORD_HEAD;
389  m_pFiffInfo->ctf_head_t.from = FIFFV_COORD_DEVICE;
390  m_pFiffInfo->ctf_head_t.to = FIFFV_COORD_HEAD;
391 
392  //
393  //Set projection data
394  //
395  m_pFiffInfo->projs.clear();
396  FiffProj proj;
397  proj.kind = 1;
398  proj.active = false;
399 
400  FiffNamedMatrix::SDPtr namedMatrix = proj.data;
401  namedMatrix->ncol = numberEEGCh/3;
402  namedMatrix->nrow = 1;
403  namedMatrix->data = MatrixXd::Ones(1, namedMatrix->ncol);
404 
405  //Set projection 1
406  for(int i=0; i<namedMatrix->ncol; i++)
407  namedMatrix->col_names << QSLChNames.at(i);
408 
409  proj.data = namedMatrix;
410  proj.desc = QString("PCA-v1");
411  m_pFiffInfo->projs.append(proj);
412 
413  //Set projection 2
414  namedMatrix->col_names.clear();
415  for(int i=0; i<namedMatrix->ncol; i++)
416  namedMatrix->col_names << QSLChNames.at(i+namedMatrix->ncol);
417 
418  proj.data = namedMatrix;
419  proj.desc = QString("PCA-v2");
420  m_pFiffInfo->projs.append(proj);
421 
422  //Set projection 3
423  namedMatrix->col_names.clear();
424  for(int i=0; i<namedMatrix->ncol; i++)
425  namedMatrix->col_names << QSLChNames.at(i+(2*namedMatrix->ncol));
426 
427  proj.data = namedMatrix;
428  proj.desc = QString("PCA-v3");
429  m_pFiffInfo->projs.append(proj);
430 }
431 
432 
433 //*************************************************************************************************************
434 
436 {
437  //Check if the thread is already or still running. This can happen if the start button is pressed immediately after the stop button was pressed. In this case the stopping process is not finished yet but the start process is initiated.
438  if(this->isRunning())
439  QThread::wait();
440 
441  if(m_bBeepTrigger)
442  m_qTimerTrigger.start();
443 
444  //Setup fiff info
445  setUpFiffInfo();
446 
447  //Set the channel size of the RMTSA - this needs to be done here and NOT in the init() function because the user can change the number of channels during runtime
448  m_pRMTSA_EEGoSports->data()->initFromFiffInfo(m_pFiffInfo);
449  m_pRMTSA_EEGoSports->data()->setMultiArraySize(1);//m_iSamplesPerBlock);
450  m_pRMTSA_EEGoSports->data()->setSamplingRate(m_iSamplingFreq);
451 
452  //Buffer
453  m_pRawMatrixBuffer_In = QSharedPointer<RawMatrixBuffer>(new RawMatrixBuffer(8, m_iNumberOfChannels, m_iSamplesPerBlock));
454  m_qListReceivedSamples.clear();
455 
456  m_pEEGoSportsProducer->start(m_iNumberOfChannels,
457  m_iSamplingFreq,
458  m_bUseChExponent,
459  m_bWriteDriverDebugToFile,
460  m_sOutputFilePath,
461  m_bCheckImpedances);
462 
463  if(m_pEEGoSportsProducer->isRunning())
464  {
465  m_bIsRunning = true;
466  QThread::start();
467  return true;
468  }
469  else
470  {
471  qWarning() << "Plugin EEGoSports - ERROR - EEGoSportsProducer thread could not be started - Either the device is turned off (check your OS device manager) or the driver DLL (TMSiSDK.dll / TMSiSDK32bit.dll) is not installed in the system32 / SysWOW64 directory" << endl;
472  return false;
473  }
474 }
475 
476 
477 //*************************************************************************************************************
478 
480 {
481  //Stop the producer thread first
482  m_pEEGoSportsProducer->stop();
483 
484  //Wait until this thread (EEGoSports) is stopped
485  m_bIsRunning = false;
486 
487  //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)
488  m_pRawMatrixBuffer_In->releaseFromPop();
489 
490  m_pRawMatrixBuffer_In->clear();
491 
492  m_pRMTSA_EEGoSports->data()->clear();
493 
494  m_qListReceivedSamples.clear();
495 
496  return true;
497 }
498 
499 
500 //*************************************************************************************************************
501 
502 void EEGoSports::setSampleData(MatrixXf &matRawBuffer)
503 {
504  m_mutex.lock();
505  m_qListReceivedSamples.append(matRawBuffer);
506  m_mutex.unlock();
507 }
508 
509 
510 //*************************************************************************************************************
511 
513 {
514  return _ISensor;
515 }
516 
517 
518 //*************************************************************************************************************
519 
520 QString EEGoSports::getName() const
521 {
522  return "EEGoSports EEG";
523 }
524 
525 
526 //*************************************************************************************************************
527 
529 {
530  EEGoSportsSetupWidget* widget = new EEGoSportsSetupWidget(this);//widget is later destroyed by CentralWidget - so it has to be created everytime new
531 
532  //init properties dialog
533  widget->initGui();
534 
535  return widget;
536 }
537 
538 
539 //*************************************************************************************************************
540 
542 {
543  while(m_bIsRunning)
544  {
545  //std::cout<<"EEGoSports::run(s)"<<std::endl;
546 
547  //pop matrix only if the producer thread is running
548  if(m_pEEGoSportsProducer->isRunning())
549  {
550  //MatrixXf matValue = m_pRawMatrixBuffer_In->pop();
551  MatrixXf matValue;
552 
553  m_mutex.lock();
554  if(m_qListReceivedSamples.isEmpty() == false)
555  {
556  //cout<<m_qListReceivedSamples.size()<<endl;
557  matValue = m_qListReceivedSamples.first();
558  m_qListReceivedSamples.removeFirst();
559  }
560  m_mutex.unlock();
561 
562  // Set Beep trigger (if activated)
563  if(m_bBeepTrigger && m_qTimerTrigger.elapsed() >= m_iTriggerInterval)
564  {
565  QtConcurrent::run(Beep, 450, 700);
566  //Set trigger in received data samples - just for one sample, so that this event is easy to detect
567  //matValue(136, m_iSamplesPerBlock-1) = 252;
568  m_qTimerTrigger.restart();
569  }
570 
571  //Write raw data to fif file
572  if(m_bWriteToFile)
573  m_pOutfid->write_raw_buffer(matValue.cast<double>(), m_cals);
574 
575  // Use preprocessing if wanted by the user
576  if(m_bUseFiltering)
577  {
578  MatrixXf temp = matValue;
579 
580  matValue = matValue - m_matOldMatrix;
581  m_matOldMatrix = temp;
582  }
583 
584  //emit values to real time multi sample array
585  m_pRMTSA_EEGoSports->data()->setValue(matValue.cast<double>());
586  }
587  }
588 
589  //Close the fif output stream
590  if(m_bWriteToFile)
591  {
592  m_pOutfid->finish_writing_raw();
593  m_bWriteToFile = false;
594  m_pTimerRecordingChange->stop();
595  m_pActionStartRecording->setIcon(QIcon(":/images/record.png"));
596  }
597 
598  //std::cout<<"EXITING - EEGoSports::run()"<<std::endl;
599 }
600 
601 
602 //*************************************************************************************************************
603 
605 {
606  // Open setup project widget
607  if(m_pEEGoSportsSetupProjectWidget == NULL)
608  m_pEEGoSportsSetupProjectWidget = QSharedPointer<EEGoSportsSetupProjectWidget>(new EEGoSportsSetupProjectWidget(this));
609 
610  if(!m_pEEGoSportsSetupProjectWidget->isVisible())
611  {
612  m_pEEGoSportsSetupProjectWidget->setWindowTitle("EEGoSports EEG Connector - Setup project");
613  m_pEEGoSportsSetupProjectWidget->initGui();
614  m_pEEGoSportsSetupProjectWidget->show();
615  m_pEEGoSportsSetupProjectWidget->raise();
616  }
617 }
618 
619 //*************************************************************************************************************
620 
622 {
623  //Setup writing to file
624  if(m_bWriteToFile)
625  {
626  m_pOutfid->finish_writing_raw();
627  m_bWriteToFile = false;
628  m_pTimerRecordingChange->stop();
629  m_pActionStartRecording->setIcon(QIcon(":/images/record.png"));
630  }
631  else
632  {
633  if(!m_bIsRunning)
634  {
635  QMessageBox msgBox;
636  msgBox.setText("Start data acquisition first!");
637  msgBox.exec();
638  return;
639  }
640 
641  if(!m_pFiffInfo)
642  {
643  QMessageBox msgBox;
644  msgBox.setText("FiffInfo missing!");
645  msgBox.exec();
646  return;
647  }
648 
649  //Initiate the stream for writing to the fif file
650  m_fileOut.setFileName(m_sOutputFilePath);
651  if(m_fileOut.exists())
652  {
653  QMessageBox msgBox;
654  msgBox.setText("The file you want to write already exists.");
655  msgBox.setInformativeText("Do you want to overwrite this file?");
656  msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
657  int ret = msgBox.exec();
658  if(ret == QMessageBox::No)
659  return;
660  }
661 
662  // Check if path exists -> otherwise create it
663  QStringList list = m_sOutputFilePath.split("/");
664  list.removeLast(); // remove file name
665  QString fileDir = list.join("/");
666 
667  if(!dirExists(fileDir.toStdString()))
668  {
669  QDir dir;
670  dir.mkpath(fileDir);
671  }
672 
673  m_pOutfid = Fiff::start_writing_raw(m_fileOut, *m_pFiffInfo, m_cals);
674  fiff_int_t first = 0;
675  m_pOutfid->write_int(FIFF_FIRST_SAMPLE, &first);
676 
677  m_bWriteToFile = true;
678 
679  m_pTimerRecordingChange = QSharedPointer<QTimer>(new QTimer);
680  connect(m_pTimerRecordingChange.data(), &QTimer::timeout, this, &EEGoSports::changeRecordingButton);
681  m_pTimerRecordingChange->start(500);
682  }
683 }
684 
685 
686 //*************************************************************************************************************
687 
689 {
690  if(m_iBlinkStatus == 0)
691  {
692  m_pActionStartRecording->setIcon(QIcon(":/images/record.png"));
693  m_iBlinkStatus = 1;
694  }
695  else
696  {
697  m_pActionStartRecording->setIcon(QIcon(":/images/record_active.png"));
698  m_iBlinkStatus = 0;
699  }
700 }
701 
702 
703 //*************************************************************************************************************
704 
705 bool EEGoSports::dirExists(const std::string& dirName_in)
706 {
707  DWORD ftyp = GetFileAttributesA(dirName_in.c_str());
708  if (ftyp == INVALID_FILE_ATTRIBUTES)
709  return false; //something is wrong with your path!
710 
711  if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
712  return true; // this is a directory!
713 
714  return false; // this is not a directory!
715 }
716 
717 
FIFF measurement file information.
Definition: fiff_info.h:96
Contains the declaration of the EEGoSports class.
OutputConnectorList m_outputConnectors
Definition: IPlugin.h:222
fiff_int_t kind
Definition: fiff_proj.h:164
Digitization point description.
QSharedDataPointer< FiffNamedMatrix > SDPtr
The EEGProducer class provides a EEG data producer for a given sampling rate.
The EEGoSportsSetupWidget class provides the EEGoSports configuration window.
void setSampleData(MatrixXf &matRawBuffer)
Definition: eegosports.cpp:502
void addPluginAction(QAction *pAction)
Definition: IPlugin.h:249
The EEGoSportsSetupProjectWidget class provides the EEGoSportsSetupProjectWidget configuration window...
virtual QWidget * setupWidget()
Definition: eegosports.cpp:528
#define FIFFV_COIL_EEG
FiffNamedMatrix::SDPtr data
Definition: fiff_proj.h:168
SSP projector data.
Definition: fiff_proj.h:89
static bool readAsaElcFile(QString path, QStringList &channelNames, QVector< QVector< double > > &location3D, QVector< QVector< double > > &location2D, QString &unit)
Channel info descriptor.
Definition: fiff_ch_info.h:87
static FiffStream::SPtr start_writing_raw(QIODevice &p_IODevice, const FiffInfo &info, RowVectorXd &cals, MatrixXi sel=defaultMatrixXi)
Definition: fiff.h:719
bool dirExists(const std::string &dirName_in)
Definition: eegosports.cpp:705
fiff_int_t coord_frame
Definition: fiff_ch_info.h:137
static QSharedPointer< PluginOutputData< T > > create(IPlugin *parent, const QString &name, const QString &descr)
virtual IPlugin::PluginType getType() const
Definition: eegosports.cpp:512
virtual QString getName() const
Definition: eegosports.cpp:520
Contains the declaration of the EEGoSportsProducer class.
fiff_int_t coil_type
Definition: fiff_ch_info.h:128
virtual QSharedPointer< IPlugin > clone() const
Definition: eegosports.cpp:103
Matrix< double, 3, 2, DontAlign > eeg_loc
Definition: fiff_ch_info.h:136
Matrix< double, 12, 1, DontAlign > loc
Definition: fiff_ch_info.h:130