56 #include <Eigen/Dense>
63 using namespace RTPROCESSINGLIB;
64 using namespace Eigen;
65 using namespace FIFFLIB;
66 using namespace UTILSLIB;
73 QSharedPointer<FiffRawData> pFiffRawData,
81 const RowVectorXi& vecPicks,
85 dCenterfreq = dCenterfreq/(dSFreq/2.0);
86 bandwidth = bandwidth/(dSFreq/2.0);
87 dTransition = dTransition/(dSFreq/2.0);
109 QSharedPointer<FiffRawData> pFiffRawData,
111 const RowVectorXi& vecPicks,
114 int iOrder = filterKernel.getFilterOrder();
117 SparseMatrix<double> mult;
119 FiffStream::SPtr outfid = FiffStream::start_writing_raw(pIODevice, pFiffRawData->info, cals);
122 fiff_int_t from = pFiffRawData->first_samp;
123 fiff_int_t to = pFiffRawData->last_samp;
126 float fFactor = 2.0f;
127 int iSize = fFactor * iOrder;
128 int residual = (to - from) % iSize;
129 while(residual < iOrder) {
130 fFactor = fFactor - 0.1f;
131 iSize = fFactor * iOrder;
132 residual = (to - from) % iSize;
134 if((iSize < iOrder)) {
135 qInfo() <<
"[Filter::filterData] Sliced data block size is too small. Filtering whole block at once.";
141 float quantum_sec = iSize/pFiffRawData->info.sfreq;
142 fiff_int_t quantum = ceil(quantum_sec*pFiffRawData->info.sfreq);
145 bool first_buffer =
true;
147 fiff_int_t first, last;
148 MatrixXd matData, matDataOverlap;
151 for(first = from; first < to; first+=quantum) {
152 last = first+quantum-1;
157 if (!pFiffRawData->read_raw_segment(matData, times, mult, first, last, sel)) {
158 qWarning(
"[Filter::filterData] Error during read_raw_segment\n");
162 qInfo() <<
"Filtering and writing block" << first <<
"to" << last;
168 first_buffer =
false;
177 outfid->write_raw_buffer(matData.block(0,iOrder/2,matData.rows(),matData.cols()-iOrder), cals);
178 }
else if(first + quantum >= to) {
179 matData.block(0,0,matData.rows(),iOrder) += matDataOverlap;
180 outfid->write_raw_buffer(matData.block(0,0,matData.rows(),matData.cols()-iOrder), cals);
182 matData.block(0,0,matData.rows(),iOrder) += matDataOverlap;
183 outfid->write_raw_buffer(matData.block(0,0,matData.rows(),matData.cols()-iOrder), cals);
186 matDataOverlap = matData.block(0,matData.cols()-iOrder,matData.rows(),iOrder);
189 outfid->finish_writing_raw();
204 const RowVectorXi& vecPicks,
209 if(mataData.cols() < iOrder){
210 qWarning() << QString(
"[Filter::filterData] Filter length/order is bigger than data length. Returning.");
215 dCenterfreq = dCenterfreq/(dSFreq/2.0);
216 bandwidth = bandwidth/(dSFreq/2.0);
217 dTransition = dTransition/(dSFreq/2.0);
240 const RowVectorXi& vecPicks,
244 int iOrder = filterKernel.getFilterOrder();
247 if(mataData.cols() < iOrder){
248 qWarning() <<
"[Filter::filterData] Filter length/order is bigger than data length. Returning.";
253 MatrixXd matDataOut(mataData.rows(), mataData.cols()+iOrder);
254 matDataOut.setZero();
255 MatrixXd sliceFiltered;
258 float fFactor = 2.0f;
259 int iSize = fFactor * iOrder;
260 int residual = mataData.cols() % iSize;
261 while(residual < iOrder) {
262 fFactor = fFactor - 0.1f;
263 iSize = fFactor * iOrder;
264 residual = mataData.cols() % iSize;
267 iSize = mataData.cols();
272 if(mataData.cols() > iSize) {
274 int numSlices = ceil(
float(mataData.cols())/
float(iSize));
276 for (
int i = 0; i < numSlices; i++) {
277 if(i == numSlices-1) {
279 iSize = mataData.cols() - (iSize * (numSlices -1));
283 sliceFiltered =
filterDataBlock(mataData.block(0,from,mataData.rows(),iSize),
290 matDataOut.block(0,0,mataData.rows(),sliceFiltered.cols()) += sliceFiltered;
292 matDataOut.block(0,from,mataData.rows(),sliceFiltered.cols()) += sliceFiltered;
307 return matDataOut.block(0,iOrder/2,matDataOut.rows(),mataData.cols());
314 const RowVectorXi& vecPicks,
318 int iOrder = filterKernel.getFilterOrder();
321 if(mataData.cols() < iOrder){
322 qWarning() << QString(
"[Filter::filterDataBlock] Filter length/order is bigger than data length. Returning.");
331 RowVectorXi vecPicksNew = vecPicks;
332 if(vecPicksNew.cols() == 0) {
333 vecPicksNew = RowVectorXi::LinSpaced(mataData.rows(), 0, mataData.rows());
337 QList<FilterObject> timeData;
341 for(qint32 i = 0; i < vecPicksNew.cols(); ++i) {
342 data.filterKernel = filterKernelSetup;
343 data.iRow = vecPicksNew[i];
344 data.vecData = mataData.row(vecPicksNew[i]);
345 timeData.append(data);
349 MatrixXd matDataOut(mataData.rows(), mataData.cols()+iOrder);
350 matDataOut.setZero();
351 matDataOut.block(0, iOrder/2, mataData.rows(), mataData.cols()) = mataData;
354 QFuture<void> future = QtConcurrent::map(timeData,
356 future.waitForFinished();
358 for(
int i = 0; i < timeData.size(); ++i) {
364 RowVectorXd tempData;
366 for(
int r = 0; r < timeData.size(); r++) {
368 matDataOut.row(timeData.at(r).iRow) = timeData.at(r).vecData;
379 channelDataTime.filterKernel.
applyFftFilter(channelDataTime.vecData,
true);
394 const RowVectorXi& vecPicks,
400 if(mataData.cols() < iOrder){
401 qWarning() << QString(
"[Filter::filterData] Filter length/order is bigger than data length. Returning.");
406 dCenterfreq = dCenterfreq/(dSFreq/2.0);
407 bandwidth = bandwidth/(dSFreq/2.0);
408 dTransition = dTransition/(dSFreq/2.0);
420 return calculate(mataData,
432 const RowVectorXi& vecPicks,
437 int iOrder = filterKernel.getFilterOrder();
440 if(mataData.cols() < iOrder){
441 qWarning() <<
"[Filter::filterData] Filter length/order is bigger than data length. Returning.";
446 if(m_matOverlapBack.cols() != iOrder || m_matOverlapBack.rows() < mataData.rows()) {
447 m_matOverlapBack.resize(mataData.rows(), iOrder);
448 m_matOverlapBack.setZero();
451 if(m_matOverlapFront.cols() != iOrder || m_matOverlapFront.rows() < mataData.rows()) {
452 m_matOverlapFront.resize(mataData.rows(), iOrder);
453 m_matOverlapFront.setZero();
457 MatrixXd matDataOut(mataData.rows(), mataData.cols()+iOrder);
458 matDataOut.setZero();
459 MatrixXd sliceFiltered;
462 float fFactor = 2.0f;
463 int iSize = fFactor * iOrder;
464 int residual = mataData.cols() % iSize;
465 while(residual < iOrder) {
466 fFactor = fFactor - 0.1f;
467 iSize = fFactor * iOrder;
468 residual = mataData.cols() % iSize;
471 iSize = mataData.cols();
476 if(mataData.cols() > iSize) {
478 int numSlices = ceil(
float(mataData.cols())/
float(iSize));
480 for (
int i = 0; i < numSlices; i++) {
481 if(i == numSlices-1) {
483 iSize = mataData.cols() - (iSize * (numSlices -1));
487 sliceFiltered =
filterDataBlock(mataData.block(0,from,mataData.rows(),iSize),
493 matDataOut.block(0,0,mataData.rows(),sliceFiltered.cols()) += sliceFiltered;
495 matDataOut.block(0,from,mataData.rows(),sliceFiltered.cols()) += sliceFiltered;
498 if(bFilterEnd && (i == 0)) {
499 matDataOut.block(0,0,matDataOut.rows(),iOrder) += m_matOverlapBack;
500 }
else if (!bFilterEnd && (i == numSlices-1)) {
501 matDataOut.block(0,matDataOut.cols()-iOrder,matDataOut.rows(),iOrder) += m_matOverlapFront;
513 matDataOut.block(0,0,matDataOut.rows(),iOrder) += m_matOverlapBack;
515 matDataOut.block(0,matDataOut.cols()-iOrder,matDataOut.rows(),iOrder) += m_matOverlapFront;
520 m_matOverlapBack = matDataOut.block(0,matDataOut.cols()-iOrder,matDataOut.rows(),iOrder);
521 m_matOverlapFront = matDataOut.block(0,0,matDataOut.rows(),iOrder);
526 return matDataOut.block(0,0,matDataOut.rows(),mataData.cols());
534 m_matOverlapBack.resize(0,0);
535 m_matOverlapFront.resize(0,0);