19 #ifndef ____itkPSMCommandLineClass__hxx 20 #define ____itkPSMCommandLineClass__hxx 22 #include "itkPSMCommandLineClass.h" 31 template <
unsigned int VDimension>
32 PSMCommandLineClass<VDimension>
33 ::PSMCommandLineClass()
35 m_ProcrustesCounter = 0;
36 m_ReportInterval = 10;
37 m_ProjectReader = ProjectReaderType::New();
38 m_Project = ProjectType::New();
39 m_ProcrustesRegistration = ProcrustesRegistrationType::New();
40 m_PSMFilter = EntropyModelFilterType::New();
45 template <
unsigned int VDimension>
56 std::cout <<
" Eigenmode variances: ";
61 std::cout << std::endl;
62 std::cout <<
" Regularization = " << o->GetRegularizationConstant() << std::endl;
67 std::cout <<
"Optimization Scale " << (o->GetCurrentScale() + 1) <<
"/" 68 << o->GetNumberOfScales() << std::endl;
70 if (o->GetNumberOfScales() > 1)
72 interval = m_ProcrustesInterval[o->GetCurrentScale()];
73 std::cout <<
"Interval = " << interval << std::endl;
76 interval = m_ProcrustesRegistration->GetProcrustesInterval();
82 this->m_ProcrustesCounter++;
86 if (this->m_ProcrustesCounter >= interval)
89 this->m_ProcrustesCounter = 0;
90 this->m_ProcrustesRegistration->RunRegistration();
91 std::cout <<
"Ran Procrustes Registration" << std::endl;
96 template <
unsigned int VDimension>
100 if (!m_Project->HasDomains())
102 throw itk::ExceptionObject(
"Domains must be defined in the project file.");
106 std::vector<std::string> domain_names = m_Project->GetDomainNames();
107 std::vector<std::string> dt_files;
108 for (
unsigned int i = 0; i < domain_names.size(); i++)
110 std::string s = (m_Project->GetDomainDistanceTransform(domain_names[i]))[0];
111 dt_files.push_back(s);
114 this->m_PSMFilter->SetDomainName(domain_names[i], i);
119 std::cout <<
"Reading distance transforms ..." << std::endl;
120 for (
unsigned int i = 0; i < dt_files.size(); i++)
122 typename itk::ImageFileReader<PSMCommandLineClass::ImageType>::Pointer reader =
123 itk::ImageFileReader<PSMCommandLineClass::ImageType>::New();
124 reader->SetFileName(input_path_prefix + dt_files[i]);
128 std::cout << domain_names[i] <<
": " << dt_files[i] << std::endl;
130 this->m_PSMFilter->SetInput(i, reader->GetOutput());
133 std::cout <<
"Done!" << std::endl;
136 template <
unsigned int VDimension>
140 if (!m_Project->HasDomains())
142 itkExceptionMacro(
"Domains must be defined in the project file.");
146 std::vector<std::string> domain_names = m_Project->GetDomainNames();
148 for (
unsigned int i = 0; i < domain_names.size(); i++)
150 if (m_Project->HasDomainCuttingPlanes(domain_names[i]))
153 std::vector<vnl_vector_fixed<double, 3> > planes
154 = m_Project->GetDomainCuttingPlanes(domain_names[i]);
158 if (planes.size() % 3 != 0)
160 itkExceptionMacro(
"Something is wrong with the cutting plane data for domain " + domain_names[i] +
". Correct number of points was not found.");
165 vnl_vector_fixed<double, 3> x;
166 vnl_vector_fixed<double, 3> y;
167 vnl_vector_fixed<double, 3> z;
168 std::vector<vnl_vector_fixed<double, 3> >::iterator it =
171 while (it != planes.end())
177 std::cout <<
"Found cutting plane for domain " << domain_names[i] <<
179 std::cout << x[0] <<
" " << x[1] <<
" " << x[2] << std::endl;
180 std::cout << y[0] <<
" " << y[1] <<
" " << y[2] << std::endl;
181 std::cout << z[0] <<
" " << z[1] <<
" " << z[2] << std::endl;
185 m_PSMFilter->AddCuttingPlane(x, y, z, domain_names[i]);
198 template<
unsigned int VDimension>
272 template <
unsigned int VDimension>
277 m_ProjectFileName = fn;
278 this->m_ProjectReader->SetFileName(fn);
279 this->m_ProjectReader->Update();
282 this->m_Project = m_ProjectReader->GetOutput();
285 template <
unsigned int VDimension>
292 std::cout <<
"Reading optimization parameters ... " << std::endl;
293 unsigned int number_of_scales = this->m_Project->GetNumberOfOptimizationScales();
294 std::cout <<
" Optimization scales = " << number_of_scales << std::endl;
296 if (number_of_scales > 0) {
298 std::vector<double> regularization_initial(number_of_scales);
299 std::vector<double> regularization_final(number_of_scales);
300 std::vector<double> regularization_decayspan(number_of_scales);
301 std::vector<double> tolerance(number_of_scales);
302 std::vector<unsigned int> maximum_iterations(number_of_scales);
303 m_ProcrustesInterval.resize(number_of_scales);
306 for (
unsigned int i = 0; i < number_of_scales; i++) {
307 std::cout <<
"Optimization parameters for scale " << i <<
": " << std::endl;
308 if (this->m_Project->HasOptimizationAttribute(
"regularization_initial", i))
310 regularization_initial[i] = this->m_Project->GetOptimizationAttribute(
"regularization_initial", i);
311 }
else {
throw itk::ExceptionObject(
"Missing parameter: regularization_initial"); }
312 std::cout <<
" regularization_initial = " << regularization_initial[i] << std::endl;
314 if (this->m_Project->HasOptimizationAttribute(
"regularization_final", i))
316 regularization_final[i] = this->m_Project->GetOptimizationAttribute(
"regularization_final", i);
317 }
else {
throw itk::ExceptionObject(
"Missing parameter: regularization_final"); }
318 std::cout <<
" regularization_final = " << regularization_final[i] << std::endl;
320 if (this->m_Project->HasOptimizationAttribute(
"regularization_decayspan", i))
322 regularization_decayspan[i]
323 = this->m_Project->GetOptimizationAttribute(
"regularization_decayspan", i);
324 }
else {
throw itk::ExceptionObject(
"Missing parameter: regularization_decayspan"); }
325 std::cout <<
" regularization_decayspan = " << regularization_decayspan[i] << std::endl;
327 if (this->m_Project->HasOptimizationAttribute(
"tolerance", i))
329 tolerance[i] = this->m_Project->GetOptimizationAttribute(
"tolerance", i);
330 }
else {
throw itk::ExceptionObject(
"Missing parameter: tolerance"); }
331 std::cout <<
" tolerance = " << tolerance[i] << std::endl;
333 if (this->m_Project->HasOptimizationAttribute(
"maximum_iterations", i))
335 maximum_iterations[i]
336 =
static_cast<unsigned int>(this->m_Project->GetOptimizationAttribute(
"maximum_iterations", i));
337 }
else {
throw itk::ExceptionObject(
"Missing parameter: maximum_iterations"); }
338 std::cout <<
" maximum_iterations = " << maximum_iterations[i] << std::endl;
342 if (this->m_Project->HasOptimizationAttribute(
"procrustes_interval", i))
344 m_ProcrustesInterval[i]
345 =
static_cast<unsigned int>(this->m_Project->GetOptimizationAttribute(
"procrustes_interval", i));
346 }
else {
throw itk::ExceptionObject(
"Missing parameter: procrustes_interval"); }
347 std::cout <<
" procrustes_interval = " << m_ProcrustesInterval[i] << std::endl;
352 this->m_PSMFilter->SetNumberOfScales(number_of_scales);
353 this->m_PSMFilter->SetRegularizationInitial(regularization_initial);
354 this->m_PSMFilter->SetRegularizationFinal(regularization_final);
355 this->m_PSMFilter->SetRegularizationDecaySpan(regularization_decayspan);
356 this->m_PSMFilter->SetTolerance(tolerance);
357 this->m_PSMFilter->SetMaximumNumberOfIterations(maximum_iterations);
360 throw itk::ExceptionObject(
"Project must define at least one optimization scale");
364 template <
unsigned int VDimension>
368 const std::vector<std::string> &out_files = this->m_Project->GetModel(std::string(
"optimized"));
369 if (out_files.size() != this->m_PSMFilter->GetParticleSystem()->GetNumberOfDomains())
371 std::cerr <<
"Number of output files does not match the number of particle domains (inputs)." << std::endl;
374 for (
unsigned int d = 0; d < this->m_PSMFilter->GetParticleSystem()->GetNumberOfDomains(); d++)
377 std::string fname = output_path + out_files[d];
378 std::ofstream out(fname.c_str());
381 std::cerr <<
"Could not open point file for output: " << std::endl;
385 for (
unsigned int j = 0; j < this->m_PSMFilter->GetParticleSystem()->GetNumberOfParticles(d); j++)
387 for (
unsigned int i = 0; i < VDimension; i++)
389 out << this->m_PSMFilter->GetParticleSystem()->GetPosition(j, d)[i] <<
" ";
402 template <
unsigned int VDimension>
404 ::Run(
const char *fname, std::string input_path_prefix,
405 std::string output_path)
409 this->ReadProjectFile(fname);
413 this->SetPSMFilterParameters();
416 this->ReadDistanceTransforms(input_path_prefix);
419 this->ReadCuttingPlanes();
423 m_IterateCmd = itk::MemberCommand<PSMCommandLineClass>::New();
425 this->m_PSMFilter->AddObserver(itk::IterationEvent(), m_IterateCmd);
428 this->m_ProcrustesRegistration->SetPSMParticleSystem(m_PSMFilter->GetParticleSystem());
431 this->m_PSMFilter->Update();
433 if (this->m_PSMFilter->GetNumberOfElapsedIterations() >= this->m_PSMFilter->GetMaximumNumberOfIterations())
435 std::cerr <<
"Optimization did not converge based on tolerance criteria." << std::endl;
438 std::cout <<
"Optimization done " << std::endl;
441 this->WriteOutputs(output_path);
unsigned int GetNumberOfElapsedIterations() const
const std::vector< double > & GetShapePCAVariances() const
This the most basic of all PSM model optimization filters. This filter assembles all of the necessary...
void IterateCallback(itk::Object *, const itk::EventObject &)
This class provides a command line tool to run the Particle Shape Modeling. It runs the optimization ...