74 throw std::runtime_error(
"Error during fiff setup raw read");
87 throw std::runtime_error(
"Error during fiff setup raw read");
118 cals = RowVectorXd();
125#include <QElapsedTimer>
131 const RowVectorXi& sel,
134 bool projAvailable =
true;
136 if (this->
proj.size() == 0) {
138 projAvailable =
false;
149 from = this->first_samp;
155 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);
162 qint32 nchan = this->
info.nchan;
166 using T = Eigen::Triplet<double>;
167 std::vector<T> tripletList;
168 tripletList.reserve(nchan);
169 for(i = 0; i < nchan; ++i)
170 tripletList.push_back(T(i, i, this->
cals[i]));
172 SparseMatrix<double> cal(nchan, nchan);
173 cal.setFromTriplets(tripletList.begin(), tripletList.end());
180 data = MatrixXd(nchan, to-from+1);
182 if (projAvailable || this->
comp.kind != -1)
185 mult_full = this->
comp.data->data*cal;
186 else if (this->
comp.kind == -1)
187 mult_full = this->
proj*cal;
189 mult_full = this->
proj*this->
comp.data->data*cal;
194 data = MatrixXd(sel.size(),to-from+1);
197 MatrixXd selVect(sel.size(), nchan);
201 if (!projAvailable && this->
comp.kind == -1)
204 tripletList.reserve(sel.size());
205 for(i = 0; i < sel.size(); ++i)
206 tripletList.push_back(T(i, i, this->
cals[sel[i]]));
207 cal = SparseMatrix<double>(sel.size(), sel.size());
208 cal.setFromTriplets(tripletList.begin(), tripletList.end());
214 qDebug() <<
"This has to be debugged! #1";
215 for( i = 0; i < sel.size(); ++i)
216 selVect.row(i) = this->
comp.data->data.block(sel[i],0,1,nchan);
217 mult_full = selVect*cal;
219 else if (this->
comp.kind == -1)
221 for( i = 0; i < sel.size(); ++i)
222 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
224 mult_full = selVect*cal;
228 qDebug() <<
"This has to be debugged! #3";
229 for( i = 0; i < sel.size(); ++i)
230 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
232 mult_full = selVect*this->
comp.data->data*cal;
241 tripletList.reserve(mult_full.rows()*mult_full.cols());
242 for(i = 0; i < mult_full.rows(); ++i)
243 for(k = 0; k < mult_full.cols(); ++k)
244 if(mult_full(i,k) != 0)
245 tripletList.push_back(T(i, k, mult_full(i,k)));
247 SparseMatrix<double> mult(mult_full.rows(),mult_full.cols());
248 if(tripletList.size() > 0)
249 mult.setFromTriplets(tripletList.begin(), tripletList.end());
253 if (!this->
file->device()->isOpen())
255 if (!this->
file->device()->open(QIODevice::ReadOnly))
257 qWarning(
"Cannot open file %s",this->
info.filename.toUtf8().constData());
266 MatrixXd one, newData, tmp_data;
267 FiffRawDir thisRawDir;
270 for(k = 0; k < this->
rawdir.size(); ++k)
272 thisRawDir = this->
rawdir[k];
276 if (thisRawDir.
last > from)
278 if (thisRawDir.
ent->kind == -1)
286 one.resize(nchan,thisRawDir.
nsamp);
288 one.resize(sel.cols(),thisRawDir.
nsamp);
294 fid->read_tag(t_pTag, thisRawDir.
ent->pos);
299 if (mult.cols() == 0)
304 one = cal*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
306 one = cal*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
308 one = cal*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
310 one = cal*(Map< MatrixShort >( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
312 qWarning(
"Data Storage Format not known yet [1]!! Type: %d\n", t_pTag->type);
317 newData.resize(sel.cols(), thisRawDir.
nsamp);
321 tmp_data = (Map< MatrixDau16 > ( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
323 for(r = 0; r < sel.size(); ++r)
324 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
328 tmp_data = (Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
330 for(r = 0; r < sel.size(); ++r)
331 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
335 tmp_data = (Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
337 for(r = 0; r < sel.size(); ++r)
338 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
342 tmp_data = (Map< MatrixShort > ( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
344 for(r = 0; r < sel.size(); ++r)
345 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
349 qWarning(
"Data Storage Format not known yet [2]!! Type: %d\n", t_pTag->type);
358 one = mult*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
360 one = mult*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
362 one = mult*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
364 qWarning(
"Data Storage Format not known yet [3]!! Type: %d\n", t_pTag->type);
370 if (to >= thisRawDir.
last && from <= thisRawDir.
first)
376 last_pick = thisRawDir.
nsamp - 1;
380 else if (from > thisRawDir.
first)
382 first_pick = from - thisRawDir.
first;
383 if(to < thisRawDir.
last)
389 last_pick = thisRawDir.
nsamp + to - thisRawDir.
last - 1;
398 last_pick = thisRawDir.
nsamp - 1;
409 last_pick = to - thisRawDir.
first;
416 picksamp = last_pick - first_pick + 1;
420 qDebug() <<
"first_pick: " << first_pick;
421 qDebug() <<
"last_pick: " << last_pick;
422 qDebug() <<
"picksamp: " << picksamp;
430 data.block(0,dest,data.rows(),picksamp) = one.block(0, first_pick, data.rows(), picksamp);
438 if (thisRawDir.
last >= to)
445 if (!this->
file->device()->isOpen()) {
446 this->
file->device()->close();
449 times = MatrixXd(1, to-from+1);
451 for (i = 0; i < times.cols(); ++i)
452 times(0, i) =
static_cast<float>(from+i) / this->
info.sfreq;
461 SparseMatrix<double>& multSegment,
464 const RowVectorXi& sel,
467 bool projAvailable =
true;
469 if (this->
proj.size() == 0) {
471 projAvailable =
false;
488 qWarning(
"No data in this range\n");
495 qint32 nchan = this->
info.nchan;
499 using T = Eigen::Triplet<double>;
500 std::vector<T> tripletList;
501 tripletList.reserve(nchan);
502 for(i = 0; i < nchan; ++i)
503 tripletList.push_back(T(i, i, this->
cals[i]));
505 SparseMatrix<double> cal(nchan, nchan);
506 cal.setFromTriplets(tripletList.begin(), tripletList.end());
513 data = MatrixXd(nchan, to-from+1);
515 if (projAvailable || this->
comp.kind != -1)
518 mult_full = this->
comp.data->data*cal;
519 else if (this->
comp.kind == -1)
520 mult_full = this->
proj*cal;
522 mult_full = this->
proj*this->
comp.data->data*cal;
527 data = MatrixXd(sel.size(),to-from+1);
530 MatrixXd selVect(sel.size(), nchan);
534 if (!projAvailable && this->
comp.kind == -1)
537 tripletList.reserve(sel.size());
538 for(i = 0; i < sel.size(); ++i)
539 tripletList.push_back(T(i, i, this->
cals[sel[i]]));
540 cal = SparseMatrix<double>(sel.size(), sel.size());
541 cal.setFromTriplets(tripletList.begin(), tripletList.end());
547 qDebug() <<
"This has to be debugged! #1";
548 for( i = 0; i < sel.size(); ++i)
549 selVect.row(i) = this->
comp.data->data.block(sel[i],0,1,nchan);
550 mult_full = selVect*cal;
552 else if (this->
comp.kind == -1)
554 for( i = 0; i < sel.size(); ++i)
555 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
557 mult_full = selVect*cal;
561 qDebug() <<
"This has to be debugged! #3";
562 for( i = 0; i < sel.size(); ++i)
563 selVect.row(i) = this->
proj.block(sel[i],0,1,nchan);
565 mult_full = selVect*this->
comp.data->data*cal;
574 tripletList.reserve(mult_full.rows()*mult_full.cols());
575 for(i = 0; i < mult_full.rows(); ++i)
576 for(k = 0; k < mult_full.cols(); ++k)
577 if(mult_full(i,k) != 0)
578 tripletList.push_back(T(i, k, mult_full(i,k)));
580 SparseMatrix<double> mult(mult_full.rows(),mult_full.cols());
581 if(tripletList.size() > 0)
582 mult.setFromTriplets(tripletList.begin(), tripletList.end());
588 if (!this->
file->device()->isOpen())
590 if (!this->
file->device()->open(QIODevice::ReadOnly))
592 qWarning(
"Cannot open file %s",this->
info.filename.toUtf8().constData());
603 for(k = 0; k < this->
rawdir.size(); ++k)
605 FiffRawDir thisRawDir = this->
rawdir[k];
609 if (thisRawDir.
last > from)
611 if (thisRawDir.
ent->kind == -1)
619 one.resize(nchan,thisRawDir.
nsamp);
621 one.resize(sel.cols(),thisRawDir.
nsamp);
628 fid->read_tag(t_pTag, thisRawDir.
ent->pos);
633 if (mult.cols() == 0)
638 one = cal*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
640 one = cal*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
642 one = cal*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
644 one = cal*(Map< MatrixShort >( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
646 qWarning(
"Data Storage Format not known yet [1]!! Type: %d\n", t_pTag->type);
652 MatrixXd newData(sel.cols(), thisRawDir.
nsamp);
656 MatrixXd tmp_data = (Map< MatrixDau16 > ( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
658 for(r = 0; r < sel.size(); ++r)
659 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
663 MatrixXd tmp_data = (Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
665 for(r = 0; r < sel.size(); ++r)
666 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
670 MatrixXd tmp_data = (Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
672 for(r = 0; r < sel.size(); ++r)
673 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
677 MatrixXd tmp_data = (Map< MatrixShort > ( t_pTag->toShort(),nchan, thisRawDir.
nsamp)).cast<double>();
679 for(r = 0; r < sel.size(); ++r)
680 newData.block(r,0,1,thisRawDir.
nsamp) = tmp_data.block(sel[r],0,1,thisRawDir.
nsamp);
684 qWarning(
"Data Storage Format not known yet [2]!! Type: %d\n", t_pTag->type);
693 one = mult*(Map< MatrixDau16 >( t_pTag->toDauPack16(),nchan, thisRawDir.
nsamp)).cast<double>();
695 one = mult*(Map< MatrixXi >( t_pTag->toInt(),nchan, thisRawDir.
nsamp)).cast<double>();
697 one = mult*(Map<const MatrixXf>(t_pTag->toFloat(),nchan, thisRawDir.
nsamp)).cast<double>();
699 qWarning(
"Data Storage Format not known yet [3]!! Type: %d\n", t_pTag->type);
705 if (to >= thisRawDir.
last && from <= thisRawDir.
first)
711 last_pick = thisRawDir.
nsamp - 1;
715 else if (from > thisRawDir.
first)
717 first_pick = from - thisRawDir.
first;
718 if(to < thisRawDir.
last)
724 last_pick = thisRawDir.
nsamp + to - thisRawDir.
last - 1;
733 last_pick = thisRawDir.
nsamp - 1;
744 last_pick = to - thisRawDir.
first;
751 picksamp = last_pick - first_pick + 1;
755 qDebug() <<
"first_pick: " << first_pick;
756 qDebug() <<
"last_pick: " << last_pick;
757 qDebug() <<
"picksamp: " << picksamp;
765 data.block(0,dest,data.rows(),picksamp) = one.block(0, first_pick, data.rows(), picksamp);
773 if (thisRawDir.
last >= to)
785 if (!this->
file->device()->isOpen()) {
786 this->
file->device()->close();
789 times = MatrixXd(1, to-from+1);
791 for (i = 0; i < times.cols(); ++i)
792 times(0, i) =
static_cast<float>(from+i) / this->
info.sfreq;
803 const RowVectorXi& sel)
const
808 from = floor(from*this->
info.sfreq);
809 to = ceil(to*this->
info.sfreq);
819 const RowVectorXi &picks,
824 if (decim < 1) decim = 1;
826 int firstSamp = (from >= 0) ? from :
first_samp;
827 int lastSamp = (to >= 0) ? to :
last_samp;
829 if (firstSamp > lastSamp) {
830 qWarning() <<
"[FiffRawData::save] Invalid sample range.";
836 if (picks.size() > 0) {
837 outInfo =
info.pick_info(picks);
844 outInfo.
sfreq =
info.sfreq /
static_cast<float>(decim);
851 qWarning() <<
"[FiffRawData::save] Cannot start writing raw file.";
856 const int blockSize = 2000;
857 int blockSamples = decim * blockSize;
859 for (
int samp = firstSamp; samp <= lastSamp; samp += blockSamples) {
860 int nsamp = qMin(blockSamples, lastSamp - samp + 1);
865 qWarning() <<
"[FiffRawData::save] Error reading data at sample" << samp;
866 pStream->finish_writing_raw();
872 int nOut = (nsamp + decim - 1) / decim;
873 MatrixXd decimData(segData.rows(), nOut);
874 for (
int s = 0, idx = 0; s < nsamp && idx < nOut; s += decim, ++idx) {
875 decimData.col(idx) = segData.col(s);
880 pStream->write_raw_buffer(segData, calsOut);
883 pStream->finish_writing_raw();
885 qInfo() <<
"[FiffRawData::save] Saved raw data from sample" << firstSamp
886 <<
"to" << lastSamp <<
"(decim=" << decim <<
")";
FiffRawData class declaration.
FiffEvents class declaration.
FiffStream class declaration.
FiffTag class declaration, which provides fiff tag I/O and processing methods.
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
FIFF measurement file information.
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
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
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