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 switch(type) {
187 case FIFFB_RAW_DATA: {
188 FiffIO::write_raw(pIODevice,idx);
189 qDebug() << "Finished writing single raw data with index" << idx << ".";
190 }
191 case FIFFB_EVOKED:
192 //ToDo: write evoked set to file
193 ;
194 }
195
196 return true;
197}
198
199//=============================================================================================================
200
201bool FiffIO::write(QFile& p_QFile,
202 const fiff_int_t type,
203 const fiff_int_t idx) const {
204 qInfo("------------------------ Writing fiff data ------------------------");
205
206 switch(type) {
207 case FIFFB_RAW_DATA: {
208 QString t_nameoftype = "raw";
209
210 if(idx == -1) {
211 for(qint32 i=0; i < m_qlistRaw.size(); ++i) {
212 QString t_fname;
213 //insert
214 qint32 p = p_QFile.fileName().indexOf(".fif");
215 t_fname = p_QFile.fileName().insert(p,QString("_"+t_nameoftype+"-"+QString::number(i)));
216
217 //assign new file name
218 qInfo("\nWriting set with index %i to file %s ...\n",i,t_fname.toUtf8().constData());
219 QFile t_file(t_fname);
220
221 FiffIO::write_raw(t_file,i);
222 }
223 }
224 else {
225 FiffIO::write_raw(p_QFile,idx);
226 }
227 qInfo("\nFinished Writing %lli raw data sets!\n",m_qlistRaw.size());
228 }
229 case FIFFB_EVOKED:
230
231 //ToDo: write evoked set to file
232 ;
233 }
234
235 return true;
236}
237
238//=============================================================================================================
239
240bool FiffIO::write_raw(QIODevice &pIODevice,
241 const fiff_int_t idx) const
242{
243 RowVectorXd cals;
244 SparseMatrix<double> mult;
245 RowVectorXi sel;
246 FiffStream::SPtr outfid = FiffStream::start_writing_raw(pIODevice, this->m_qlistRaw[idx]->info, cals);
247
248 //Setup reading parameters
249 fiff_int_t from = m_qlistRaw[idx]->first_samp;
250 fiff_int_t to = m_qlistRaw[idx]->last_samp;
251 float quantum_sec = 30.0f;//read and write in 30 sec junks
252 fiff_int_t quantum = ceil(quantum_sec*m_qlistRaw[idx]->info.sfreq);
253
254 // Uncomment to read the whole file at once. Warning Matrix may be none-initialisable because its huge
255 //quantum = to - from + 1;
256
257 // Read and write all the data
258 bool first_buffer = true;
259
260 fiff_int_t first, last;
261 MatrixXd data;
262 MatrixXd times;
263
264 for(first = from; first < to; first+=quantum) {
265 last = first+quantum-1;
266 if (last > to)
267 last = to;
268
269 if (!m_qlistRaw[idx]->read_raw_segment(data, times, mult, first, last, sel)) {
270 qWarning("error during read_raw_segment\n");
271 return false;
272 }
273
274 qInfo("Writing...");
275 if (first_buffer) {
276 if (first > 0)
277 outfid->write_int(FIFF_FIRST_SAMPLE,&first);
278 first_buffer = false;
279 }
280 outfid->write_raw_buffer(data, cals);
281 qInfo("[done]\n");
282 }
283
284 outfid->finish_writing_raw();
285
286 return true;
287}
High-level convenience reader/writer that loads a whole FIFF measurement file into FIFFLIB containers...
Set of averaged evoked responses sharing a FiffInfo, plus the ave-style category / rejection descript...
#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
Static MATLAB-style FIFF facade: thin wrapper functions kept for parity with the historical mne-matla...
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
FIFF file I/O, in-memory data structures and high-level readers/writers.
QSharedPointer< FiffDirNode > SPtr
Single averaged evoked response: time axis, data, baseline, channel info and averaging metadata.
Definition fiff_evoked.h:75
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:88
bool write(QIODevice &pIODevice, const fiff_int_t type, const fiff_int_t idx) const
Definition fiff_io.cpp:183
QList< QSharedPointer< FiffEvoked > > m_qlistEvoked
Definition fiff_io.h:212
bool read(QIODevice &pIODevice)
Definition fiff_io.cpp:103
bool write_raw(QIODevice &pIODevice, const fiff_int_t idx) const
Definition fiff_io.cpp:240
static bool setup_read(QIODevice &pIODevice, FiffInfo &info, FiffDirNode::SPtr &dirTree)
Definition fiff_io.cpp:81
FiffIO()
Definition fiff_io.cpp:51
~FiffIO()
Definition fiff_io.cpp:57
QList< QSharedPointer< FiffRawData > > m_qlistRaw
Definition fiff_io.h:211
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)