ex_fiff_sniffer
Read a FIFF file from a memory buffer with a chosen byte order and summarise its contents.
Libraries: Connectivity, MNE Core, FIFF I/O
Options
| Option | Description |
|---|---|
--file | The input file <in>. |
--endian | The file's endianness. 'little' or 'big' |
--pad | Adds -1 to end of stream to account for unfinished file (use for neuromag2ft) |
Build and run
cmake --build build/developer-dynamic --target ex_fiff_sniffer
./out/Release/examples/ex_fiff_sniffer --help
The default inputs come from the MNE sample dataset.
Used in the API reference
Source
src/examples/ex_fiff_sniffer/main.cpp
//=============================================================================================================
/**
* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2010-2026 MNE-CPP Authors
*
* @file main.cpp
* @author Gabriel Motta <gabrielbenmotta@gmail.com>;
* Christoph Dinh <christoph.dinh@mne-cpp.org>
* @brief Read a FIFF file from a memory buffer with a chosen byte order and summarise its contents
*/
//=============================================================================================================
// INCLUDES
//=============================================================================================================
#include <QCoreApplication>
#include <fiff/fiff.h>
#include <mne/mne.h>
#include <fiff/fiff_io.h>
#include <fiff/fiff_stream.h>
#include <fiff/fiff_digitizer_data.h>
////////////////////////
#include <connectivity/network/network.h>
#include <fiff/fiff_ch_info.h>
#include <fiff/fiff_digitizer_data.h>
#include <mne/mne_msh_display_surface_set.h>
#include <mne/mne_surface_or_volume.h>
//////////////////////
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================
#include <QCommandLineParser>
#include <QBuffer>
#include <QtEndian>
//=============================================================================================================
// STL INCLUDES
//=============================================================================================================
#include <iostream>
//=============================================================================================================
// MAIN
//=============================================================================================================
using namespace CONNECTIVITYLIB;
using namespace MNELIB;
using namespace FIFFLIB;
int main(int argc, char* argv[])
{
QCoreApplication a(argc, argv);
QCommandLineParser parser;
parser.setApplicationDescription("Fiff Sniffer Example");
parser.addHelpOption();
QCommandLineOption inputOption({"file", "f"}, "The input file <in>.", "in", QCoreApplication::applicationDirPath() + "/../resources/data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif");
QCommandLineOption endianOption({"endian", "e", "en"}, "The file's endianness. 'little' or 'big'", "endian", "big");
QCommandLineOption padEndOption("pad", "Adds -1 to end of stream to account for unfinished file (use for neuromag2ft)");
parser.addOption(inputOption);
parser.addOption(endianOption);
parser.addOption(padEndOption);
parser.process(a);
bool littleEndian = false;
if (parser.value(endianOption) == "little") {
littleEndian = true;
}
QFile t_fileRaw(parser.value(inputOption));
std::cout << "\n------------ Fiff Sniffer ------------\n";
std::cout << "Input file : " << t_fileRaw.fileName().toStdString() << "\n";
if (!t_fileRaw.exists()) {
std::cout << "File cannot be found.\n";
std::cout << "\nBye!\n";
} else { //file found
QBuffer buffer;
if (!buffer.open(QIODevice::ReadWrite)) {
std::cout << "Buffer can't be opened.\n";
return 1;
}
if (!t_fileRaw.open(QIODevice::ReadOnly)) {
std::cout << "Input file can't be opened.\n";
return 1;
}
buffer.write(t_fileRaw.readAll());
t_fileRaw.close();
qint32_le iIntToChar;
char cCharFromInt[sizeof(qint32)];
if (parser.isSet(padEndOption)) {
iIntToChar = -1;
memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
buffer.write(cCharFromInt);
iIntToChar = -1;
memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
buffer.write(cCharFromInt);
iIntToChar = -1;
memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
buffer.write(cCharFromInt);
iIntToChar = -1;
memcpy(cCharFromInt, &iIntToChar, sizeof(qint32));
buffer.write(cCharFromInt);
}
buffer.reset();
FIFFLIB::FiffStream stream(&buffer);
if (littleEndian) {
stream.setByteOrder(QDataStream::LittleEndian);
} else {
stream.setByteOrder(QDataStream::BigEndian);
}
if (stream.open()) {
FIFFLIB::FiffInfo FifInfo;
FIFFLIB::FiffDirNode::SPtr DirNode;
FIFFLIB::FiffDigitizerData digData;
if (stream.read_meas_info(stream.dirtree(), FifInfo, DirNode)) {
FIFFLIB::FiffIO p_fiffIO(t_fileRaw);
std::cout << "Num. raw dat sets: " << p_fiffIO.m_qlistRaw.size() << "\n";
std::cout << "Num. evoked sets: " << p_fiffIO.m_qlistEvoked.size() << "\n";
int count = 0;
for (auto& data : p_fiffIO.m_qlistRaw) {
std::cout << "--- \n";
std::cout << "Raw Set " << count << "\n";
std::cout << "Sample frequency: " << data->info.sfreq << "\n";
std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
std::cout << "First sample: " << data->first_samp << " | Last sample: " << data->last_samp << "\n";
std::cout << "Number of samples: " << data->last_samp - data->first_samp << " | Time: " << (data->last_samp - data->first_samp) / data->info.sfreq << " sec. \n";
std::cout << "Number of digitizer points: " << data->info.dig.size() << "\n";
for (auto& point : data->info.dig) {
if (point.kind == FIFFV_POINT_HPI) {
std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
}
}
}
count = 0;
for (auto& data : p_fiffIO.m_qlistEvoked) {
std::cout << "--- \n";
std::cout << "Evoked Set " << count << "\n";
std::cout << "Sample frequency: " << data->info.sfreq << "\n";
std::cout << "LineFreq: " << data->info.linefreq << " | Highpass: " << data->info.highpass << " | Lowpass: " << data->info.lowpass << "\n";
std::cout << "Num. averaged epochs: " << data->nave << "\n";
}
std::cout << "--- \n";
std::cout << "--------------------------------------\n";
}
if (stream.read_digitizer_data(stream.dirtree(), digData)) {
std::cout << "Digitizer data found.\n";
std::cout << "Number of digitizer points: " << digData.points.size() << "\n";
for (auto& point : digData.points) {
if (point.kind == FIFFV_POINT_HPI) {
std::cout << "HPI Point " << point.ident << " - " << point.r[0] << ", " << point.r[1] << ", " << point.r[2] << "\n";
}
}
}
}
}
return 0;
}