v2.0.0
Loading...
Searching...
No Matches
fiff_io.cpp
Go to the documentation of this file.
1//=============================================================================================================
22
23//=============================================================================================================
24// INCLUDES
25//=============================================================================================================
26
27#include "fiff_io.h"
28#include "fiff.h"
29#include "fiff_evoked_set.h"
30#include "fiff_stream.h"
31
32//=============================================================================================================
33// STL INCLUDES
34//=============================================================================================================
35
36#include <iostream>
37#include <stdexcept>
38#include <QDebug>
39
40//=============================================================================================================
41// USED NAMESPACES
42//=============================================================================================================
43
44using namespace FIFFLIB;
45using namespace Eigen;
46
47//=============================================================================================================
48// DEFINE MEMBER METHODS
49//=============================================================================================================
50
54
55//=============================================================================================================
56
60
61//=============================================================================================================
62
63FiffIO::FiffIO(QIODevice& pIODevice)
64{
65 // execute read method
66 FiffIO::read(pIODevice);
67}
68
69//=============================================================================================================
70
71FiffIO::FiffIO(QList<QIODevice*>& p_qlistIODevices)
72{
73 QList<QIODevice*>::iterator i;
74 for (i = p_qlistIODevices.begin(); i != p_qlistIODevices.end(); ++i) {
75 FiffIO::read((**i));
76 }
77}
78
79//=============================================================================================================
80
81bool FiffIO::setup_read(QIODevice& pIODevice,
82 FiffInfo& info,
83 FiffDirNode::SPtr& dirTree)
84{
85 //Open the file
86 FiffStream::SPtr p_pStream(new FiffStream(&pIODevice));
87 QString t_sFileName = p_pStream->streamName();
88
89 qInfo("Opening fiff data %s...\n", t_sFileName.toUtf8().constData());
90
91 if (!p_pStream->open())
92 return false;
93
94 //Read the measurement info
95 if (!p_pStream->read_meas_info(p_pStream->dirtree(), info, dirTree))
96 return false;
97
98 return true;
99}
100
101//=============================================================================================================
102
103bool FiffIO::read(QIODevice& pIODevice)
104{
105 //Read dirTree from fiff data (raw,evoked,fwds,cov)
106 FiffInfo t_fiffInfo;
107 FiffDirNode::SPtr t_dirTree;
108 bool hasRaw = false;
109 bool hasEvoked = false; // hasFwds=false;
110
111 FiffIO::setup_read(pIODevice, t_fiffInfo, t_dirTree);
112 pIODevice.close(); //file can be closed, since IODevice is already read
113
114 if (!t_dirTree) {
115 qWarning() << "[FiffIO::read] Dir tree could not be read";
116 return false;
117 }
118
119 //Search dirTree for specific data types
120 if (t_dirTree->has_kind(FIFFB_EVOKED)) {
121 hasEvoked = true;
122 }
123
124 if (t_dirTree->has_kind(FIFFB_RAW_DATA) ||
125 t_dirTree->has_kind(FIFFB_PROCESSED_DATA) ||
126 t_dirTree->has_kind(FIFFB_CONTINUOUS_DATA) ||
127 t_dirTree->has_kind(FIFFB_SMSH_RAW_DATA)) {
128 hasRaw = true;
129 }
130
131 // if(t_Tree.has_kind(FIFFB_MNE_FORWARD_SOLUTION))
132 // hasFwds = true;
133
134 //Read all sort of types
135 //raw data
136 if (hasRaw) {
137 try {
138 QSharedPointer<FiffRawData> p_fiffRawData(new FiffRawData(pIODevice));
139 pIODevice.close();
140
141 //append to corresponding member qlist
142 m_qlistRaw.append(p_fiffRawData);
143
144 qInfo("Finished reading raw data!\n");
145 } catch (const std::exception& e) {
146 qWarning() << "[FiffIO::read] Could not read raw data:" << e.what();
147 pIODevice.close();
148 }
149 }
150
151 //evoked data + projections
152 if (hasEvoked) {
153 try {
154 FiffEvokedSet p_fiffEvokedSet(pIODevice);
155 pIODevice.close();
156
157 //append to corresponding member qlist
158 for (qint32 i = 0; i < p_fiffEvokedSet.evoked.size(); ++i) {
159 m_qlistEvoked.append(QSharedPointer<FiffEvoked>(new FiffEvoked(p_fiffEvokedSet.evoked[i])));
160 }
161 } catch (const std::exception& e) {
162 qWarning() << "[FiffIO::read] Could not read evoked data:" << e.what();
163 pIODevice.close();
164 }
165 }
166
167 // //forward solutions
168 // if(hasFwds) {
169 // MNEForwardSolution p_forwardSolution(pIODevice);
170
171 // //append to corresponding member qlist
172 // m_qlistFwd.append(QSharedPointer<MNEForwardSolution>(&p_forwardSolution));
173 // }
174
175 //print summary
176 //std::cout << *this << std::endl;
177
178 return true;
179}
180
181//=============================================================================================================
182
183bool FiffIO::write(QIODevice& pIODevice,
184 const fiff_int_t type,
185 const fiff_int_t idx) const
186{
187 switch (type) {
188 case FIFFB_RAW_DATA: {
189 FiffIO::write_raw(pIODevice, idx);
190 qDebug() << "Finished writing single raw data with index" << idx << ".";
191 }
192 case FIFFB_EVOKED:
193 //ToDo: write evoked set to file
194 ;
195 }
196
197 return true;
198}
199
200//=============================================================================================================
201
202bool FiffIO::write(QFile& p_QFile,
203 const fiff_int_t type,
204 const fiff_int_t idx) const
205{
206 qInfo("------------------------ Writing fiff data ------------------------");
207
208 switch (type) {
209 case FIFFB_RAW_DATA: {
210 QString t_nameoftype = "raw";
211
212 if (idx == -1) {
213 for (qint32 i = 0; i < m_qlistRaw.size(); ++i) {
214 QString t_fname;
215 //insert
216 qint32 p = p_QFile.fileName().indexOf(".fif");
217 t_fname = p_QFile.fileName().insert(p, QString("_" + t_nameoftype + "-" + QString::number(i)));
218
219 //assign new file name
220 qInfo("\nWriting set with index %i to file %s ...\n", i, t_fname.toUtf8().constData());
221 QFile t_file(t_fname);
222
223 FiffIO::write_raw(t_file, i);
224 }
225 } else {
226 FiffIO::write_raw(p_QFile, idx);
227 }
228 qInfo("\nFinished Writing %lld raw data sets!\n", static_cast<long long>(m_qlistRaw.size()));
229 }
230 case FIFFB_EVOKED:
231
232 //ToDo: write evoked set to file
233 ;
234 }
235
236 return true;
237}
238
239//=============================================================================================================
240
241bool FiffIO::write_raw(QIODevice& pIODevice,
242 const fiff_int_t idx) const
243{
244 RowVectorXd cals;
245 SparseMatrix<double> mult;
246 RowVectorXi sel;
247 FiffStream::SPtr outfid = FiffStream::start_writing_raw(pIODevice, this->m_qlistRaw[idx]->info, cals);
248 if (!outfid) {
249 return false;
250 }
251
252 //Setup reading parameters
253 fiff_int_t from = m_qlistRaw[idx]->first_samp;
254 fiff_int_t to = m_qlistRaw[idx]->last_samp;
255 float quantum_sec = 30.0f; //read and write in 30 sec junks
256 fiff_int_t quantum = ceil(quantum_sec * m_qlistRaw[idx]->info.sfreq);
257
258 // Uncomment to read the whole file at once. Warning Matrix may be none-initialisable because its huge
259 //quantum = to - from + 1;
260
261 // Read and write all the data
262 bool first_buffer = true;
263
264 fiff_int_t first, last;
265 MatrixXd data;
266 MatrixXd times;
267
268 for (first = from; first < to; first += quantum) {
269 last = first + quantum - 1;
270 if (last > to)
271 last = to;
272
273 if (!m_qlistRaw[idx]->read_raw_segment(data, times, mult, first, last, sel)) {
274 qWarning("error during read_raw_segment\n");
275 return false;
276 }
277
278 qInfo("Writing...");
279 if (first_buffer) {
280 if (first > 0)
281 outfid->write_int(FIFF_FIRST_SAMPLE, &first);
282 first_buffer = false;
283 }
284 outfid->write_raw_buffer(data, cals);
285 qInfo("[done]\n");
286 }
287
288 outfid->finish_writing_raw();
289
290 return true;
291}
Static MATLAB-style FIFF facade: thin wrapper functions kept for parity with the historical mne-matla...
Set of averaged evoked responses sharing a FiffInfo, plus the ave-style category / rejection descript...
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
#define FIFF_FIRST_SAMPLE
Definition fiff_file.h:454
#define FIFFB_RAW_DATA
Definition fiff_file.h:357
#define FIFFB_SMSH_RAW_DATA
Definition fiff_file.h:375
#define FIFFB_PROCESSED_DATA
Definition fiff_file.h:358
#define FIFFB_CONTINUOUS_DATA
Definition fiff_file.h:368
#define FIFFB_EVOKED
Definition fiff_file.h:359
High-level convenience reader/writer that loads a whole FIFF measurement file into FIFFLIB containers...
FIFF file I/O, in-memory data structures and high-level readers/writers.
qint32 fiff_int_t
Definition fiff_types.h:86
QSharedPointer< FiffDirNode > SPtr
Single averaged evoked response: time axis, data, baseline, channel info and averaging metadata.
Definition fiff_evoked.h:77
Set of FiffEvoked instances sharing one FiffInfo, plus channel-picking and compensation helpers.
QList< FiffEvoked > evoked
Full FIFF measurement info: per-channel descriptors, sampling and filter setup, projectors,...
Definition fiff_info.h:90
QList< QSharedPointer< FiffRawData > > m_qlistRaw
Definition fiff_io.h:218
bool write(QIODevice &pIODevice, const fiff_int_t type, const fiff_int_t idx) const
Definition fiff_io.cpp:183
bool read(QIODevice &pIODevice)
Definition fiff_io.cpp:103
bool write_raw(QIODevice &pIODevice, const fiff_int_t idx) const
Definition fiff_io.cpp:241
QList< QSharedPointer< FiffEvoked > > m_qlistEvoked
Definition fiff_io.h:219
static bool setup_read(QIODevice &pIODevice, FiffInfo &info, FiffDirNode::SPtr &dirTree)
Definition fiff_io.cpp:81
Continuous FIFF raw recording: FiffInfo plus a random-access directory of FIFF_DATA_BUFFER tags.
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
QSharedPointer< FiffStream > SPtr
static FiffStream::SPtr start_writing_raw(QIODevice &p_IODevice, const FiffInfo &info, Eigen::RowVectorXd &cals, Eigen::MatrixXi sel=defaultMatrixXi, bool bResetRange=true)