59 throw std::runtime_error(
"Error during fiff setup raw read");
72 throw std::runtime_error(
"Error during fiff setup raw read");
103 cals = RowVectorXd();
110#include <QElapsedTimer>
116 const RowVectorXi& sel,
119 bool projAvailable =
true;
121 if (this->
proj.size() == 0) {
123 projAvailable =
false;
140 qWarning(
"No data in this range %d ... %d = %9.3f ... %9.3f secs...", from, to, (
static_cast<float>(from))/this->
info.sfreq, (
static_cast<float>(to))/this->info.sfreq);
147 qint32 nchan = this->
info.nchan;
151 using T = Eigen::Triplet<double>;
152 std::vector<T> tripletList;
153 tripletList.reserve(nchan);
154 for(i = 0; i < nchan; ++i)
155 tripletList.push_back(T(i, i, this->
cals[i]));
157 SparseMatrix<double> cal(nchan, nchan);
158 cal.setFromTriplets(tripletList.begin(), tripletList.end());
165 data = MatrixXd(nchan, to-from+1);
167 if (projAvailable || this->
comp.kind != -1)
170 mult_full = this->
comp.data->data*cal;
171 else if (this->
comp.kind == -1)
172 mult_full = this->
proj*cal;
174 mult_full = this->
proj*this->
comp.data->data*cal;
179 data = MatrixXd(sel.size(),to-from+1);
182 MatrixXd selVect(sel.size(), nchan);
186 if (!projAvailable && this->
comp.kind == -1)
189 tripletList.reserve(sel.size());
190 for(i = 0; i < sel.size(); ++i)
191 tripletList.push_back(T(i, i, this->
cals[sel[i]]));
192 cal = SparseMatrix<double>(sel.size(), sel.size());
193 cal.setFromTriplets(tripletList.begin(), tripletList.end());
199 qDebug() <<
"This has to be debugged! #1";
200 for( i = 0; i < sel.size(); ++i)
201 selVect.row(i) = this->
comp.data->data.block(sel[i],0,1,nchan);
202 mult_full = selVect*cal;
204 else if (this->
comp.kind == -1)
206 for( i = 0; i < sel.size(); ++i)
207 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
209 mult_full = selVect*cal;
213 qDebug() <<
"This has to be debugged! #3";
214 for( i = 0; i < sel.size(); ++i)
215 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
217 mult_full = selVect*this->
comp.data->data*cal;
226 tripletList.reserve(mult_full.rows()*mult_full.cols());
227 for(i = 0; i < mult_full.rows(); ++i)
228 for(k = 0; k < mult_full.cols(); ++k)
229 if(mult_full(i,k) != 0)
230 tripletList.push_back(T(i, k, mult_full(i,k)));
232 SparseMatrix<double> mult(mult_full.rows(),mult_full.cols());
233 if(tripletList.size() > 0)
234 mult.setFromTriplets(tripletList.begin(), tripletList.end());
238 if (!this->
file->device()->isOpen())
240 if (!this->
file->device()->open(QIODevice::ReadOnly))
242 qWarning(
"Cannot open file %s",this->
info.filename.toUtf8().constData());
251 MatrixXd one, newData, tmp_data;
252 FiffRawDir thisRawDir;
254 fiff_int_t first_pick, last_pick, picksamp;
255 for(k = 0; k < this->
rawdir.size(); ++k)
257 thisRawDir = this->
rawdir[k];
261 if (thisRawDir.
last > from)
263 if (thisRawDir.
ent->kind == -1)
271 one.resize(nchan,thisRawDir.
nsamp);
273 one.resize(sel.cols(),thisRawDir.
nsamp);
279 fid->read_tag(t_pTag, thisRawDir.
ent->pos);
284 if (mult.cols() == 0)
289 one = cal*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
291 one = cal*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
293 one = cal*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
295 one = cal*(Map< MatrixShort >( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
297 qWarning(
"Data Storage Format not known yet [1]!! Type: %d\n", t_pTag->type);
302 newData.resize(sel.cols(), thisRawDir.
nsamp);
306 tmp_data = (Map< MatrixDau16 > ( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
308 for(r = 0; r < sel.size(); ++r)
309 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
313 tmp_data = (Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
315 for(r = 0; r < sel.size(); ++r)
316 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
320 tmp_data = (Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
322 for(r = 0; r < sel.size(); ++r)
323 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
327 tmp_data = (Map< MatrixShort > ( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
329 for(r = 0; r < sel.size(); ++r)
330 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
334 qWarning(
"Data Storage Format not known yet [2]!! Type: %d\n", t_pTag->type);
343 one = mult*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
345 one = mult*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
347 one = mult*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
349 qWarning(
"Data Storage Format not known yet [3]!! Type: %d\n", t_pTag->type);
355 if (to >= thisRawDir.
last && from <= thisRawDir.
first)
361 last_pick = thisRawDir.
nsamp - 1;
365 else if (from > thisRawDir.
first)
367 first_pick = from - thisRawDir.
first;
368 if(to < thisRawDir.
last)
374 last_pick = thisRawDir.
nsamp + to - thisRawDir.
last - 1;
383 last_pick = thisRawDir.
nsamp - 1;
394 last_pick = to - thisRawDir.
first;
401 picksamp = last_pick - first_pick + 1;
405 qDebug() <<
"first_pick: " << first_pick;
406 qDebug() <<
"last_pick: " << last_pick;
407 qDebug() <<
"picksamp: " << picksamp;
415 data.block(0,dest,data.rows(),picksamp) = one.block(0, first_pick, data.rows(), picksamp);
423 if (thisRawDir.
last >= to)
430 if (!this->
file->device()->isOpen()) {
431 this->
file->device()->close();
434 times = MatrixXd(1, to-from+1);
436 for (i = 0; i < times.cols(); ++i)
437 times(0, i) =
static_cast<float>(from+i) / this->
info.sfreq;
446 SparseMatrix<double>& multSegment,
449 const RowVectorXi& sel,
452 bool projAvailable =
true;
454 if (this->
proj.size() == 0) {
456 projAvailable =
false;
473 qWarning(
"No data in this range\n");
480 qint32 nchan = this->
info.nchan;
484 using T = Eigen::Triplet<double>;
485 std::vector<T> tripletList;
486 tripletList.reserve(nchan);
487 for(i = 0; i < nchan; ++i)
488 tripletList.push_back(T(i, i, this->
cals[i]));
490 SparseMatrix<double> cal(nchan, nchan);
491 cal.setFromTriplets(tripletList.begin(), tripletList.end());
498 data = MatrixXd(nchan, to-from+1);
500 if (projAvailable || this->
comp.kind != -1)
503 mult_full = this->
comp.data->data*cal;
504 else if (this->
comp.kind == -1)
505 mult_full = this->
proj*cal;
507 mult_full = this->
proj*this->
comp.data->data*cal;
512 data = MatrixXd(sel.size(),to-from+1);
515 MatrixXd selVect(sel.size(), nchan);
519 if (!projAvailable && this->
comp.kind == -1)
522 tripletList.reserve(sel.size());
523 for(i = 0; i < sel.size(); ++i)
524 tripletList.push_back(T(i, i, this->
cals[sel[i]]));
525 cal = SparseMatrix<double>(sel.size(), sel.size());
526 cal.setFromTriplets(tripletList.begin(), tripletList.end());
532 qDebug() <<
"This has to be debugged! #1";
533 for( i = 0; i < sel.size(); ++i)
534 selVect.row(i) = this->
comp.data->data.block(sel[i],0,1,nchan);
535 mult_full = selVect*cal;
537 else if (this->
comp.kind == -1)
539 for( i = 0; i < sel.size(); ++i)
540 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
542 mult_full = selVect*cal;
546 qDebug() <<
"This has to be debugged! #3";
547 for( i = 0; i < sel.size(); ++i)
548 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
550 mult_full = selVect*this->
comp.data->data*cal;
559 tripletList.reserve(mult_full.rows()*mult_full.cols());
560 for(i = 0; i < mult_full.rows(); ++i)
561 for(k = 0; k < mult_full.cols(); ++k)
562 if(mult_full(i,k) != 0)
563 tripletList.push_back(T(i, k, mult_full(i,k)));
565 SparseMatrix<double> mult(mult_full.rows(),mult_full.cols());
566 if(tripletList.size() > 0)
567 mult.setFromTriplets(tripletList.begin(), tripletList.end());
573 if (!this->
file->device()->isOpen())
575 if (!this->
file->device()->open(QIODevice::ReadOnly))
577 qWarning(
"Cannot open file %s",this->
info.filename.toUtf8().constData());
587 fiff_int_t first_pick, last_pick, picksamp;
588 for(k = 0; k < this->
rawdir.size(); ++k)
590 FiffRawDir thisRawDir = this->
rawdir[k];
594 if (thisRawDir.
last > from)
596 if (thisRawDir.
ent->kind == -1)
604 one.resize(nchan,thisRawDir.
nsamp);
606 one.resize(sel.cols(),thisRawDir.
nsamp);
613 fid->read_tag(t_pTag, thisRawDir.
ent->pos);
618 if (mult.cols() == 0)
623 one = cal*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
625 one = cal*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
627 one = cal*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
629 one = cal*(Map< MatrixShort >( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
631 qWarning(
"Data Storage Format not known yet [1]!! Type: %d\n", t_pTag->type);
637 MatrixXd newData(sel.cols(), thisRawDir.
nsamp);
641 MatrixXd tmp_data = (Map< MatrixDau16 > ( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
643 for(r = 0; r < sel.size(); ++r)
644 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
648 MatrixXd tmp_data = (Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
650 for(r = 0; r < sel.size(); ++r)
651 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
655 MatrixXd tmp_data = (Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
657 for(r = 0; r < sel.size(); ++r)
658 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
662 MatrixXd tmp_data = (Map< MatrixShort > ( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
664 for(r = 0; r < sel.size(); ++r)
665 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
669 qWarning(
"Data Storage Format not known yet [2]!! Type: %d\n", t_pTag->type);
678 one = mult*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
680 one = mult*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
682 one = mult*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
684 qWarning(
"Data Storage Format not known yet [3]!! Type: %d\n", t_pTag->type);
690 if (to >= thisRawDir.
last && from <= thisRawDir.
first)
696 last_pick = thisRawDir.
nsamp - 1;
700 else if (from > thisRawDir.
first)
702 first_pick = from - thisRawDir.
first;
703 if(to < thisRawDir.
last)
709 last_pick = thisRawDir.
nsamp + to - thisRawDir.
last - 1;
718 last_pick = thisRawDir.
nsamp - 1;
729 last_pick = to - thisRawDir.
first;
736 picksamp = last_pick - first_pick + 1;
740 qDebug() <<
"first_pick: " << first_pick;
741 qDebug() <<
"last_pick: " << last_pick;
742 qDebug() <<
"picksamp: " << picksamp;
750 data.block(0,dest,data.rows(),picksamp) = one.block(0, first_pick, data.rows(), picksamp);
758 if (thisRawDir.
last >= to)
770 if (!this->
file->device()->isOpen()) {
771 this->
file->device()->close();
774 times = MatrixXd(1, to-from+1);
776 for (i = 0; i < times.cols(); ++i)
777 times(0, i) =
static_cast<float>(from+i) / this->
info.sfreq;
788 const RowVectorXi& sel)
const
793 from = floor(
static_cast<double>(from)*this->
info.sfreq);
794 to = ceil(
static_cast<double>(to)*this->
info.sfreq);
804 const RowVectorXi &picks,
809 if (decim < 1) decim = 1;
811 int firstSamp = (from >= 0) ? from :
first_samp;
812 int lastSamp = (to >= 0) ? to :
last_samp;
814 if (firstSamp > lastSamp) {
815 qWarning() <<
"[FiffRawData::save] Invalid sample range.";
821 if (picks.size() > 0) {
822 outInfo =
info.pick_info(picks);
829 outInfo.
sfreq =
info.sfreq /
static_cast<float>(decim);
836 qWarning() <<
"[FiffRawData::save] Cannot start writing raw file.";
841 const int blockSize = 2000;
842 int blockSamples = decim * blockSize;
844 for (
int samp = firstSamp; samp <= lastSamp; samp += blockSamples) {
845 int nsamp = qMin(blockSamples, lastSamp - samp + 1);
850 qWarning() <<
"[FiffRawData::save] Error reading data at sample" << samp;
851 pStream->finish_writing_raw();
857 int nOut = (nsamp + decim - 1) / decim;
858 MatrixXd decimData(segData.rows(), nOut);
859 for (
int s = 0, idx = 0; s < nsamp && idx < nOut; s += decim, ++idx) {
860 decimData.col(idx) = segData.col(s);
865 pStream->write_raw_buffer(segData, calsOut);
868 pStream->finish_writing_raw();
870 qInfo() <<
"[FiffRawData::save] Saved raw data from sample" << firstSamp
871 <<
"to" << lastSamp <<
"(decim=" << decim <<
")";
FIFF continuous raw recording: FiffInfo plus a directory of FIFF_DATA_BUFFER tags for random-access s...
Stim-channel event list (sample, previous value, new value triples) with FIFF read/write helpers.
FIFF tag: the 16-byte tag header (kind, type, size, next) plus its decoded payload.
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.
Full FIFF measurement info: per-channel descriptors, sampling and filter setup, projectors,...
bool save(QIODevice &p_IODevice, const Eigen::RowVectorXi &picks=Eigen::RowVectorXi(), int decim=1, int from=-1, int to=-1) const
bool read_raw_segment_times(Eigen::MatrixXd &data, Eigen::MatrixXd ×, float from, float to, const Eigen::RowVectorXi &sel=defaultRowVectorXi) const
bool read_raw_segment(Eigen::MatrixXd &data, Eigen::MatrixXd ×, fiff_int_t from=-1, fiff_int_t to=-1, const Eigen::RowVectorXi &sel=defaultRowVectorXi, bool do_debug=false) const
QList< FiffRawDir > rawdir
QSharedPointer< FiffStream > SPtr
static bool setup_read_raw(QIODevice &p_IODevice, FiffRawData &data, bool allow_maxshield=true, bool is_littleEndian=false)
static FiffStream::SPtr start_writing_raw(QIODevice &p_IODevice, const FiffInfo &info, Eigen::RowVectorXd &cals, Eigen::MatrixXi sel=defaultMatrixXi, bool bResetRange=true)
std::unique_ptr< FiffTag > UPtr