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_iHemi(-1)
69 {
70 }
71 
72 //=============================================================================================================
73 
74 Annotation::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 
84 Annotation::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 
92 Annotation::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 
101 {
102 }
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 
116 bool 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 
128 bool 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 
140 bool 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 
288 bool 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 }
FSLIB::Colortable::struct_names
QStringList struct_names
Definition: colortable.h:112
FSLIB::Colortable::clear
void clear()
Definition: colortable.cpp:62
FSLIB::Colortable::numEntries
qint32 numEntries
Definition: colortable.h:111
FSLIB::Annotation::clear
void clear()
Definition: annotation.cpp:106
FSLIB::Surface::hemi
qint32 hemi() const
Definition: surface.h:301
FSLIB::Annotation::Annotation
Annotation()
Definition: annotation.cpp:67
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::Label
Freesurfer/MNE label.
Definition: label.h:80
annotation.h
Annotation class declaration.
label.h
Label class declaration.
FSLIB::Annotation::~Annotation
~Annotation()
Definition: annotation.cpp:100
FSLIB::Colortable::getNames
QStringList getNames() const
Definition: colortable.h:131
FSLIB::Annotation::hemi
qint32 hemi() const
Definition: annotation.h:287
surface.h
Surface class declaration.
FSLIB::Colortable::getLabelIds
Eigen::VectorXi getLabelIds() const
Definition: colortable.h:120
FSLIB::Annotation
Free surfer annotation.
Definition: annotation.h:80
FSLIB::Surface
FreeSurfer surface mesh.
Definition: surface.h:75
FSLIB::Colortable::table
Eigen::MatrixXi table
Definition: colortable.h:113
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:288
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:116