53#include <QtConcurrent>
87 const MatrixXi& events,
91 const QMap<QString,double>& mapReject,
92 const QStringList& lExcludeChs,
93 const RowVectorXi& picks)
100 MatrixXi selected = MatrixXi::Zero(1, events.rows());
101 for (p = 0; p < events.rows(); ++p)
103 if (events(p,1) == 0 && events(p,2) == event)
105 selected(0,count) = p;
109 selected.conservativeResize(1, count);
111 qInfo(
"[MNEEpochDataList::readEpochs] %d matching events found",count);
113 qWarning(
"[MNEEpochDataList::readEpochs] No desired events found.");
118 RowVectorXi picksNew = picks;
119 if(picks.cols() <= 0) {
120 picksNew.resize(raw.
info.
chs.size());
121 for(
int i = 0; i < raw.
info.
chs.size(); ++i) {
131 std::unique_ptr<MNEEpochData> epoch(Q_NULLPTR);
133 for (p = 0; p < count; ++p) {
135 event_samp = events(selected(p),0);
137 to = event_samp + floor(tmax*raw.
info.
sfreq + 0.5);
143 times.resize(1, to-from+1);
144 for (qint32 i = 0; i < times.cols(); ++i)
145 times(0, i) = ((float)(from-event_samp+i)) / raw.
info.
sfreq;
148 epoch->event = event;
157 if (epoch->bReject) {
162 if(!data.isEmpty()) {
163 if(epoch->epoch.size() == data.last()->epoch.size()) {
170 qWarning(
"[MNEEpochDataList::readEpochs] Can't read the event data segments.");
174 qInfo().noquote() <<
"[MNEEpochDataList::readEpochs] Read a total of"<< data.size() <<
"epochs of type" <<
event <<
"and marked"<< dropCount <<
"for rejection.";
189 qInfo(
"[MNEEpochDataList::average] Calculate evoked. ");
193 if(this->size() > 0) {
194 matAverage = MatrixXd::Zero(this->at(0)->epoch.rows(), this->at(0)->epoch.cols());
201 p_evoked.
nave = sel.size();
203 for(qint32 i = 0; i < sel.size(); ++i) {
204 matAverage.array() += this->at(sel(i))->epoch.array();
207 p_evoked.
nave = this->size();
209 for(qint32 i = 0; i < this->size(); ++i) {
210 matAverage.array() += this->at(i)->epoch.array();
213 matAverage.array() /= p_evoked.
nave;
215 qInfo(
"[MNEEpochDataList::average] %d averages used [done]", p_evoked.
nave);
221 p_evoked.
first = first;
222 p_evoked.
last = last;
224 p_evoked.
times = RowVectorXf::LinSpaced(this->first()->epoch.cols(), this->first()->tmin, this->first()->tmax);
226 p_evoked.
times[
static_cast<int>(this->first()->tmin * -1 * info.
sfreq)] = 0;
228 p_evoked.
comment = QString::number(this->at(0)->event);
230 if(p_evoked.
proj.rows() > 0) {
231 matAverage = p_evoked.
proj * matAverage;
232 qInfo(
"[MNEEpochDataList::average] SSP projectors applied to the evoked data");
235 p_evoked.
data = matAverage;
245 QMutableListIterator<MNEEpochData::SPtr> i(*
this);
246 while (i.hasNext()) {
247 i.next()->applyBaselineCorrection(baseline);
255 QMutableListIterator<MNEEpochData::SPtr> i(*
this);
256 while (i.hasNext()) {
257 if (i.next()->bReject) {
267 QMutableListIterator<MNEEpochData::SPtr> i(*
this);
268 while (i.hasNext()) {
269 i.next()->pick_channels(sel);
277 const QMap<QString,double>& mapReject,
278 const QStringList& lExcludeChs)
282 bool bReject =
false;
285 QList<ArtifactRejectionData> lchData;
288 if(mapReject.contains(
"grad") ||
289 mapReject.contains(
"mag") ) {
293 if(mapReject.contains(
"eeg")) {
297 if(mapReject.contains(
"eog")) {
301 if(lChTypes.isEmpty()) {
305 for(
int i = 0; i < pFiffInfo.
chs.size(); ++i) {
306 if(lChTypes.contains(pFiffInfo.
chs.at(i).kind)
307 && !lExcludeChs.contains(pFiffInfo.
chs.at(i).ch_name)
308 && !pFiffInfo.
bads.contains(pFiffInfo.
chs.at(i).ch_name)
312 tempData.
data = data.row(i);
314 switch (pFiffInfo.
chs.at(i).kind) {
332 tempData.
sChName = pFiffInfo.
chs.at(i).ch_name;
333 lchData.append(tempData);
337 if(lchData.isEmpty()) {
338 qWarning() <<
"[MNEEpochDataList::checkForArtifact] No channels found to scan for artifacts. Do not reject. Returning.";
347 future.waitForFinished();
349 for(
int i = 0; i < lchData.size(); ++i) {
350 if(lchData.at(i).bRejected) {
352 qInfo().noquote() <<
"[MNEEpochDataList::checkForArtifact] Reject trial because of channel"<<lchData.at(i).sChName;
364 RowVectorXd temp = inputData.
data;
369 double min = temp.minCoeff();
370 double max = temp.maxCoeff();
373 double pp = max - min;
397 const MatrixXi &events,
398 const QList<int> &eventCodes,
399 const QStringList &comments,
402 const QMap<QString,double> &mapReject,
403 const QPair<float,float> &baseline,
412 bool doBaseline = (baseline.first != baseline.second);
415 for (
int j = 0; j < eventCodes.size(); ++j) {
416 int eventCode = eventCodes[j];
417 QString comment = (j < comments.size()) ? comments[j]
418 : QString(
"cat_%1").arg(eventCode);
435 int minSamp =
static_cast<int>(std::round(tmin * sfreq));
436 int maxSamp =
static_cast<int>(std::round(tmax * sfreq));
445 evokedSet.
evoked.append(evoked);
#define FIFFV_COIL_BABY_REF_MAG
#define FIFFV_COIL_BABY_REF_MAG2
FiffEvokedSet class declaration.
#define FIFFV_ASPECT_AVERAGE
#define FIFFV_ASPECT_STD_ERR
MNEMath class declaration.
MNEEpochDataList class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
void setInfo(const FiffInfo &p_info, bool proj=true)
QList< FiffEvoked > evoked
FIFF measurement file information.
FIFF raw measurement data.
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
QSharedPointer< MNEEpochData > SPtr
Artifact rejection thresholds and flags for each channel type (grad, mag, eeg, eog) used during epoch...
FIFFLIB::FiffEvoked average(const FIFFLIB::FiffInfo &p_info, FIFFLIB::fiff_int_t first, FIFFLIB::fiff_int_t last, Eigen::VectorXi sel=FIFFLIB::defaultVectorXi, bool proj=false)
void applyBaselineCorrection(const QPair< float, float > &baseline)
static MNEEpochDataList readEpochs(const FIFFLIB::FiffRawData &raw, const Eigen::MatrixXi &events, float tmin, float tmax, qint32 event, const QMap< QString, double > &mapReject, const QStringList &lExcludeChs=QStringList(), const Eigen::RowVectorXi &picks=Eigen::RowVectorXi())
static void checkChThreshold(ArtifactRejectionData &inputData)
void pick_channels(const Eigen::RowVectorXi &sel)
static FIFFLIB::FiffEvokedSet averageCategories(const FIFFLIB::FiffRawData &raw, const Eigen::MatrixXi &events, const QList< int > &eventCodes, const QStringList &comments, float tmin, float tmax, const QMap< QString, double > &mapReject=QMap< QString, double >(), const QPair< float, float > &baseline=QPair< float, float >(0.0f, 0.0f), bool proj=false)
static bool checkForArtifact(const Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &pFiffInfo, const QMap< QString, double > &mapReject, const QStringList &lExcludeChs=QStringList())