MNE-CPP  beta 1.0
fiffsimulator.cpp
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "fiffsimulator.h"
43 #include "fiffproducer.h"
44 #include <stdlib.h>
45 
46 
47 //*************************************************************************************************************
48 //=============================================================================================================
49 // FIFF INCLUDES
50 //=============================================================================================================
51 
52 #include <fiff/fiff.h>
53 #include <fiff/fiff_types.h>
54 
55 
56 //*************************************************************************************************************
57 //=============================================================================================================
58 // MNE INCLUDES
59 //=============================================================================================================
60 
61 #include <mne/mne.h>
63 
64 
65 //*************************************************************************************************************
66 //=============================================================================================================
67 // QT INCLUDES
68 //=============================================================================================================
69 
70 #include <QtCore/QtPlugin>
71 #include <QFile>
72 #include <QCoreApplication>
73 #include <QDebug>
74 
75 
76 //*************************************************************************************************************
77 //=============================================================================================================
78 // USED NAMESPACES
79 //=============================================================================================================
80 
81 using namespace FiffSimulatorPlugin;
82 using namespace FIFFLIB;
83 using namespace MNELIB;
84 
85 //*************************************************************************************************************
86 //=============================================================================================================
87 // DEFINE MEMBER CONSTANTS
88 //=============================================================================================================
89 
90 const QString FiffSimulator::Commands::BUFSIZE = "bufsize";
91 const QString FiffSimulator::Commands::GETBUFSIZE = "getbufsize";
92 const QString FiffSimulator::Commands::ACCEL = "accel";
93 const QString FiffSimulator::Commands::GETACCEL = "getaccel";
94 const QString FiffSimulator::Commands::SIMFILE = "simfile";
95 
96 
97 //*************************************************************************************************************
98 //=============================================================================================================
99 // DEFINE MEMBER METHODS
100 //=============================================================================================================
101 
103 : m_pFiffProducer(new FiffProducer(this))
104 , m_sResourceDataPath(QString("%1/MNE-sample-data/MEG/sample/sample_audvis_raw.fif").arg(QCoreApplication::applicationDirPath()))
105 //, m_sResourceDataPath(QString("%1/MNE-sample-data/MEG/sample/baby_sample_raw.fif").arg(QCoreApplication::applicationDirPath()))
106 , m_uiBufferSampleSize(100)//(4)
107 , m_AccelerationFactor(1.0)
108 , m_TrueSamplingRate(0.0)
109 , m_pRawMatrixBuffer(NULL)
110 , m_bIsRunning(false)
111 {
112  this->init();
113 }
114 
115 
116 //*************************************************************************************************************
117 
119 {
120  qDebug() << "Destroy FiffSimulator::~FiffSimulator()";
121 
122  delete m_pFiffProducer;
123 
124  m_bIsRunning = false;
125  QThread::wait();
126 }
127 
128 
129 //*************************************************************************************************************
130 
131 void FiffSimulator::comBufsize(Command p_command)
132 {
133  //ToDO JSON
134 
135  quint32 t_uiBuffSize = p_command.pValues()[0].toUInt();
136 
137  if(t_uiBuffSize > 0)
138  {
139 // printf("bufsize %d\n", t_uiBuffSize);
140 
141  bool t_bWasRunning = m_bIsRunning;
142 
143  if(m_bIsRunning)
144  {
145  m_pFiffProducer->stop();
146  this->stop();
147  }
148 
149  m_uiBufferSampleSize = t_uiBuffSize;
150 
151  if(t_bWasRunning)
152  this->start();
153 
154  QString str = QString("\tSet %1 buffer sample size to %2 samples\r\n\n").arg(getName()).arg(t_uiBuffSize);
155 
156  m_commandManager[Commands::BUFSIZE].reply(str);
157  }
158  else
159  m_commandManager[Commands::BUFSIZE].reply("Buffer size not set\r\n");
160 }
161 
162 
163 //*************************************************************************************************************
164 
165 void FiffSimulator::comGetBufsize(Command p_command)
166 {
167  bool t_bCommandIsJson = p_command.isJson();
168  if(t_bCommandIsJson)
169  {
170  //
171  //create JSON help object
172  //
173  QJsonObject t_qJsonObjectRoot;
174  t_qJsonObjectRoot.insert(Commands::BUFSIZE, QJsonValue((double)m_uiBufferSampleSize));
175  QJsonDocument p_qJsonDocument(t_qJsonObjectRoot);
176 
177  m_commandManager[Commands::GETBUFSIZE].reply(p_qJsonDocument.toJson());
178  }
179  else
180  {
181  QString str = QString("\t%1\r\n\n").arg(m_uiBufferSampleSize);
182  m_commandManager[Commands::GETBUFSIZE].reply(str);
183  }
184 }
185 
186 //*************************************************************************************************************
187 
188 void FiffSimulator::comAccel(Command p_command)
189 {
190  //ToDO JSON
191 
192  float t_uiAccel = p_command.pValues()[0].toFloat();
193 
194  if(t_uiAccel > 0)
195  {
196 
197  bool t_bWasRunning = m_bIsRunning;
198 
199  if(m_bIsRunning)
200  {
201  m_pFiffProducer->stop();
202  this->stop();
203  }
204 
205  m_AccelerationFactor = t_uiAccel;
206  m_RawInfo.info.sfreq = m_AccelerationFactor * m_TrueSamplingRate;
207 
208  if(t_bWasRunning)
209  this->start();
210 
211  QString str = QString("\tSet acceleration factor to %0.3f\r\n\n").arg(t_uiAccel);
212 
213  m_commandManager[Commands::ACCEL].reply(str);
214  }
215  else
216  m_commandManager[Commands::ACCEL].reply("Acceleration facor not set\r\n");
217 }
218 
219 //*************************************************************************************************************
220 
221 void FiffSimulator::comGetAccel(Command p_command)
222 {
223  bool t_bCommandIsJson = p_command.isJson();
224  if(t_bCommandIsJson)
225  {
226  //
227  //create JSON help object
228  //
229  QJsonObject t_qJsonObjectRoot;
230  t_qJsonObjectRoot.insert(Commands::ACCEL, QJsonValue((double)m_AccelerationFactor));
231  QJsonDocument p_qJsonDocument(t_qJsonObjectRoot);
232 
233  m_commandManager[Commands::GETACCEL].reply(p_qJsonDocument.toJson());
234  }
235  else
236  {
237  QString str = QString("\t%0.3f\r\n\n").arg(m_AccelerationFactor);
238  m_commandManager[Commands::GETACCEL].reply(str);
239  }
240 }
241 
242 //*************************************************************************************************************
243 
244 void FiffSimulator::comSimfile(Command p_command)
245 {
246  //
247  // simulation file
248  //
249  QFile t_file(p_command.pValues()[0].toString());
250 
251  QString t_sResourceDataPathOld = m_sResourceDataPath;
252 
253  if(t_file.exists())
254  {
255  m_sResourceDataPath = p_command.pValues()[0].toString();
256  m_RawInfo = FiffRawData();
257 
258  if (this->readRawInfo())
259  {
260  m_pFiffProducer->stop();
261  this->stop();
262 
263  m_commandManager[Commands::SIMFILE].reply("New simulation file set succefully.\r\n");
264  }
265  else
266  {
267  qDebug() << "Didn't set new file";
268  m_sResourceDataPath = t_sResourceDataPathOld;
269 
270  m_commandManager[Commands::SIMFILE].reply("Simulation file not set.\r\n");
271  }
272  }
273  else
274  {
275  qDebug() << "File does not exist on server!";
276  m_sResourceDataPath = t_sResourceDataPathOld;
277  m_commandManager[Commands::SIMFILE].reply("Simulation file not set.\r\n");
278  }
279 }
280 
281 
282 //*************************************************************************************************************
283 
285 {
286  //Connect slots
287  QObject::connect(&m_commandManager[Commands::BUFSIZE], &Command::executed, this, &FiffSimulator::comBufsize);
288  QObject::connect(&m_commandManager[Commands::GETBUFSIZE], &Command::executed, this, &FiffSimulator::comGetBufsize);
289  QObject::connect(&m_commandManager[Commands::ACCEL], &Command::executed, this, &FiffSimulator::comAccel);
290  QObject::connect(&m_commandManager[Commands::GETACCEL], &Command::executed, this, &FiffSimulator::comGetAccel);
291  QObject::connect(&m_commandManager[Commands::SIMFILE], &Command::executed, this, &FiffSimulator::comSimfile);
292 }
293 
294 
295 //*************************************************************************************************************
296 
297 ConnectorID FiffSimulator::getConnectorID() const
298 {
299  return _FIFFSIMULATOR;
300 }
301 
302 
303 //*************************************************************************************************************
304 
305 const char* FiffSimulator::getName() const
306 {
307  return "Fiff File Simulator";
308 }
309 
310 
311 //*************************************************************************************************************
312 
313 void FiffSimulator::init()
314 {
315  //
316  // Read cfg file
317  //
318  QFile t_qFile(QString("%1/mne_rt_server_plugins/FiffSimulation.cfg").arg(QCoreApplication::applicationDirPath()));
319  if (t_qFile.open(QIODevice::ReadOnly | QIODevice::Text))
320  {
321  QTextStream in(&t_qFile);
322  QString key = "simFile = ";
323  while (!in.atEnd()) {
324  QString line = in.readLine();
325  if(line.contains(key, Qt::CaseInsensitive))
326  {
327  qint32 idx = line.indexOf(key);
328  idx += key.size();
329 
330  QString sFileName = line.mid(idx, line.size()-idx);
331 
332  QFile t_qFileMeas(sFileName);
333 
334  if (t_qFileMeas.open(QIODevice::ReadOnly))
335  {
336  m_sResourceDataPath = sFileName;
337  std::cout << "\tLoad simulation file: " << sFileName.toLatin1().constData() << std::endl;
338  t_qFileMeas.close();
339  }
340  }
341  }
342  t_qFile.close();
343  }
344 
345  if(m_pRawMatrixBuffer)
346  delete m_pRawMatrixBuffer;
347  m_pRawMatrixBuffer = NULL;
348 
349  if(!m_RawInfo.isEmpty())
350  m_pRawMatrixBuffer = new RawMatrixBuffer(RAW_BUFFFER_SIZE, m_RawInfo.info.nchan, this->m_uiBufferSampleSize);
351 }
352 
353 
354 //*************************************************************************************************************
355 
357 {
358  this->init();
359 
360  // Start threads
361  m_pFiffProducer->start();
362 
363  QThread::start();
364 
365  return true;
366 }
367 
368 
369 //*************************************************************************************************************
370 
372 {
373  this->m_pFiffProducer->stop();
374  m_bIsRunning = false;
375  QThread::wait();
376 
377  return true;
378 }
379 
380 
381 //*************************************************************************************************************
382 
383 void FiffSimulator::info(qint32 ID)
384 {
385 
386  if(m_RawInfo.isEmpty())
387  readRawInfo();
388 
389  if(!m_RawInfo.isEmpty())
390  emit remitMeasInfo(ID, m_RawInfo.info);
391 }
392 
393 
394 //*************************************************************************************************************
395 
396 bool FiffSimulator::readRawInfo()
397 {
398  if(m_RawInfo.isEmpty())
399  {
400  QFile t_File(m_sResourceDataPath);
401 
402  mutex.lock();
403 
404  if(!FiffStream::setup_read_raw(t_File, m_RawInfo))
405  {
406  printf("Error: Not able to read raw info!\n");
407  m_RawInfo.clear();
408  return false;
409  }
410 
411  m_TrueSamplingRate = m_RawInfo.info.sfreq;
412  m_RawInfo.info.sfreq *= m_AccelerationFactor;
413 
414 // bool in_samples = false;
415 //
416 // bool keep_comp = true;
417 //
418 // //
419 // // Set up pick list: MEG + STI 014 - bad channels
420 // //
421 // //
422 // QStringList include;
423 // include << "STI 014";
424 // bool want_meg = true;
425 // bool want_eeg = true;
426 // bool want_stim = true;
427 
428 // // MatrixXi picks = Fiff::pick_types(m_RawInfo.info, want_meg, want_eeg, want_stim, include, m_RawInfo.info.bads);
429 // MatrixXi picks = m_RawInfo.info.pick_types(want_meg, want_eeg, want_stim, include, m_RawInfo.info.bads); //Prefer member function
430 
431 
432 // //
433 // // Set up projection
434 // //
435 // qint32 k = 0;
436 // if (m_RawInfo.info.projs.size() == 0)
437 // printf("No projector specified for these data\n");
438 // else
439 // {
440 // //
441 // // Activate the projection items
442 // //
443 // for (k = 0; k < m_RawInfo.info.projs.size(); ++k)
444 // m_RawInfo.info.projs[k].active = true;
445 
446 // printf("%d projection items activated\n",m_RawInfo.info.projs.size());
447 // //
448 // // Create the projector
449 // //
450 // // fiff_int_t nproj = MNE::make_projector_info(m_RawInfo.info, m_RawInfo.proj); Using the member function instead
451 // fiff_int_t nproj = m_RawInfo.info.make_projector_info(m_RawInfo.proj);
452 
453 
454 // // qDebug() << m_RawInfo.proj.data->data.rows();
455 // // qDebug() << m_RawInfo.proj.data->data.cols();
456 // // std::cout << "proj: \n" << m_RawInfo.proj.data->data.block(0,0,10,10);
457 
458 // if (nproj == 0)
459 // {
460 // printf("The projection vectors do not apply to these channels\n");
461 // }
462 // else
463 // {
464 // printf("Created an SSP operator (subspace dimension = %d)\n",nproj);
465 // }
466 // }
467 
468 // //
469 // // Set up the CTF compensator
470 // //
471 // // qint32 current_comp = MNE::get_current_comp(m_RawInfo.info);
472 // qint32 current_comp = m_RawInfo.info.get_current_comp();
473 // qint32 dest_comp = -1;
474 
475 // if (current_comp > 0)
476 // printf("Current compensation grade : %d\n",current_comp);
477 
478 // if (keep_comp)
479 // dest_comp = current_comp;
480 
481 // if (current_comp != dest_comp)
482 // {
483 // qDebug() << "This part needs to be debugged";
484 // if(MNE::make_compensator(*m_RawInfo.info.data(), current_comp, dest_comp, m_RawInfo.comp))
485 // {
486 // // m_RawInfo.info.chs = MNE::set_current_comp(m_RawInfo.info.chs,dest_comp);
487 // m_RawInfo.info.set_current_comp(dest_comp);
488 // printf("Appropriate compensator added to change to grade %d.\n",dest_comp);
489 // }
490 // else
491 // {
492 // printf("Could not make the compensator\n");
493 // return -1;
494 // }
495 // }
496 
497  //
498  // Create circular buffer to transfer data form producer to simulator
499  //
500  if(m_pRawMatrixBuffer)
501  delete m_pRawMatrixBuffer;
502  m_pRawMatrixBuffer = new RawMatrixBuffer(10, m_RawInfo.info.nchan, m_uiBufferSampleSize);
503 
504  mutex.unlock();
505  }
506 
507  return true;
508 }
509 
510 
511 //*************************************************************************************************************
512 
514 {
515  m_bIsRunning = true;
516 
517  float t_fSamplingFrequency = m_RawInfo.info.sfreq;
518  float t_fBuffSampleSize = (float)m_uiBufferSampleSize;
519 
520  quint32 uiSamplePeriod = (unsigned int) ((t_fBuffSampleSize/t_fSamplingFrequency)*1000000.0f);
521 
522 // quint32 count = 0;
523 
524  while(m_bIsRunning)
525  {
526  QSharedPointer<Eigen::MatrixXf> t_pRawBuffer(new Eigen::MatrixXf(m_pRawMatrixBuffer->pop()));
527 // ++count;
528 // printf("%d raw buffer (%d x %d) generated\r\n", count, t_pRawBuffer->rows(), t_pRawBuffer->cols());
529 
530  emit remitRawBuffer(t_pRawBuffer);
531  usleep(uiSamplePeriod);
532  }
533 }
bool isEmpty() const
Old fiff_type declarations - replace them.
MNEEpochDataList class declaration.
CommandManager m_commandManager
Definition: IConnector.h:228
virtual ConnectorID getConnectorID() const
FIFF raw measurement data.
Definition: fiff_raw_data.h:94
static bool setup_read_raw(QIODevice &p_IODevice, FiffRawData &data, bool allow_maxshield=false)
The FiffProducer class provides a ECG data producer for a given sampling rate.
Definition: fiffproducer.h:87
QList< QVariant > & pValues()
Definition: command.h:370
Definition: fiff.h:98
void executed(Command p_command)
FIFF class declaration, which provides static wrapper functions to stay consistent with mne matlab to...
virtual const char * getName() const