Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
MRSignal2ConcentrationMiniApp.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 // std includes
14 #include <string>
15 
16 // itk includes
17 #include "itksys/SystemTools.hxx"
18 
19 // CTK includes
20 #include "mitkCommandLineParser.h"
21 
22 // MITK includes
23 #include <mitkIOUtil.h>
24 #include <mitkImageTimeSelector.h>
25 #include <mitkImageCast.h>
27 #include <mitkModelFitUIDHelper.h>
28 
30 
31 std::string inFilename;
32 std::string outFileName;
33 
35 
36 bool verbose(false);
37 
38 bool t1_absolute(false);
39 bool t1_relative(false);
40 bool t1_flash(false);
41 bool t2(false);
42 
43 float k(1.0);
44 float te(0);
45 float rec_time(0);
46 float relaxivity(0);
47 float rel_time(0);
48 
50 {
51  // set general information about your MiniApp
52  parser.setCategory("Dynamic Data Analysis Tools");
53  parser.setTitle("MR Signal to Concentration Converter");
54  parser.setDescription("MiniApp that allows to convert a T1 or T2 signal image into a concentration image for perfusion analysis.");
55  parser.setContributor("DKFZ MIC");
57 
59  // how should arguments be prefixed
60  parser.setArgumentPrefix("--", "-");
61  // add each argument, unless specified otherwise each argument is optional
62  // see mitkCommandLineParser::addArgument for more information
63  parser.beginGroup("Required I/O parameters");
64  parser.addArgument(
65  "input", "i", mitkCommandLineParser::File, "Input file", "input 3D+t image file", us::Any(), false, false, false, mitkCommandLineParser::Input);
66  parser.addArgument("output",
67  "o",
69  "Output file",
70  "where to save the output concentration image.",
71  us::Any(),
72  false, false, false, mitkCommandLineParser::Output);
73  parser.endGroup();
74 
75  parser.beginGroup("Conversion parameters");
76  parser.addArgument(
77  "t1-absolute", "", mitkCommandLineParser::Bool, "T1 absolute signal enhancement", "Activate conversion for T1 absolute signal enhancement.");
78  parser.addArgument(
79  "t1-relative", "", mitkCommandLineParser::Bool, "T1 relative signal enhancement", "Activate conversion for T1 relative signal enhancement.");
80  parser.addArgument(
81  "t1-flash", "", mitkCommandLineParser::Bool, "T1 turbo flash", "Activate specific conversion for T1 turbo flash sequences.");
82  parser.addArgument(
83  "t2", "", mitkCommandLineParser::Bool, "T2 signal conversion", "Activate conversion for T2 signal enhancement to concentration.");
84 
85  parser.addArgument(
86  "k", "k", mitkCommandLineParser::Float, "Conversion factor k", "Needed for the following conversion modes: T1-absolute, T1-relative, T2. Default value is 1.", us::Any(1));
87  parser.addArgument(
88  "recovery-time", "", mitkCommandLineParser::Float, "Recovery time", "Needed for the following conversion modes: T1-flash.");
89  parser.addArgument(
90  "relaxivity", "", mitkCommandLineParser::Float, "Relaxivity", "Needed for the following conversion modes: T1-flash.");
91  parser.addArgument(
92  "relaxation-time", "", mitkCommandLineParser::Float, "Relaxation time", "Needed for the following conversion modes: T1-flash.");
93  parser.addArgument(
94  "te", "", mitkCommandLineParser::Float, "Echo time TE", "Needed for the following conversion modes: T2.", us::Any(1));
95 
96  parser.beginGroup("Optional parameters");
97  parser.addArgument(
98  "verbose", "v", mitkCommandLineParser::Bool, "Verbose Output", "Whether to produce verbose output");
99  parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text");
100  parser.endGroup();
102 }
103 
104 bool configureApplicationSettings(std::map<std::string, us::Any> parsedArgs)
105 {
106  if (parsedArgs.size() == 0)
107  return false;
108 
109  inFilename = us::any_cast<std::string>(parsedArgs["input"]);
110  outFileName = us::any_cast<std::string>(parsedArgs["output"]);
111 
112  verbose = false;
113  if (parsedArgs.count("verbose"))
114  {
115  verbose = us::any_cast<bool>(parsedArgs["verbose"]);
116  }
117 
118  t1_absolute = false;
119  if (parsedArgs.count("t1-absolute"))
120  {
121  t1_absolute = us::any_cast<bool>(parsedArgs["t1-absolute"]);
122  }
123 
124  t1_relative = false;
125  if (parsedArgs.count("t1-relative"))
126  {
127  t1_relative = us::any_cast<bool>(parsedArgs["t1-relative"]);
128  }
129 
130  t1_flash = false;
131  if (parsedArgs.count("t1-flash"))
132  {
133  t1_flash = us::any_cast<bool>(parsedArgs["t1-flash"]);
134  }
135 
136  t2 = false;
137  if (parsedArgs.count("t2"))
138  {
139  t2 = us::any_cast<bool>(parsedArgs["t2"]);
140  }
141 
142  k = 0.0;
143  if (parsedArgs.count("k"))
144  {
145  k = us::any_cast<float>(parsedArgs["k"]);
146  }
147 
148  relaxivity = 0.0;
149  if (parsedArgs.count("relaxivity"))
150  {
151  relaxivity = us::any_cast<float>(parsedArgs["relaxivity"]);
152  }
153 
154  rec_time = 0.0;
155  if (parsedArgs.count("recovery-time"))
156  {
157  rec_time = us::any_cast<float>(parsedArgs["recovery-time"]);
158  }
159 
160  rel_time = 0.0;
161  if (parsedArgs.count("relaxation-time"))
162  {
163  rel_time = us::any_cast<float>(parsedArgs["relaxation-time"]);
164  }
165 
166  te = 0.0;
167  if (parsedArgs.count("te"))
168  {
169  te = us::any_cast<float>(parsedArgs["te"]);
170  }
171 
172  //consistency checks
173  int modeCount = 0;
174  if (t1_absolute) ++modeCount;
175  if (t1_flash) ++modeCount;
176  if (t1_relative) ++modeCount;
177  if (t2) ++modeCount;
178 
179  if (modeCount==0)
180  {
181  mitkThrow() << "Invalid program call. Please select the type of conversion.";
182  }
183 
184  if (modeCount >1)
185  {
186  mitkThrow() << "Invalid program call. Please select only ONE type of conversion.";
187  }
188 
189  if (!k && (t2 || t1_absolute || t1_relative))
190  {
191  mitkThrow() << "Invalid program call. Please set 'k', if you use t1-absolute, t1-relative or t2.";
192  }
193 
194  if (!te && t2)
195  {
196  mitkThrow() << "Invalid program call. Please set 'te', if you use t2 mode.";
197  }
198 
199  if ((!rec_time||!rel_time||!relaxivity) && t1_flash)
200  {
201  mitkThrow() << "Invalid program call. Please set 'recovery-time', 'relaxation-time' and 'relaxivity', if you use t1-flash mode.";
202  }
203 
204  return true;
205 }
206 
208 {
209  mitk::ConcentrationCurveGenerator::Pointer concentrationGen =
211  concentrationGen->SetDynamicImage(image);
212 
213  concentrationGen->SetisTurboFlashSequence(t1_flash);
214  concentrationGen->SetAbsoluteSignalEnhancement(t1_absolute);
215  concentrationGen->SetRelativeSignalEnhancement(t1_relative);
216 
217  concentrationGen->SetisT2weightedImage(t2);
218 
219  if (t1_flash)
220  {
221  concentrationGen->SetRecoveryTime(rec_time);
222  concentrationGen->SetRelaxationTime(rel_time);
223  concentrationGen->SetRelaxivity(relaxivity);
224  }
225  else if (t2)
226  {
227  concentrationGen->SetT2Factor(k);
228  concentrationGen->SetT2EchoTime(te);
229  }
230  else
231  {
232  concentrationGen->SetFactor(k);
233  }
234 
235  mitk::Image::Pointer concentrationImage = concentrationGen->GetConvertedImage();
236 
237  mitk::EnsureModelFitUID(concentrationImage);
238  mitk::IOUtil::Save(concentrationImage, outFileName);
239 
240  std::cout << "Store result: " << outFileName << std::endl;
241 }
242 
243 int main(int argc, char* argv[])
244 {
245  mitkCommandLineParser parser;
246  setupParser(parser);
247  const std::map<std::string, us::Any>& parsedArgs = parser.parseArguments(argc, argv);
248  if (!configureApplicationSettings(parsedArgs))
249  {
250  return EXIT_FAILURE;
251  };
252 
253  mitk::PreferenceListReaderOptionsFunctor readerFilterFunctor = mitk::PreferenceListReaderOptionsFunctor({ "MITK DICOM Reader v2 (classic config)" }, { "MITK DICOM Reader" });
254 
255  // Show a help message
256  if (parsedArgs.count("help") || parsedArgs.count("h"))
257  {
258  std::cout << parser.helpText();
259  return EXIT_SUCCESS;
260  }
261 
263  try
264  {
265  image = mitk::IOUtil::Load<mitk::Image>(inFilename, &readerFilterFunctor);
266  std::cout << "Input: " << inFilename << std::endl;
267 
268  doConversion();
269 
270  std::cout << "Processing finished." << std::endl;
271 
272  return EXIT_SUCCESS;
273  }
274  catch (const itk::ExceptionObject& e)
275  {
276  MITK_ERROR << e.what();
277  return EXIT_FAILURE;
278  }
279  catch (const std::exception& e)
280  {
281  MITK_ERROR << e.what();
282  return EXIT_FAILURE;
283  }
284  catch (...)
285  {
286  MITK_ERROR << "Unexpected error encountered.";
287  return EXIT_FAILURE;
288  }
289 }
Option callback functor with a preference list/ black list option selection strategy.
float k(1.0)
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void setupParser(mitkCommandLineParser &parser)
bool configureApplicationSettings(std::map< std::string, us::Any > parsedArgs)
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
mitk::Image::Pointer image
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, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
std::string inFilename
float relaxivity(0)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
std::string outFileName
bool t1_absolute(false)
bool t1_relative(false)
#define mitkThrow()
bool t2(false)
Definition: usAny.h:163
NodeUIDType MITKMODELFIT_EXPORT EnsureModelFitUID(mitk::BaseData *data)
float rec_time(0)
std::string helpText() const
int main(int argc, char *argv[])
void setCategory(std::string category)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:774
float rel_time(0)
void setTitle(std::string title)
void setDescription(std::string description)
bool verbose(false)
bool t1_flash(false)
void beginGroup(const std::string &description)
float te(0)