1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#ifndef antsRegistrationCommandIterationUpdate__h_
#define antsRegistrationCommandIterationUpdate__h_
namespace ants
{
/** \class antsRegistrationCommandIterationUpdate
* \brief change parameters between iterations of registration
*/
template <typename TFilter>
class antsRegistrationCommandIterationUpdate final : public itk::Command
{
public:
typedef antsRegistrationCommandIterationUpdate Self;
typedef itk::Command Superclass;
typedef itk::SmartPointer<Self> Pointer;
itkNewMacro(Self);
protected:
antsRegistrationCommandIterationUpdate()
{
m_clock.Start();
m_clock.Stop();
const itk::RealTimeClock::TimeStampType now = m_clock.GetTotal();
this->m_lastTotalTime = now;
m_clock.Start();
this->m_LogStream = &std::cout;
}
public:
void
Execute(itk::Object * caller, const itk::EventObject & event) final
{
Execute((const itk::Object *)caller, event);
}
void
Execute(const itk::Object * object, const itk::EventObject & event) final
{
TFilter const * const filter = dynamic_cast<const TFilter *>(object);
if (typeid(event) == typeid(itk::InitializeEvent))
{
const unsigned int currentLevel = filter->GetCurrentLevel();
typename TFilter::ShrinkFactorsPerDimensionContainerType shrinkFactors =
filter->GetShrinkFactorsPerDimension(currentLevel);
typename TFilter::SmoothingSigmasArrayType smoothingSigmas = filter->GetSmoothingSigmasPerLevel();
typename TFilter::TransformParametersAdaptorsContainerType adaptors =
filter->GetTransformParametersAdaptorsPerLevel();
bool smoothingSigmasAreInPhysicalUnits = filter->GetSmoothingSigmasAreSpecifiedInPhysicalUnits();
m_clock.Stop();
const itk::RealTimeClock::TimeStampType now = m_clock.GetTotal();
this->Logger() << " Current level = " << currentLevel + 1 << " of " << this->m_NumberOfIterations.size()
<< std::endl;
this->Logger() << " number of iterations = " << this->m_NumberOfIterations[currentLevel] << std::endl;
this->Logger() << " shrink factors = " << shrinkFactors << std::endl;
this->Logger() << " smoothing sigmas = " << smoothingSigmas[currentLevel];
if (smoothingSigmasAreInPhysicalUnits)
{
this->Logger() << " mm" << std::endl;
}
else
{
this->Logger() << " vox" << std::endl;
}
this->Logger() << " required fixed parameters = " << adaptors[currentLevel]->GetRequiredFixedParameters()
<< std::flush << std::endl;
// this->Logger() << "\n LEVEL_TIME_INDEX: " << now << " SINCE_LAST: " << (now-this->m_lastTotalTime) <<
// std::endl;
this->m_lastTotalTime = now;
m_clock.Start();
typedef itk::GradientDescentOptimizerv4Template<typename TFilter::RealType> GradientDescentOptimizerType;
GradientDescentOptimizerType * optimizer =
reinterpret_cast<GradientDescentOptimizerType *>(const_cast<TFilter *>(filter)->GetModifiableOptimizer());
// TODO: This looks very wrong. There is a const_cast above, and then the change
// of the number of iterations here on what should be a const object.
optimizer->SetNumberOfIterations(this->m_NumberOfIterations[currentLevel]);
}
else if (typeid(event) == typeid(itk::IterationEvent))
{
const unsigned int lCurrentIteration = filter->GetCurrentIteration();
if (lCurrentIteration == 1)
{
// Print header line one time
this->Logger() << "XDIAGNOSTIC,Iteration,metricValue,convergenceValue,ITERATION_TIME_INDEX,SINCE_LAST"
<< std::flush << std::endl;
}
m_clock.Stop();
const itk::RealTimeClock::TimeStampType now = m_clock.GetTotal();
this->Logger() << "WDIAGNOSTIC, " << std::setw(5) << lCurrentIteration << ", " << std::scientific
<< std::setprecision(12) << filter->GetCurrentMetricValue() << ", " << std::scientific
<< std::setprecision(12) << filter->GetCurrentConvergenceValue() << ", " << std::setprecision(4)
<< now << ", " << std::setprecision(4) << (now - this->m_lastTotalTime) << ", " << std::flush
<< std::endl;
this->m_lastTotalTime = now;
m_clock.Start();
}
}
void
SetNumberOfIterations(const std::vector<unsigned int> & iterations)
{
this->m_NumberOfIterations = iterations;
}
void
SetLogStream(std::ostream & logStream)
{
this->m_LogStream = &logStream;
}
private:
std::ostream &
Logger() const
{
return *m_LogStream;
}
std::vector<unsigned int> m_NumberOfIterations;
std::ostream * m_LogStream;
itk::TimeProbe m_clock;
itk::RealTimeClock::TimeStampType m_lastTotalTime;
// typename ImageType::Pointer m_origFixedImage;
// typename ImageType::Pointer m_origMovingImage;
};
} // end namespace ants
#endif // antsRegistrationCommandIterationUpdate__h_
|