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