ANIMA  4.0
animaDTIProbabilisticTractography.cxx
Go to the documentation of this file.
2 #include <itkTimeProbe.h>
3 
4 #include <tclap/CmdLine.h>
5 
8 
9 #include <itkCommand.h>
10 
11 #include <animaShapesWriter.h>
12 
13 void ComputeKappaPolynomialCoefficients(std::vector <double> &resVal)
14 {
15  // Values fitted from [Zhang, 2009, Fig.3] : NEEDS TO BE RE-CHECKED
16  resVal[2] = 198.81;
17  resVal[1] = -73.214;
18  resVal[0] = 10.976;
19 }
20 
21 //Update progression of the process
22 void eventCallback (itk::Object* caller, const itk::EventObject& event, void* clientData)
23 {
24  itk::ProcessObject * processObject = (itk::ProcessObject*) caller;
25  std::cout<<"\033[K\rProgression: "<<(int)(processObject->GetProgress() * 100)<<"%"<<std::flush;
26 }
27 
28 int main(int argc, char* argv[])
29 {
30  TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);
31 
32  // Mandatory arguments
33  TCLAP::ValueArg<std::string> dtiArg("i","dti","Input diffusion tensor image",true,"","dti image",cmd);
34  TCLAP::ValueArg<std::string> seedMaskArg("s","seed-mask","Seed mask",true,"","seed",cmd);
35  TCLAP::ValueArg<std::string> fibersArg("o","fibers","Output fibers",true,"","fibers",cmd);
36  TCLAP::ValueArg<std::string> b0Arg("b","b0","B0 image",true,"","b0 image",cmd);
37  TCLAP::ValueArg<std::string> noiseArg("N","noise","Noise image",true,"","noise image",cmd);
38 
39  TCLAP::ValueArg<unsigned int> colinearityModeArg("","col-init-mode",
40  "Colinearity mode for initialization - 0: center, 1: outward, 2: top, 3: bottom, 4: left, 5: right, 6: front, 7: back (default: 0)",
41  false,0,"colinearity mode for initialization",cmd);
42  TCLAP::ValueArg<unsigned int> initialDirectionModeArg("","init-mode",
43  "Mode for initialization - 0: take most colinear direction, 1: take highest weighted direction (default: 1)",
44  false,1,"mode for initialization",cmd);
45 
46  // Optional mask arguments
47  TCLAP::ValueArg<std::string> cutMaskArg("c","cut-mask","Mask for cutting fibers (default: none)",false,"","cut mask",cmd);
48  TCLAP::ValueArg<std::string> forbiddenMaskArg("f","forbidden-mask","Mask for removing fibers (default: none)",false,"","remove mask",cmd);
49  TCLAP::ValueArg<std::string> filterMaskArg("","filter-mask","Mask for filtering fibers (default: none)",false,"","filter mask",cmd);
50 
51  TCLAP::ValueArg<double> faThrArg("","fa-thr","FA threshold (default: 0.2)",false,0.2,"fa threshold",cmd);
52  TCLAP::ValueArg<double> stepLengthArg("","step-length","Length of each step (default: 1)",false,1.0,"step length",cmd);
53  TCLAP::ValueArg<int> nbFibersArg("","nb-fibers","Number of starting particle filters (n*n*n) per voxel (default: 1)",false,1,"number of seeds per voxel",cmd);
54 
55  TCLAP::ValueArg<double> minLengthArg("","min-length","Minimum length for a fiber to be considered for computation (default: 10mm)",false,10.0,"minimum length",cmd);
56  TCLAP::ValueArg<double> maxLengthArg("","max-length","Maximum length of a tract (default: 150mm)",false,150.0,"maximum length",cmd);
57 
58  TCLAP::ValueArg<unsigned int> nbParticlesArg("n","nb-particles","Number of particles per filter (default: 1000)",false,1000,"number of particles",cmd);
59  TCLAP::ValueArg<unsigned int> clusterMinSizeArg("","cluster-min-size","Minimal number of particles per cluster before split (default: 10)",false,10,"minimal cluster size",cmd);
60 
61  TCLAP::ValueArg<double> resampThrArg("r","resamp-thr","Resampling relative threshold (default: 0.8)",false,0.8,"resampling threshold",cmd);
62 
63  TCLAP::ValueArg<double> prolateThrArg("p","prolate-thr","Threshold between prolate and oblate tensors (default: 0.25)",false,0.25,"tensor shape threshold",cmd);
64  TCLAP::ValueArg<double> trashThrArg("","trash-thr","Relative threshold to keep fibers in trash (default: 0.1)",false,0.1,"trash threshold",cmd);
65  TCLAP::ValueArg<double> kappaPriorArg("k","kappa-prior","Kappa of prior distribution (default: 15)",false,15.0,"prior kappa",cmd);
66 
67  TCLAP::ValueArg<double> distThrArg("","dist-thr","Hausdorff distance threshold for mergine clusters (default: 0.5)",false,0.5,"merging threshold",cmd);
68  TCLAP::ValueArg<double> kappaThrArg("","kappa-thr","Kappa threshold for splitting clusters (default: 30)",false,30.0,"splitting threshold",cmd);
69 
70  TCLAP::ValueArg<unsigned int> clusterDistArg("","cluster-dist","Distance between clusters: choices are 0 (AHD), 1 (HD, default) or 2 (MHD)",false,1,"cluster distance",cmd);
71 
72  TCLAP::SwitchArg averageClustersArg("M","average-clusters","Output only cluster mean",cmd,false);
73  TCLAP::SwitchArg addLocalDataArg("L","local-data","Add local data information to output tracks",cmd);
74 
75  TCLAP::ValueArg<unsigned int> nbThreadsArg("T","nb-threads","Number of threads to run on (default: all available)",false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),"number of threads",cmd);
76 
77  try
78  {
79  cmd.parse(argc,argv);
80  }
81  catch (TCLAP::ArgException& e)
82  {
83  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
84  return(1);
85  }
86 
88  typedef MainFilterType::InputModelImageType InputModelImageType;
89  typedef MainFilterType::MaskImageType MaskImageType;
90  typedef MainFilterType::Vector3DType Vector3DType;
91 
92  MainFilterType::Pointer dtiTracker = MainFilterType::New();
93 
94  // Load model image
95  typedef anima::LogTensorImageFilter <double, 3> LogFilterType;
96 
97  LogFilterType::Pointer logFilter = LogFilterType::New();
98  logFilter->SetInput(anima::readImage <InputModelImageType> (dtiArg.getValue()));
99  logFilter->SetNumberOfWorkUnits(nbThreadsArg.getValue());
100 
101  logFilter->Update();
102  dtiTracker->SetInputModelImage(logFilter->GetOutput());
103 
104  dtiTracker->SetInitialColinearityDirection((MainFilterType::ColinearityDirectionType)colinearityModeArg.getValue());
105  dtiTracker->SetInitialDirectionMode((MainFilterType::InitialDirectionModeType)initialDirectionModeArg.getValue());
106 
107  std::vector <double> kappaCoefficients(3,0);
108  ComputeKappaPolynomialCoefficients(kappaCoefficients);
109  dtiTracker->SetKappaPolynomialCoefficients(kappaCoefficients);
110 
111  // Load seed mask
112  dtiTracker->SetSeedMask(anima::readImage <MaskImageType> (seedMaskArg.getValue()));
113 
114  // Load cut mask
115  if (cutMaskArg.getValue() != "")
116  dtiTracker->SetCutMask(anima::readImage <MaskImageType> (cutMaskArg.getValue()));
117 
118  // Load forbidden mask
119  if (forbiddenMaskArg.getValue() != "")
120  dtiTracker->SetForbiddenMask(anima::readImage <MaskImageType> (forbiddenMaskArg.getValue()));
121 
122  // Load filter mask
123  if (filterMaskArg.getValue() != "")
124  dtiTracker->SetFilterMask(anima::readImage <MaskImageType> (filterMaskArg.getValue()));
125 
126  typedef MainFilterType::ScalarImageType ScalarImageType;
127  dtiTracker->SetB0Image(anima::readImage <ScalarImageType> (b0Arg.getValue()));
128  dtiTracker->SetNoiseImage(anima::readImage <ScalarImageType> (noiseArg.getValue()));
129 
130  dtiTracker->SetNumberOfFibersPerPixel(nbFibersArg.getValue());
131  dtiTracker->SetStepProgression(stepLengthArg.getValue());
132  dtiTracker->SetFAThreshold(faThrArg.getValue());
133  dtiTracker->SetMinLengthFiber(minLengthArg.getValue());
134  dtiTracker->SetMaxLengthFiber(maxLengthArg.getValue());
135 
136  dtiTracker->SetNumberOfParticles(nbParticlesArg.getValue());
137  dtiTracker->SetMinimalNumberOfParticlesPerClass(clusterMinSizeArg.getValue());
138  dtiTracker->SetResamplingThreshold(resampThrArg.getValue());
139  dtiTracker->SetFiberTrashThreshold(trashThrArg.getValue());
140 
141  dtiTracker->SetThresholdForProlateTensor(prolateThrArg.getValue());
142  dtiTracker->SetKappaOfPriorDistribution(kappaPriorArg.getValue());
143 
144  dtiTracker->SetPositionDistanceFuseThreshold(distThrArg.getValue());
145  dtiTracker->SetKappaSplitThreshold(kappaThrArg.getValue());
146 
147  dtiTracker->SetClusterDistance(clusterDistArg.getValue());
148 
149  bool computeLocalColors = (fibersArg.getValue().find(".fds") != std::string::npos) && (addLocalDataArg.isSet());
150  dtiTracker->SetComputeLocalColors(computeLocalColors);
151  dtiTracker->SetMAPMergeFibers(averageClustersArg.isSet());
152  dtiTracker->SetNumberOfWorkUnits(nbThreadsArg.getValue());
153 
154  itk::CStyleCommand::Pointer callback = itk::CStyleCommand::New();
155  callback->SetCallback(eventCallback);
156  dtiTracker->AddObserver(itk::ProgressEvent(), callback);
157 
158  itk::TimeProbe tmpTime;
159  tmpTime.Start();
160 
161  dtiTracker->Update();
162  dtiTracker->RemoveAllObservers();
163 
164  tmpTime.Stop();
165  std::cout << "Tracking time: " << tmpTime.GetTotal() << "s" << std::endl;
166 
167  anima::ShapesWriter writer;
168  writer.SetInputData(dtiTracker->GetOutput());
169  writer.SetFileName(fibersArg.getValue());
170  writer.Update();
171 
172  return EXIT_SUCCESS;
173 }
void SetInputData(vtkPolyData *data)
void eventCallback(itk::Object *caller, const itk::EventObject &event, void *clientData)
int main(int argc, char *argv[])
void ComputeKappaPolynomialCoefficients(std::vector< double > &resVal)
void SetFileName(std::string &name)