Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkConnectomicsSyntheticNetworkGenerator.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include <sstream>
20 #include <vector>
21 
24 
25 #include <vtkMatrix4x4.h>
26 
27 //for random number generation
28 #include "vnl/vnl_random.h"
29 #include "vnl/vnl_math.h"
30 
32 : m_LastGenerationWasSuccess( false )
33 {
34 }
35 
37 {
38 }
39 
41 {
43 
44  m_LastGenerationWasSuccess = false;
45  // give the network an artificial geometry
46  network->SetGeometry( this->GenerateDefaultGeometry() );
47 
48  switch (networkTypeId) {
49  case 0:
50  GenerateSyntheticCubeNetwork( network, paramterOne, parameterTwo );
51  break;
52  case 1:
53  GenerateSyntheticCenterToSurfaceNetwork( network, paramterOne, parameterTwo );
54  break;
55  case 2:
56  GenerateSyntheticRandomNetwork( network, paramterOne, parameterTwo );
57  break;
58  case 3:
59  //GenerateSyntheticScaleFreeNetwork( network, 1000 );
60  break;
61  case 4:
62  //GenerateSyntheticSmallWorldNetwork( network, 1000 );
63  break;
64  default:
65  MBI_ERROR << "Unrecognized Network ID";
66  }
67 
68  network->UpdateBounds();
69  network->SetProperty(connectomicsDataAdditionalHeaderInformation.c_str(), mitk::StringProperty::New("Synthetic Network"));
70 
71  return network;
72 
73 }
74 
76 {
78 
79  double zero( 0.0 );
80  double one( 1.0 );
81  // origin = {0,0,0}
82  mitk::Point3D origin;
83 
84  origin[0] = zero;
85  origin[1] = zero;
86  origin[2] = zero;
87  geometry->SetOrigin(origin);
88 
89  // spacing = {1,1,1}
90  ScalarType spacing[3];
91  spacing[0] = one;
92  spacing[1] = one;
93  spacing[2] = one;
94  geometry->SetSpacing(spacing);
95 
96  // transform
97  vtkMatrix4x4* transformMatrix = vtkMatrix4x4::New();
98  transformMatrix->SetElement(0,0,one);
99  transformMatrix->SetElement(1,0,zero);
100  transformMatrix->SetElement(2,0,zero);
101  transformMatrix->SetElement(0,1,zero);
102  transformMatrix->SetElement(1,1,one);
103  transformMatrix->SetElement(2,1,zero);
104  transformMatrix->SetElement(0,2,zero);
105  transformMatrix->SetElement(1,2,zero);
106  transformMatrix->SetElement(2,2,one);
107 
108  transformMatrix->SetElement(0,3,origin[0]);
109  transformMatrix->SetElement(1,3,origin[1]);
110  transformMatrix->SetElement(2,3,origin[2]);
111  transformMatrix->SetElement(3,3,1);
112  geometry->SetIndexToWorldTransformByVtkMatrix( transformMatrix );
113 
114  geometry->SetImageGeometry(true);
115 
116  return geometry;
117 }
118 
120  mitk::ConnectomicsNetwork::Pointer network, int cubeExtent, double distance )
121 {
122  // map for storing the conversion from indices to vertex descriptor
123  std::map< int, mitk::ConnectomicsNetwork::VertexDescriptorType > idToVertexMap;
124 
125  int vertexID(0);
126  for( int loopX( 0 ); loopX < cubeExtent; loopX++ )
127  {
128  for( int loopY( 0 ); loopY < cubeExtent; loopY++ )
129  {
130  for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ )
131  {
132  std::vector< float > position;
133  std::string label;
134  std::stringstream labelStream;
135  labelStream << vertexID;
136  label = labelStream.str();
137 
138  position.push_back( loopX * distance );
139  position.push_back( loopY * distance );
140  position.push_back( loopZ * distance );
141 
142  mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( vertexID );
143  network->SetLabel( newVertex, label );
144  network->SetCoordinates( newVertex, position );
145 
146  if ( idToVertexMap.count( vertexID ) > 0 )
147  {
148  MITK_ERROR << "Aborting network creation, duplicate vertex ID generated.";
149  m_LastGenerationWasSuccess = false;
150  return;
151  }
152  idToVertexMap.insert( std::pair< int, mitk::ConnectomicsNetwork::VertexDescriptorType >( vertexID, newVertex) );
153 
154  vertexID++;
155  }
156  }
157  }
158 
159  int edgeID(0), edgeSourceID(0), edgeTargetID(0);
160  // uniform weight of one
161  int edgeWeight(1);
162 
165 
166  for( int loopX( 0 ); loopX < cubeExtent; loopX++ )
167  {
168  for( int loopY( 0 ); loopY < cubeExtent; loopY++ )
169  {
170  for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ )
171  {
172  // to avoid creating an edge twice (this being an undirected graph) we only generate
173  // edges in three directions, the others will be supplied by the corresponding nodes
174  if( loopX != 0 )
175  {
176  edgeTargetID = edgeSourceID - cubeExtent * cubeExtent;
177 
178  source = idToVertexMap.find( edgeSourceID )->second;
179  target = idToVertexMap.find( edgeTargetID )->second;
180  network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight);
181 
182  edgeID++;
183  }
184  if( loopY != 0 )
185  {
186  edgeTargetID = edgeSourceID - cubeExtent;
187 
188  source = idToVertexMap.find( edgeSourceID )->second;
189  target = idToVertexMap.find( edgeTargetID )->second;
190  network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight);
191 
192  edgeID++;
193  }
194  if( loopZ != 0 )
195  {
196  edgeTargetID = edgeSourceID - 1;
197 
198  source = idToVertexMap.find( edgeSourceID )->second;
199  target = idToVertexMap.find( edgeTargetID )->second;
200  network->AddEdge( source, target, edgeSourceID, edgeTargetID, edgeWeight);
201 
202  edgeID++;
203  }
204 
205  edgeSourceID++;
206  } // end for( int loopZ( 0 ); loopZ < cubeExtent; loopZ++ )
207  } // end for( int loopY( 0 ); loopY < cubeExtent; loopY++ )
208  } // end for( int loopX( 0 ); loopX < cubeExtent; loopX++ )
209  m_LastGenerationWasSuccess = true;
210 }
211 
213  mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double radius )
214 {
215 
216  vnl_random rng( (unsigned int) rand() );
217 
219  int vertexID(0);
220  { //add center vertex
221  std::vector< float > position;
222  std::string label;
223  std::stringstream labelStream;
224  labelStream << vertexID;
225  label = labelStream.str();
226 
227  position.push_back( 0 );
228  position.push_back( 0 );
229  position.push_back( 0 );
230 
231  centerVertex = network->AddVertex( vertexID );
232  network->SetLabel( centerVertex, label );
233  network->SetCoordinates( centerVertex, position );
234  }//end add center vertex
235 
236  // uniform weight of one
237  int edgeWeight(1);
238 
239  //add vertices on sphere surface
240  for( int loopID( 1 ); loopID < numberOfPoints; loopID++ )
241  {
242 
243  std::vector< float > position;
244  std::string label;
245  std::stringstream labelStream;
246  labelStream << loopID;
247  label = labelStream.str();
248 
249  //generate random, uniformly distributed points on a sphere surface
250  const double uVariable = rng.drand64( 0.0 , 1.0);
251  const double vVariable = rng.drand64( 0.0 , 1.0);
252  const double phi = 2 * vnl_math::pi * uVariable;
253  const double theta = std::acos( 2 * vVariable - 1 );
254 
255  double xpos = radius * std::cos( phi ) * std::sin( theta );
256  double ypos = radius * std::sin( phi ) * std::sin( theta );
257  double zpos = radius * std::cos( theta );
258 
259  position.push_back( xpos );
260  position.push_back( ypos );
261  position.push_back( zpos );
262 
263  mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( loopID );
264  network->SetLabel( newVertex, label );
265  network->SetCoordinates( newVertex, position );
266 
267  network->AddEdge( newVertex, centerVertex, loopID, 0, edgeWeight);
268  }
269  m_LastGenerationWasSuccess = true;
270 }
271 
273  mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double threshold )
274 {
275  // as the surface is proportional to the square of the radius the density stays the same
276  double radius = 5 * std::sqrt( (float) numberOfPoints );
277 
278  vnl_random rng( (unsigned int) rand() );
279 
280  // map for storing the conversion from indices to vertex descriptor
281  std::map< int, mitk::ConnectomicsNetwork::VertexDescriptorType > idToVertexMap;
282 
283  //add vertices on sphere surface
284  for( int loopID( 0 ); loopID < numberOfPoints; loopID++ )
285  {
286 
287  std::vector< float > position;
288  std::string label;
289  std::stringstream labelStream;
290  labelStream << loopID;
291  label = labelStream.str();
292 
293  //generate random, uniformly distributed points on a sphere surface
294  const double uVariable = rng.drand64( 0.0 , 1.0);
295  const double vVariable = rng.drand64( 0.0 , 1.0);
296  const double phi = 2 * vnl_math::pi * uVariable;
297  const double theta = std::acos( 2 * vVariable - 1 );
298 
299  double xpos = radius * std::cos( phi ) * std::sin( theta );
300  double ypos = radius * std::sin( phi ) * std::sin( theta );
301  double zpos = radius * std::cos( theta );
302 
303  position.push_back( xpos );
304  position.push_back( ypos );
305  position.push_back( zpos );
306 
307  mitk::ConnectomicsNetwork::VertexDescriptorType newVertex = network->AddVertex( loopID );
308  network->SetLabel( newVertex, label );
309  network->SetCoordinates( newVertex, position );
310 
311  if ( idToVertexMap.count( loopID ) > 0 )
312  {
313  MITK_ERROR << "Aborting network creation, duplicate vertex ID generated.";
314  m_LastGenerationWasSuccess = false;
315  return;
316  }
317  idToVertexMap.insert( std::pair< int, mitk::ConnectomicsNetwork::VertexDescriptorType >( loopID, newVertex) );
318  }
319 
320  int edgeID(0);
321  // uniform weight of one
322  int edgeWeight(1);
323 
326 
327  for( int loopID( 0 ); loopID < numberOfPoints; loopID++ )
328  {
329  // to avoid creating an edge twice (this being an undirected graph) we only
330  // potentially generate edges with all nodes with a bigger ID
331  for( int innerLoopID( loopID ); innerLoopID < numberOfPoints; innerLoopID++ )
332  {
333  if( rng.drand64( 0.0 , 1.0) > threshold)
334  {
335  // do nothing
336  }
337  else
338  {
339  source = idToVertexMap.find( loopID )->second;
340  target = idToVertexMap.find( innerLoopID )->second;
341  network->AddEdge( source, target, loopID, innerLoopID, edgeWeight);
342 
343  edgeID++;
344  }
345  } // end for( int innerLoopID( loopID ); innerLoopID < numberOfPoints; innerLoopID++ )
346  } // end for( int loopID( 0 ); loopID < numberOfPoints; loopID++ )
347  m_LastGenerationWasSuccess = true;
348 }
349 
351 {
352  return m_LastGenerationWasSuccess;
353 }
This file defines the data properties for connectomics networks in MITK.
mitk::ConnectomicsNetwork::Pointer CreateSyntheticNetwork(int networkTypeId, int paramterOne, double parameterTwo)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
double ScalarType
void GenerateSyntheticCubeNetwork(mitk::ConnectomicsNetwork::Pointer network, int cubeExtent, double distance)
static Pointer New()
void GenerateSyntheticRandomNetwork(mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double threshold)
static Pointer New()
void GenerateSyntheticCenterToSurfaceNetwork(mitk::ConnectomicsNetwork::Pointer network, int numberOfPoints, double radius)
boost::graph_traits< NetworkType >::vertex_descriptor VertexDescriptorType
const std::string connectomicsDataAdditionalHeaderInformation
Additional header information.
static Pointer New()
#define MBI_ERROR
Definition: mbilog.h:223
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.