64 return QStringLiteral(
"brain");
66 return QStringLiteral(
"eog");
68 return QStringLiteral(
"ecg");
70 return QStringLiteral(
"muscle");
72 return QStringLiteral(
"other");
74 return QStringLiteral(
"unknown");
80 const MatrixXd& matEog,
81 const MatrixXd& matEcg,
86 QList<IcaLabelResult> results;
88 const int nComp =
static_cast<int>(matSources.rows());
92 const double dMuscleThresh = 0.7;
94 for (
int k = 0; k < nComp; ++k) {
100 VectorXd source = matSources.row(k).transpose();
103 double eogCorr = 0.0;
104 if (matEog.rows() > 0 && matEog.cols() == matSources.cols())
108 double ecgCorr = 0.0;
109 if (matEcg.rows() > 0 && matEcg.cols() == matSources.cols())
116 if (eogCorr >= dEogThresh && eogCorr >= ecgCorr && eogCorr >= muscle) {
119 }
else if (ecgCorr >= dEcgThresh && ecgCorr >= eogCorr && ecgCorr >= muscle) {
122 }
else if (muscle >= dMuscleThresh) {
128 res.
confidence = 1.0 - std::max({eogCorr, ecgCorr, muscle});
141 QVector<int> artifacts;
142 for (
const auto& res : labels) {
146 artifacts.append(res.componentIndex);
156 const int n =
static_cast<int>(source.size());
161 double srcMean = source.mean();
162 VectorXd srcCentered = source.array() - srcMean;
163 double srcStd = std::sqrt(srcCentered.squaredNorm() /
static_cast<double>(n - 1));
168 double maxCorr = 0.0;
169 for (
int r = 0; r < matRef.rows(); ++r) {
170 VectorXd ref = matRef.row(r).transpose();
171 double refMean = ref.mean();
172 VectorXd refCentered = ref.array() - refMean;
173 double refStd = std::sqrt(refCentered.squaredNorm() /
static_cast<double>(n - 1));
178 double corr = std::abs(srcCentered.dot(refCentered) / (
static_cast<double>(n - 1) * srcStd * refStd));
193 const int n =
static_cast<int>(source.size());
194 if (n < 3 || dSFreq <= 0.0)
197 double totalVar = 0.0;
198 double srcMean = source.mean();
199 for (
int i = 0; i < n; ++i) {
200 double d = source[i] - srcMean;
203 totalVar /=
static_cast<double>(n - 1);
205 if (totalVar < 1e-30)
210 for (
int i = 1; i < n - 1; ++i) {
211 double d2 = source[i + 1] - 2.0 * source[i] + source[i - 1];
214 hfVar /=
static_cast<double>(n - 2);
218 double ratio = hfVar / (6.0 * totalVar);
220 return std::min(ratio, 1.0);
Automatic ICA component labelling for artefact identification on M/EEG.
Supervised and unsupervised spatial-filter decompositions for M/EEG decoding.
IcaComponentLabel
Categorical label assigned to a single ICA component.
Outcome of labelling a single ICA component.
static QString labelToString(IcaComponentLabel label)
static double muscleScore(const Eigen::VectorXd &source, double dSFreq)
static QList< IcaLabelResult > classify(const Eigen::MatrixXd &matSources, const Eigen::MatrixXd &matEog, const Eigen::MatrixXd &matEcg, double dSFreq, double dEogThresh=0.3, double dEcgThresh=0.3)
static double maxAbsCorrelation(const Eigen::VectorXd &source, const Eigen::MatrixXd &matRef)
static QVector< int > findArtifactComponents(const QList< IcaLabelResult > &labels)