141 qint32 first_comp = -1;
144 for (k = 0; k < this->
nchan; ++k)
148 comp = this->
chs[k].chpos.coil_type >> 16;
151 else if (comp != first_comp)
152 qWarning(
"Compensation is not set equally on all MEG channels");
162 MatrixXd C1, C2, comp_tmp;
180 qWarning(
"Cannot create compensator C1\n");
181 qWarning(
"Desired compensation matrix (kind = %d) not found\n",from);
192 qWarning(
"Cannot create compensator C2\n");
193 qWarning(
"Desired compensation matrix (kind = %d) not found\n",to);
202 comp_tmp = MatrixXd::Identity(this->
nchan,this->
nchan) + C1 - C2 - C2*C1;
205 if (exclude_comp_chs)
207 VectorXi pick = MatrixXi::Zero(1,this->
nchan);
209 for (k = 0; k < this->
nchan; ++k)
219 qWarning(
"Nothing remains after excluding the compensation channels\n");
223 ctf_comp.data->data.resize(npick,this->nchan);
224 for (k = 0; k < npick; ++k)
225 ctf_comp.data->data.row(k) = comp_tmp.block(pick(k), 0, 1, this->nchan);
238 MatrixXd presel, postsel;
239 qint32 k, col, c, ch=0, row, row_ch=0, channelAvailable;
241 for (k = 0; k < this->comps.size(); ++k)
243 if (this->comps[k].kind == kind)
245 this_data = this->comps[k].data;
250 presel = MatrixXd::Zero(this_data->ncol,this->nchan);
252 for(col = 0; col < this_data->ncol; ++col)
254 channelAvailable = 0;
255 for (c = 0; c < this->ch_names.size(); ++c)
257 if (QString::compare(this_data->col_names.at(col),this->ch_names.at(c)) == 0)
263 if (channelAvailable == 0)
265 qWarning(
"Channel %s is not available in data\n",this_data->col_names.at(col).toUtf8().constData());
268 else if (channelAvailable > 1)
270 qWarning(
"Ambiguous channel %s",this_data->col_names.at(col).toUtf8().constData());
273 presel(col,ch) = 1.0;
278 postsel = MatrixXd::Zero(this->nchan,this_data->nrow);
280 for (c = 0; c < this->nchan; ++c)
282 channelAvailable = 0;
283 for (row = 0; row < this_data->row_names.size(); ++row)
285 if (QString::compare(this->ch_names.at(c),this_data->row_names.at(row)) == 0)
291 if (channelAvailable > 1)
293 qWarning(
"Ambiguous channel %s", this->ch_names.at(c).toUtf8().constData());
296 else if (channelAvailable == 1)
298 postsel(c,row_ch) = 1.0;
301 this_comp = postsel*this_data->data*presel;
305 this_comp = defaultMatrixXd;
322 for(qint32 i = 0; i < sel.size(); ++i)
325 res.
chs.append(this->
chs[idx]);
328 res.
nchan =
static_cast<int>(sel.size());
337 QList<FiffChInfo> newList;
341 for(k = 0; k < listFiffChInfo.size(); ++k)
342 newList.append(listFiffChInfo[k]);
344 qint32 lower_half = 65535;
345 for (k = 0; k < listFiffChInfo.size(); ++k)
349 coil_type = listFiffChInfo[k].chpos.coil_type & lower_half;
350 newList[k].chpos.coil_type = (coil_type | (value << 16));
361 const QStringList&
bads,
362 QList<FiffChInfo>& chsp,
374 if (!stream->read_meas_info(stream->dirtree(), info, infoNode)) {
375 qCritical(
"%s : could not read measurement info", name.toUtf8().data());
381 QList<FiffChInfo> meg;
382 QList<FiffChInfo> eeg;
384 for (
int k = 0; k < info.
chs.size(); k++) {
385 if (
bads.contains(info.
chs[k].ch_name))
388 meg.append(info.
chs[k]);
389 else if (do_eeg && info.
chs[k].isValidEeg())
390 eeg.append(info.
chs[k]);
394 chsp.reserve(meg.size() + eeg.size());
412 QList<FiffChInfo>
chs;
414 for(k = 0; k < this->nchan; ++k)
424 if(this->
meas_id.version != -1)
438 bool have_hpi_result =
false;
439 bool have_isotrak =
false;
443 if (!this->
acq_pars.isEmpty() || !this->acq_stim.isEmpty())
457 if (!have_hpi_result)
468 if (this->
dig.size() > 0 && !have_isotrak)
471 for (qint32 k = 0; k < this->
dig.size(); ++k)
487 if (this->
bads.size() > 0)
513 MatrixXd cals(1,
nchan);
515 for(k = 0; k <
nchan; ++k)
522 cals(0,k) =
static_cast<double>(
chs[k].cal);
534 std::cout <<
"Sample frequency: " <<
sfreq <<
"\n";
536 std::cout <<
"Number of digitizer points: " <<
dig.size() <<
"\n";
537 for (
auto& point :
dig){
539 std::cout <<
"HPI Point " << point.ident <<
" - " << point.r[0] <<
", " << point.r[1] <<
", " << point.r[2] <<
"\n";
FiffInfo class declaration.
#define FIFF_MNE_CH_NAME_LIST
#define FIFFB_MNE_BAD_CHANNELS
FiffStream class declaration.
Header file describing the numerical values used in fif files.
#define FIFF_GANTRY_ANGLE
#define FIFF_PARENT_BLOCK_ID
#define FIFF_EXPERIMENTER
IOUtils class declaration.
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
CTF software compensation data.
QSharedPointer< FiffDirNode > SPtr
Universally unique identifier.
FiffInfo pick_info(const Eigen::RowVectorXi &sel=defaultVectorXi) const
void set_current_comp(fiff_int_t value)
static bool readMegEegChannels(const QString &name, bool do_meg, bool do_eeg, const QStringList &bads, QList< FiffChInfo > &chsp, int &nmegp, int &neegp)
void writeToStream(FiffStream *p_pStream) const
QList< FiffCtfComp > comps
qint32 get_current_comp()
bool make_compensator(fiff_int_t from, fiff_int_t to, FiffCtfComp &ctf_comp, bool exclude_comp_chs=false) const
QList< FiffDigPoint > dig
FiffCoordTrans ctf_head_t
FiffCoordTrans dev_head_t
QSharedDataPointer< FiffNamedMatrix > SDPtr
fiff_long_t start_block(fiff_int_t kind)
fiff_long_t write_proj(const QList< FiffProj > &projs)
QSharedPointer< FiffStream > SPtr
fiff_long_t write_dig_point(const FiffDigPoint &dig)
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)
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_coord_trans(const FiffCoordTrans &trans)
fiff_long_t write_name_list(fiff_int_t kind, const QStringList &data)
fiff_long_t write_string(fiff_int_t kind, const QString &data)
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
fiff_long_t write_ch_info(const FiffChInfo &ch)
fiff_long_t write_ctf_comp(const QList< FiffCtfComp > &comps)