64 using namespace FIFFLIB;
65 using namespace UTILSLIB;
66 using namespace Eigen;
78 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >(
"QSharedPointer<FIFFLIB::FiffCov>");
79 qRegisterMetaType<FIFFLIB::FiffCov>(
"FIFFLIB::FiffCov");
92 if(!t_pStream->open())
94 printf(
"\tNot able to open IODevice.\n");
99 printf(
"\tFiff covariance not found.\n");
101 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >(
"QSharedPointer<FIFFLIB::FiffCov>");
102 qRegisterMetaType<FIFFLIB::FiffCov>(
"FIFFLIB::FiffCov");
108 : QSharedData(p_FiffCov)
109 , kind(p_FiffCov.kind)
110 , diag(p_FiffCov.diag)
112 , names(p_FiffCov.names)
113 , data(p_FiffCov.data)
114 , projs(p_FiffCov.projs)
115 , bads(p_FiffCov.bads)
116 , nfree(p_FiffCov.nfree)
118 , eigvec(p_FiffCov.eigvec)
120 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >(
"QSharedPointer<FIFFLIB::FiffCov>");
121 qRegisterMetaType<FIFFLIB::FiffCov>(
"FIFFLIB::FiffCov");
155 res.
dim = sel.size();
157 for(qint32
k = 0;
k < sel.size(); ++
k)
158 res.
names << this->names[sel(
k)];
161 for(qint32 i = 0; i < res.
dim; ++i)
162 for(qint32 j = 0; j < res.
dim; ++j)
163 res.
data(i, j) = this->
data(sel(i), sel(j));
166 for(qint32
k = 0;
k < this->
bads.size(); ++
k)
167 if(res.
names.contains(this->bads[
k]))
180 VectorXi C_ch_idx = VectorXi::Zero(p_NoiseCov.
names.size());
182 for(qint32 i = 0; i < p_ChNames.size(); ++i)
184 qint32 idx = p_NoiseCov.
names.indexOf(p_ChNames[i]);
187 C_ch_idx[count] = idx;
191 C_ch_idx.conservativeResize(count);
193 MatrixXd C(count, count);
196 for(qint32 i = 0; i < count; ++i)
197 for(qint32 j = 0; j < count; ++j)
198 C(i,j) = p_NoiseCov.
data(C_ch_idx(i), C_ch_idx(j));
201 qWarning(
"Warning in FiffCov::prepare_noise_cov: This has to be debugged - not done before!");
202 C = MatrixXd::Zero(count, count);
203 for(qint32 i = 0; i < count; ++i)
204 C.diagonal()[i] = p_NoiseCov.
data(C_ch_idx(i),0);
211 if (ncomp > 0 && proj.rows() == count)
213 printf(
"Created an SSP operator (subspace dimension = %d)\n", ncomp);
214 C = proj * (C * proj.transpose());
216 qWarning(
"Warning in FiffCov::prepare_noise_cov: No projections applied since no projectors specified or projector dimensions do not match!");
219 RowVectorXi pick_meg = p_Info.
pick_types(
true,
false,
false, defaultQStringList, p_Info.
bads);
220 RowVectorXi pick_eeg = p_Info.
pick_types(
false,
true,
false, defaultQStringList, p_Info.
bads);
222 QStringList meg_names, eeg_names;
224 for(qint32 i = 0; i < pick_meg.size(); ++i)
225 meg_names << p_Info.
chs[pick_meg[i]].ch_name;
226 VectorXi C_meg_idx = VectorXi::Zero(p_NoiseCov.
names.size());
228 for(qint32
k = 0;
k < C.rows(); ++
k)
230 if(meg_names.indexOf(p_ChNames[
k]) > -1)
232 C_meg_idx[count] =
k;
237 C_meg_idx.conservativeResize(count);
239 C_meg_idx = VectorXi();
242 for(qint32 i = 0; i < pick_eeg.size(); ++i)
243 eeg_names << p_Info.
chs[pick_eeg(0,i)].ch_name;
244 VectorXi C_eeg_idx = VectorXi::Zero(p_NoiseCov.
names.size());
246 for(qint32
k = 0;
k < C.rows(); ++
k)
248 if(eeg_names.indexOf(p_ChNames[
k]) > -1)
250 C_eeg_idx[count] =
k;
256 C_eeg_idx.conservativeResize(count);
258 C_eeg_idx = VectorXi();
260 bool has_meg = C_meg_idx.size() > 0;
261 bool has_eeg = C_eeg_idx.size() > 0;
263 MatrixXd C_meg, C_eeg;
264 VectorXd C_meg_eig, C_eeg_eig;
265 MatrixXd C_meg_eigvec, C_eeg_eigvec;
268 count = C_meg_idx.rows();
269 C_meg = MatrixXd(count,count);
270 for(qint32 i = 0; i < count; ++i)
271 for(qint32 j = 0; j < count; ++j)
272 C_meg(i,j) = C(C_meg_idx(i), C_meg_idx(j));
273 MNEMath::get_whitener(C_meg,
false, QString(
"MEG"), C_meg_eig, C_meg_eigvec);
278 count = C_eeg_idx.rows();
279 C_eeg = MatrixXd(count,count);
280 for(qint32 i = 0; i < count; ++i)
281 for(qint32 j = 0; j < count; ++j)
282 C_eeg(i,j) = C(C_eeg_idx(i), C_eeg_idx(j));
283 MNEMath::get_whitener(C_eeg,
false, QString(
"EEG"), C_eeg_eig, C_eeg_eigvec);
286 qint32 n_chan = p_ChNames.size();
287 p_NoiseCov.
eigvec = MatrixXd::Zero(n_chan, n_chan);
288 p_NoiseCov.
eig = VectorXd::Zero(n_chan);
292 for(qint32 i = 0; i < C_meg_idx.rows(); ++i)
293 for(qint32 j = 0; j < C_meg_idx.rows(); ++j)
294 p_NoiseCov.
eigvec(C_meg_idx[i], C_meg_idx[j]) = C_meg_eigvec(i, j);
295 for(qint32 i = 0; i < C_meg_idx.rows(); ++i)
296 p_NoiseCov.
eig(C_meg_idx[i]) = C_meg_eig[i];
300 for(qint32 i = 0; i < C_eeg_idx.rows(); ++i)
301 for(qint32 j = 0; j < C_eeg_idx.rows(); ++j)
302 p_NoiseCov.
eigvec(C_eeg_idx[i], C_eeg_idx[j]) = C_eeg_eigvec(i, j);
303 for(qint32 i = 0; i < C_eeg_idx.rows(); ++i)
304 p_NoiseCov.
eig(C_eeg_idx[i]) = C_eeg_eig[i];
307 if (C_meg_idx.size() + C_eeg_idx.size() != n_chan)
309 printf(
"Error in FiffCov::prepare_noise_cov: channel sizes do no match!\n");
314 p_NoiseCov.
dim = p_ChNames.size();
315 p_NoiseCov.
diag =
false;
316 p_NoiseCov.
names = p_ChNames;
327 if(p_exclude.size() == 0)
329 p_exclude = p_info.
bads;
330 for(qint32 i = 0; i < cov.
bads.size(); ++i)
331 if(!p_exclude.contains(cov.
bads[i]))
332 p_exclude << cov.
bads[i];
338 for(
int i=0; i<p_info.
chs.size(); i++) {
339 if(p_info.
chs[i].kind == FIFFV_STIM_CH) {
340 p_exclude << p_info.
chs[i].ch_name;
345 RowVectorXi sel_eeg = p_info.
pick_types(
false,
true,
false, defaultQStringList, p_exclude);
346 RowVectorXi sel_mag = p_info.
pick_types(QString(
"mag"),
false,
false, defaultQStringList, p_exclude);
347 RowVectorXi sel_grad = p_info.
pick_types(QString(
"grad"),
false,
false, defaultQStringList, p_exclude);
349 QStringList info_ch_names = p_info.
ch_names;
350 QStringList ch_names_eeg, ch_names_mag, ch_names_grad;
351 for(qint32 i = 0; i < sel_eeg.size(); ++i)
352 ch_names_eeg << info_ch_names[sel_eeg(i)];
353 for(qint32 i = 0; i < sel_mag.size(); ++i)
354 ch_names_mag << info_ch_names[sel_mag(i)];
355 for(qint32 i = 0; i < sel_grad.size(); ++i)
356 ch_names_grad << info_ch_names[sel_grad(i)];
361 QStringList ch_names = cov_good.
names;
363 std::vector<qint32> idx_eeg, idx_mag, idx_grad;
364 for(qint32 i = 0; i < ch_names.size(); ++i)
366 if(ch_names_eeg.contains(ch_names[i]))
367 idx_eeg.push_back(i);
368 else if(ch_names_mag.contains(ch_names[i]))
369 idx_mag.push_back(i);
370 else if(ch_names_grad.contains(ch_names[i]))
371 idx_grad.push_back(i);
374 MatrixXd C(cov_good.
data);
377 if((
unsigned) C.rows() - iNoStimCh != idx_eeg.size() + idx_mag.size() + idx_grad.size()) {
378 printf(
"Error in FiffCov::regularize: Channel dimensions do not fit.\n");
381 QList<FiffProj> t_listProjs;
389 QMap<QString, QPair<double, std::vector<qint32> > > regData;
390 regData.insert(
"EEG", QPair<
double, std::vector<qint32> >(p_fRegEeg, idx_eeg));
391 regData.insert(
"MAG", QPair<
double, std::vector<qint32> >(p_fRegMag, idx_mag));
392 regData.insert(
"GRAD", QPair<
double, std::vector<qint32> >(p_fRegGrad, idx_grad));
397 QMap<QString, QPair<double, std::vector<qint32> > >::Iterator it;
398 for(it = regData.begin(); it != regData.end(); ++it)
400 QString desc(it.key());
401 double reg = it.value().first;
402 std::vector<qint32> idx = it.value().second;
404 if(idx.size() == 0 || reg == 0.0)
405 printf(
"\tNothing to regularize within %s data.\n", desc.toUtf8().constData());
408 printf(
"\tRegularize %s: %f\n", desc.toUtf8().constData(), reg);
409 MatrixXd this_C(idx.size(), idx.size());
410 for(quint32 i = 0; i < idx.size(); ++i)
411 for(quint32 j = 0; j < idx.size(); ++j)
412 this_C(i,j) = cov_good.
data(idx[i], idx[j]);
418 QStringList this_ch_names;
419 for(quint32
k = 0;
k < idx.size(); ++
k)
420 this_ch_names << ch_names[idx[
k]];
425 JacobiSVD<MatrixXd> svd(P, ComputeFullU);
427 VectorXd t_s = svd.singularValues();
428 MatrixXd t_U = svd.matrixU();
429 MNEMath::sort<double>(t_s, t_U);
431 U = t_U.block(0,0, t_U.rows(), t_U.cols()-ncomp);
435 printf(
"\tCreated an SSP operator for %s (dimension = %d).\n", desc.toUtf8().constData(), ncomp);
436 this_C = U.transpose() * (this_C * U);
440 double sigma = this_C.diagonal().mean();
441 this_C.diagonal() = this_C.diagonal().array() + reg * sigma;
442 if(p_bProj && ncomp > 0)
443 this_C = U * (this_C * U.transpose());
445 for(qint32 i = 0; i < this_C.rows(); ++i)
446 for(qint32 j = 0; j < this_C.cols(); ++j)
447 C(idx[i],idx[j]) = this_C(i,j);
453 for(qint32 i = 0; i < idx.size(); ++i)
454 for(qint32 j = 0; j < idx.size(); ++j)
455 cov.
data(idx[i], idx[j]) = C(i, j);