v2.0.0
Loading...
Searching...
No Matches
bids_coordinate_system.cpp
Go to the documentation of this file.
1//=============================================================================================================
34
35//=============================================================================================================
36// INCLUDES
37//=============================================================================================================
38
40
41//=============================================================================================================
42// QT INCLUDES
43//=============================================================================================================
44
45#include <QFile>
46#include <QJsonDocument>
47#include <QJsonObject>
48#include <QJsonArray>
49#include <QDebug>
50
51//=============================================================================================================
52// USED NAMESPACES
53//=============================================================================================================
54
55using namespace BIDSLIB;
56
57//=============================================================================================================
58// STATIC METHODS
59//=============================================================================================================
60
62{
64 cs.transform = Eigen::Matrix4d::Identity();
65
66 QFile file(sFilePath);
67 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
68 qWarning() << "[BidsCoordinateSystem::readJson] Cannot open" << sFilePath;
69 return cs;
70 }
71
72 QJsonParseError error;
73 QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
74 file.close();
75
76 if(error.error != QJsonParseError::NoError) {
77 qWarning() << "[BidsCoordinateSystem::readJson] Parse error in" << sFilePath
78 << ":" << error.errorString();
79 return cs;
80 }
81
82 QJsonObject json = doc.object();
83
84 // Try iEEG fields first, fall back to EEG fields
85 cs.system = json.value(QStringLiteral("iEEGCoordinateSystem")).toString();
86 if(cs.system.isEmpty())
87 cs.system = json.value(QStringLiteral("EEGCoordinateSystem")).toString();
88
89 cs.units = json.value(QStringLiteral("iEEGCoordinateUnits")).toString();
90 if(cs.units.isEmpty())
91 cs.units = json.value(QStringLiteral("EEGCoordinateUnits")).toString();
92
93 cs.description = json.value(QStringLiteral("iEEGCoordinateSystemDescription")).toString();
94 if(cs.description.isEmpty())
95 cs.description = json.value(QStringLiteral("EEGCoordinateSystemDescription")).toString();
96
97 cs.processingDescription = json.value(QStringLiteral("iEEGCoordinateProcessingDescription")).toString();
98 if(cs.processingDescription.isEmpty())
99 cs.processingDescription = json.value(QStringLiteral("EEGCoordinateProcessingDescription")).toString();
100
101 cs.associatedImagePath = json.value(QStringLiteral("IntendedFor")).toString();
102
103 // Parse 4x4 transform if provided as "iEEGCoordinateProcessingTransform" or "Transform"
104 QString transformKey;
105 if(json.contains(QStringLiteral("iEEGCoordinateProcessingTransform")))
106 transformKey = QStringLiteral("iEEGCoordinateProcessingTransform");
107 else if(json.contains(QStringLiteral("Transform")))
108 transformKey = QStringLiteral("Transform");
109
110 if(!transformKey.isEmpty()) {
111 QJsonArray rows = json.value(transformKey).toArray();
112 if(rows.size() == 4) {
113 for(int r = 0; r < 4; ++r) {
114 QJsonArray cols = rows[r].toArray();
115 if(cols.size() == 4) {
116 for(int c = 0; c < 4; ++c)
117 cs.transform(r, c) = cols[c].toDouble();
118 }
119 }
120 }
121 }
122
123 return cs;
124}
125
126//=============================================================================================================
127
128bool BidsCoordinateSystem::writeJson(const QString& sFilePath,
129 const BidsCoordinateSystem& cs)
130{
131 QJsonObject json;
132
133 json[QStringLiteral("iEEGCoordinateSystem")] = cs.system;
134 json[QStringLiteral("iEEGCoordinateUnits")] = cs.units;
135
136 if(!cs.description.isEmpty())
137 json[QStringLiteral("iEEGCoordinateSystemDescription")] = cs.description;
138 if(!cs.processingDescription.isEmpty())
139 json[QStringLiteral("iEEGCoordinateProcessingDescription")] = cs.processingDescription;
140 if(!cs.associatedImagePath.isEmpty())
141 json[QStringLiteral("IntendedFor")] = cs.associatedImagePath;
142
143 // Serialize the 4x4 transform matrix
144 if(!cs.transform.isIdentity(1e-15)) {
145 QJsonArray rows;
146 for(int r = 0; r < 4; ++r) {
147 QJsonArray cols;
148 for(int c = 0; c < 4; ++c)
149 cols.append(cs.transform(r, c));
150 rows.append(cols);
151 }
152 json[QStringLiteral("iEEGCoordinateProcessingTransform")] = rows;
153 }
154
155 QFile file(sFilePath);
156 if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
157 qWarning() << "[BidsCoordinateSystem::writeJson] Cannot open" << sFilePath << "for writing";
158 return false;
159 }
160
161 file.write(QJsonDocument(json).toJson(QJsonDocument::Indented));
162 file.close();
163 return true;
164}
165
166//=============================================================================================================
167
169{
170 Eigen::Matrix4f matTrans = transform.cast<float>();
171 return FIFFLIB::FiffCoordTrans(fromFrame, toFrame, matTrans);
172}
BidsCoordinateSystem struct — iEEG coordinate system from *_coordsystem.json.
BIDS dataset reading, writing, path construction, and sidecar metadata handling for iEEG/EEG/MEG.
Coordinate system metadata from *_coordsystem.json.
static bool writeJson(const QString &sFilePath, const BidsCoordinateSystem &cs)
Write a BIDS *_coordsystem.json file.
static BidsCoordinateSystem readJson(const QString &sFilePath)
Read a BIDS *_coordsystem.json file.
FIFFLIB::FiffCoordTrans toFiffCoordTrans(int fromFrame=FIFFV_COORD_MRI, int toFrame=FIFFV_COORD_HEAD) const
Convert parsed transform to a FiffCoordTrans.
Coordinate transformation description.