Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
NetworkStatistics.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 
17 // std includes
18 #include <string>
19 #include <sstream>
20 #include <fstream>
21 #include <vector>
22 #include <map>
23 #include <utility>
24 
25 // boost includes
26 #include <boost/algorithm/string.hpp>
27 
28 // ITK includes
29 #include <itkImageFileWriter.h>
30 
31 // CTK includes
32 #include "mitkCommandLineParser.h"
33 
34 // MITK includes
38 #include <mitkIOUtil.h>
39 
40 int main(int argc, char* argv[])
41 {
42  mitkCommandLineParser parser;
43 
44  parser.setTitle("Network Creation");
45  parser.setCategory("Connectomics");
46  parser.setDescription("");
47  parser.setContributor("MBI");
48 
49  parser.setArgumentPrefix("--", "-");
50 
51  parser.addArgument("inputNetwork", "i", mitkCommandLineParser::InputFile, "Input network", "input connectomics network (.cnf)", us::Any(), false);
52  parser.addArgument("outputFile", "o", mitkCommandLineParser::OutputFile, "Output file", "name of output file", us::Any(), false);
53 
54  parser.addArgument("noGlobalStatistics", "g", mitkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics");
55  parser.addArgument("createConnectivityMatriximage", "I", mitkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image");
56  parser.addArgument("binaryConnectivity", "b", mitkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix");
57  parser.addArgument("rescaleConnectivity", "r", mitkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix");
58  parser.addArgument("localStatistics", "L", mitkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any());
59  parser.addArgument("regionList", "R", mitkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any());
60  parser.addArgument("granularity", "gr", mitkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider",1);
61  parser.addArgument("startDensity", "d", mitkCommandLineParser::Float, "Start Density", "Largest density for the range",1.0);
62  parser.addArgument("thresholdStepSize", "t", mitkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds",3);
63 
64  parser.setCategory("Connectomics");
65  parser.setTitle("Network Statistics");
66  parser.setDescription("");
67  parser.setContributor("MBI");
68 
69  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
70  if (parsedArgs.size()==0)
71  return EXIT_FAILURE;
72 
73  //default values
74  bool noGlobalStatistics( false );
75  bool binaryConnectivity( false );
76  bool rescaleConnectivity( false );
77  bool createConnectivityMatriximage( false );
78  int granularity( 1 );
79  double startDensity( 1.0 );
80  int thresholdStepSize( 3 );
81 
82 
83  // parse command line arguments
84  std::string networkName = us::any_cast<std::string>(parsedArgs["inputNetwork"]);
85  std::string outName = us::any_cast<std::string>(parsedArgs["outputFile"]);
86 
88 
89  if(parsedArgs.count("localStatistics"))
90  {
91  localLabels = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["localStatistics"]);
92  }
93 
95  std::map< std::string, std::vector<std::string> > parsedRegions;
96  std::map< std::string, std::vector<std::string> >::iterator parsedRegionsIterator;
97 
98  if(parsedArgs.count("regionList"))
99  {
100  unparsedRegions = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["regionList"]);
101 
102  for(unsigned int index(0); index < unparsedRegions.size(); index++ )
103  {
104  std::vector< std::string > tempRegionVector;
105 
106  boost::split(tempRegionVector, unparsedRegions.at(index), boost::is_any_of(";"));
107 
108  std::vector< std::string >::const_iterator begin = tempRegionVector.begin();
109  std::vector< std::string >::const_iterator last = tempRegionVector.begin() + tempRegionVector.size();
110  std::vector< std::string > insertRegionVector(begin + 1, last);
111 
112  if( parsedRegions.count( tempRegionVector.at(0) ) == 0 )
113  {
114  parsedRegions.insert( std::pair< std::string, std::vector<std::string> >( tempRegionVector.at(0), insertRegionVector) );
115  }
116  else
117  {
118  MITK_ERROR << "Region already exists. Skipping second occurrence.";
119  }
120  }
121  }
122 
123  if (parsedArgs.count("noGlobalStatistics"))
124  noGlobalStatistics = us::any_cast<bool>(parsedArgs["noGlobalStatistics"]);
125  if (parsedArgs.count("binaryConnectivity"))
126  binaryConnectivity = us::any_cast<bool>(parsedArgs["binaryConnectivity"]);
127  if (parsedArgs.count("rescaleConnectivity"))
128  rescaleConnectivity = us::any_cast<bool>(parsedArgs["rescaleConnectivity"]);
129  if (parsedArgs.count("createConnectivityMatriximage"))
130  createConnectivityMatriximage = us::any_cast<bool>(parsedArgs["createConnectivityMatriximage"]);
131  if (parsedArgs.count("granularity"))
132  granularity = us::any_cast<int>(parsedArgs["granularity"]);
133  if (parsedArgs.count("startDensity"))
134  startDensity = us::any_cast<float>(parsedArgs["startDensity"]);
135  if (parsedArgs.count("thresholdStepSize"))
136  thresholdStepSize = us::any_cast<int>(parsedArgs["thresholdStepSize"]);
137 
138  try
139  {
140  // load network
141  std::vector<mitk::BaseData::Pointer> networkFile =
142  mitk::IOUtil::Load( networkName);
143  if( networkFile.empty() )
144  {
145  std::string errorMessage = "File at " + networkName + " could not be read. Aborting.";
146  MITK_ERROR << errorMessage;
147  return EXIT_FAILURE;
148  }
149  mitk::BaseData* networkBaseData = networkFile.at(0);
150  mitk::ConnectomicsNetwork* network = dynamic_cast<mitk::ConnectomicsNetwork*>( networkBaseData );
151 
152  if( !network )
153  {
154  std::string errorMessage = "Read file at " + networkName + " could not be recognized as network. Aborting.";
155  MITK_ERROR << errorMessage;
156  return EXIT_FAILURE;
157  }
158 
159  // streams
160  std::stringstream globalHeaderStream;
161  globalHeaderStream << "NumberOfVertices "
162  << "NumberOfEdges "
163  << "AverageDegree "
164  << "ConnectionDensity "
165  << "NumberOfConnectedComponents "
166  << "AverageComponentSize "
167  << "LargestComponentSize "
168  << "RatioOfNodesInLargestComponent "
169  << "HopPlotExponent "
170  << "EffectiveHopDiameter "
171  << "AverageClusteringCoefficientsC "
172  << "AverageClusteringCoefficientsD "
173  << "AverageClusteringCoefficientsE "
174  << "AverageVertexBetweennessCentrality "
175  << "AverageEdgeBetweennessCentrality "
176  << "NumberOfIsolatedPoints "
177  << "RatioOfIsolatedPoints "
178  << "NumberOfEndPoints "
179  << "RatioOfEndPoints "
180  << "Diameter "
181  << "Diameter90 "
182  << "Radius "
183  << "Radius90 "
184  << "AverageEccentricity "
185  << "AverageEccentricity90 "
186  << "AveragePathLength "
187  << "NumberOfCentralPoints "
188  << "RatioOfCentralPoints "
189  << "SpectralRadius "
190  << "SecondLargestEigenValue "
191  << "AdjacencyTrace "
192  << "AdjacencyEnergy "
193  << "LaplacianTrace "
194  << "LaplacianEnergy "
195  << "LaplacianSpectralGap "
196  << "NormalizedLaplacianTrace "
197  << "NormalizedLaplacianEnergy "
198  << "NormalizedLaplacianNumberOf2s "
199  << "NormalizedLaplacianNumberOf1s "
200  << "NormalizedLaplacianNumberOf0s "
201  << "NormalizedLaplacianLowerSlope "
202  << "NormalizedLaplacianUpperSlope "
203  << "SmallWorldness"
204  << std::endl;
205 
206  std::stringstream localHeaderStream;
207  std::stringstream regionalHeaderStream;
208 
209  std::stringstream globalDataStream;
210  std::stringstream localDataStream;
211  std::stringstream regionalDataStream;
212 
213  std::string globalOutName = outName + "_global.txt";
214  std::string localOutName = outName + "_local.txt";
215  std::string regionalOutName = outName + "_regional.txt";
216 
217  bool firstRun( true );
218  // iterate over all three possible methods
219  for(unsigned int method( 0 ); method < 3; method++)
220  {
221  // 0 - Random removal threshold
222  // 1 - Largest density below threshold
223  // 2 - Threshold based
224 
225  // iterate over possible targets
226  for( unsigned int step( 0 ); step < granularity; step++ )
227  {
228  double targetValue( 0.0 );
229  bool newStep( true );
230 
231  switch ( method )
232  {
235  targetValue = startDensity * (1 - static_cast<double>( step ) / ( granularity + 0.5 ) );
236  break;
238  targetValue = static_cast<double>( thresholdStepSize * step );
239  break;
240  default:
241  MITK_ERROR << "Invalid thresholding method called, aborting.";
242  return EXIT_FAILURE;
243  break;
244  }
245 
247  thresholder->SetNetwork( network );
248  thresholder->SetTargetThreshold( targetValue );
249  thresholder->SetTargetDensity( targetValue );
250  thresholder->SetThresholdingScheme( static_cast<mitk::ConnectomicsNetworkThresholder::ThresholdingSchemes>(method) );
251  mitk::ConnectomicsNetwork::Pointer thresholdedNetwork = thresholder->GetThresholdedNetwork();
252 
254  statisticsCalculator->SetNetwork( thresholdedNetwork );
255  statisticsCalculator->Update();
256 
257  // global statistics
258  if( !noGlobalStatistics )
259  {
260  globalDataStream << statisticsCalculator->GetNumberOfVertices() << " "
261  << statisticsCalculator->GetNumberOfEdges() << " "
262  << statisticsCalculator->GetAverageDegree() << " "
263  << statisticsCalculator->GetConnectionDensity() << " "
264  << statisticsCalculator->GetNumberOfConnectedComponents() << " "
265  << statisticsCalculator->GetAverageComponentSize() << " "
266  << statisticsCalculator->GetLargestComponentSize() << " "
267  << statisticsCalculator->GetRatioOfNodesInLargestComponent() << " "
268  << statisticsCalculator->GetHopPlotExponent() << " "
269  << statisticsCalculator->GetEffectiveHopDiameter() << " "
270  << statisticsCalculator->GetAverageClusteringCoefficientsC() << " "
271  << statisticsCalculator->GetAverageClusteringCoefficientsD() << " "
272  << statisticsCalculator->GetAverageClusteringCoefficientsE() << " "
273  << statisticsCalculator->GetAverageVertexBetweennessCentrality() << " "
274  << statisticsCalculator->GetAverageEdgeBetweennessCentrality() << " "
275  << statisticsCalculator->GetNumberOfIsolatedPoints() << " "
276  << statisticsCalculator->GetRatioOfIsolatedPoints() << " "
277  << statisticsCalculator->GetNumberOfEndPoints() << " "
278  << statisticsCalculator->GetRatioOfEndPoints() << " "
279  << statisticsCalculator->GetDiameter() << " "
280  << statisticsCalculator->GetDiameter90() << " "
281  << statisticsCalculator->GetRadius() << " "
282  << statisticsCalculator->GetRadius90() << " "
283  << statisticsCalculator->GetAverageEccentricity() << " "
284  << statisticsCalculator->GetAverageEccentricity90() << " "
285  << statisticsCalculator->GetAveragePathLength() << " "
286  << statisticsCalculator->GetNumberOfCentralPoints() << " "
287  << statisticsCalculator->GetRatioOfCentralPoints() << " "
288  << statisticsCalculator->GetSpectralRadius() << " "
289  << statisticsCalculator->GetSecondLargestEigenValue() << " "
290  << statisticsCalculator->GetAdjacencyTrace() << " "
291  << statisticsCalculator->GetAdjacencyEnergy() << " "
292  << statisticsCalculator->GetLaplacianTrace() << " "
293  << statisticsCalculator->GetLaplacianEnergy() << " "
294  << statisticsCalculator->GetLaplacianSpectralGap() << " "
295  << statisticsCalculator->GetNormalizedLaplacianTrace() << " "
296  << statisticsCalculator->GetNormalizedLaplacianEnergy() << " "
297  << statisticsCalculator->GetNormalizedLaplacianNumberOf2s() << " "
298  << statisticsCalculator->GetNormalizedLaplacianNumberOf1s() << " "
299  << statisticsCalculator->GetNormalizedLaplacianNumberOf0s() << " "
300  << statisticsCalculator->GetNormalizedLaplacianLowerSlope() << " "
301  << statisticsCalculator->GetNormalizedLaplacianUpperSlope() << " "
302  << statisticsCalculator->GetSmallWorldness()
303  << std::endl;
304 
305  } // end global statistics
306 
307  //create connectivity matrix png
308  if( createConnectivityMatriximage )
309  {
310  std::string connectivity_png_postfix = "_connectivity";
311  if( binaryConnectivity )
312  {
313  connectivity_png_postfix += "_binary";
314  }
315  else if( rescaleConnectivity )
316  {
317  connectivity_png_postfix += "_rescaled";
318  }
319  connectivity_png_postfix += ".png";
320 
321  /* File format
322  * A png file depicting the binary connectivity matrix
323  */
325  filter->SetInputNetwork( network );
326  filter->SetBinaryConnectivity( binaryConnectivity );
327  filter->SetRescaleConnectivity( rescaleConnectivity );
328  filter->Update();
329 
331 
333 
334  connectivityWriter->SetInput( filter->GetOutput() );
335  connectivityWriter->SetFileName( outName + connectivity_png_postfix);
336  connectivityWriter->Update();
337 
338  std::cout << "Connectivity matrix image written.";
339  } // end create connectivity matrix png
340 
341  /*
342  * We can either calculate local indices for specific nodes, or specific regions
343  */
344 
345  // Create LabelToIndex translation
346  std::map< std::string, int > labelToIdMap;
347  std::vector< mitk::ConnectomicsNetwork::NetworkNode > nodeVector = thresholdedNetwork->GetVectorOfAllNodes();
348  for(int loop(0); loop < nodeVector.size(); loop++)
349  {
350  labelToIdMap.insert( std::pair< std::string, int>(nodeVector.at(loop).label, nodeVector.at(loop).id) );
351  }
352 
353  std::vector< int > degreeVector = thresholdedNetwork->GetDegreeOfNodes();
354  std::vector< double > ccVector = thresholdedNetwork->GetLocalClusteringCoefficients( );
355  std::vector< double > bcVector = thresholdedNetwork->GetNodeBetweennessVector( );
356 
357 
358  // calculate local indices
359 
360  {
361  // only add to header for the first step of the first method
362  if( firstRun )
363  {
364  localHeaderStream << "Th_method " << "Th_target " << "density";
365  }
366 
367  double density = statisticsCalculator->GetConnectionDensity();
368 
369  localDataStream << "\n"
370  << method << " "
371  << targetValue << " "
372  << density;
373 
374  for(unsigned int loop(0); loop < localLabels.size(); loop++ )
375  {
376  if( network->CheckForLabel(localLabels.at( loop )) )
377  {
378  if( firstRun )
379  {
380  localHeaderStream << " "
381  << localLabels.at( loop ) << "_Degree "
382  << localLabels.at( loop ) << "_CC "
383  << localLabels.at( loop ) << "_BC";
384  }
385 
386  localDataStream << " " << degreeVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
387  << " " << ccVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
388  << " " << bcVector.at( labelToIdMap.find( localLabels.at( loop ) )->second );
389  }
390  else
391  {
392  MITK_ERROR << "Illegal label. Label: \"" << localLabels.at( loop ) << "\" not found.";
393  }
394  }
395  }
396 
397  // calculate regional indices
398 
399  {
400  // only add to header for the first step of the first method
401  if( firstRun )
402  {
403  regionalHeaderStream << "Th_method " << "Th_target " << "density";
404  }
405 
406  double density = statisticsCalculator->GetConnectionDensity();
407 
408  regionalDataStream << "\n"
409  << method << " "
410  << targetValue << " "
411  << density;
412 
413  for( parsedRegionsIterator = parsedRegions.begin(); parsedRegionsIterator != parsedRegions.end(); parsedRegionsIterator++ )
414  {
415  std::vector<std::string> regionLabelsVector = parsedRegionsIterator->second;
416  std::string regionName = parsedRegionsIterator->first;
417 
418  double sumDegree( 0 );
419  double sumCC( 0 );
420  double sumBC( 0 );
421  double count( 0 );
422 
423  for( int loop(0); loop < regionLabelsVector.size(); loop++ )
424  {
425  if( thresholdedNetwork->CheckForLabel(regionLabelsVector.at( loop )) )
426  {
427  sumDegree = sumDegree + degreeVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
428  sumCC = sumCC + ccVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
429  sumBC = sumBC + bcVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
430  count = count + 1;
431  }
432  else
433  {
434  MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at( loop ) << "\" not found.";
435  }
436  }
437 
438  // only add to header for the first step of the first method
439  if( firstRun )
440  {
441  regionalHeaderStream << " " << regionName << "_LocalAverageDegree "
442  << regionName << "_LocalAverageCC "
443  << regionName << "_LocalAverageBC "
444  << regionName << "_NumberOfNodes";
445  }
446 
447  regionalDataStream << " " << sumDegree / count
448  << " " << sumCC / count
449  << " " << sumBC / count
450  << " " << count;
451 
452  // count number of connections and fibers between regions
453  std::map< std::string, std::vector<std::string> >::iterator loopRegionsIterator;
454  for (loopRegionsIterator = parsedRegionsIterator; loopRegionsIterator != parsedRegions.end(); loopRegionsIterator++)
455  {
456  int numberConnections(0), possibleConnections(0);
457  double summedFiberCount(0.0);
458  std::vector<std::string> loopLabelsVector = loopRegionsIterator->second;
459  std::string loopName = loopRegionsIterator->first;
460 
461  for (int loop(0); loop < regionLabelsVector.size(); loop++)
462  {
463  if (thresholdedNetwork->CheckForLabel(regionLabelsVector.at(loop)))
464  {
465  for (int innerLoop(0); innerLoop < loopLabelsVector.size(); innerLoop++)
466  {
467  if (thresholdedNetwork->CheckForLabel(loopLabelsVector.at(loop)))
468  {
469  bool exists = thresholdedNetwork->EdgeExists(
470  labelToIdMap.find(regionLabelsVector.at(loop))->second,
471  labelToIdMap.find(loopLabelsVector.at(innerLoop))->second);
472  possibleConnections++;
473  if (exists)
474  {
475  numberConnections++;
476  summedFiberCount += thresholdedNetwork->GetEdge(
477  labelToIdMap.find(regionLabelsVector.at(loop))->second,
478  labelToIdMap.find(loopLabelsVector.at(innerLoop))->second).weight;
479  }
480  }
481  else
482  {
483  MITK_ERROR << "Illegal label. Label: \"" << loopLabelsVector.at(loop) << "\" not found.";
484  }
485  }
486  }
487  else
488  {
489  MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at(loop) << "\" not found.";
490  }
491  }
492 
493  if (firstRun)
494  {
495  regionalHeaderStream << " " << regionName << "_" << loopName << "_Connections "
496  << " " << regionName << "_" << loopName << "_possibleConnections "
497  << " " << regionName << "_" << loopName << "_ConnectingFibers";
498  }
499 
500  regionalDataStream << " " << numberConnections
501  << " " << possibleConnections
502  << " " << summedFiberCount;
503 
504  }
505  }
506  }
507 
508  firstRun = false;
509  }
510 
511  }// end calculate local averages
512 
513  if( !noGlobalStatistics )
514  {
515  std::cout << "Writing to " << globalOutName;
516  std::ofstream glocalOutFile( globalOutName.c_str(), ios::out );
517  if( ! glocalOutFile.is_open() )
518  {
519  std::string errorMessage = "Could not open " + globalOutName + " for writing.";
520  MITK_ERROR << errorMessage;
521  return EXIT_FAILURE;
522  }
523  glocalOutFile << globalHeaderStream.str() << globalDataStream.str();
524  glocalOutFile.close();
525  }
526 
527  if( localLabels.size() > 0 )
528  {
529  std::cout << "Writing to " << localOutName;
530  std::ofstream localOutFile( localOutName.c_str(), ios::out );
531  if( ! localOutFile.is_open() )
532  {
533  std::string errorMessage = "Could not open " + localOutName + " for writing.";
534  MITK_ERROR << errorMessage;
535  return EXIT_FAILURE;
536  }
537  localOutFile << localHeaderStream.str() << localDataStream.str();
538  localOutFile.close();
539  }
540 
541  if( parsedRegions.size() > 0 )
542  {
543  std::cout << "Writing to " << regionalOutName;
544  std::ofstream regionalOutFile( regionalOutName.c_str(), ios::out );
545  if( ! regionalOutFile.is_open() )
546  {
547  std::string errorMessage = "Could not open " + regionalOutName + " for writing.";
548  MITK_ERROR << errorMessage;
549  return EXIT_FAILURE;
550  }
551  regionalOutFile << regionalHeaderStream.str() << regionalDataStream.str();
552  regionalOutFile.close();
553  }
554 
555  return EXIT_SUCCESS;
556  }
557  catch (itk::ExceptionObject e)
558  {
559  std::cout << e;
560  return EXIT_FAILURE;
561  }
562  catch (std::exception e)
563  {
564  std::cout << e.what();
565  return EXIT_FAILURE;
566  }
567  catch (...)
568  {
569  std::cout << "ERROR!?!";
570  return EXIT_FAILURE;
571  }
572  std::cout << "DONE";
573  return EXIT_SUCCESS;
574 }
itk::SmartPointer< Self > Pointer
bool CheckForLabel(std::string targetLabel) const
Base of all data objects.
Definition: mitkBaseData.h:39
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false)
Definition: usAny.h:163
void setCategory(std::string category)
int main(int argc, char *argv[])
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
std::vector< std::string > StringContainerType
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage)
Load a file into the given DataStorage.
Definition: mitkIOUtil.cpp:483
void setTitle(std::string title)
Connectomics Network Class.
void setDescription(std::string description)
static std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.