87 QList<FIFFLIB::FiffChInfo>& megp,
89 QList<FIFFLIB::FiffChInfo>& meg_compp,
91 QList<FIFFLIB::FiffChInfo>& eegp,
103 QList<FIFFLIB::FiffChInfo> chs;
105 QList<FIFFLIB::FiffChInfo> meg;
107 QList<FIFFLIB::FiffChInfo> meg_comp;
109 QList<FIFFLIB::FiffChInfo> eeg;
111 std::unique_ptr<FiffId> id;
112 QList<FiffDirNode::SPtr> nodes;
125 if (nodes.size() == 0) {
127 if (nodes.size() == 0) {
128 qCritical (
"Could not find the channel information.");
134 for (k = 0; k < info->nent(); k++) {
135 kind = info->dir[k]->kind;
136 pos = info->dir[k]->pos;
139 if (!stream->read_tag(t_pTag,pos))
141 nchan = *t_pTag->toInt();
143 for (j = 0; j < nchan; j++) {
151 if(!stream->read_tag(t_pTag, pos))
153 id = std::make_unique<FiffId>(*(
FiffId*)t_pTag->data());
157 if(!stream->read_tag(t_pTag, pos))
166 if(!stream->read_tag(t_pTag, pos))
169 this_ch = t_pTag->toChInfo();
171 printf (
"FIFF_CH_INFO : scan # out of range %d (%d)!",this_ch.
scanNo,nchan);
175 chs[this_ch.
scanNo-1] = this_ch;
181 qCritical(
"Some of the channel information was missing.");
184 if (t.
isEmpty() && meg_head_t != NULL) {
190 qCritical(
"MEG -> head coordinate transformation not found.");
197 for (k = 0; k < nchan; k++) {
202 meg_comp.append(chs[k]);
217 meg_compp = meg_comp;
219 *nmeg_compp = nmeg_comp;
232 if (meg_head_t == NULL) {
245#define MNE_CTFV_COMP_UNKNOWN -1
246#define MNE_CTFV_COMP_NONE 0
247#define MNE_CTFV_COMP_G1BR 0x47314252
248#define MNE_CTFV_COMP_G2BR 0x47324252
249#define MNE_CTFV_COMP_G3BR 0x47334252
250#define MNE_CTFV_COMP_G2OI 0x47324f49
251#define MNE_CTFV_COMP_G3OI 0x47334f49
268 for (k = 0; compMap[k].grad_comp >= 0; k++)
270 return compMap[k].grad_comp;
286 int nrow =
static_cast<int>(dense.rows());
287 int ncol =
static_cast<int>(dense.cols());
291 float maxval = dense.cwiseAbs().maxCoeff();
293 small = maxval*std::fabs(small);
295 small = std::fabs(small);
297 for (j = 0, nz = 0; j < nrow; j++)
298 for (k = 0; k < ncol; k++) {
299 if (std::fabs(dense(j,k)) > small)
304 qWarning(
"No nonzero elements found.");
308 qWarning(
"Unknown sparse matrix storage type: %d",stor_type);
312 sparse->
coding = stor_type;
316 sparse->
data.resize(nz);
317 sparse->
inds.resize(nz);
320 sparse->
ptrs.resize(nrow + 1);
321 for (j = 0, nz = 0; j < nrow; j++) {
323 for (k = 0; k < ncol; k++)
324 if (std::fabs(dense(j,k)) > small) {
325 sparse->
data[nz] = dense(j,k);
328 sparse->
inds[nz++] = k;
330 sparse->
ptrs[j] = ptr;
332 sparse->
ptrs[nrow] = nz;
333 for (j = nrow - 1; j >= 0; j--)
334 if (sparse->
ptrs[j] < 0)
335 sparse->
ptrs[j] = sparse->
ptrs[j+1];
338 sparse->
ptrs.resize(ncol + 1);
339 for (k = 0, nz = 0; k < ncol; k++) {
341 for (j = 0; j < nrow; j++)
342 if (std::fabs(dense(j,k)) > small) {
343 sparse->
data[nz] = dense(j,k);
346 sparse->
inds[nz++] = j;
348 sparse->
ptrs[k] = ptr;
350 sparse->
ptrs[ncol] = nz;
351 for (k = ncol-1; k >= 0; k--)
352 if (sparse->
ptrs[k] < 0)
353 sparse->
ptrs[k] = sparse->
ptrs[k+1];
368 for (i = 0; i < mat->
m; i++) {
370 for (j = mat->
ptrs[i]; j < mat->ptrs[i+1]; j++)
371 res[i] += mat->
data[j]*vector[mat->
inds[j]];
376 for (i = 0; i < mat->
m; i++)
378 for (i = 0; i < mat->
n; i++)
379 for (j = mat->
ptrs[i]; j < mat->ptrs[i+1]; j++)
380 res[mat->
inds[j]] += mat->
data[j]*vector[i];
384 qWarning(
"mne_sparse_vec_mult2: unknown sparse matrix storage type: %d",mat->
coding);
396 float res = sdot(&nn,v1,&one,v2,&one);
402 for (k = 0; k < nn; k++)
403 res = res + v1[k]*v2[k];
417 for (j = 0; j < d1; j++)
443 for (int k = 0; k < set.ncomp; k++)
445 this->comps.append(new MNECTFCompData(*set.comps[k]));
446 this->ncomp = this->comps.size();
452 this->undo = std::make_unique<MNECTFCompData>(*set.
undo);
455 this->current = std::make_unique<MNECTFCompData>(*set.
current);
463 for (
int k = 0; k <
comps.size(); k++)
478 std::unique_ptr<MNECTFCompDataSet> set;
480 QList<FiffDirNode::SPtr> nodes;
481 QList<FiffDirNode::SPtr>
comps;
485 QList<FiffChInfo>
chs;
492 QList<FiffChInfo> comp_chs, temp;
506 for (k = 0; k < ncompch; k++)
507 chs.append(comp_chs[k]);
516 set = std::make_unique<MNECTFCompDataSet>();
521 if (nodes.size() == 0)
524 if (
comps.size() == 0)
535 for (k = 0; k <
ncomp; k++) {
541 kind = *t_pTag->toInt();
547 calibrated = *t_pTag->toInt();
555 one->
data = std::move(mat);
561 printf(
"Warning: Compensation data for '%s' omitted\n",
explain_comp(one->
kind).toUtf8().constData());
566 set->comps.append(one);
571 printf(
"%d CTF compensation data sets read from %s\n",set->ncomp,name);
590 QList<FiffChInfo> compchs,
596 Eigen::VectorXi
comps;
600 Eigen::VectorXi comp_sel;
605 std::unique_ptr<FiffSparseMatrix> presel;
606 std::unique_ptr<FiffSparseMatrix> postsel;
607 std::unique_ptr<MNENamedMatrix> data;
609 QStringList emptyList;
611 if (compchs.isEmpty()) {
615 printf(
"Setting up compensation data...\n");
622 comps[k] =
chs[k].chpos.coil_type >> 16;
625 first_comp =
comps[k];
627 if (
comps[k] != first_comp) {
628 printf(
"We do not support nonuniform compensation yet.");
638 if (need_comp == 0) {
639 printf(
"\tNo compensation set. Nothing more to do.\n");
642 printf(
"\t%d out of %d channels have the compensation set.\n",need_comp,
nch);
646 for (k = 0, this_comp = NULL; k < this->ncomp; k++) {
647 if (this->comps[k]->mne_kind == first_comp) {
648 this_comp = this->comps[k];
653 printf(
"Did not find the desired compensation data : %s",
661 comp_sel.resize(this_comp->
data->ncol);
662 for (k = 0; k < this_comp->
data->ncol; k++) {
664 name = this_comp->
data->collist[k];
665 for (p = 0; p <
ncomp; p++)
666 if (QString::compare(name,compchs[p].ch_name) == 0) {
670 if (comp_sel[k] < 0) {
671 printf(
"Compensation channel %s not found",name.toUtf8().constData());
675 printf(
"\tAll compensation channels found.\n");
680 Eigen::MatrixXf sel = Eigen::MatrixXf::Zero(this_comp->
data->ncol,
ncomp);
681 for (j = 0; j < this_comp->
data->ncol; j++)
682 sel(j, comp_sel[j]) = 1.0f;
687 printf(
"\tPreselector created.\n");
692 for (k = 0; k <
nch; k++) {
694 names.append(
chs[k].ch_name);
698 auto d = this_comp->
data->pick(names, need_comp, emptyList, 0);
703 printf(
"\tCompensation data matrix created.\n");
708 Eigen::MatrixXf sel = Eigen::MatrixXf::Zero(
nch, data->nrow);
709 for (j = 0, p = 0; j <
nch; j++) {
717 printf(
"\tPostselector created.\n");
719 current = std::make_unique<MNECTFCompData>();
722 current->data = std::move(data);
723 current->presel = std::move(presel);
724 current->postsel = std::move(postsel);
726 printf(
"\tCompensation set up.\n");
741 for (k = 0, nset = 0; k <
nch; k++) {
743 chs[k].chpos.coil_type = (
chs[k].chpos.coil_type & 0xFFFF) | (comp << 16);
747 printf(
"A new compensation value (%s) was assigned to %d MEG channels.\n",
756 return apply(do_it, data, data);
767 int ndata =
static_cast<int>(data.size());
768 int ncompdata =
static_cast<int>(compdata.size());
777 if (this_comp->
presel->n != ncompdata) {
778 printf(
"Compensation data dimension mismatch. Expected %d, got %d channels.",
779 this_comp->
presel->n,ncompdata);
783 else if (this_comp->
data->ncol != ncompdata) {
784 printf(
"Compensation data dimension mismatch. Expected %d, got %d channels.",
785 this_comp->
data->ncol,ncompdata);
789 if (this_comp->
postsel->m != ndata) {
790 printf(
"Data dimension mismatch. Expected %d, got %d channels.",
795 else if (this_comp->
data->nrow != ndata) {
796 printf(
"Data dimension mismatch. Expected %d, got %d channels.",
797 this_comp->
data->nrow,ndata);
812 presel = compdata.data();
819 Eigen::Map<const Eigen::VectorXf> preselVec(presel, this_comp->
data->ncol);
820 Eigen::Map<Eigen::VectorXf> compVec(this_comp->
comp_data.data(), this_comp->
data->nrow);
821 compVec = this_comp->
data->data * preselVec;
839 Eigen::Map<const Eigen::VectorXf> compVec(comp, ndata);
854 using RowMatrixXf = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
857 int ndata =
static_cast<int>(data.rows());
858 int ns =
static_cast<int>(data.cols());
859 int ncompdata = ndata;
868 if (this_comp->
presel->n != ncompdata) {
869 printf(
"Compensation data dimension mismatch. Expected %d, got %d channels.",
870 this_comp->
presel->n,ncompdata);
874 else if (this_comp->
data->ncol != ncompdata) {
875 printf(
"Compensation data dimension mismatch. Expected %d, got %d channels.",
876 this_comp->
data->ncol,ncompdata);
880 if (this_comp->
postsel->m != ndata) {
881 printf(
"Data dimension mismatch. Expected %d, got %d channels.",
886 else if (this_comp->
data->nrow != ndata) {
887 printf(
"Data dimension mismatch. Expected %d, got %d channels.",
888 this_comp->
data->nrow,ndata);
894 Eigen::MatrixXf preselMat;
896 preselMat.resize(this_comp->
presel->m, ns);
899 for (
int i = 0; i < sp->
m; i++)
900 for (
int c = 0; c < ns; c++) {
902 for (
int j = sp->
ptrs[i]; j < sp->ptrs[i+1]; j++)
903 val += sp->
data[j] * data(sp->
inds[j], c);
904 preselMat(i, c) = val;
908 for (
int c = 0; c < ns; c++)
909 for (
int i = 0; i < sp->
n; i++)
910 for (
int j = sp->
ptrs[i]; j < sp->ptrs[i+1]; j++)
911 preselMat(sp->
inds[j], c) += sp->
data[j] * data(i, c);
913 printf(
"Unknown sparse matrix storage type: %d", sp->
coding);
924 Eigen::MatrixXf comp = this_comp->
data->data * preselMat;
929 Eigen::MatrixXf postselMat(this_comp->
postsel->m, ns);
932 for (
int i = 0; i < sp->
m; i++)
933 for (
int c = 0; c < ns; c++) {
935 for (
int j = sp->
ptrs[i]; j < sp->ptrs[i+1]; j++)
936 val += sp->
data[j] * comp(sp->
inds[j], c);
937 postselMat(i, c) = val;
940 postselMat.setZero();
941 for (
int c = 0; c < ns; c++)
942 for (
int i = 0; i < sp->
n; i++)
943 for (
int j = sp->
ptrs[i]; j < sp->ptrs[i+1]; j++)
944 postselMat(sp->
inds[j], c) += sp->
data[j] * comp(i, c);
946 printf(
"Unknown sparse matrix storage type: %d", sp->
coding);
949 comp = std::move(postselMat);
969 for (k = 0, first_comp = -1; k <
nch; k++) {
971 comp =
chs[k].chpos.coil_type >> 16;
974 else if (first_comp != comp) {
975 printf(
"Non uniform compensation not supported.");
994 for (k = 0; compMap[k].grad_comp >= 0; k++)
996 return compMap[k].ctf_comp;
1004 static const struct {
1016 if (explain[k].kind == kind)
1017 return QString::fromLatin1(explain[k].expl);
1018 return QString::fromLatin1(explain[k].expl);
1024 QList<FiffChInfo>&
chs,
1026 QList<FiffChInfo> comp_chs,
1036 if (comp_chs.isEmpty()) {
1042 for (k = 0, have_comp_chs = 0; k < ncomp_chan; k++)
1046 printf(
"No compensation channels in these data.");
1058 printf(
"No further compensation necessary (comp = %s)\n",
explain_comp(
current->kind).toUtf8().constData());
1064 printf(
"No compensation was requested.\n");
1070 comp_was =
undo->mne_kind;
1075 printf(
"Compensation set up as requested (%s -> %s).\n",
#define FIFF_MNE_CTF_COMP_KIND
#define FIFFV_COORD_DEVICE
#define FIFFB_MNE_CTF_COMP_DATA
#define FIFF_MNE_CTF_COMP_CALIBRATED
#define FIFF_MNE_CTF_COMP_DATA
#define FIFFB_MNE_CTF_COMP
#define FIFFB_MNE_PARENT_MEAS_FILE
#define FIFF_PARENT_BLOCK_ID
Old fiff_type declarations - replace them.
FiffCoordTrans class declaration.
#define MNE_CTFV_COMP_G2BR
#define MNE_CTFV_COMP_NONE
#define MNE_CTFV_COMP_UNKNOWN
#define MNE_CTFV_COMP_G3BR
#define MNE_CTFV_COMP_G1BR
MNECTFCompDataSet class declaration.
Legacy MNE-C constants and common typedefs.
MNECTFCompData class declaration.
float mne_dot_vectors_32(float *v1, float *v2, int nn)
void mne_mat_vec_mult2_32(float **m, float *v, float *result, int d1, int d2)
FiffSparseMatrix * mne_convert_to_sparse(const Eigen::MatrixXf &dense, int stor_type, float small)
int mne_unmap_ctf_comp_kind(int ctf_comp)
int mne_sparse_vec_mult2_32(FiffSparseMatrix *mat, float *vector, float *res)
int mne_read_meg_comp_eeg_ch_info_32(const QString &name, QList< FIFFLIB::FiffChInfo > &megp, int *nmegp, QList< FIFFLIB::FiffChInfo > &meg_compp, int *nmeg_compp, QList< FIFFLIB::FiffChInfo > &eegp, int *neegp, FiffCoordTrans *meg_head_t, fiffId *idp)
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
FiffId * fiffId
Backward-compatible pointer typedef for the old fiffId pointer.
Coordinate transformation description.
QSharedPointer< FiffDirNode > SPtr
Universally unique identifier.
FIFF sparse matrix storage.
FIFFLIB::fiff_int_t coding
QSharedPointer< FiffStream > SPtr
std::unique_ptr< FiffTag > UPtr
Represents a single CTF compensation data element.
std::unique_ptr< FIFFLIB::FiffSparseMatrix > postsel
std::unique_ptr< MNENamedMatrix > data
Eigen::VectorXf comp_data
int calibrate(const QList< FIFFLIB::FiffChInfo > &chs, int nch, int do_it)
std::unique_ptr< FIFFLIB::FiffSparseMatrix > presel
Eigen::VectorXf postsel_data
Eigen::VectorXf presel_data
std::unique_ptr< MNECTFCompData > undo
int make_comp(const QList< FIFFLIB::FiffChInfo > &chs, int nch, QList< FIFFLIB::FiffChInfo > compchs, int ncomp)
std::unique_ptr< MNECTFCompData > current
QList< FIFFLIB::FiffChInfo > chs
static int set_comp(QList< FIFFLIB::FiffChInfo > &chs, int nch, int comp)
static std::unique_ptr< MNECTFCompDataSet > read(const QString &name)
int apply_transpose(int do_it, Eigen::MatrixXf &data)
static QString explain_comp(int kind)
QList< MNECTFCompData * > comps
static int get_comp(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
int set_compensation(int compensate_to, QList< FIFFLIB::FiffChInfo > &chs, int nchan, QList< FIFFLIB::FiffChInfo > comp_chs, int ncomp_chan)
static int map_comp_kind(int grad)
int apply(int do_it, Eigen::Ref< Eigen::VectorXf > data, Eigen::Ref< const Eigen::VectorXf > compdata)
static std::unique_ptr< MNENamedMatrix > read(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &node, int kind)
Factory: read a named matrix from a FIFF file.
static FiffCoordTrans readMeasTransform(const QString &name)
static FiffCoordTrans readFromTag(const std::unique_ptr< FiffTag > &tag)