MNE-CPP  0.1.9
A Framework for Electrophysiology
networktreeitem.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //=============================================================================================================
37 // INCLUDES
38 //=============================================================================================================
39 
40 #include "networktreeitem.h"
41 #include "../common/metatreeitem.h"
42 #include "../../3dhelpers/renderable3Dentity.h"
43 #include "../../materials/networkmaterial.h"
44 #include "../../3dhelpers/custommesh.h"
45 #include "../../3dhelpers/geometrymultiplier.h"
46 #include "../../materials/geometrymultipliermaterial.h"
47 
49 
52 
53 #include <fiff/fiff_types.h>
54 
55 #include <mne/mne_sourceestimate.h>
57 
58 //=============================================================================================================
59 // QT INCLUDES
60 //=============================================================================================================
61 
62 #include <Qt3DExtras/QSphereGeometry>
63 #include <Qt3DExtras/QCylinderGeometry>
64 #include <Qt3DCore/QTransform>
65 
66 //=============================================================================================================
67 // EIGEN INCLUDES
68 //=============================================================================================================
69 
70 #include <Eigen/Core>
71 
72 //=============================================================================================================
73 // USED NAMESPACES
74 //=============================================================================================================
75 
76 using namespace Eigen;
77 using namespace MNELIB;
78 using namespace DISP3DLIB;
79 using namespace CONNECTIVITYLIB;
80 using namespace DISPLIB;
81 
82 //=============================================================================================================
83 // DEFINE MEMBER METHODS
84 //=============================================================================================================
85 
86 NetworkTreeItem::NetworkTreeItem(Qt3DCore::QEntity *p3DEntityParent, int iType, const QString &text)
87 : Abstract3DTreeItem(p3DEntityParent, iType, text)
88 {
89  initItem();
90 }
91 
92 //=============================================================================================================
93 
94 void NetworkTreeItem::initItem()
95 {
96  this->setEditable(false);
97  this->setCheckable(true);
98  this->setCheckState(Qt::Checked);
99  this->setToolTip("Network item");
100 
101  //Add meta information as item children
102  QList<QStandardItem*> list;
103  QVariant data;
104 
105  QVector3D vecEdgeTrehshold(0,0.5,1);
106  if(!m_pItemNetworkThreshold) {
107  m_pItemNetworkThreshold = new MetaTreeItem(MetaTreeItemTypes::DataThreshold,
108  QString("%1,%2,%3").arg(vecEdgeTrehshold.x()).arg(vecEdgeTrehshold.y()).arg(vecEdgeTrehshold.z()));
109  }
110 
111  list << m_pItemNetworkThreshold;
112  list << new QStandardItem(m_pItemNetworkThreshold->toolTip());
113  this->appendRow(list);
114  data.setValue(vecEdgeTrehshold);
115  m_pItemNetworkThreshold->setData(data, MetaTreeItemRoles::DataThreshold);
116  connect(m_pItemNetworkThreshold.data(), &MetaTreeItem::dataChanged,
117  this, &NetworkTreeItem::onNetworkThresholdChanged);
118 
119  MetaTreeItem* pItemColormapType = new MetaTreeItem(MetaTreeItemTypes::ColormapType, "Viridis");
120  connect(pItemColormapType, &MetaTreeItem::dataChanged,
121  this, &NetworkTreeItem::onColormapTypeChanged);
122  list.clear();
123  list << pItemColormapType;
124  list << new QStandardItem(pItemColormapType->toolTip());
125  this->appendRow(list);
126  data.setValue(QString("Hot"));
127  pItemColormapType->setData(data, MetaTreeItemRoles::ColormapType);
128 
129  list.clear();
130  MetaTreeItem* pItemNetworkMatrix = new MetaTreeItem(MetaTreeItemTypes::NetworkMatrix, "Show network matrix");
131  list << pItemNetworkMatrix;
132  list << new QStandardItem(pItemNetworkMatrix->toolTip());
133  this->appendRow(list);
134 
135 // //Set material
136 // NetworkMaterial* pNetworkMaterial = new NetworkMaterial();
137 // this->setMaterial(pNetworkMaterial);
138 }
139 
140 //=============================================================================================================
141 
142 void NetworkTreeItem::addData(const Network& tNetworkData)
143 {
144  //Add data which is held by this NetworkTreeItem
145  QVariant data;
146 
147  Network tNetwork = tNetworkData;
148  tNetwork.setThreshold(m_pItemNetworkThreshold->data(MetaTreeItemRoles::DataThreshold).value<QVector3D>().x());
149 
150  data.setValue(tNetwork);
151  this->setData(data, Data3DTreeModelItemRoles::NetworkData);
152 
153  MatrixXd matDist = tNetwork.getFullConnectivityMatrix();
154 // MatrixXd matDist = tNetwork.getThresholdedConnectivityMatrix();
155  data.setValue(matDist);
156  this->setData(data, Data3DTreeModelItemRoles::Data);
157 
158  //Plot network
159  if(this->checkState() == Qt::Checked) {
160  plotNetwork(tNetwork);
161  }
162 }
163 
164 //=============================================================================================================
165 
166 void NetworkTreeItem::setThresholds(const QVector3D& vecThresholds)
167 {
168  if(m_pItemNetworkThreshold) {
169  QVariant data;
170  data.setValue(vecThresholds);
171  m_pItemNetworkThreshold->setData(data, MetaTreeItemRoles::DataThreshold);
172 
173  QString sTemp = QString("%1,%2,%3").arg(vecThresholds.x()).arg(vecThresholds.y()).arg(vecThresholds.z());
174  data.setValue(sTemp);
175  m_pItemNetworkThreshold->setData(data, Qt::DisplayRole);
176  }
177 }
178 
179 //=============================================================================================================
180 
181 void NetworkTreeItem::onNetworkThresholdChanged(const QVariant& vecThresholds)
182 {
183  if(vecThresholds.canConvert<QVector3D>()) {
184  Network tNetwork = this->data(Data3DTreeModelItemRoles::NetworkData).value<Network>();
185  addData(tNetwork);
186  }
187 }
188 
189 //=============================================================================================================
190 
191 void NetworkTreeItem::onColorChanged(const QVariant& color)
192 {
193  if(color.canConvert<QColor>()) {
194  QColor networkColor = color.value<QColor>();
195 
196  Network tNetwork = this->data(Data3DTreeModelItemRoles::NetworkData).value<Network>();
197  VisualizationInfo info = tNetwork.getVisualizationInfo();
198  info.sMethod = "Color";
199  info.colEdges = Vector4i(networkColor.red(),
200  networkColor.green(),
201  networkColor.blue(),
202  networkColor.alpha());
203  info.colNodes = Vector4i(networkColor.red(),
204  networkColor.green(),
205  networkColor.blue(),
206  networkColor.alpha());
207  tNetwork.setVisualizationInfo(info);
208 
209  QVariant data;
210  data.setValue(tNetwork);
211 
212  this->setData(data, Data3DTreeModelItemRoles::NetworkData);
213 
214  plotNetwork(tNetwork);
215  }
216 }
217 
218 //=============================================================================================================
219 
220 void NetworkTreeItem::onColormapTypeChanged(const QVariant& sColormapType)
221 {
222  if(sColormapType.canConvert<QString>()) {
223  Network tNetwork = this->data(Data3DTreeModelItemRoles::NetworkData).value<Network>();
224  VisualizationInfo info = tNetwork.getVisualizationInfo();
225  info.sMethod = "Map";
226  info.sColormap = sColormapType.toString();
227  tNetwork.setVisualizationInfo(info);
228 
229  QVariant data;
230  data.setValue(tNetwork);
231 
232  this->setData(data, Data3DTreeModelItemRoles::NetworkData);
233 
234  plotNetwork(tNetwork);
235  }
236 }
237 
238 //=============================================================================================================
239 
240 void NetworkTreeItem::plotNetwork(const Network& tNetworkData)
241 {
242  //Draw network nodes and edges
243  plotNodes(tNetworkData);
244  plotEdges(tNetworkData);
245 }
246 
247 //=============================================================================================================
248 
249 void NetworkTreeItem::plotNodes(const Network& tNetworkData)
250 {
251  if(tNetworkData.isEmpty()) {
252  qDebug() << "NetworkTreeItem::plotNodes - Network data is empty. Returning.";
253  return;
254  }
255 
256  QList<NetworkNode::SPtr> lNetworkNodes = tNetworkData.getNodes();
257  qint16 iMaxDegree = tNetworkData.getMinMaxThresholdedDegrees().second;
258 
259  VisualizationInfo visualizationInfo = tNetworkData.getVisualizationInfo();
260 
261  if(!m_pNodesEntity) {
262  m_pNodesEntity = new QEntity(this);
263  }
264 
265  //create geometry
266  if(!m_pNodes) {
267  if(!m_pNodesGeometry) {
268  m_pNodesGeometry = QSharedPointer<Qt3DExtras::QSphereGeometry>::create();
269  m_pNodesGeometry->setRadius(0.6f);
270  }
271 
272  m_pNodes = new GeometryMultiplier(m_pNodesGeometry);
273 
274  m_pNodesEntity->addComponent(m_pNodes);
275 
276  //Add material
278  pMaterial->setAlpha(1.0);
279  m_pNodesEntity->addComponent(pMaterial);
280  }
281 
282  //Create transform matrix for each sphere instance
283  QVector<QMatrix4x4> vTransforms;
284  QVector<QColor> vColorsNodes;
285  QVector3D tempPos;
286  qint16 iDegree = 0;
287 
288  for(int i = 0; i < lNetworkNodes.size(); ++i) {
289  iDegree = lNetworkNodes.at(i)->getThresholdedDegree();
290 
291  if(iDegree != 0) {
292  tempPos = QVector3D(lNetworkNodes.at(i)->getVert()(0),
293  lNetworkNodes.at(i)->getVert()(1),
294  lNetworkNodes.at(i)->getVert()(2));
295 
296  //Set position and scale
297  QMatrix4x4 tempTransform;
298  tempTransform.translate(tempPos);
299  tempTransform.scale(((float)iDegree/(float)iMaxDegree)*(0.005f-0.0006f)+0.0006f);
300 
301  vTransforms.push_back(tempTransform);
302 
303  if(visualizationInfo.sMethod == "Map") {
304  // Normalize colors
305  if(iMaxDegree != 0.0f) {
306  QColor color = ColorMap::valueToColor((float)iDegree/(float)iMaxDegree, visualizationInfo.sColormap);
307  color.setAlphaF(pow((float)iDegree/(float)iMaxDegree,4));
308  vColorsNodes.push_back(color);
309  } else {
310  QColor color = ColorMap::valueToColor(0.0, visualizationInfo.sColormap);
311  //color.setAlphaF(0);
312  vColorsNodes.push_back(color);
313  }
314  } else {
315  vColorsNodes.push_back(QColor(visualizationInfo.colEdges[0],
316  visualizationInfo.colEdges[1],
317  visualizationInfo.colEdges[2],
318  visualizationInfo.colEdges[3]));
319  }
320  }
321  }
322 
323  m_pNodes->setTransforms(vTransforms);
324  m_pNodes->setColors(vColorsNodes);
325 }
326 
327 //=============================================================================================================
328 
329 void NetworkTreeItem::plotEdges(const Network &tNetworkData)
330 {
331  if(tNetworkData.isEmpty()) {
332  qDebug() << "NetworkTreeItem::plotEdges - Network data is empty. Returning.";
333  return;
334  }
335 
336  double dMaxWeight = tNetworkData.getMinMaxThresholdedWeights().second;
337  double dMinWeight = tNetworkData.getMinMaxThresholdedWeights().first;
338 
339  QList<NetworkEdge::SPtr> lNetworkEdges = tNetworkData.getThresholdedEdges();
340  QList<NetworkNode::SPtr> lNetworkNodes = tNetworkData.getNodes();
341 
342  VisualizationInfo visualizationInfo = tNetworkData.getVisualizationInfo();
343 
344  if(!m_pEdgeEntity) {
345  m_pEdgeEntity = new QEntity(this);
346  }
347 
348  //create geometry
349  if(!m_pEdges) {
350  if(!m_pEdgesGeometry) {
351  m_pEdgesGeometry = QSharedPointer<Qt3DExtras::QCylinderGeometry>::create();
352  m_pEdgesGeometry->setRadius(0.001f);
353  m_pEdgesGeometry->setLength(1.0f);
354  }
355 
356  m_pEdges = new GeometryMultiplier(m_pEdgesGeometry);
357 
358  m_pEdgeEntity->addComponent(m_pEdges);
359 
360  //Add material
362  pMaterial->setAlpha(1.0f);
363  m_pEdgeEntity->addComponent(pMaterial);
364  }
365 
366  //Create transform matrix for each cylinder instance
367  QVector<QMatrix4x4> vTransformsEdges;
368  QVector<QColor> vColorsEdges;
369  QVector3D startPos, endPos, edgePos, diff;
370  double dWeight = 0.0;
371  int iStartID, iEndID;
372 
373  for(int i = 0; i < lNetworkEdges.size(); ++i) {
374  //Plot in edges
375  NetworkEdge::SPtr pNetworkEdge = lNetworkEdges.at(i);
376 
377  if(pNetworkEdge->isActive()) {
378  iStartID = pNetworkEdge->getStartNodeID();
379  iEndID = pNetworkEdge->getEndNodeID();
380 
381  RowVectorXf vectorStart = lNetworkNodes.at(iStartID)->getVert();
382  startPos = QVector3D(vectorStart(0),
383  vectorStart(1),
384  vectorStart(2));
385 
386  RowVectorXf vectorEnd = lNetworkNodes.at(iEndID)->getVert();
387  endPos = QVector3D(vectorEnd(0),
388  vectorEnd(1),
389  vectorEnd(2));
390 
391  if(startPos != endPos) {
392  dWeight = fabs(pNetworkEdge->getWeight());
393  if(dWeight != 0.0) {
394  diff = endPos - startPos;
395  edgePos = endPos - diff/2;
396 
397  QMatrix4x4 tempTransform;
398  tempTransform.translate(edgePos);
399  tempTransform.rotate(QQuaternion::rotationTo(QVector3D(0,1,0), diff.normalized()).normalized());
400  tempTransform.scale(fabs((dWeight-dMinWeight)/(dMaxWeight-dMinWeight)),diff.length(),fabs((dWeight-dMinWeight)/(dMaxWeight-dMinWeight)));
401  //tempTransform.scale(pow(fabs(dWeight/dMaxWeight),4)*4,diff.length(),pow(fabs(dWeight/dMaxWeight),4)*4);
402 
403  vTransformsEdges.push_back(tempTransform);
404 
405  // Colors
406  if(visualizationInfo.sMethod == "Map") {
407  // Normalize colors
408  if(dMaxWeight != 0.0f) {
409  QColor color = ColorMap::valueToColor(fabs(dWeight/dMaxWeight), visualizationInfo.sColormap);
410  color.setAlphaF(pow(fabs(dWeight/dMaxWeight),1.5));
411  //qDebug() << "fabs(dWeight/dMaxWeight)"<< fabs(dWeight/dMaxWeight);
412  //qDebug() << "color"<<color;
413  vColorsEdges.push_back(color);
414  } else {
415  QColor color = ColorMap::valueToColor(0.0, visualizationInfo.sColormap);
416  color.setAlphaF(0.0);
417  vColorsEdges.push_back(color);
418  }
419  } else {
420  vColorsEdges.push_back(QColor(visualizationInfo.colNodes[0],
421  visualizationInfo.colNodes[1],
422  visualizationInfo.colNodes[2],
423  visualizationInfo.colNodes[3]));
424  }
425  }
426  }
427  }
428  }
429 
430  m_pEdges->setTransforms(vTransformsEdges);
431  m_pEdges->setColors(vColorsEdges);
432 }
433 
void addData(const CONNECTIVITYLIB::Network &tNetworkData)
Old fiff_type declarations - replace them.
void setThreshold(double dThreshold=0.0)
Definition: network.cpp:331
Eigen::MatrixXd getFullConnectivityMatrix(bool bGetMirroredVersion=true) const
Definition: network.cpp:93
void setVisualizationInfo(const VisualizationInfo &visualizationInfo)
Definition: network.cpp:477
QPair< int, int > getMinMaxThresholdedDegrees() const
Definition: network.cpp:241
const QList< QSharedPointer< NetworkEdge > > & getThresholdedEdges() const
Definition: network.cpp:148
MNESourceEstimate class declaration.
void setThresholds(const QVector3D &vecThresholds)
NetworkEdge class declaration.
Instaced based renderer.
void dataChanged(const QVariant &data)
NetworkTreeItem class declaration.
Provides the basic tree item.
QPair< double, double > getMinMaxThresholdedWeights() const
Definition: network.cpp:216
Custom phong alpha material for instanced rendering.
bool isEmpty() const
Definition: network.cpp:438
This class holds information about a network, can compute a distance table and provide network metric...
Definition: network.h:87
QSharedPointer< NetworkEdge > SPtr
Definition: networkedge.h:83
VisualizationInfo getVisualizationInfo() const
Definition: network.cpp:470
NetworkNode class declaration.
const QList< QSharedPointer< NetworkNode > > & getNodes() const
Definition: network.cpp:155
void setData(const QVariant &value, int role=Qt::UserRole+1)
Provides a generic brain tree item.
Definition: metatreeitem.h:74
MNEForwardSolution class declaration, which provides the forward solution including the source space ...
ColorMap class declaration.