MNE-CPP  0.1.9
A Framework for Electrophysiology
label.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "label.h"
42 #include "surface.h"
43 
44 //=============================================================================================================
45 // QT INCLUDES
46 //=============================================================================================================
47 
48 #include <QFile>
49 #include <QTextStream>
50 #include <QStringList>
51 #include <QSet>
52 #include <QRegularExpression>
53 //#include <QDebug>
54 
55 #include <iostream>
56 #include <vector>
57 
58 //=============================================================================================================
59 // USED NAMESPACES
60 //=============================================================================================================
61 
62 using namespace FSLIB;
63 using namespace Eigen;
64 
65 //=============================================================================================================
66 // DEFINE MEMBER METHODS
67 //=============================================================================================================
68 
70 : hemi(-1)
71 , label_id(-1)
72 {
73 }
74 
75 //=============================================================================================================
76 
77 Label::Label(const VectorXi &p_vertices,
78  const MatrixX3f &p_pos,
79  const VectorXd &p_values,
80  qint32 p_hemi,
81  const QString &p_name,
82  qint32 p_id)
83 : vertices(p_vertices)
84 , pos(p_pos)
85 , values(p_values)
86 , hemi(p_hemi)
87 , name(p_name)
88 , label_id(p_id)
89 {
90 }
91 
92 //=============================================================================================================
93 
95 {
96 }
97 
98 //=============================================================================================================
99 
101 {
102  comment = QString("");
103  hemi = -1;
104  name = QString("");
105  vertices = VectorXi();
106  pos = MatrixX3f(0,3);
107  values = VectorXd();
108 
109  label_id = -1;
110 }
111 
112 //=============================================================================================================
113 
114 MatrixX3i Label::selectTris(const Surface & p_Surface)
115 {
116 // //check whether there are data to create the tris
117 // if(this->vertices.size() == 0)
118 // return MatrixX3i(0,3);
119 
120 // MatrixX3i tris(p_Surface.tris().rows(),3);
121 
122 // QSet<int> verts;
123 // verts.reserve(this->vertices.size());
124 // for(qint32 i = 0; i < this->vertices.size(); ++i)
125 // verts.insert(this->vertices[i]);
126 
127 // //
128 // // Search for all the tris where is at least one corner part of the label
129 // //
130 // qint32 t_size = 0;
131 // for(qint32 i = 0; i < p_Surface.tris().rows(); ++i)
132 // {
133 // if(verts.contains(p_Surface.tris()(i,0)) || verts.contains(p_Surface.tris()(i,1)) || verts.contains(p_Surface.tris()(i,2)))
134 // {
135 // tris.row(t_size) = p_Surface.tris().row(i);
136 // ++t_size;
137 // }
138 // }
139 
140 // tris.conservativeResize(t_size, 3);
141 
142  return this->selectTris(p_Surface.tris());//tris;
143 }
144 
145 //=============================================================================================================
146 
147 MatrixX3i Label::selectTris(const MatrixX3i &p_matTris)
148 {
149  //check whether there are data to create the tris
150  if(this->vertices.size() == 0)
151  return MatrixX3i(0,3);
152 
153  MatrixX3i tris(p_matTris.rows(),3);
154 
155  QSet<int> verts;
156  verts.reserve(this->vertices.size());
157  for(qint32 i = 0; i < this->vertices.size(); ++i)
158  verts.insert(this->vertices[i]);
159 
160  //
161  // Search for all the tris where is at least one corner part of the label
162  //
163  qint32 t_size = 0;
164  for(qint32 i = 0; i < p_matTris.rows(); ++i)
165  {
166  if(verts.contains(p_matTris(i,0)) || verts.contains(p_matTris(i,1)) || verts.contains(p_matTris(i,2)))
167  {
168  tris.row(t_size) = p_matTris.row(i);
169  ++t_size;
170  }
171  }
172 
173  tris.conservativeResize(t_size, 3);
174 
175  return tris;
176 }
177 
178 //=============================================================================================================
179 
180 bool Label::read(const QString& p_sFileName, Label &p_Label)
181 {
182  p_Label.clear();
183 
184  if(p_sFileName.mid(p_sFileName.size()-6,6).compare(".label") != 0)
185  {
186  qWarning("Given file (%s) is not a .label file!\n", p_sFileName.toUtf8().constData());
187  return false;
188  }
189 
190  printf("Reading label...");
191  QFile t_File(p_sFileName);
192 
193  if (!t_File.open(QIODevice::ReadOnly | QIODevice::Text))
194  {
195  qWarning("\tError: Couldn't open the label file\n");
196  return false;
197  }
198 
199  QTextStream t_TextStream(&t_File);
200 
201  QString comment = t_TextStream.readLine();
202  qint32 nv = t_TextStream.readLine().toInt();
203 
204  MatrixXd data(nv, 5);
205 
206  QStringList list;
207  qint32 count;
208  bool isNumber;
209  double value;
210  for(qint32 i = 0; i < nv; ++i)
211  {
212  count = 0;
213 
214 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
215  auto skip = QString::SkipEmptyParts;
216 #else
217  auto skip = Qt::SkipEmptyParts;
218 #endif
219 
220  list = t_TextStream.readLine().split(QRegularExpression("\\s+"), skip);
221 
222  for(qint32 j = 0; j < list.size(); ++j)
223  {
224  value = list[j].toDouble(&isNumber);
225  if(isNumber)
226  {
227  data(i, count) = value;
228  ++count;
229  }
230  }
231  }
232 
233  p_Label.comment = comment.mid(1,comment.size()-1);
234  if(t_File.fileName().contains("lh."))
235  p_Label.hemi = 0;
236  else
237  p_Label.hemi = 1;
238 
239  //This structure is not need since we don't mix both hemis
240 // p_Label.vertices.insert(p_Label.hemi, data.cast<int>().block(0,0,data.rows(),1));
241 // p_Label.pos.insert(p_Label.hemi, data.cast<float>().block(0,1,data.rows(),3).array() * 1e-3);
242 // p_Label.values.insert(p_Label.hemi, data.block(0,4,data.rows(),1));
243  p_Label.vertices = data.cast<int>().block(0,0,data.rows(),1);
244  p_Label.pos = data.cast<float>().block(0,1,data.rows(),3).array() * 1e-3f;
245  p_Label.values = data.block(0,4,data.rows(),1);
246 
247  if(t_File.fileName().contains("lh.label"))
248  {
249  QStringList tmpList = t_File.fileName().split("lh.")[0].split(QRegularExpression("\\W+"));
250  p_Label.name = tmpList[tmpList.size()-1];
251  }
252  else if(t_File.fileName().contains("lh."))
253  p_Label.name = t_File.fileName().split("lh.")[1].split(QRegularExpression("\\W+"))[0];
254 
255  printf("[done]\n");
256 
257  t_File.close();
258 
259  return true;
260 }
FSLIB::Label::hemi
qint32 hemi
Definition: label.h:169
FSLIB::Label::clear
void clear()
Definition: label.cpp:100
FSLIB::Label::name
QString name
Definition: label.h:171
FSLIB::Label::Label
Label()
Definition: label.cpp:69
FSLIB::Label::~Label
~Label()
Definition: label.cpp:94
FSLIB::Label::selectTris
Eigen::MatrixX3i selectTris(const Surface &p_Surface)
Definition: label.cpp:114
FSLIB::Label
Freesurfer/MNE label.
Definition: label.h:80
FSLIB::Surface::tris
const Eigen::MatrixX3i & tris() const
Definition: surface.h:329
FSLIB::Label::vertices
Eigen::VectorXi vertices
Definition: label.h:166
FSLIB::Label::label_id
qint32 label_id
Definition: label.h:172
FSLIB::Label::values
Eigen::VectorXd values
Definition: label.h:168
label.h
Label class declaration.
FSLIB::Label::read
static bool read(const QString &p_sFileName, Label &p_Label)
Definition: label.cpp:180
FSLIB::Label::pos
Eigen::MatrixX3f pos
Definition: label.h:167
FSLIB::Label::comment
QString comment
Definition: label.h:165
surface.h
Surface class declaration.
FSLIB::Surface
FreeSurfer surface mesh.
Definition: surface.h:75