45 #include "FormFiles/babymegprojectdialog.h"
58 #include <QtCore/QtPlugin>
59 #include <QtCore/QTextStream>
60 #include <QtCore/QFile>
85 , m_bWriteToFile(false)
86 , m_sCurrentParadigm(
"")
88 , m_pRawMatrixBuffer(0)
89 , m_sFiffHeader(QCoreApplication::applicationDirPath() +
"/mne_x_plugins/resources/babymeg/header.fif")
90 , m_sBadChannels(QCoreApplication::applicationDirPath() +
"/mne_x_plugins/resources/babymeg/both.bad")
92 m_pActionSetupProject =
new QAction(QIcon(
":/images/database.png"), tr(
"Setup Project"),
this);
94 m_pActionSetupProject->setStatusTip(tr(
"Setup Project"));
95 connect(m_pActionSetupProject, &QAction::triggered,
this, &BabyMEG::showProjectDialog);
98 m_pActionUpdateFiffInfo =
new QAction(QIcon(
":/images/latestFiffInfo.png"), tr(
"Update Fiff Info"),
this);
99 m_pActionUpdateFiffInfo->setStatusTip(tr(
"Update Fiff Info"));
103 m_pActionRecordFile =
new QAction(QIcon(
":/images/record.png"), tr(
"Start Recording"),
this);
105 m_pActionRecordFile->setStatusTip(tr(
"Start Recording"));
111 m_pActionSqdCtrl =
new QAction(QIcon(
":/images/sqdctrl.png"), tr(
"Squid Control"),
this);
113 m_pActionSqdCtrl->setStatusTip(tr(
"Squid Control"));
114 connect(m_pActionSqdCtrl, &QAction::triggered,
this, &BabyMEG::showSqdCtrlDialog);
124 if(this->isRunning())
127 if(myClient && myClient->isConnected())
137 QSharedPointer<BabyMEG> pBabyMEGClone(
new BabyMEG());
138 return pBabyMEGClone;
146 QString sFilePath = m_sBabyMEGDataPath +
"/" + m_sCurrentProject +
"/" + m_sCurrentSubject;
151 sTimeStamp = QDateTime::currentDateTime().toString(
"yyMMdd_hhmmss");
153 sTimeStamp =
"<YYMMDD_HMS>";
155 if(m_sCurrentParadigm.isEmpty())
156 sFilePath.append(
"/"+ sTimeStamp +
"_" + m_sCurrentSubject +
"_raw.fif");
158 sFilePath.append(
"/"+ sTimeStamp +
"_" + m_sCurrentSubject +
"_" + m_sCurrentParadigm +
"_raw.fif");
169 m_sBabyMEGDataPath = QDir::homePath() +
"/BabyMEGData";
170 if(!QDir(m_sBabyMEGDataPath).exists())
171 QDir().mkdir(m_sBabyMEGDataPath);
173 if(!QDir(m_sBabyMEGDataPath+
"/TestProject").exists())
174 QDir().mkdir(m_sBabyMEGDataPath+
"/TestProject");
176 m_sCurrentProject = settings.value(QString(
"Plugin/%1/currentProject").arg(getName()),
"TestProject").toString();
178 if(!QDir(m_sBabyMEGDataPath+
"/TestProject/TestSubject").exists())
179 QDir().mkdir(m_sBabyMEGDataPath+
"/TestProject/TestSubject");
180 m_sCurrentSubject = settings.value(QString(
"Plugin/%1/currentSubject").arg(getName()),
"TestSubject").toString();
183 pInfo = QSharedPointer<BabyMEGInfo>(
new BabyMEGInfo());
184 connect(pInfo.data(), &BabyMEGInfo::fiffInfoAvailable,
this, &BabyMEG::setFiffInfo);
185 connect(pInfo.data(), &BabyMEGInfo::SendDataPackage,
this, &BabyMEG::setFiffData);
186 connect(pInfo.data(), &BabyMEGInfo::SendCMDPackage,
this, &BabyMEG::setCMDData);
187 connect(pInfo.data(), &BabyMEGInfo::GainInfoUpdate,
this, &BabyMEG::setFiffGainInfo);
189 myClient = QSharedPointer<BabyMEGClient>(
new BabyMEGClient(6340,
this));
192 myClientComm = QSharedPointer<BabyMEGClient>(
new BabyMEGClient(6341,
this));
194 myClientComm->start();
198 myClient->ConnectToBabyMEG();
219 void BabyMEG::initConnector()
224 m_pRTMSABabyMEG->data()->setName(this->getName());
226 m_pRTMSABabyMEG->data()->initFromFiffInfo(m_pFiffInfo);
227 m_pRTMSABabyMEG->data()->setMultiArraySize(2);
229 m_pRTMSABabyMEG->data()->setSamplingRate(m_pFiffInfo->sfreq);
231 m_pRTMSABabyMEG->data()->setVisibility(
true);
249 void BabyMEG::showProjectDialog()
252 projectDialog.exec();
258 void BabyMEG::showSqdCtrlDialog()
263 if (SQUIDCtrlDlg == NULL)
266 if (!SQUIDCtrlDlg->isVisible())
268 SQUIDCtrlDlg->show();
269 SQUIDCtrlDlg->raise();
270 SQUIDCtrlDlg->Init();
293 qDebug() <<
"Split recording file";
295 QString nextFileName = m_sRecordFile.remove(
"_raw.fif");
296 nextFileName += QString(
"-%1_raw.fif").arg(m_iSplitCount);
302 m_pOutfid->start_block(FIFFB_REF);
303 data = FIFFV_ROLE_NEXT_FILE;
304 m_pOutfid->write_int(FIFF_REF_ROLE,&data);
305 m_pOutfid->write_string(FIFF_REF_FILE_NAME, nextFileName);
306 m_pOutfid->write_id(FIFF_REF_FILE_ID);
307 data = m_iSplitCount - 1;
308 m_pOutfid->write_int(FIFF_REF_FILE_NUM, &data);
309 m_pOutfid->end_block(FIFFB_REF);
312 m_pOutfid->finish_writing_raw();
315 m_qFileOut.setFileName(nextFileName);
317 fiff_int_t first = 0;
318 m_pOutfid->write_int(FIFF_FIRST_SAMPLE, &first);
329 m_pOutfid->finish_writing_raw();
330 m_bWriteToFile =
false;
331 m_pTimerRecordingChange->stop();
332 m_pActionRecordFile->setIcon(QIcon(
":/images/record.png"));
342 msgBox.setText(
"FiffInfo missing!");
350 m_qFileOut.setFileName(m_sRecordFile);
351 if(m_qFileOut.exists())
354 msgBox.setText(
"The file you want to write already exists.");
355 msgBox.setInformativeText(
"Do you want to overwrite this file?");
356 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
357 int ret = msgBox.exec();
358 if(ret == QMessageBox::No)
363 fiff_int_t first = 0;
364 m_pOutfid->write_int(FIFF_FIRST_SAMPLE, &first);
366 m_bWriteToFile =
true;
368 m_pTimerRecordingChange = QSharedPointer<QTimer>(
new QTimer);
369 connect(m_pTimerRecordingChange.data(), &QTimer::timeout,
this, &BabyMEG::changeRecordingButton);
370 m_pTimerRecordingChange->start(500);
377 void BabyMEG::setFiffData(QByteArray DATA)
380 int dformat = DATA.left(1).toInt();
383 qint32 rows = m_pFiffInfo->nchan;
384 qint32 cols = (DATA.size()/dformat)/rows;
386 qDebug() <<
"[BabyMEG] Matrix " << rows <<
"x" << cols <<
" [Data bytes:" << dformat <<
"]";
388 MatrixXf rawData(Map<MatrixXf>( (
float*)DATA.data(),rows, cols ));
390 for(qint32 i = 0; i < rows*cols; ++i)
396 if(!m_pRawMatrixBuffer)
399 m_pRawMatrixBuffer->
push(&rawData);
414 void BabyMEG::setFiffInfo(
FiffInfo p_FiffInfo)
416 m_pFiffInfo = QSharedPointer<FiffInfo>(
new FiffInfo(p_FiffInfo));
418 if(!readProjectors())
420 qDebug() <<
"Not able to read projectors";
424 if(!readBadChannels())
426 qDebug() <<
"Not able to read bad channels";
430 m_iBufferSize = pInfo->dataLength;
431 sfreq = pInfo->sfreq;
436 m_cals = RowVectorXd(m_pFiffInfo->nchan);
438 for (qint32 k = 0; k < m_pFiffInfo->nchan; ++k)
439 m_cals[k] = m_pFiffInfo->chs[k].range*m_pFiffInfo->chs[k].cal;
444 typedef Eigen::Triplet<double> T;
445 std::vector<T> tripletList;
446 tripletList.reserve(m_pFiffInfo->nchan);
447 for(qint32 i = 0; i < m_pFiffInfo->nchan; ++i)
448 tripletList.push_back(T(i, i, this->m_cals[i]));
450 m_sparseMatCals = SparseMatrix<double>(m_pFiffInfo->nchan, m_pFiffInfo->nchan);
451 m_sparseMatCals.setFromTriplets(tripletList.begin(), tripletList.end());
458 void BabyMEG::setFiffGainInfo(QStringList GainInfo)
463 msgBox.setText(
"FiffInfo missing!");
470 qDebug()<<
"Set Gain Info";
471 for(qint32 i = 0; i < m_pFiffInfo->nchan; i++)
473 m_pFiffInfo->chs[i].range = 1.0f/GainInfo.at(i).toFloat();
481 void BabyMEG::setCMDData(QByteArray DATA)
483 qDebug()<<
"------"<<DATA;
486 qDebug()<<
"Data has been received.";
491 void BabyMEG::comFLL(QString t_sFLLControlCommand)
493 qDebug()<<
"FLL commands";
495 qDebug() <<
"BabyMeg Received" << t_sFLLControlCommand;
496 int strlen = t_sFLLControlCommand.size();
498 QByteArray SC = QByteArray(
"COMS")+Scmd;
499 SC.append(t_sFLLControlCommand);
506 bool BabyMEG::start()
509 if(this->isRunning())
518 if(!myClient->isConnected())
519 myClient->ConnectToBabyMEG();
531 if(myClient->isConnected())
532 myClient->DisConnectBabyMEG();
534 m_bIsRunning =
false;
540 m_pRawMatrixBuffer->
clear();
556 QString BabyMEG::getName()
const
566 if(!myClient->isConnected())
567 myClient->ConnectToBabyMEG();
579 MatrixXd BabyMEG::calibrate(
const MatrixXf& data)
582 if(m_pFiffInfo && m_sparseMatCals.cols() == m_pFiffInfo->nchan)
583 one = m_sparseMatCals*data.cast<
double>();
585 one = data.cast<
double>();
593 bool BabyMEG::readProjectors()
595 QFile t_headerFiffFile(m_sFiffHeader);
601 QString t_sFileName = t_pStream->streamName();
603 printf(
"Opening header data %s...\n",t_sFileName.toUtf8().constData());
606 QList<FiffDirEntry> t_Dir;
608 if(!t_pStream->open(t_Tree, t_Dir))
611 QList<FiffProj> q_ListProj = t_pStream->read_proj(t_Tree);
613 if (q_ListProj.size() == 0)
615 printf(
"Could not find projectors\n");
619 m_pFiffInfo->projs = q_ListProj;
622 t_pStream->device()->close();
630 bool BabyMEG::readBadChannels()
635 QFile t_badChannelsFile(m_sBadChannels);
637 if (!t_badChannelsFile.open(QIODevice::ReadOnly | QIODevice::Text))
640 printf(
"Reading bad channels from %s...\n", m_sBadChannels.toUtf8().constData());
642 QTextStream in(&t_badChannelsFile);
644 QStringList t_sListbads;
645 while (!in.atEnd()) {
646 QString channel = in.readLine();
647 if(channel.isEmpty())
650 printf(
"Channel %i: %s\n",count,channel.toUtf8().constData());
651 t_sListbads << channel;
654 m_pFiffInfo->bads = t_sListbads;
671 if(m_pRawMatrixBuffer)
674 matValue = m_pRawMatrixBuffer->
pop();
679 size += matValue.rows()*matValue.cols() * 4;
681 if(size > MAX_DATA_LEN)
687 m_pOutfid->write_raw_buffer(matValue.cast<
double>());
693 m_pRTMSABabyMEG->data()->setValue(this->calibrate(matValue));
705 void BabyMEG::changeRecordingButton()
707 if(m_iBlinkStatus == 0)
709 m_pActionRecordFile->setIcon(QIcon(
":/images/record.png"));
714 m_pActionRecordFile->setIcon(QIcon(
":/images/record_active.png"));
FIFF measurement file information.
OutputConnectorList m_outputConnectors
The BabyMEGClient class provides a TCP/IP communication between Qt and Labview.
void splitRecordingFile()
void SendCommandToBabyMEGShortConnection(QByteArray s)
void SetInfo(BabyMEGInfo *pInfo)
void DataToSquidCtrlGUI(MatrixXf tmp)
QSharedPointer< CircularMatrixBuffer > SPtr
void addPluginAction(QAction *pAction)
void toggleRecordingFile()
void SendCMDDataToSQUIDControl(QByteArray DATA)
QSharedPointer< FiffStream > SPtr
void push(const Matrix< _Tp, Dynamic, Dynamic > *pMatrix)
QString getFilePath(bool currentTime=false) const
Directory tree structure.
Matrix< _Tp, Dynamic, Dynamic > pop()
The BabyMEGClient class provides a TCP/IP communication between Qt and Labview.
static void swap_floatp(float *source)
static FiffStream::SPtr start_writing_raw(QIODevice &p_IODevice, const FiffInfo &info, RowVectorXd &cals, MatrixXi sel=defaultMatrixXi)
QByteArray MGH_LM_Int2Byte(int a)
The BabyMEGSQUIDControlDgl class provides the SQUID control dialog.
virtual QWidget * setupWidget()
static QSharedPointer< PluginOutputData< T > > create(IPlugin *parent, const QString &name, const QString &descr)
virtual QSharedPointer< IPlugin > clone() const
virtual IPlugin::PluginType getType() const
IOUtils class declaration.