34static const QString NA = QStringLiteral(
"n/a");
36QString naToEmpty(
const QString& s)
38 return (s == NA) ? QString() : s;
51 QList<BidsElectrode> electrodes;
52 electrodes.reserve(rawRows.size());
54 for(
const auto& row : rawRows) {
56 elec.
name = row.value(QStringLiteral(
"name"));
57 elec.
x = row.value(QStringLiteral(
"x"), NA);
58 elec.
y = row.value(QStringLiteral(
"y"), NA);
59 elec.
z = row.value(QStringLiteral(
"z"), NA);
60 elec.
size = naToEmpty(row.value(QStringLiteral(
"size")));
61 elec.
type = naToEmpty(row.value(QStringLiteral(
"type")));
62 elec.
material = naToEmpty(row.value(QStringLiteral(
"material")));
63 elec.
impedance = naToEmpty(row.value(QStringLiteral(
"impedance")));
64 electrodes.append(elec);
73 const QList<BidsElectrode>& electrodes)
75 QStringList headers = {
76 QStringLiteral(
"name"),
80 QStringLiteral(
"size"),
81 QStringLiteral(
"type"),
82 QStringLiteral(
"material"),
83 QStringLiteral(
"impedance"),
86 QList<BidsTsvRow> rows;
87 rows.reserve(electrodes.size());
89 for(
const auto& elec : electrodes) {
91 row[QStringLiteral(
"name")] = elec.name;
92 row[QStringLiteral(
"x")] = elec.x;
93 row[QStringLiteral(
"y")] = elec.y;
94 row[QStringLiteral(
"z")] = elec.z;
95 row[QStringLiteral(
"size")] = elec.size;
96 row[QStringLiteral(
"type")] = elec.type;
97 row[QStringLiteral(
"material")] = elec.material;
98 row[QStringLiteral(
"impedance")] = elec.impedance;
108 const QList<BidsElectrode>& electrodes,
116 const bool hasTransform = (trans.
from != 0 || trans.
to != 0);
120 bool xOk =
false, yOk =
false, zOk =
false;
121 float xVal = elec.x.toFloat(&xOk);
122 float yVal = elec.y.toFloat(&yOk);
123 float zVal = elec.z.toFloat(&zOk);
125 if (!xOk || !yOk || !zOk) {
131 point.
ident = ident++;
138 Eigen::Vector3f pos(point.
r[0], point.
r[1], point.
r[2]);
139 Eigen::Vector3f transformed = (trans.
trans.block<3,3>(0,0).cast<
float>() * pos
140 + trans.
trans.block<3,1>(0,3).cast<
float>());
141 point.
r[0] = transformed(0);
142 point.
r[1] = transformed(1);
143 point.
r[2] = transformed(2);
Generic tab-separated-value reader/writer for BIDS sidecars (UTF-8, LF, n/a for missing values,...
Reader/writer for the BIDS _electrodes.tsv sidecar plus a bridge into FIFF digitizer-point space.
BIDS dataset reading, writing, path construction, and sidecar metadata handling for iEEG/EEG/MEG.
QMap< QString, QString > BidsTsvRow
FIFF file I/O, in-memory data structures and high-level readers/writers.
Electrode position record corresponding to one row in *_electrodes.tsv.
static bool writeTsv(const QString &sFilePath, const QList< BidsElectrode > &electrodes)
Write a BIDS *_electrodes.tsv file.
static QList< BidsElectrode > readTsv(const QString &sFilePath)
Read a BIDS *_electrodes.tsv file.
static FIFFLIB::FiffDigPointSet toFiffDigPoints(const QList< BidsElectrode > &electrodes, const FIFFLIB::FiffCoordTrans &trans=FIFFLIB::FiffCoordTrans())
Convert a list of BIDS electrodes to a FIFF digitizer point set.
static QList< BidsTsvRow > readTsv(const QString &sFilePath, QStringList &headers)
static bool writeTsv(const QString &sFilePath, const QStringList &headers, const QList< BidsTsvRow > &rows)
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > trans
One digitizer point: kind (cardinal/HPI/EEG/extra), ident, 3D position in FIFFV_COORD_HEAD.
Collection of FiffDigPoint records as parsed from a FIFFB_ISOTRAK block.