55 using namespace Eigen;
140 qint32 first_comp = -1;
143 for (k = 0; k < this->
nchan; ++k)
145 if (this->
chs[k].kind == FIFFV_MEG_CH)
147 comp = this->
chs[k].chpos.coil_type >> 16;
150 else if (comp != first_comp)
151 printf(
"Compensation is not set equally on all MEG channels");
161 MatrixXd C1, C2, comp_tmp;
165 ctf_comp.
data->clear();
169 ctf_comp.
data->data = MatrixXd::Identity(this->
nchan, this->
nchan);
179 printf(
"Cannot create compensator C1\n");
180 printf(
"Desired compensation matrix (kind = %d) not found\n",from);
191 printf(
"Cannot create compensator C2\n");
192 printf(
"Desired compensation matrix (kind = %d) not found\n",to);
201 comp_tmp = MatrixXd::Identity(this->
nchan,this->
nchan) + C1 - C2 - C2*C1;
204 if (exclude_comp_chs)
206 VectorXi pick = MatrixXi::Zero(1,this->
nchan);
208 for (k = 0; k < this->
nchan; ++k)
218 printf(
"Nothing remains after excluding the compensation channels\n");
222 ctf_comp.
data->data.resize(npick,this->nchan);
223 for (k = 0; k < npick; ++k)
224 ctf_comp.
data->data.row(k) = comp_tmp.block(pick(k), 0, 1, this->nchan);
226 ctf_comp.
data->data = comp_tmp;
237 MatrixXd presel, postsel;
238 qint32 k, col, c, ch=0, row, row_ch=0, channelAvailable;
240 for (k = 0; k < this->
comps.size(); ++k)
242 if (this->
comps[k].kind == kind)
244 this_data = this->
comps[k].data;
249 presel = MatrixXd::Zero(this_data->ncol,this->nchan);
251 for(col = 0; col < this_data->ncol; ++col)
253 channelAvailable = 0;
254 for (c = 0; c < this->
ch_names.size(); ++c)
256 if (QString::compare(this_data->col_names.at(col),this->
ch_names.at(c)) == 0)
262 if (channelAvailable == 0)
264 printf(
"Channel %s is not available in data\n",this_data->col_names.at(col).toUtf8().constData());
267 else if (channelAvailable > 1)
269 printf(
"Ambiguous channel %s",this_data->col_names.at(col).toUtf8().constData());
272 presel(col,ch) = 1.0;
277 postsel = MatrixXd::Zero(this->
nchan,this_data->nrow);
279 for (c = 0; c < this->
nchan; ++c)
281 channelAvailable = 0;
282 for (row = 0; row < this_data->row_names.size(); ++row)
284 if (QString::compare(this->
ch_names.at(c),this_data->row_names.at(row)) == 0)
290 if (channelAvailable > 1)
292 printf(
"Ambiguous channel %s", this->
ch_names.at(c).toUtf8().constData());
295 else if (channelAvailable == 1)
297 postsel(c,row_ch) = 1.0;
300 this_comp = postsel*this_data->data*presel;
304 this_comp = defaultMatrixXd;
321 for(qint32 i = 0; i < sel.size(); ++i)
324 res.
chs.append(this->
chs[idx]);
327 res.
nchan =
static_cast<int>(sel.size());
336 QList<FiffChInfo> newList;
338 fiff_int_t coil_type;
340 for(k = 0; k < listFiffChInfo.size(); ++k)
341 newList.append(listFiffChInfo[k]);
343 qint32 lower_half = 65535;
344 for (k = 0; k < listFiffChInfo.size(); ++k)
346 if (listFiffChInfo[k].kind == FIFFV_MEG_CH)
348 coil_type = listFiffChInfo[k].chpos.coil_type & lower_half;
349 newList[k].chpos.coil_type = (coil_type | (value << 16));
362 fiff_int_t data_type = 4;
364 QList<FiffChInfo>
chs;
366 for(k = 0; k < this->
nchan; ++k)
369 fiff_int_t nchan = chs.size();
390 bool have_hpi_result =
false;
391 bool have_isotrak =
false;
399 p_pStream->
write_string(FIFF_DACQ_PARS, this->acq_pars);
402 p_pStream->
write_string(FIFF_DACQ_STIM, this->acq_stim);
409 if (!have_hpi_result)
420 if (this->
dig.size() > 0 && !have_isotrak)
423 for (qint32 k = 0; k < this->
dig.size(); ++k)
439 if (this->
bads.size() > 0)
443 p_pStream->
end_block(FIFFB_MNE_BAD_CHANNELS);
465 MatrixXd cals(1,nchan);
467 for(k = 0; k <
nchan; ++k)
474 cals(0,k) =
static_cast<double>(chs[k].cal);
486 std::cout <<
"Sample frequency: " <<
sfreq <<
"\n";
488 std::cout <<
"Number of digitizer points: " <<
dig.size() <<
"\n";
489 for (
auto& point :
dig){
490 if (point.kind == FIFFV_POINT_HPI){
491 std::cout <<
"HPI Point " << point.ident <<
" - " << point.r[0] <<
", " << point.r[1] <<
", " << point.r[2] <<
"\n";
fiff_long_t write_ctf_comp(const QList< FiffCtfComp > &comps)
FiffInfo class declaration.
FiffCoordTrans ctf_head_t
FiffStream class declaration.
FiffNamedMatrix::SDPtr data
CTF software compensation data.
IOUtils class declaration.
fiff_long_t write_name_list(fiff_int_t kind, const QStringList &data)
fiff_long_t write_dig_point(const FiffDigPoint &dig)
Header file describing the numerical values used in fif files.
#define FIFF_EXPERIMENTER
fiff_long_t write_proj(const QList< FiffProj > &projs)
fiff_long_t write_coord_trans(const FiffCoordTrans &trans)
FiffCoordTrans dev_head_t
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
bool make_compensator(fiff_int_t from, fiff_int_t to, FiffCtfComp &ctf_comp, bool exclude_comp_chs=false) const
QList< FiffCtfComp > comps
qint32 get_current_comp()
QSharedDataPointer< FiffNamedMatrix > SDPtr
fiff_long_t start_block(fiff_int_t kind)
fiff_long_t write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
fiff_long_t write_id(fiff_int_t kind, const FiffId &id=FiffId::getDefault())
fiff_long_t write_int(fiff_int_t kind, const fiff_int_t *data, fiff_int_t nel=1, fiff_int_t next=FIFFV_NEXT_SEQ)
void set_current_comp(fiff_int_t value)
FiffInfo pick_info(const Eigen::RowVectorXi &sel=defaultVectorXi) const
FIFF measurement file information.
#define FIFF_GANTRY_ANGLE
QList< FiffDigPoint > dig
Universially unique identifier.
fiff_long_t write_ch_info(const FiffChInfo &ch)
void writeToStream(FiffStream *p_pStream) const
fiff_long_t write_string(fiff_int_t kind, const QString &data)