43double BadChannelDetect::pearsonCorr(
const RowVectorXd& a,
const RowVectorXd& b)
45 if (a.size() != b.size() || a.size() == 0)
48 RowVectorXd ac = a.array() - a.mean();
49 RowVectorXd bc = b.array() - b.mean();
51 double normA = ac.norm();
52 double normB = bc.norm();
53 if (normA < 1e-30 || normB < 1e-30)
56 return ac.dot(bc) / (normA * normB);
61double BadChannelDetect::median(QVector<double> values)
65 std::sort(values.begin(), values.end());
66 const int n = values.size();
69 return 0.5 * (values[n / 2 - 1] + values[n / 2]);
84 QVector<bool> flagged(
static_cast<int>(matData.rows()),
false);
86 if (i >= 0 && i < matData.rows())
89 if (i >= 0 && i < matData.rows())
92 if (i >= 0 && i < matData.rows())
96 for (
int i = 0; i < static_cast<int>(matData.rows()); ++i) {
109 for (
int ch = 0; ch < matData.rows(); ++ch) {
110 const RowVectorXd row = matData.row(ch);
111 double ptp = row.maxCoeff() - row.minCoeff();
112 if (ptp < dThreshold)
123 const int nCh =
static_cast<int>(matData.rows());
128 QVector<double> stds(nCh);
129 for (
int ch = 0; ch < nCh; ++ch) {
130 const RowVectorXd row = matData.row(ch);
131 double mean = row.mean();
132 double var = (row.array() - mean).square().mean();
133 stds[ch] = std::sqrt(var);
137 double med = median(stds);
139 QVector<double> absDevs(nCh);
140 for (
int ch = 0; ch < nCh; ++ch)
141 absDevs[ch] = std::abs(stds[ch] - med);
142 double mad = median(absDevs);
145 double sigma = 1.4826 * mad;
150 double meanStd = 0.0;
151 for (
double value : stds) {
154 meanStd /=
static_cast<double>(nCh);
157 for (
double value : stds) {
158 const double diff = value - meanStd;
159 varStd += diff * diff;
161 sigma = std::sqrt(varStd /
static_cast<double>(nCh));
168 for (
int ch = 0; ch < nCh; ++ch) {
169 double z = (stds[ch] - med) / sigma;
182 const int nCh =
static_cast<int>(matData.rows());
188 for (
int ch = 0; ch < nCh; ++ch) {
192 int lo = std::max(0, ch - iNeighbours);
193 int hi = std::min(nCh - 1, ch + iNeighbours);
195 for (
int nb = lo; nb <= hi; ++nb) {
198 double c = std::abs(pearsonCorr(matData.row(ch), matData.row(nb)));
206 double meanCorr = sumC /
static_cast<double>(nValid);
207 if (meanCorr < dCorrThresh)
Declaration of BadChannelDetect — automated detection of bad MEG/EEG channels.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
BadChannelDetectParams Params
static QVector< int > detect(const Eigen::MatrixXd &matData, const Params ¶ms=Params())
static QVector< int > detectHighVariance(const Eigen::MatrixXd &matData, double dZThresh=4.0)
static QVector< int > detectLowCorrelation(const Eigen::MatrixXd &matData, double dCorrThresh=0.4, int iNeighbours=5)
static QVector< int > detectFlat(const Eigen::MatrixXd &matData, double dThreshold=1e-13)