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