Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.