MNE-CPP  beta 1.0
stcdatamodel.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "stcdatamodel.h"
42 #include <mne/mne_sourceestimate.h>
43 
44 
45 //*************************************************************************************************************
46 //=============================================================================================================
47 // Qt INCLUDES
48 //=============================================================================================================
49 
50 #include <QDebug>
51 #include <QColor>
52 
53 
54 //*************************************************************************************************************
55 //=============================================================================================================
56 // USED NAMESPACES
57 //=============================================================================================================
58 
59 using namespace DISP3DNEWLIB;
60 using namespace MNELIB;
61 
62 
63 //*************************************************************************************************************
64 //=============================================================================================================
65 // DEFINE MEMBER METHODS
66 //=============================================================================================================
67 
68 StcDataModel::StcDataModel(QObject *parent)
69 : QAbstractTableModel(parent)
70 , m_pWorker(new StcDataWorker)
71 , m_bRTMode(true)
72 , m_bModelInit(false)
73 , m_bDataInit(false)
74 , m_bIntervallSet(false)
75 , m_dStcNormMax(10.0)
76 , m_dStcNorm(1)
77 {
78  qRegisterMetaType<MatrixXd>("MatrixXd");
79  qRegisterMetaType<VectorXd>("VectorXd");
80  qRegisterMetaType<Matrix3Xf>("Matrix3Xf");
81 
82  connect(m_pWorker.data(), &StcDataWorker::stcSample, this, &StcDataModel::setStcSample);
83 
84 // m_pWorker->setLoop(true);
85 
86 }
87 
88 
89 //*************************************************************************************************************
90 
91 StcDataModel::~StcDataModel()
92 {
93 }
94 
95 
96 //*************************************************************************************************************
97 //virtual functions
98 int StcDataModel::rowCount(const QModelIndex & /*parent*/) const
99 {
100  if(m_vecCurStc.rows() != 0)
101  return m_vecCurStc.rows();
102  else
103  return 0;
104 }
105 
106 
107 //*************************************************************************************************************
108 
109 int StcDataModel::columnCount(const QModelIndex & /*parent*/) const
110 {
111  return 7;
112 }
113 
114 
115 //*************************************************************************************************************
116 
117 QVariant StcDataModel::data(const QModelIndex &index, int role) const
118 {
119 // if(role != Qt::DisplayRole && role != Qt::BackgroundRole)
120 // return QVariant();
121 
122  if (index.isValid()) {
123  qint32 row = index.row();
124 
125  switch(index.column()) {
126  case 0: { // index
127  if(role == Qt::DisplayRole)
128  return QVariant(row);
129  break;
130  }
131  case 1: { // vertex index
132 // std::cout<<"StcDataModel::data() - LH - vertno.rows(): "<<m_forwardSolution.src[0].vertno.rows()<<std::endl;
133 // std::cout<<"StcDataModel::data() - RH - vertno.rows(): "<<m_forwardSolution.src[1].vertno.rows()<<std::endl;
134 
135  if(m_bDataInit && role == StcDataModelRoles::GetIndexLH)
136  return QVariant(m_forwardSolution.src[0].vertno(row));
137  //return QVariant(m_qListLabels[row].label_id);//m_vertLabelIds(row));
138 
139  if(m_bDataInit && role == StcDataModelRoles::GetIndexRH)
140  return QVariant(m_forwardSolution.src[1].vertno(row));
141 
142  break;
143  }
144  case 2: // stc data
145  {
146  int numDipolesLH = m_forwardSolution.src[0].vertno.rows();
147  int numDipolesRH = m_forwardSolution.src[1].vertno.rows();
148 
149  //std::cout<<"StcDataModel::data() - numDipolesLH: "<<numDipolesLH<<std::endl;
150  //std::cout<<"StcDataModel::data() - numDipolesRH: "<<numDipolesRH<<std::endl;
151 
152  QVariant v;
153  if(m_bDataInit && role == StcDataModelRoles::GetStcValLH) {
154  VectorXd valVec(numDipolesLH);
155 
156  for(qint32 i = 0; i < valVec.rows(); ++i)
157  valVec(i) = m_vecCurStc(i);
158 
159  v.setValue(valVec);
160  }
161 
162  if(m_bDataInit && role == StcDataModelRoles::GetStcValRH) {
163  VectorXd valVec(numDipolesRH);
164 
165  for(qint32 i = numDipolesLH; i < numDipolesLH+numDipolesRH; ++i)
166  valVec(i-numDipolesLH) = m_vecCurStc(i);
167 
168  v.setValue(valVec);
169  }
170 
171  return v;
172  }
173 
174  case 4: // smoothed stc data
175  {
176  QVariant v;
177  if(m_bDataInit && role == StcDataModelRoles::GetSmoothedStcValLH) {
178  v.setValue(smoothEstimates(1, 0));
179  }
180 
181  if(m_bDataInit && role == StcDataModelRoles::GetSmoothedStcValRH) {
182  v.setValue(smoothEstimates(1, 1));
183  }
184 
185  return v;
186 
187  break;
188  }
189 
190  case 5: { // Label
191  if(role == Qt::DisplayRole)
192  {
193  QVariant v;
194  v.setValue(m_qListLabels[row]);
195  return v;
196  }
197  break;
198  }
199 
200  case 6: { // Color
201  if(role == Qt::DisplayRole)
202  return QVariant(QColor(m_qListRGBAs[row](0),m_qListRGBAs[row](1),m_qListRGBAs[row](2),255));
203  break;
204  }
205  case 7: { // Tri RRs
206  if(role == Qt::DisplayRole)
207  {
208  QVariant v;
209  v.setValue(m_qListTriRRs[row]);
210  return v;
211  }
212  break;
213  }
214  }
215  } // end index.valid() check
216 
217  return QVariant();
218 }
219 
220 
221 //*************************************************************************************************************
222 
223 QVariant StcDataModel::headerData(int section, Qt::Orientation orientation, int role) const
224 {
225  if(role != Qt::DisplayRole)// && role != Qt::TextAlignmentRole)
226  return QVariant();
227 
228  if(orientation == Qt::Horizontal) {
229  switch(section) {
230  case 0: //index column
231  return QVariant("Index");
232  case 1: //vertex column
233  return QVariant("Vertex/Label ID");
234  case 2: //stc data column
235  return QVariant("STC");
236  case 3: //realtive stc data column
237  return QVariant("Relative STC");
238  case 4: //smoothed stc data column
239  return QVariant("Smoothed STC");
240  case 5: //roi name column
241  return QVariant("Label");
242  case 6: //roi color column
243  return QVariant("Color");
244  case 7: //roi Tri Coords
245  return QVariant("Tri Coords");
246  }
247  }
248  else if(orientation == Qt::Vertical) {
249  QModelIndex mdlIdx = createIndex(section,0);
250  switch(role) {
251  case Qt::DisplayRole:
252  return QVariant(data(mdlIdx).toString());
253  }
254  }
255 
256  return QVariant();
257 }
258 
259 
260 //*************************************************************************************************************
261 
262 void StcDataModel::addData(const MNESourceEstimate &stc)
263 {
264  //std::cout<<"START - StcDataModel::addData()"<<std::endl;
265 
266  if(!m_bModelInit || stc.isEmpty()) {
267  std::cout<<"stc is empty or model was not correctly initialized"<<std::endl;
268  return;
269  }
270 
271  if(m_vertLabelIds.size() != stc.data.rows())
272  {
273  //TODO MAP data 416 to labels 150!!!!!!!!
274  //ToDo Map the indices to the regions
275  setVertLabelIDs(stc.vertices);
276  }
277 
278  QList<VectorXd> data;
279  for(qint32 i = 0; i < stc.data.cols(); ++i)
280  data.append(stc.data.col(i));
281 
282  m_pWorker->addData(data);
283 
284  m_bDataInit = true;
285 
286  //std::cout<<"END - StcDataModel::addData()"<<std::endl;
287 }
288 
289 
290 //*************************************************************************************************************
291 
292 void StcDataModel::init(const QString &subject_id, qint32 hemi, const QString &surf, const QString &subjects_dir, const QString &atlas, const MNEForwardSolution &forwardSolution)
293 {
294  beginResetModel();
295  m_forwardSolution = forwardSolution;
296 
297  m_bModelInit = true;
298 
299  endResetModel();
300 
301  //start the worker
302  m_pWorker->start();
303 }
304 
305 
306 //*************************************************************************************************************
307 
308 void StcDataModel::setAverage(qint32 samples)
309 {
310  m_pWorker->setAverage(samples);
311 }
312 
313 
314 //*************************************************************************************************************
315 
316 void StcDataModel::setLoop(bool looping)
317 {
318  m_pWorker->setLoop(looping);
319 }
320 
321 
322 //*************************************************************************************************************
323 
324 void StcDataModel::setNormalization(qint32 fraction)
325 {
326  m_dStcNorm = (m_dStcNormMax/100.0) * (double)fraction;
327 }
328 
329 
330 //*************************************************************************************************************
331 
332 void StcDataModel::setStcSample(const VectorXd &sample)
333 {
334  //std::cout<<"StcDataModel::setStcSample()"<<std::endl;
335  m_vecCurStc = sample;
336 
337  m_vecCurRelStc = sample/m_dStcNorm;
338 
339  //std::cout<<"StcDataModel::setStcSample() - m_vecCurStc.rows(): "<<m_vecCurStc.rows()<<std::endl;
340  //std::cout<<"StcDataModel::setStcSample() - m_vecCurRelStc.rows(): "<<m_vecCurRelStc.rows()<<std::endl;
341 
342  //Update data content -> Bug in QTableView which updates the whole table http://qt-project.org/forums/viewthread/14723
343  QModelIndex topLeft = this->index(0,2);
344  QModelIndex bottomRight = this->index(this->rowCount()-1,3);
345  QVector<int> roles; roles << Qt::DisplayRole;
346  emit dataChanged(topLeft, bottomRight, roles);
347 }
348 
349 
350 //*************************************************************************************************************
351 
352 void StcDataModel::setVertLabelIDs(const VectorXi &vertLabelIDs)
353 {
354  QMap<qint32, qint32> t_qMapLabelIdChannel;
355  for(qint32 i = 0; i < vertLabelIDs.size(); ++i)
356  t_qMapLabelIdChannel.insertMulti(vertLabelIDs(i),i);
357 
358  QList<qint32> qListLastIdcs = t_qMapLabelIdChannel.values(vertLabelIDs(vertLabelIDs.size() - 1));
359 
360  qint32 lhIdx = 0;
361  qint32 maxIdx = qListLastIdcs[0];
362  qint32 minIdx = qListLastIdcs[0];
363 
364  for(qint32 i = 0; i < qListLastIdcs.size(); ++i)
365  {
366  if(maxIdx < qListLastIdcs[i])
367  maxIdx = qListLastIdcs[i];
368  if(minIdx > qListLastIdcs[i])
369  minIdx = qListLastIdcs[i];
370  }
371 
372  qint32 upperBound = maxIdx - (maxIdx*0.25);
373  for(qint32 i = 0; i < qListLastIdcs.size(); ++i)
374  {
375  if(lhIdx < qListLastIdcs[i] && qListLastIdcs[i] < upperBound)
376  lhIdx = qListLastIdcs[i];
377  }
378 
379  m_qMapLabelIdChannelLH.clear();
380  m_qMapLabelIdChannelRH.clear();
381 
382  QMap<qint32, qint32>::iterator it;
383  for (it = t_qMapLabelIdChannel.begin(); it != t_qMapLabelIdChannel.end(); ++it)
384  {
385  if(it.value() <= lhIdx)
386  m_qMapLabelIdChannelLH.insertMulti(it.key(),it.value());
387  else
388  m_qMapLabelIdChannelRH.insertMulti(it.key(),it.value());
389  }
390 
391  m_vertLabelIds = vertLabelIDs;
392 }
393 
394 
395 //*************************************************************************************************************
396 
397 VectorXd StcDataModel::smoothEstimates(int niter, int hemi) const
398 {
399  std::cout<<"START - StcDataModel::smoothEstimates()"<<std::endl;
400 
401  //smooth data for both hemispheres
402  MNEHemisphere sp = m_forwardSolution.src[hemi];
403  VectorXi vertno = sp.vertno;
404  int nvert = sp.vertno.rows();
405 
406  VectorXi undef = VectorXi::Ones(sp.np);
407  VectorXi prev_undef(sp.np);
408  VectorXd prev_val(sp.np);
409 
410  VectorXd vecCurSmoothedStc = VectorXd::Zero(sp.np);
411 
412  int n,k,p,it,nv;
413  float sum;
414 
415  if(hemi == 0) {
416  for (k = 0; k < nvert; k++) {
417  undef[vertno[k]] = 0;
418  vecCurSmoothedStc[vertno[k]] = m_vecCurRelStc[k];
419  }
420  }
421  else {
422  for (k = 0 ; k < nvert; k++) {
423  undef[vertno[k]] = 0;
424  vecCurSmoothedStc[vertno[k]] = m_vecCurRelStc[m_forwardSolution.src[0].nuse+k];
425  }
426  }
427 
428  for (it = 0; it < niter; it++) {
429  prev_undef = undef;
430  prev_val = vecCurSmoothedStc;
431 
432  for (k = 0; k < sp.np; k++) {
433  sum = 0;
434  n = 0;
435 
436  if (prev_undef[k] == 1) {
437  sum = vecCurSmoothedStc[k];
438  n = 1;
439  }
440 
441  for (p = 0; p < sp.neighbor_vert[k].size(); p++) {
442  nv = sp.neighbor_vert[k][p];
443 
444  if (prev_undef[nv] == 0) {
445  sum += prev_val[nv];
446  n++;
447  }
448  }
449 
450  if (n > 0) {
451  vecCurSmoothedStc[k] = sum/n;
452  undef[k] = 0;
453  }
454  }
455  }
456 
457  std::cout<<"END - StcDataModel::smoothEstimates()"<<std::endl;
458 
459  return vecCurSmoothedStc;
460 }
QVariant data(int row, int column, int role=Qt::DisplayRole) const
Definition: stcdatamodel.h:218
StcDataModel class declaration.
QMap< int, QVector< int > > neighbor_vert
Hemisphere provides geometry information.
MNESourceEstimate class declaration.