33#include <Eigen/Cholesky>
50MatrixXd demeanedRows(
const MatrixXd& data,
const QVector<int>& rows)
52 MatrixXd out(rows.size(), data.cols());
53 for (
int i = 0; i < rows.size(); ++i)
54 out.row(i) = data.row(rows[i]).array() - data.row(rows[i]).mean();
66 const QStringList& eogChannels)
68 m_vecEogIndices.clear();
69 m_vecTargetIndices.clear();
72 if (eogChannels.isEmpty()) {
73 for (
int i = 0; i < info.
chs.size(); ++i) {
75 m_vecEogIndices.append(i);
78 for (
const QString& name : eogChannels) {
79 const int idx =
static_cast<int>(info.
ch_names.indexOf(name));
81 m_vecEogIndices.append(idx);
83 qWarning() <<
"[EogRegression::fit] EOG channel not found:" << name;
86 if (m_vecEogIndices.isEmpty()) {
87 qWarning() <<
"[EogRegression::fit] No EOG channels found. Data will not be modified.";
93 m_vecTargetIndices.append(i);
96 const MatrixXd E = demeanedRows(data, m_vecEogIndices);
97 const MatrixXd T = demeanedRows(data, m_vecTargetIndices);
98 m_matBeta = (E * E.transpose()).ldlt().solve(E * T.transpose()).transpose();
110 qWarning() <<
"[EogRegression::apply] Not fitted yet. Call fit() first.";
113 const MatrixXd E = demeanedRows(data, m_vecEogIndices);
114 for (
int i = 0; i < m_vecTargetIndices.size(); ++i)
115 data.row(m_vecTargetIndices[i]) -= m_matBeta.row(i) * E;
122 const QStringList& eogChannels)
125 reg.
fit(data, info, eogChannels);
126 reg.
apply(data, info);
FIFF channel descriptor record (FIFF_CH_INFO): per-channel logical/scanner numbers,...
Symbolic FIFF tag, block, value, unit and channel-type constants shared across FIFFLIB.
constexpr auto FIFFV_EOG_CH
Full FIFF measurement metadata: everything from FIFFB_MEAS / FIFFB_MEAS_INFO needed to interpret a re...
Declaration of EogRegression — EOG artifact removal via linear regression.
FIFF file I/O, in-memory data structures and high-level readers/writers.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
void apply(Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &info) const
Apply the fitted regression to remove EOG artifacts in-place.
static void fitApply(Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &info, const QStringList &eogChannels=QStringList())
Convenience: fit and apply in one step.
void fit(const Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &info, const QStringList &eogChannels=QStringList())
Fit regression coefficients from EOG to all other channels.
Full FIFF measurement info: per-channel descriptors, sampling and filter setup, projectors,...
Eigen::RowVectorXi pick_data_channels(const QStringList &exclude=defaultQStringList) const