Shapeworks Studio  2.1
Shape analysis software suite
itkPSMEntropyModelFilterMultiscaleTest.cxx
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #include <iostream>
19 #include "itkImage.h"
20 #include "itkImageFileReader.h"
21 #include "itkPSMEntropyModelFilter.h"
22 #include "itkPSMProjectReader.h"
23 #include "itkCommand.h"
24 
25 namespace itk{
26 
27 class MyMultiscaleIterationCommand : public itk::Command
28 {
29 public:
32  typedef Command Superclass;
33  typedef SmartPointer< Self > Pointer;
34  typedef SmartPointer< const Self > ConstPointer;
35 
36  typedef Image<float, 3> ImageType;
37 
40 
42  itkNewMacro(Self);
43 
45  virtual void Execute(Object *caller, const EventObject &)
46  {
48  = static_cast<PSMEntropyModelFilter<ImageType> *>(caller);
49 
50  // Print every 10 iterations
51  if (o->GetNumberOfElapsedIterations() % 10 != 0) return;
52 
53  std::cout << "Scale = " << o->GetCurrentScale() << std::endl;
54  std::cout << "Iteration # " << o->GetNumberOfElapsedIterations() << std::endl;
55  std::cout << " Eigenmode variances: ";
56  for (unsigned int i = 0; i < o->GetShapePCAVariances().size(); i++)
57  {
58  std::cout << o->GetShapePCAVariances()[i] << " ";
59  }
60  std::cout << std::endl;
61  std::cout << " Regularization = " << o->GetRegularizationConstant() << std::endl;
62  }
63  virtual void Execute(const Object *, const EventObject &)
64  {
65  std::cout << "SHOULDN'T BE HERE" << std::endl;
66  }
67 
68 protected:
71 private:
72  MyMultiscaleIterationCommand(const Self &); //purposely not implemented
73  void operator=(const Self &); //purposely not implemented
74 };
75 
76 } // end namespace itk
77 
79 int itkPSMEntropyModelFilterMultiscaleTest(int argc, char* argv[] )
80 {
81  bool passed = true;
82  std::string errstring = "";
83  std::string output_path = "";
84  std::string input_path_prefix = "";
85 
86  // Check for proper arguments
87  if (argc < 2)
88  {
89  std::cout << "Wrong number of arguments. \nUse: "
90  << "itkPSMEntropyModelFilterTest parameter_file [output_path]\n"
91  << "See itk::PSMParameterFileReader for documentation on the parameter file format."
92  << std::endl;
93  return EXIT_FAILURE;
94  }
95 
96  if (argc >2)
97  {
98  output_path = std::string(argv[2]);
99  }
100 
101  if (argc >3)
102  {
103  input_path_prefix = std::string(argv[3]);
104  }
105 
106  typedef itk::Image<float, 3> ImageType;
107 
108  try
109  {
110  // Read the project parameters
111  itk::PSMProjectReader::Pointer xmlreader =
112  itk::PSMProjectReader::New();
113  xmlreader->SetFileName(argv[1]);
114  xmlreader->Update();
115 
116  itk::PSMProject::Pointer project = xmlreader->GetOutput();
117 
118  // Create the modeling filter and set up the optimization.
119  itk::PSMEntropyModelFilter<ImageType>::Pointer P
121 
122  // Setup the Callback function that is executed after each
123  // iteration of the solver.
124  itk::MyMultiscaleIterationCommand::Pointer mycommand = itk::MyMultiscaleIterationCommand::New();
125  P->AddObserver(itk::IterationEvent(), mycommand);
126 
127  // Load the distance transforms
128  const std::vector<std::string> &dt_files = project->GetDistanceTransforms();
129  std::cout << "Reading distance transforms ..." << std::endl;
130  for (unsigned int i = 0; i < dt_files.size(); i++)
131  {
132  itk::ImageFileReader<ImageType>::Pointer reader =
133  itk::ImageFileReader<ImageType>::New();
134  reader->SetFileName(input_path_prefix + dt_files[i]);
135  reader->Update();
136 
137  std::cout << " " << (input_path_prefix + dt_files[i]) << std::endl;
138 
139  P->SetInput(i,reader->GetOutput());
140  }
141  std::cout << "Done!" << std::endl;
142 
143  // Exception on failure
144  unsigned int number_of_scales = project->GetNumberOfOptimizationScales();
145  std::cout << "Found " << number_of_scales << " number of scales. " << std::endl;
146 
147  // We need vectors of parameters, one for each scale.
148  std::vector<double> regularization_initial(number_of_scales);
149  std::vector<double> regularization_final(number_of_scales);
150  std::vector<double> regularization_decayspan(number_of_scales);
151  std::vector<double> tolerance(number_of_scales);
152  std::vector<unsigned int> maximum_iterations(number_of_scales);
153 
154  // Read parameters for each scale
155  for (unsigned int i = 0; i < number_of_scales; i++)
156  {
157  std::cout << "Optimization parameters for scale " << i << ": " << std::endl;
158  regularization_initial[i] = project->GetOptimizationAttribute("regularization_initial",i);
159  std::cout << " regularization_initial = " << regularization_initial[i] << std::endl;
160  regularization_final[i] = project->GetOptimizationAttribute("regularization_final",i);
161  std::cout << " regularization_final = " << regularization_final[i] << std::endl;
162  regularization_decayspan[i] = project->GetOptimizationAttribute("regularization_decayspan",i);
163  std::cout << " regularization_decayspan = " << regularization_decayspan[i] << std::endl;
164  tolerance[i] = project->GetOptimizationAttribute("tolerance",i);
165  std::cout << " tolerance = " << tolerance[i] << std::endl;
166  maximum_iterations[i] = static_cast<unsigned int>(project->GetOptimizationAttribute("maximum_iterations",i));
167  std::cout << " maximum_iterations = " << maximum_iterations[i] << std::endl;
168  }
169 
170  P->SetNumberOfScales(number_of_scales);
171  P->SetRegularizationDecaySpan(regularization_decayspan);
172  P->SetRegularizationInitial(regularization_initial);
173  P->SetRegularizationFinal(regularization_final);
174  P->SetTolerance(tolerance);
175  P->SetMaximumNumberOfIterations(maximum_iterations);
176  P->Update();
177 
178  // Print out points for domain d
179  // Load the model initialization. It should be specified as a model with a name.
180  const std::vector<std::string> &out_files = project->GetModel(std::string("optimized"));
181  if (out_files.size() != P->GetParticleSystem()->GetNumberOfDomains())
182  {
183  errstring += "Number of output files does not match the number of particle domains (inputs).";
184  passed = false;
185  }
186 
187  if (passed = true)
188  {
189  for (unsigned int d = 0; d < P->GetParticleSystem()->GetNumberOfDomains(); d++)
190  {
191  // Open the output file.
192  std::string fname = output_path + out_files[d];
193  std::ofstream out( fname.c_str() );
194  if ( !out )
195  {
196  errstring += "Could not open point file for output: ";
197  }
198  else
199  {
200  for (unsigned int j = 0; j < P->GetParticleSystem()->GetNumberOfParticles(d); j++)
201  {
202  for (unsigned int i = 0; i < 3; i++)
203  {
204  out << P->GetParticleSystem()->GetPosition(j,d)[i] << " ";
205  }
206  out << std::endl;
207  }
208  }
209  }
210  }
211 
212 
213  }
214  catch(itk::ExceptionObject &e)
215  {
216  errstring = "ITK exception with description: " + std::string(e.GetDescription())
217  + std::string("\n at location:") + std::string(e.GetLocation())
218  + std::string("\n in file:") + std::string(e.GetFile());
219  passed = false;
220  }
221  catch(...)
222  {
223  errstring = "Unknown exception thrown";
224  passed = false;
225  }
226 
227  if (passed)
228  {
229  std::cout << "All tests passed" << std::endl;
230  return EXIT_SUCCESS;
231  }
232  else
233  {
234  std::cout << "Test failed with the following error:" << std::endl;
235  std::cout << errstring << std::endl;
236  return EXIT_FAILURE;
237  }
238 }
239 
void SetMaximumNumberOfIterations(const std::vector< unsigned int > &n)
void SetNumberOfScales(unsigned int n)
unsigned int GetNumberOfElapsedIterations() const
virtual void Execute(Object *caller, const EventObject &)
const std::vector< double > & GetShapePCAVariances() const
itkTypeMacro(MyMultiscaleIterationCommand, Command)
void SetRegularizationInitial(const std::vector< double > &v)
void SetInput(const std::string &s, itk::DataObject *o)
void SetTolerance(const std::vector< double > &v)