Skip to content
3 changes: 2 additions & 1 deletion applications/mne_scan/plugins/ftbuffer/ftbuffertypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ typedef struct {
qint32 nevents;
} samples_events_t;

enum class HeaderChunk : int{
enum class HeaderChunkType : int{
FT_CHUNK_CHANNEL_NAMES = 1,
FT_CHUNK_NEUROMAG_HEADER = 8,
FT_CHUNK_NEUROMAG_ISOTRAK = 9,
FT_CHUNK_NEUROMAG_HPIRESULT = 10
Expand Down
4 changes: 2 additions & 2 deletions applications/mne_scan/plugins/ftbuffer/ftbuffproducer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void FtBuffProducer::runMainLoop()
QThread::usleep(50000);
}

while(!m_pFtConnector->getHeader()) {
while(!m_pFtConnector->getFixedHeader()) {
QThread::usleep(50000);
}

Expand Down Expand Up @@ -127,7 +127,7 @@ void FtBuffProducer::connectToBuffer(QString addr,

//Try to get info from buffer first, then resort to file
if(m_pFtConnector->connect()) {
auto metadata = m_pFtConnector->parseBufferHeaders();
auto metadata = m_pFtConnector->parseBufferHeader();
if (m_pFtBuffer->setupRTMSA(metadata)){
emit connecStatus(true);
return;
Expand Down
105 changes: 67 additions & 38 deletions applications/mne_scan/plugins/ftbuffer/ftconnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

#include <QThread>
#include <QtEndian>
#include <QDateTime>

//=============================================================================================================
// EIGEN INCLUDES
Expand All @@ -69,7 +70,7 @@ FtConnector::FtConnector()
, m_iExtendedHeaderSize(0)
, m_iPort(1972)
, m_bNewData(false)
, m_fSampleFreq(0)
, m_fSamplingFreq(0)
, m_sAddress("127.0.0.1")
, m_pSocket(Q_NULLPTR)
{
Expand Down Expand Up @@ -119,7 +120,7 @@ bool FtConnector::connect()

//=============================================================================================================

bool FtConnector::getHeader()
bool FtConnector::getFixedHeader()
{
qInfo() << "[FtConnector::getHeader] Attempting to get header...";

Expand All @@ -140,7 +141,7 @@ bool FtConnector::getHeader()

//Parse return message from buffer
QBuffer msgBuffer;
prepBuffer(msgBuffer, sizeof (messagedef_t));
copyResponse(msgBuffer, sizeof (messagedef_t));
int bufsize = parseMessageDef(msgBuffer);

if (bufsize == 0) {
Expand All @@ -155,7 +156,7 @@ bool FtConnector::getHeader()

//Parse header info from buffer
QBuffer hdrBuffer;
prepBuffer(hdrBuffer, sizeof (headerdef_t)); // if implementing header chunks: change from sizeof (headerdef) to bufsize
copyResponse(hdrBuffer, sizeof (headerdef_t)); // if implementing header chunks: change from sizeof (headerdef) to bufsize
parseHeaderDef(hdrBuffer);

return true;
Expand Down Expand Up @@ -205,11 +206,11 @@ bool FtConnector::parseHeaderDef(QBuffer &readBuffer)

//Save paramerters
m_iNumChannels = headerdef.nchans;
m_fSampleFreq = headerdef.fsample;
m_fSamplingFreq = headerdef.fsample;
m_iNumNewSamples = headerdef.nsamples;
m_iDataType = headerdef.data_type;
m_iExtendedHeaderSize = headerdef.bufsize;
m_iMinSampleRead = static_cast<int>(m_fSampleFreq/2);
m_iMinSampleRead = static_cast<int>(m_fSamplingFreq/2);

qInfo() << "[FtConnector::parseHeaderDef] Got header parameters.";

Expand Down Expand Up @@ -287,7 +288,7 @@ bool FtConnector::getData()

//Parse return message from buffer
QBuffer msgBuffer;
prepBuffer(msgBuffer, sizeof (messagedef_t));
copyResponse(msgBuffer, sizeof (messagedef_t));
int bufsize = parseMessageDef(msgBuffer);

//Waiting for response.
Expand All @@ -297,12 +298,12 @@ bool FtConnector::getData()

//Parse return data def from buffer
QBuffer datadefBuffer;
prepBuffer(datadefBuffer, sizeof (datadef_t));
copyResponse(datadefBuffer, sizeof (datadef_t));
bufsize = parseDataDef(datadefBuffer);

//Parse actual data from buffer
QBuffer datasampBuffer;
prepBuffer(datasampBuffer, bufsize);
copyResponse(datasampBuffer, bufsize);
parseData(datasampBuffer, bufsize);

//update sample tracking
Expand Down Expand Up @@ -334,8 +335,8 @@ bool FtConnector::setPort(const int &iPort)

//=============================================================================================================

void FtConnector::prepBuffer(QBuffer &buffer,
int numBytes)
void FtConnector::copyResponse(QBuffer &buffer,
int numBytes)
{
buffer.open(QIODevice::ReadWrite);
buffer.write(m_pSocket->read(numBytes));
Expand Down Expand Up @@ -395,7 +396,7 @@ void FtConnector::echoStatus()
qInfo() << "| Socket: " << m_pSocket->state();
qInfo() << "| Address: " << m_sAddress << ":" << m_iPort;
qInfo() << "| Channels: " << m_iNumChannels;
qInfo() << "| Frequency: " << m_fSampleFreq;
qInfo() << "| Frequency: " << m_fSamplingFreq;
qInfo() << "| Samples read:" << m_iNumSamples;
qInfo() << "| New samples: " << m_iNumNewSamples;
qInfo() << "|================================";
Expand Down Expand Up @@ -430,7 +431,7 @@ int FtConnector::totalBuffSamples()

//Parse return message from buffer
QBuffer msgBuffer;
prepBuffer(msgBuffer, sizeof (messagedef_t));
copyResponse(msgBuffer, sizeof (messagedef_t));
parseMessageDef(msgBuffer);

//Waiting for response.
Expand All @@ -441,7 +442,7 @@ int FtConnector::totalBuffSamples()
qint32 iNumSamp;

QBuffer sampeventsBuffer;
prepBuffer(sampeventsBuffer, sizeof(samples_events_t));
copyResponse(sampeventsBuffer, sizeof(samples_events_t));

char cSamps[sizeof(iNumSamp)];
sampeventsBuffer.read(cSamps, sizeof(iNumSamp));
Expand All @@ -468,19 +469,6 @@ bool FtConnector::parseData(QBuffer &datasampBuffer,
QByteArray dataArray = datasampBuffer.readAll();
float* fdata = reinterpret_cast<float*> (dataArray.data());

//TODO: Implement receiving other types of data
// switch (m_iDataType) {
// case DATATYPE_FLOAT32:
// auto data = reinterpret_cast<float*>(dataArray.data(), bufsize);
// qDebug() << "*** Would you look at that, we're all the way here ***";
// qDebug() << "Data sample:";

// for (int i = 0; i < 10 ; i++) {
// qDebug() << data[i];
// }
// break;
// }

//format data into eigen matrix to pass up
Eigen::MatrixXf matData;
matData.resize(m_iNumChannels, m_iMsgSamples);
Expand Down Expand Up @@ -542,24 +530,22 @@ QString FtConnector::getAddr()

//=============================================================================================================

MetaData FtConnector::parseBufferHeaders()
MetaData FtConnector::parseBufferHeader()
{
qInfo() << "[FtConnector::parseNeuromagHeader] Attempting to get extended header...";

MetaData metadata;
QBuffer chunkBuffer;

getHeader();
prepBuffer(chunkBuffer, m_iExtendedHeaderSize);
getFixedHeader();

std::cout << "Parsing extended header\n";
qInfo() << "[FtConnector::parseNeuromagHeader] Parsing extended header\n";
QBuffer allChunksBuffer;
copyResponse(allChunksBuffer, m_iExtendedHeaderSize);

FtHeaderParser parser;
metadata = parser.parseHeader(chunkBuffer);
metadata = parser.parseExtendedHeader(allChunksBuffer);

if (!metadata.bFiffInfo){
metadata.setFiffinfo(infoFromSimpleHeader());
}
checkForMissingMetadataFields(metadata);

return metadata;
}
Expand Down Expand Up @@ -587,11 +573,14 @@ BufferInfo FtConnector::getBufferInfo()

//=============================================================================================================

FIFFLIB::FiffInfo FtConnector::infoFromSimpleHeader()
FIFFLIB::FiffInfo FtConnector::infoFromSimpleHeader() const
{
FIFFLIB::FiffInfo defaultInfo;

defaultInfo.sfreq = m_fSampleFreq;
defaultInfo.meas_date[0] = static_cast<int32_t>(QDateTime::currentDateTime().toSecsSinceEpoch());
defaultInfo.meas_date[1] = 0;

defaultInfo.sfreq = m_fSamplingFreq;
defaultInfo.nchan = m_iNumChannels;

defaultInfo.chs.clear();
Expand All @@ -612,3 +601,43 @@ FIFFLIB::FiffInfo FtConnector::infoFromSimpleHeader()

return defaultInfo;
}

//=============================================================================================================

void FtConnector::checkForMissingMetadataFields(MetaData& data) const
{
if (!data.bFiffInfo){
data.setFiffinfo(infoFromSimpleHeader());
} else {
if ( data.info.meas_date[0] == -1 )
{
data.info.meas_date[0] = static_cast<int32_t>(QDateTime::currentDateTime().toSecsSinceEpoch());
data.info.meas_date[1] = 0;
}

if ( data.info.sfreq <= 0 )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as long as we have not set on a specific formatting rule, I would propose follow the old style aka no spaces before and after (as well as )

{
data.info.sfreq = m_fSamplingFreq;
}
if ( data.info.nchan == -1 )
{
data.info.nchan = m_iNumChannels;
data.info.chs.clear();
for (int chani = 0; chani< m_iNumChannels; chani++)
{
FIFFLIB::FiffChInfo channel;

channel.ch_name = "Ch. " + QString::number(chani);
channel.kind = FIFFV_MEG_CH;
channel.unit = FIFF_UNIT_T;
channel.unit_mul = FIFF_UNITM_NONE;
channel.chpos.coil_type = FIFFV_COIL_NONE;

data.info.chs.append(channel);

data.info.ch_names.append("Ch. " + QString::number(chani));

}
}
}
}
21 changes: 15 additions & 6 deletions applications/mne_scan/plugins/ftbuffer/ftconnector.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class FtConnector : public QObject
*
* @return true if successful, false if unsuccessful.
*/
bool getHeader();
bool getFixedHeader();

//=========================================================================================================
/**
Expand Down Expand Up @@ -209,7 +209,7 @@ class FtConnector : public QObject
*
* @return returns the FiffInfo from the parsed fif file from the neuromag header chunk.
*/
MetaData parseBufferHeaders();
MetaData parseBufferHeader();

//=========================================================================================================
/**
Expand Down Expand Up @@ -293,8 +293,8 @@ class FtConnector : public QObject
* @param[out] buffer QBuffer to which daa will be written.
* @param[in] numBytes How many bytes to read from socket.
*/
void prepBuffer(QBuffer &buffer,
int numBytes);
void copyResponse(QBuffer &buffer,
int numBytes);

//=========================================================================================================
/**
Expand All @@ -310,7 +310,16 @@ class FtConnector : public QObject
*
* @return FiffInfo object based on filedtrip header
*/
FIFFLIB::FiffInfo infoFromSimpleHeader();
FIFFLIB::FiffInfo infoFromSimpleHeader() const;

//=========================================================================================================
/**
* Checks for empty or invalid important fields in the parsed metadata and attempts to fill them.
*
* @param[in] data FiffInfo structure with information parsed from the FTBuffer headers.
*
*/
void checkForMissingMetadataFields(MetaData& data) const;

int m_iMinSampleRead; /**< Number of samples that need to be added t obuffer before we try to read. */
int m_iNumSamples; /**< Number of samples we've read from the buffer. */
Expand All @@ -323,7 +332,7 @@ class FtConnector : public QObject

bool m_bNewData; /**< Indicate whether we've received new data. */

float m_fSampleFreq; /**< Sampling frequency of data in the buffer. */
float m_fSamplingFreq; /**< Sampling frequency of data in the buffer. */

QString m_sAddress; /**< Address where the ft buffer is found. */

Expand Down
Loading