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 static const QStringList dataTypes{
"mag",
"grad",
"ref_meg",
"eeg",
"csd",
"seeg",
"ecog",
"dbs",
"hbo",
"hbr"};
143 for (
int i = 0; i <
chs.size(); ++i) {
144 const QString type = channelTypeName(
chs[i]);
145 if ((dataTypes.contains(type) || type.startsWith(QLatin1String(
"fnirs_"))) && !exclude.contains(
chs[i].ch_name))
148 return Map<const RowVectorXi>(picks.data(), picks.size());
155 const QRegularExpression re(QRegularExpression::anchoredPattern(regexp + QStringLiteral(
".*")),
156 QRegularExpression::DotMatchesEverythingOption);
158 for (
int k = 0; k <
ch_names.size(); ++k) {
159 if (re.match(
ch_names[k]).hasMatch())
162 return Eigen::Map<const RowVectorXi>(sel.constData(), sel.size());
182RowVectorXi
FiffInfoBase::pick_types(
const QString meg,
bool eeg,
bool stim,
const QStringList& include,
const QStringList& exclude)
const
185 const qint32 nchPresent =
static_cast<qint32
>(this->
chs.size());
186 RowVectorXi pick = RowVectorXi::Zero(nchPresent);
190 for (k = 0; k < nchPresent; ++k) {
191 kind = this->
chs[k].kind;
194 if (meg.compare(
"all") == 0) {
196 }
else if (meg.compare(
"grad") == 0 && this->chs[k].unit ==
FIFF_UNIT_T_M) {
198 }
else if (meg.compare(
"mag") == 0 && this->chs[k].unit ==
FIFF_UNIT_T) {
209 QStringList myinclude;
210 for (k = 0; k < nchPresent; ++k) {
217 if (include.size() > 0) {
218 for (k = 0; k < include.size(); ++k) {
219 myinclude << include[k];
236 return this->
pick_types(QString(
"all"), eeg, stim, include, exclude);
238 return this->
pick_types(QString(
""), eeg, stim, include, exclude);
245 RowVectorXi sel = RowVectorXi::Zero(
ch_names.size());
247 QStringList t_includedSelection;
250 for (qint32 k = 0; k <
ch_names.size(); ++k) {
251 if ((include.size() == 0 || include.contains(
ch_names[k])) && !exclude.contains(
ch_names[k])) {
253 if (!t_includedSelection.contains(
ch_names[k])) {
260 sel.conservativeResize(count);
277 for (qint32 i = 0; i < sel->size(); ++i) {
279 res.
chs.append(this->
chs[idx]);
282 res.
nchan = sel->size();
283 res.
bads.removeIf([&res](
const QString& bad) {
return !res.
ch_names.contains(bad); });
291 QList<FiffChInfo>& meg_compp,
293 QList<FiffChInfo>& eegp,
298 for (
int k = 0; k <
nchan; k++) {
303 meg_compp.append(
chs[k]);
318 QStringList lChannelTypes;
320 const QString type = channelTypeName(ch);
321 if (!type.isEmpty() && !lChannelTypes.contains(type))
322 lChannelTypes << type;
324 return lChannelTypes;
331 if (name.isEmpty()) {
337 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
338 qCritical() <<
"Cannot open bad channel file:" << name;
343 QTextStream in(&file);
344 while (!in.atEnd()) {
345 QString line = in.readLine().trimmed();
346 if (line.isEmpty() || line.startsWith(
'#'))
351 if (file.error() != QFileDevice::NoError) {
352 qCritical() <<
"Error reading bad channel file:" << name;
constexpr auto FIFF_UNIT_T_M
constexpr auto FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE
constexpr auto FIFFV_ECG_CH
constexpr auto FIFFV_EXCI_CH
constexpr auto FIFFV_SYST_CH
constexpr auto FIFFV_GOODNESS_FIT_CH
constexpr auto FIFFV_COIL_EYETRACK_POS
constexpr auto FIFFV_DBS_CH
constexpr auto FIFFV_IAS_CH
constexpr auto FIFFV_COIL_FNIRS_OD
constexpr auto FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN
constexpr auto FIFFV_COIL_FNIRS_CW_AMPLITUDE
constexpr auto FIFFV_COIL_EEG_CSD
constexpr auto FIFFV_COIL_EEG
constexpr auto FIFFV_MISC_CH
constexpr auto FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE
constexpr auto FIFFV_SEEG_CH
constexpr auto FIFFV_COIL_FNIRS_HBR
constexpr auto FIFFV_COIL_EEG_BIPOLAR
constexpr auto FIFFV_GALVANIC_CH
constexpr auto FIFFV_ECOG_CH
constexpr auto FIFFV_COIL_NONE
constexpr auto FIFFV_STIM_CH
constexpr auto FIFFV_EYETRACK_CH
constexpr auto FIFFV_BIO_CH
constexpr auto FIFF_UNIT_T
constexpr auto FIFFV_DIPOLE_WAVE_CH
constexpr auto FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE
constexpr auto FIFFV_COIL_FNIRS_FD_PHASE
constexpr auto FIFFV_EMG_CH
constexpr auto FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY
constexpr auto FIFFV_TEMPERATURE_CH
constexpr auto FIFFV_FNIRS_CH
constexpr auto FIFFV_COIL_FNIRS_HBO
constexpr auto FIFFV_EOG_CH
constexpr auto FIFFV_COIL_EYETRACK_PUPIL
constexpr auto FIFFV_REF_MEG_CH
constexpr auto FIFFV_RESP_CH
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)
Eigen::RowVectorXi pick_data_channels(const QStringList &exclude=defaultQStringList) const
FiffCoordTrans dev_head_t