29#include <QRegularExpression>
81 static const QHash<int, QString> byKind{
82 {
FIFFV_REF_MEG_CH,
"ref_meg"}, {
FIFFV_STIM_CH,
"stim"}, {
FIFFV_EOG_CH,
"eog"}, {
FIFFV_EMG_CH,
"emg"}, {
FIFFV_ECG_CH,
"ecg"}, {
FIFFV_RESP_CH,
"resp"}, {
FIFFV_MISC_CH,
"misc"}, {
FIFFV_EXCI_CH,
"exci"}, {
FIFFV_IAS_CH,
"ias"}, {
FIFFV_SYST_CH,
"syst"}, {
FIFFV_SEEG_CH,
"seeg"}, {
FIFFV_DBS_CH,
"dbs"}, {
FIFFV_BIO_CH,
"bio"}, {
FIFFV_DIPOLE_WAVE_CH,
"dipole"}, {
FIFFV_GOODNESS_FIT_CH,
"gof"}, {
FIFFV_ECOG_CH,
"ecog"}, {
FIFFV_TEMPERATURE_CH,
"temperature"}, {
FIFFV_GALVANIC_CH,
"gsr"}};
83 static const QHash<int, QString> eegByCoil{
85 static const QHash<int, QString> fnirsByCoil{
86 {
FIFFV_COIL_FNIRS_HBO,
"hbo"}, {
FIFFV_COIL_FNIRS_HBR,
"hbr"}, {
FIFFV_COIL_FNIRS_CW_AMPLITUDE,
"fnirs_cw_amplitude"}, {
FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE,
"fnirs_fd_ac_amplitude"}, {
FIFFV_COIL_FNIRS_FD_PHASE,
"fnirs_fd_phase"}, {
FIFFV_COIL_FNIRS_OD,
"fnirs_od"}, {
FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE,
"fnirs_td_gated_amplitude"}, {
FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY,
"fnirs_td_moments_intensity"}, {
FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN,
"fnirs_td_moments_mean"}, {
FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE,
"fnirs_td_moments_variance"}};
89 const auto refine = [](
const QHash<int, QString>& rule,
int key) {
90 return rule.value(key);
102 return refine(byKind, ch.
kind);
111 const QString type = channelTypeName(this->
chs[idx]);
113 throw std::invalid_argument(
"Unknown channel type for channel " + this->
chs[idx].ch_name.toStdString());
121 QMap<QString, QList<int>> byType;
122 for (
const char* type : {
"grad",
"mag",
"ref_meg",
"eeg",
"csd",
"seeg",
"dbs",
"ecog",
"eog",
"emg",
"ecg",
"resp",
"bio",
123 "misc",
"stim",
"exci",
"syst",
"ias",
"gof",
"dipole",
"chpi",
"temperature",
"gsr",
"hbo",
"hbr",
124 "fnirs_cw_amplitude",
"fnirs_fd_ac_amplitude",
"fnirs_fd_phase",
"fnirs_od",
125 "fnirs_td_gated_amplitude",
"fnirs_td_moments_intensity",
"fnirs_td_moments_mean",
126 "fnirs_td_moments_variance",
"eyegaze",
"pupil"}) {
127 byType.insert(QString::fromLatin1(type), {});
129 const qsizetype count = picks.isEmpty() ?
chs.size() : picks.size();
130 for (qsizetype k = 0; k < count; ++k) {
131 const int idx = picks.isEmpty() ?
static_cast<int>(k) : picks[k];
141 const QRegularExpression re(QRegularExpression::anchoredPattern(regexp + QStringLiteral(
".*")),
142 QRegularExpression::DotMatchesEverythingOption);
144 for (
int k = 0; k <
ch_names.size(); ++k) {
145 if (re.match(
ch_names[k]).hasMatch())
148 return Eigen::Map<const RowVectorXi>(sel.constData(), sel.size());
168RowVectorXi
FiffInfoBase::pick_types(
const QString meg,
bool eeg,
bool stim,
const QStringList& include,
const QStringList& exclude)
const
171 const qint32 nchPresent =
static_cast<qint32
>(this->
chs.size());
172 RowVectorXi pick = RowVectorXi::Zero(nchPresent);
176 for (k = 0; k < nchPresent; ++k) {
177 kind = this->
chs[k].kind;
180 if (meg.compare(
"all") == 0) {
182 }
else if (meg.compare(
"grad") == 0 && this->chs[k].unit ==
FIFF_UNIT_T_M) {
184 }
else if (meg.compare(
"mag") == 0 && this->chs[k].unit ==
FIFF_UNIT_T) {
195 QStringList myinclude;
196 for (k = 0; k < nchPresent; ++k) {
203 if (include.size() > 0) {
204 for (k = 0; k < include.size(); ++k) {
205 myinclude << include[k];
222 return this->
pick_types(QString(
"all"), eeg, stim, include, exclude);
224 return this->
pick_types(QString(
""), eeg, stim, include, exclude);
231 RowVectorXi sel = RowVectorXi::Zero(
ch_names.size());
233 QStringList t_includedSelection;
236 for (qint32 k = 0; k <
ch_names.size(); ++k) {
237 if ((include.size() == 0 || include.contains(
ch_names[k])) && !exclude.contains(
ch_names[k])) {
239 if (!t_includedSelection.contains(
ch_names[k])) {
246 sel.conservativeResize(count);
263 for (qint32 i = 0; i < sel->size(); ++i) {
265 res.
chs.append(this->
chs[idx]);
268 res.
nchan = sel->size();
276 QList<FiffChInfo>& meg_compp,
278 QList<FiffChInfo>& eegp,
283 for (
int k = 0; k <
nchan; k++) {
288 meg_compp.append(
chs[k]);
303 QStringList lChannelTypes;
305 const QString type = channelTypeName(ch);
306 if (!type.isEmpty() && !lChannelTypes.contains(type))
307 lChannelTypes << type;
309 return lChannelTypes;
316 if (name.isEmpty()) {
322 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
323 qCritical() <<
"Cannot open bad channel file:" << name;
328 QTextStream in(&file);
329 while (!in.atEnd()) {
330 QString line = in.readLine().trimmed();
331 if (line.isEmpty() || line.startsWith(
'#'))
336 if (file.error() != QFileDevice::NoError) {
337 qCritical() <<
"Error reading bad channel file:" << name;
#define FIFFV_COIL_FNIRS_HBO
#define FIFFV_COIL_FNIRS_CW_AMPLITUDE
#define FIFFV_EYETRACK_CH
#define FIFFV_COIL_EYETRACK_POS
#define FIFFV_GALVANIC_CH
#define FIFFV_COIL_FNIRS_OD
#define FIFFV_GOODNESS_FIT_CH
#define FIFFV_COIL_EEG_BIPOLAR
#define FIFFV_COIL_FNIRS_FD_PHASE
#define FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE
#define FIFFV_COIL_EYETRACK_PUPIL
#define FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY
#define FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN
#define FIFFV_DIPOLE_WAVE_CH
#define FIFFV_COIL_EEG_CSD
#define FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE
#define FIFFV_TEMPERATURE_CH
#define FIFFV_COIL_FNIRS_HBR
#define FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE
Minimal measurement-info subset (channel list, sampling rate, basic transforms) shared by FIFF reader...
FIFF file I/O, in-memory data structures and high-level readers/writers.
Per-channel FIFF descriptor: identifiers, kind, calibration, coil type, channel-frame coil position a...
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
128-bit FIFF identifier: hardware machine ID plus creation time, stamped on every file and block.
QList< FiffCoordTrans > all_coord_trans
static Eigen::RowVectorXi pick_channels_regexp(const QStringList &ch_names, const QString ®exp)
static Eigen::RowVectorXi pick_channels(const QStringList &ch_names, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList)
QMap< QString, QList< int > > channel_indices_by_type(const QList< int > &picks={}) const
QString channel_type(qint32 idx) const
FiffInfoBase pick_info(const Eigen::RowVectorXi *sel=nullptr) const
FiffCoordTrans ctf_head_t
QStringList get_channel_types()
Eigen::RowVectorXi pick_types(const QString meg, bool eeg=false, bool stim=false, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList) const
void mne_read_meg_comp_eeg_ch_info(QList< FiffChInfo > &megp, int &nmegp, QList< FiffChInfo > &meg_compp, int &nmeg_compp, QList< FiffChInfo > &eegp, int &neegp, FiffCoordTrans &meg_head_t, FiffId &idp) const
static bool readBadChannelsFromFile(const QString &name, QStringList &listOut)
FiffCoordTrans dev_head_t