MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
annotation.cpp
Go to the documentation of this file.
1//=============================================================================================================
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "annotation.h"
42#include "label.h"
43#include "surface.h"
44
45#include <iostream>
46
47//=============================================================================================================
48// QT INCLUDES
49//=============================================================================================================
50
51#include <QDebug>
52#include <QFile>
53#include <QDataStream>
54#include <QFileInfo>
55
56//=============================================================================================================
57// USED NAMESPACES
58//=============================================================================================================
59
60using namespace FSLIB;
61using namespace Eigen;
62
63//=============================================================================================================
64// DEFINE MEMBER METHODS
65//=============================================================================================================
66
68: m_iHemi(-1)
69{
70}
71
72//=============================================================================================================
73
74Annotation::Annotation(const QString& p_sFileName)
75: m_sFileName(p_sFileName)
76{
77 Annotation t_Annotation;
78 Annotation::read(m_sFileName, t_Annotation);
79 *this = t_Annotation;
80}
81
82//=============================================================================================================
83
84Annotation::Annotation(const QString &subject_id, qint32 hemi, const QString &atlas, const QString &subjects_dir)
85: m_iHemi(-1)
86{
87 Annotation::read(subject_id, hemi, atlas, subjects_dir, *this);
88}
89
90//=============================================================================================================
91
92Annotation::Annotation(const QString &path, qint32 hemi, const QString &atlas)
93: m_iHemi(-1)
94{
95 Annotation::read(path, hemi, atlas, *this);
96}
97
98//=============================================================================================================
99
103
104//=============================================================================================================
105
107{
108 m_sFileName = QString("");
109 m_Vertices = VectorXi::Zero(0);
110 m_LabelIds = VectorXi::Zero(0);
111 m_Colortable.clear();
112}
113
114//=============================================================================================================
115
116bool Annotation::read(const QString &subject_id, qint32 hemi, const QString &atlas, const QString &subjects_dir, Annotation &p_Annotation)
117{
118 if(hemi != 0 && hemi != 1)
119 return false;
120
121 QString p_sFile = QString("%1/%2/label/%3.%4.annot").arg(subjects_dir).arg(subject_id).arg(hemi == 0 ? "lh" : "rh").arg(atlas);
122
123 return read(p_sFile, p_Annotation);
124}
125
126//=============================================================================================================
127
128bool Annotation::read(const QString &path, qint32 hemi, const QString &atlas, Annotation &p_Annotation)
129{
130 if(hemi != 0 && hemi != 1)
131 return false;
132
133 QString p_sFile = QString("%1/%2.%3.annot").arg(path).arg(hemi == 0 ? "lh" : "rh").arg(atlas);
134
135 return read(p_sFile, p_Annotation);
136}
137
138//=============================================================================================================
139
140bool Annotation::read(const QString& p_sFileName, Annotation &p_Annotation)
141{
142 p_Annotation.clear();
143
144 printf("Reading annotation...\n");
145 QFile t_File(p_sFileName);
146 QFileInfo fileInfo(t_File.fileName());
147
148 p_Annotation.m_sFileName = fileInfo.fileName();
149 p_Annotation.m_sFilePath = fileInfo.filePath();
150
151 if (!t_File.open(QIODevice::ReadOnly))
152 {
153 printf("\tError: Couldn't open the file\n");
154 return false;
155 }
156
157 QDataStream t_Stream(&t_File);
158 t_Stream.setByteOrder(QDataStream::BigEndian);
159
160 qint32 numEl;
161 t_Stream >> numEl;
162
163 p_Annotation.m_Vertices = VectorXi(numEl);
164 p_Annotation.m_LabelIds = VectorXi(numEl);
165
166 for(qint32 i = 0; i < numEl; ++i)
167 {
168 t_Stream >> p_Annotation.m_Vertices[i];
169 t_Stream >> p_Annotation.m_LabelIds[i];
170 }
171
172 qint32 hasColortable;
173 t_Stream >> hasColortable;
174 if (hasColortable)
175 {
176 p_Annotation.m_Colortable.clear();
177
178 //Read colortable
179 qint32 numEntries;
180 t_Stream >> numEntries;
181 qint32 len;
182 if(numEntries > 0)
183 {
184
185 printf("\tReading from Original Version\n");
186 p_Annotation.m_Colortable.numEntries = numEntries;
187 t_Stream >> len;
188 QByteArray tmp;
189 tmp.resize(len);
190 t_Stream.readRawData(tmp.data(),len);
191 p_Annotation.m_Colortable.orig_tab = tmp;
192
193 for(qint32 i = 0; i < numEntries; ++i)
194 p_Annotation.m_Colortable.struct_names.append("");
195
196 p_Annotation.m_Colortable.table = MatrixXi(numEntries,5);
197
198 for(qint32 i = 0; i < numEntries; ++i)
199 {
200 t_Stream >> len;
201 tmp.resize(len);
202 t_Stream.readRawData(tmp.data(),len);
203
204 p_Annotation.m_Colortable.struct_names[i]= tmp;
205
206 for(qint32 j = 0; j < 4; ++j)
207 t_Stream >> p_Annotation.m_Colortable.table(i,j);
208
209 p_Annotation.m_Colortable.table(i,4) = p_Annotation.m_Colortable.table(i,0)
210 + p_Annotation.m_Colortable.table(i,1) * 256 //(2^8)
211 + p_Annotation.m_Colortable.table(i,2) * 65536 //(2^16)
212 + p_Annotation.m_Colortable.table(i,3) * 16777216; //(2^24);
213 }
214 }
215 else
216 {
217 qint32 version = -numEntries;
218 if(version != 2)
219 printf("\tError! Does not handle version %d\n", version);
220 else
221 printf("\tReading from version %d\n", version);
222
223 t_Stream >> numEntries;
224 p_Annotation.m_Colortable.numEntries = numEntries;
225
226 t_Stream >> len;
227 QByteArray tmp;
228 tmp.resize(len);
229 t_Stream.readRawData(tmp.data(),len);
230 p_Annotation.m_Colortable.orig_tab = tmp;
231
232 for(qint32 i = 0; i < numEntries; ++i)
233 p_Annotation.m_Colortable.struct_names.append("");
234
235 p_Annotation.m_Colortable.table = MatrixXi(numEntries,5);
236
237 qint32 numEntriesToRead;
238 t_Stream >> numEntriesToRead;
239
240 qint32 structure;
241 for(qint32 i = 0; i < numEntriesToRead; ++i)
242 {
243
244 t_Stream >> structure;
245 if (structure < 0)
246 printf("\tError! Read entry, index %d\n", structure);
247
248 if(!p_Annotation.m_Colortable.struct_names[structure].isEmpty())
249 printf("Error! Duplicate Structure %d", structure);
250
251 t_Stream >> len;
252 tmp.resize(len);
253 t_Stream.readRawData(tmp.data(),len);
254
255 p_Annotation.m_Colortable.struct_names[structure]= tmp;
256
257 for(qint32 j = 0; j < 4; ++j)
258 t_Stream >> p_Annotation.m_Colortable.table(structure,j);
259
260 p_Annotation.m_Colortable.table(structure,4) = p_Annotation.m_Colortable.table(structure,0)
261 + p_Annotation.m_Colortable.table(structure,1) * 256 //(2^8)
262 + p_Annotation.m_Colortable.table(structure,2) * 65536 //(2^16)
263 + p_Annotation.m_Colortable.table(structure,3) * 16777216; //(2^24);
264 }
265 }
266 printf("\tcolortable with %d entries read\n\t(originally %s)\n", p_Annotation.m_Colortable.numEntries, p_Annotation.m_Colortable.orig_tab.toUtf8().constData());
267 }
268 else
269 {
270 printf("\tError! No colortable stored\n");
271 }
272
273 // hemi info
274 if(t_File.fileName().contains("lh."))
275 p_Annotation.m_iHemi = 0;
276 else
277 p_Annotation.m_iHemi = 1;
278
279 printf("[done]\n");
280
281 t_File.close();
282
283 return true;
284}
285
286//=============================================================================================================
287
288bool Annotation::toLabels(const Surface &p_surf,
289 QList<Label> &p_qListLabels,
290 QList<RowVector4i> &p_qListLabelRGBAs,
291 const QStringList& lLabelPicks) const
292{
293 if(this->m_iHemi != p_surf.hemi())
294 {
295 qWarning("Annotation and surface hemisphere (annot = %d; surf = %d) do not match!\n", this->m_iHemi, p_surf.hemi());
296 return false;
297 }
298
299 if(m_LabelIds.size() == 0)
300 {
301 qWarning("Annotation doesn't' contain data!\n");
302 return false;
303 }
304
305 printf("Converting labels from annotation...");
306
307//n_read = 0
308//labels = list()
309//label_colors = list()
310
311 VectorXi label_ids = m_Colortable.getLabelIds();
312 QStringList label_names = m_Colortable.getNames();
313 MatrixX4i label_rgbas = m_Colortable.getRGBAs();
314
315 // load the vertex positions from surface
316 MatrixX3f vert_pos = p_surf.rr();
317
318// qDebug() << label_rgbas.rows() << label_ids.size() << label_names.size();
319
320// std::cout << label_ids;
321
322 qint32 label_id, count;
323 RowVector4i label_rgba;
324 VectorXi vertices;
325 VectorXd values;
326 MatrixX3f pos;
327 QString name;
328 for(qint32 i = 0; i < label_rgbas.rows(); ++i)
329 {
330 label_id = label_ids[i];
331 label_rgba = label_rgbas.row(i);
332 count = 0;
333 vertices.resize(m_LabelIds.size());
334 //Where
335 for(qint32 j = 0; j < m_LabelIds.size(); ++j)
336 {
337 if(m_LabelIds[j] == label_id)
338 {
339 vertices[count] = j;
340 ++count;
341 }
342 }
343 // check if label is part of cortical surface
344 if(count == 0)
345 continue;
346 vertices.conservativeResize(count);
347
348 pos.resize(count, 3);
349 for(qint32 j = 0; j < count; ++j)
350 pos.row(j) = vert_pos.row(vertices[j]);
351
352 values = VectorXd::Zero(count);
353 name = QString("%1-%2").arg(label_names[i]).arg(this->m_iHemi == 0 ? "lh" : "rh");
354
355 // put it all together
356 if(lLabelPicks.isEmpty()) {
357 //t_tris
358 p_qListLabels.append(Label(vertices, pos, values, this->m_iHemi, name, label_id));
359 // store the color
360 p_qListLabelRGBAs.append(label_rgba);
361 } else if (lLabelPicks.indexOf(name) != -1) {
362 //t_tris
363 p_qListLabels.append(Label(vertices, pos, values, this->m_iHemi, name, label_id));
364 // store the color
365 p_qListLabelRGBAs.append(label_rgba);
366 }
367 }
368
369// for label_id, label_name, label_rgba in
370// zip(label_ids, label_names, label_rgbas):
371// vertices = np.where(annot == label_id)[0]
372// if len(vertices) == 0:
373// # label is not part of cortical surface
374// continue
375// pos = vert_pos[vertices, :]
376// values = np.zeros(len(vertices))
377// name = label_name + '-' + hemi
378// label = Label(vertices, pos, values, hemi, name=name)
379// labels.append(label)
380
381// # store the color
382// label_rgba = tuple(label_rgba / 255.)
383// label_colors.append(label_rgba)
384
385// n_read = len(labels) - n_read
386// logger.info(' read %d labels from %s' % (n_read, fname))
387
388//# sort the labels and colors by label name
389//names = [label.name for label in labels]
390//labels, label_colors = zip(*((label, color) for (name, label, color)
391// in sorted(zip(names, labels, label_colors))))
392//# convert tuples to lists
393//labels = list(labels)
394//label_colors = list(label_colors)
395
396 printf("[done]\n");
397
398 return true;
399}
Label class declaration.
Annotation class declaration.
Surface class declaration.
Free surfer annotation.
Definition annotation.h:81
bool toLabels(const Surface &p_surf, QList< Label > &p_qListLabels, QList< Eigen::RowVector4i > &p_qListLabelRGBAs, const QStringList &lLabelPicks=QStringList()) const
static bool read(const QString &subject_id, qint32 hemi, const QString &atlas, const QString &subjects_dir, Annotation &p_Annotation)
qint32 hemi() const
Definition annotation.h:287
Eigen::MatrixX4i getRGBAs() const
Definition colortable.h:138
QStringList getNames() const
Definition colortable.h:131
Eigen::VectorXi getLabelIds() const
Definition colortable.h:120
QStringList struct_names
Definition colortable.h:112
Eigen::MatrixXi table
Definition colortable.h:113
Freesurfer/MNE label.
Definition label.h:81
FreeSurfer surface mesh.
Definition surface.h:76
const Eigen::MatrixX3f & rr() const
Definition surface.h:322
qint32 hemi() const
Definition surface.h:301