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
TumorResponseEvaluationTool.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 // MITK - DataCollection
18 #include <mitkCollectionReader.h>
19 #include <mitkCollectionWriter.h>
20 #include <mitkDataCollection.h>
21 #include <mitkImageCast.h>
22 
26 // CTK
27 #include "mitkCommandLineParser.h"
28 // ITK
29 #include <itkImageRegionIterator.h>
30 
31 using namespace std;
32 
33 int main(int argc, char *argv[])
34 {
35  // Setup CLI Module parsable interface
36  mitkCommandLineParser parser;
37  parser.setTitle("Tumor Invasion Analysis");
38  parser.setCategory("Tumor Analysis");
39  parser.setDescription("Learns and predicts Invasion behavior");
40  parser.setContributor("MBI");
41 
42  parser.setArgumentPrefix("--", "-");
43  // Add command line argument names
44  parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Show options");
45  parser.addArgument("loadFile", "l", mitkCommandLineParser::InputFile, "DataCollection File");
46  parser.addArgument(
47  "colIds", "c", mitkCommandLineParser::String, "Patient Identifiers from DataCollection used for training");
48  parser.addArgument(
49  "testId", "t", mitkCommandLineParser::String, "Patient Identifier from DataCollection used for testing");
50  parser.addArgument("features", "b", mitkCommandLineParser::String, "Features");
51  parser.addArgument("stats", "s", mitkCommandLineParser::String, "Output file for stats");
52  parser.addArgument("ratio", "q", mitkCommandLineParser::Float, "ratio of tumor to healthy");
53  parser.addArgument("treeDepth", "d", mitkCommandLineParser::Int, "limits tree depth");
54  parser.addArgument("forestSize", "f", mitkCommandLineParser::Int, "number of trees");
55  parser.addArgument("configName", "n", mitkCommandLineParser::String, "human readable name for configuration");
56  parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "output folder for results");
57  parser.addArgument("forest", "t", mitkCommandLineParser::OutputFile, "store trained forest to file");
58 
59  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
60  // Show a help message
61  if (parsedArgs.size() == 0)
62  return EXIT_SUCCESS;
63  if (parsedArgs.count("help") || parsedArgs.count("h"))
64  {
65  std::cout << parser.helpText();
66  return EXIT_SUCCESS;
67  }
68 
69  // Default values
70  float ratio = 1.0;
71  bool useStatsFile = false;
72  unsigned int forestSize = 250;
73  unsigned int treeDepth = 0;
74  std::string configName = "";
75  std::string outputFolder = "";
76  std::string forestFile = "";
77 
78  std::vector<std::string> features;
79  std::vector<std::string> trainingIds;
80  std::vector<std::string> testingIds;
81  std::vector<std::string> loadIds; // features + masks needed for training and evaluation
82  std::string outputFile;
83  std::string xmlFile;
84  std::ofstream experimentFS;
85 
86  // Parse input parameters
87  {
88  if (parsedArgs.count("colIds") || parsedArgs.count("c"))
89  {
90  std::istringstream ss(us::any_cast<string>(parsedArgs["colIds"]));
91  std::string token;
92 
93  while (std::getline(ss, token, ','))
94  trainingIds.push_back(token);
95  }
96 
97  if (parsedArgs.count("output") || parsedArgs.count("o"))
98  {
99  outputFolder = us::any_cast<string>(parsedArgs["output"]);
100  }
101 
102  if (parsedArgs.count("configName") || parsedArgs.count("n"))
103  {
104  configName = us::any_cast<string>(parsedArgs["configName"]);
105  }
106 
107  if (parsedArgs.count("features") || parsedArgs.count("b"))
108  {
109  std::istringstream ss(us::any_cast<string>(parsedArgs["features"]));
110  std::string token;
111 
112  while (std::getline(ss, token, ','))
113  features.push_back(token);
114  }
115 
116  if (parsedArgs.count("treeDepth") || parsedArgs.count("d"))
117  {
118  treeDepth = us::any_cast<int>(parsedArgs["treeDepth"]);
119  }
120 
121  if (parsedArgs.count("ratio") || parsedArgs.count("q"))
122  {
123  ratio = us::any_cast<float>(parsedArgs["ratio"]);
124  }
125 
126  if (parsedArgs.count("forestSize") || parsedArgs.count("f"))
127  {
128  forestSize = us::any_cast<int>(parsedArgs["forestSize"]);
129  }
130 
131  if (parsedArgs.count("stats") || parsedArgs.count("s"))
132  {
133  useStatsFile = true;
134  experimentFS.open(us::any_cast<string>(parsedArgs["stats"]).c_str(), std::ios_base::app);
135  }
136 
137  if (parsedArgs.count("forest") || parsedArgs.count("t"))
138  {
139  forestFile = us::any_cast<string>(parsedArgs["stats"]);
140  }
141 
142  if (parsedArgs.count("testId") || parsedArgs.count("t"))
143  {
144  std::istringstream ss(us::any_cast<string>(parsedArgs["testId"]));
145  std::string token;
146 
147  while (std::getline(ss, token, ','))
148  testingIds.push_back(token);
149  }
150 
151  for (unsigned int i = 0; i < features.size(); i++)
152  {
153  loadIds.push_back(features.at(i));
154  }
155  loadIds.push_back("GTV");
156  loadIds.push_back("BRAINMASK");
157  loadIds.push_back("TARGET");
158 
159  if (parsedArgs.count("stats") || parsedArgs.count("s"))
160  {
161  outputFile = us::any_cast<string>(parsedArgs["stats"]);
162  }
163 
164  if (parsedArgs.count("loadFile") || parsedArgs.count("l"))
165  {
166  xmlFile = us::any_cast<string>(parsedArgs["loadFile"]);
167  }
168  else
169  {
170  MITK_ERROR << parser.helpText();
171  return EXIT_FAILURE;
172  }
173  }
174 
175  mitk::DataCollection::Pointer trainCollection;
176  mitk::DataCollection::Pointer testCollection;
177  {
178  mitk::CollectionReader colReader;
179  // Load only relevant images
180  colReader.SetDataItemNames(loadIds);
181  colReader.AddSubColIds(testingIds);
182  testCollection = colReader.LoadCollection(xmlFile);
183  colReader.ClearDataElementIds();
184  colReader.ClearSubColIds();
185  colReader.SetDataItemNames(loadIds);
186  colReader.AddSubColIds(trainingIds);
187  trainCollection = colReader.LoadCollection(xmlFile);
188  }
189 
190  std::cout << "Setup Training" << std::endl;
192 
193  classifier.SetClassRatio(ratio);
194  classifier.SamplesWeightingActivated(true);
195  classifier.PrepareResponseSamples(trainCollection);
196  // Learning stage
197  std::cout << "Start Training" << std::endl;
198  classifier.LearnProgressionFeatures(trainCollection, features, forestSize, treeDepth);
199 
200  if (forestFile != "")
201  classifier.SaveRandomForest(forestFile);
202 
203  std::cout << "Start Predict" << std::endl;
204  classifier.PredictInvasion(testCollection, features);
205 
206  if (outputFolder != "")
207  {
208  std::cout << "Saving files to " << outputFolder << std::endl;
209  mitk::CollectionWriter::ExportCollectionToFolder(trainCollection, "/tmp/dumple");
210  }
211 
212  /* prepare target values to match training values:
213  * 0 - excluded (e.g. out of brainmask)
214  * 1 - no involvement (healthy all the time)
215  * 2 - formerly healthy, now tumor (rezivid)
216  * 3 - formerly tumor, now necroses (responsive)
217  */
218 
219  {
220  mitk::DataCollectionImageIterator<unsigned char, 3> gtvIter(testCollection, "GTV");
221  mitk::DataCollectionImageIterator<unsigned char, 3> targetIt(testCollection, "TARGET");
222 
223  while (!gtvIter.IsAtEnd())
224  {
225  if (targetIt.GetVoxel() == 0 && gtvIter.GetVoxel() == 0)
226  targetIt.SetVoxel(1);
227 
228  if (targetIt.GetVoxel() == 0 && gtvIter.GetVoxel() == 1)
229  targetIt.SetVoxel(3);
230 
231  if (targetIt.GetVoxel() == 1 && gtvIter.GetVoxel() == 0)
232  targetIt.SetVoxel(2);
233 
234  targetIt++;
235  gtvIter++;
236  }
237  }
238 
240  mitk::ProgressionValueToIndexMapper progressionValueToIndexMapper;
241  mitk::BinaryValueToIndexMapper binaryValueToIndexMapper;
242 
243  stats.SetCollection(testCollection);
244  stats.SetClassCount(4);
245  stats.SetGoldName("TARGET");
246  stats.SetTestName("RESULT");
247  stats.SetMaskName("BRAINMASK");
248  stats.SetGroundTruthValueToIndexMapper(&binaryValueToIndexMapper);
249  stats.SetTestValueToIndexMapper(&binaryValueToIndexMapper);
250 
251  stats.Update();
252  std::ostringstream outStr;
253  stats.Print(outStr, std::cout, true);
254  std::cout << std::endl << std::endl << outStr.str() << std::endl;
255 
256  if (useStatsFile)
257  std::cout << "dummy" << std::endl;
258 
259  if (outputFolder != "")
260  {
261  std::cout << "Saving files to " << outputFolder << std::endl;
262  mitk::CollectionWriter::ExportCollectionToFolder(testCollection, outputFolder);
263  }
264 
265  return EXIT_SUCCESS;
266 }
void SamplesWeightingActivated(bool isActive)
SamplesWeightingActivated If activated a weighted mask for the samples is calculated, weighting samples according to their location and ratio.
DataCollection::Pointer LoadCollection(const std::string &xmlFileName)
Build up a mitk::DataCollection from a XML resource.
int main(int argc, char *argv[])
void SetDataItemNames(std::vector< std::string > itemNames)
void Print(std::ostream &out, std::ostream &sout=std::cout, bool withHeader=false, std::string label="None")
void SaveRandomForest(std::string filename)
SaveRandomForest - Saves a trained random forest.
void SetTestName(std::string name)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void setContributor(std::string contributor)
void SetTestValueToIndexMapper(const ValueToIndexMapper *mapper)
STL namespace.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
void SetGroundTruthValueToIndexMapper(const ValueToIndexMapper *mapper)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
void PrepareResponseSamples(DataCollection *collection)
PrepareResponseSamples.
void SetMaskName(std::string name)
void SetGoldName(std::string name)
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)
void PredictInvasion(DataCollection *collection, std::vector< std::string > modalitiesList)
PredictGrowth - Classify voxels into remaining healthy / turning into tumor.
void SetCollection(DataCollection::Pointer collection)
void SetClassCount(vcl_size_t count)
void setCategory(std::string category)
static bool ExportCollectionToFolder(DataCollection *dataCollection, std::string xmlFile, std::vector< std::string > filter)
ExportCollectionToFolder.
The TumorInvasionAnalysis class - Classifies Tumor progression using RF and predicts on new cases...
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
void LearnProgressionFeatures(DataCollection *collection, std::vector< std::string > modalitiesList, vcl_size_t forestSize=300, vcl_size_t treeDepth=10)
LearnProgressionFeatures.
void SetClassRatio(ScalarType ratio)
SetClassRatio - set ratio of tumor voxels to healthy voxels that is to be used for training...
void AddSubColIds(std::vector< std::string > subColIds)
const char features[]
std::string helpText() const
void setTitle(std::string title)
void setDescription(std::string description)