diff --git a/Code/Algorithms/Common/include/mapRegistrationAlgorithm.tpp b/Code/Algorithms/Common/include/mapRegistrationAlgorithm.tpp index 09c7deb..64ccafc 100644 --- a/Code/Algorithms/Common/include/mapRegistrationAlgorithm.tpp +++ b/Code/Algorithms/Common/include/mapRegistrationAlgorithm.tpp @@ -1,209 +1,209 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) // Subversion HeadURL: $HeadURL$ */ #ifndef __REGISTRATION_ALGORITHM_TPP #define __REGISTRATION_ALGORITHM_TPP #include "mapRegistrationAlgorithm.h" #include "mapAlgorithmEvents.h" #include "mapLogbookMacros.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace algorithm { // **** public methods **** // ************************ template unsigned int RegistrationAlgorithm:: getMovingDimensions() const { return VMovingDimensions; } template unsigned int RegistrationAlgorithm:: getTargetDimensions() const { return VTargetDimensions; } template typename RegistrationAlgorithm::RegistrationPointer RegistrationAlgorithm:: getRegistration() { - this->_determinationLock.Lock(); + this->_determinationLock.lock(); try { if (registrationIsOutdated()) { mapLogInfoMacro( << "Registration is outdated. Redetermine registration."); this->InvokeEvent(::map::events::AlgorithmEvent(this, "Registration is outdated. Redetermine registration.")); doDetermineRegistration(); } } catch (...) { - this->_determinationLock.Unlock(); + this->_determinationLock.unlock(); throw; } - this->_determinationLock.Unlock(); + this->_determinationLock.unlock(); return doGetRegistration(); }; template const typename RegistrationAlgorithm::MovingRepresentationDescriptorType* RegistrationAlgorithm:: getMovingRepresentation() const { this->doBeforeGetMovingRepresentation(); return _spMovingRepresentation; }; template void RegistrationAlgorithm:: setMovingRepresentation(const MovingRepresentationDescriptorType* pDescriptor) { if (_spMovingRepresentation.GetPointer() != pDescriptor) { this->doBeforeSetMovingRepresentation(pDescriptor); this->Modified(); this->_spMovingRepresentation = pDescriptor; this->doAfterSetMovingRepresentation(); } }; template const typename RegistrationAlgorithm::TargetRepresentationDescriptorType* RegistrationAlgorithm:: getTargetRepresentation() const { this->doBeforeGetTargetRepresentation(); return _spTargetRepresentation; }; template void RegistrationAlgorithm:: setTargetRepresentation(const TargetRepresentationDescriptorType* pDescriptor) { if (_spTargetRepresentation.GetPointer() != pDescriptor) { this->doBeforeSetTargetRepresentation(pDescriptor); this->Modified(); this->_spTargetRepresentation = pDescriptor; this->doAfterSetTargetRepresentation(); } }; // **** protected methods **** // *************************** template bool RegistrationAlgorithm:: registrationIsOutdated() const { bool result = doGetRegistration().IsNull(); return result; }; template RegistrationAlgorithm:: RegistrationAlgorithm() { _spMovingRepresentation = nullptr; _spTargetRepresentation = nullptr; }; template RegistrationAlgorithm:: ~RegistrationAlgorithm() = default; template void RegistrationAlgorithm:: doBeforeSetMovingRepresentation(const MovingRepresentationDescriptorType* pMovingRepresentation) { //default implementation does nothing }; template void RegistrationAlgorithm:: doAfterSetMovingRepresentation() { //default implementation does nothing }; template void RegistrationAlgorithm:: doBeforeSetTargetRepresentation(const TargetRepresentationDescriptorType* pTargetRepresentation) { //default implementation does nothing }; template void RegistrationAlgorithm:: doAfterSetTargetRepresentation() { //default implementation does nothing }; template void RegistrationAlgorithm:: doBeforeGetMovingRepresentation() const { //default implementation does nothing }; template void RegistrationAlgorithm:: doBeforeGetTargetRepresentation() const { //default implementation does nothing }; } // end namespace algorithm } // end namespace map #endif diff --git a/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.tpp b/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.tpp index 528c761..c7c19ba 100644 --- a/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.tpp +++ b/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.tpp @@ -1,407 +1,407 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) // Subversion HeadURL: $HeadURL$ */ #ifndef __MAP_IMAGE_REGISTRATION_ALGORITHM_TPP #define __MAP_IMAGE_REGISTRATION_ALGORITHM_TPP #include "mapAlgorithmException.h" #include "mapPreCachedRegistrationKernel.h" #include "mapInverseRegistrationKernelGenerator.h" #include "mapRegistrationManipulator.h" #include "mapAlgorithmWrapperEvent.h" #include "mapITKMVNLOptimizerControlInterface.h" #include "mapITKSVNLOptimizerControlInterface.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace algorithm { namespace boxed { template bool ITKDemonsRegistrationAlgorithm:: isStoppable() const { return true; }; template typename ITKDemonsRegistrationAlgorithm::IterationCountType ITKDemonsRegistrationAlgorithm:: doGetCurrentIteration() const { return this->_currentIterationCount; }; template typename ITKDemonsRegistrationAlgorithm::IterationCountType ITKDemonsRegistrationAlgorithm:: doGetMaxIterations() const { return this->_internalRegistrationMethod->GetNumberOfIterations(); }; template bool ITKDemonsRegistrationAlgorithm:: hasIterationCount() const { return true; }; template bool ITKDemonsRegistrationAlgorithm:: hasMaxIterationCount() const { return true; }; template bool ITKDemonsRegistrationAlgorithm:: hasCurrentOptimizerValue() const { //TODO return false; }; template ITKDemonsRegistrationAlgorithm:: ITKDemonsRegistrationAlgorithm() { _currentIterationCount = 0; }; template ITKDemonsRegistrationAlgorithm:: ~ITKDemonsRegistrationAlgorithm() { }; template typename ITKDemonsRegistrationAlgorithm::InterimRegistrationPointer ITKDemonsRegistrationAlgorithm:: determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const { //TODO //InterimRegistrationPointer spResult = NULL; //if (this->_currentIterationCount>0) //{ //the algorithm has iterated at least once so we can determin an interim registration // const TransformBaseType* pTransformModel = this->getTransformInternal(); // if (!pTransformModel) // { // mapExceptionMacro(AlgorithmException, <<"Error. Cannot determine interim registration. No transform model present on internal level (getTransformInternal(). Pleas ensure proper setup of algorithm."); // } // //clone the transform model // TransformBaseType::Pointer spInterimTransformModel = pTransformModel->clone(); // if (spInterimTransformModel.IsNull()) // { // mapExceptionMacro(AlgorithmException, <<"Error. Cannot determine interim registration. Unable to clone transform model. Current model: "<<*pTransformModel); // } // //set the parameter of the interim transform model to the current transform parameters of the algorithm // //We set the parameter by Value and not by using SetParameter() because otherwise // //it could cause errors with itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). // //This transforms would be invalid as soon as we leave this method. // spInterimTransformModel->SetParametersByValue(this->getCurrentTransformParameters()); // //now build the inverse kernel (main kernel of a image based registration algorithm) // typedef core::PreCachedRegistrationKernel InverseKernelType; // InverseKernelType::Pointer spIKernel = InverseKernelType::New(); // spIKernel->setTransformModel(spInterimTransformModel); // //now build the direct kernel via inversion of the inverse kernel // typedef core::InverseRegistrationKernelGenerator GeneratorType; // GeneratorType::Pointer spGenerator = GeneratorType::New(); // typedef GeneratorType::InverseKernelBaseType DirectKernelType; // DirectKernelType::Pointer spDKernel = spGenerator->generateInverse(*(spIKernel.GetPointer()), pMovingRepresentation); // if (spDKernel.IsNull()) // { // mapExceptionMacro(AlgorithmException, <<"Error. Cannot determine direct mapping kernel of interim registration. Current inverse kernel: "< manipulator(spResult); // manipulator.setDirectMapping(spDKernel); // manipulator.setInverseMapping(spIKernel); // manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); //} //return spResult; }; template bool ITKDemonsRegistrationAlgorithm:: doStopAlgorithm() { bool result = true; _internalRegistrationMethod->StopRegistration(); return result; }; template void ITKDemonsRegistrationAlgorithm:: prepareAlgorithm() { if (!this->getMovingImage()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no moving image."); } if (!this->getTargetImage()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no target image."); } this->_currentIterationCount = 0; //create method this->_internalRegistrationMethod = InternalRegistrationMethodType::New(); //initialize registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Transfer cached MetaProperties.")); this->configureAlgorithmByMetaProperties(); //assemble registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing itk registration method.")); this->prepInitializeTransformation(); //Connect images this->InvokeEvent(::map::events::AlgorithmEvent(this, "Connect images to itk registration method.")); this->_internalRegistrationMethod->SetFixedImage(this->getTargetImage()); this->_internalRegistrationMethod->SetMovingImage(this->getMovingImage()); //Register observers typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onIterationEvent); this->_internalRegistrationMethod->AddObserver(::itk::IterationEvent(), spCommand); spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralRegistrationMethodEvent); this->_internalRegistrationMethod->AddObserver(::itk::AnyEvent(), spCommand); }; template bool ITKDemonsRegistrationAlgorithm:: runAlgorithm() { this->_internalRegistrationMethod->Update(); return true; }; template void ITKDemonsRegistrationAlgorithm:: finalizeAlgorithm() { typename RegistrationType::Pointer spResult = NULL; //now build the inverse kernel (main kernel of a image based registration algorithm) typedef typename ::map::core::PreCachedRegistrationKernel InverseKernelType; typename FieldTransformType::Pointer transform = FieldTransformType::New(); transform->SetDisplacementField(this->_internalRegistrationMethod->GetDeformationField()); typename InverseKernelType::Pointer spIKernel = InverseKernelType::New(); spIKernel->setTransformModel(transform); //now build the direct kernel via inversion of the inverse kernel typedef core::InverseRegistrationKernelGenerator GeneratorType; typename GeneratorType::Pointer spGenerator = GeneratorType::New(); typedef typename GeneratorType::InverseKernelBaseType DirectKernelType; typename DirectKernelType::Pointer spDKernel = spGenerator->generateInverse(* (spIKernel.GetPointer()), this->getMovingRepresentation()); if (spDKernel.IsNull()) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine direct mapping kernel of final registration. Current inverse kernel: " << spIKernel); } //now create the registration an set the kernels spResult = RegistrationType::New(); ::map::core::RegistrationManipulator manipulator(spResult); manipulator.setDirectMapping(spDKernel); manipulator.setInverseMapping(spIKernel); manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); _spFinalizedRegistration = spResult; }; template void ITKDemonsRegistrationAlgorithm:: prepInitializeTransformation() { }; template typename ITKDemonsRegistrationAlgorithm::RegistrationPointer ITKDemonsRegistrationAlgorithm:: doGetRegistration() const { return _spFinalizedRegistration; }; template void ITKDemonsRegistrationAlgorithm:: onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock > LockHolderType; + typedef std::lock_guard LockHolderType; LockHolderType holder(this->_currentIterationLock); //*@TODO seems to be extremly outdated. rework needed. //bool hasCurrentValue = this->getOptimizerInternal()->hasCurrentValue(); //OptimizerBaseType::SVNLMeasureType currentValue = this->getOptimizerInternal()->getCurrentMeasure(); - // this->_currentIterationLock.Lock(); + // this->_currentIterationLock.lock(); // ++_currentIterationCount; // _currentTransformParameters = currentParams; // os << "Iteration #"<<_currentIterationCount << "; params: "; // os << currentParams << "; optimizer position: "; // if (hasCurrentPosition) // { // os << currentPosition; // } // else // { // os << "unkown"; // } // os << "; metric value: "; // if (hasCurrentValue) // { // os << currentValue; // } // else // { // os << "unkown"; // } - // this->_currentIterationLock.Unlock(); + // this->_currentIterationLock.unlock(); // this->InvokeEvent(::map::events::AlgorithmIterationEvent(this,os.str())); }; template void ITKDemonsRegistrationAlgorithm:: onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal registration method event"); this->InvokeEvent(wrappedEvent); }; template bool ITKDemonsRegistrationAlgorithm:: registrationIsOutdated() const { bool outdated = _spFinalizedRegistration.IsNull(); if (_spFinalizedRegistration.IsNotNull()) { if (!outdated) { //check if the inputs have been changed outdated = _internalRegistrationMethod->GetMovingImage() != this->getMovingImage(); } if (!outdated) { //check if the inputs have been changed outdated = _internalRegistrationMethod->GetFixedImage() != this->getTargetImage(); } } return outdated; }; template typename ITKDemonsRegistrationAlgorithm::OptimizerMeasureType ITKDemonsRegistrationAlgorithm:: doGetCurrentOptimizerValue() const { OptimizerMeasureType result; //*@TODO Return of current optimization value //const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); // //if (pOptimizer) //{ // if (pOptimizer->hasCurrentValue()) // { // result = pOptimizer->getCurrentValue(); // } //} return result; }; template void ITKDemonsRegistrationAlgorithm:: PrintSelf(std::ostream& os, ::itk::Indent indent) const { Superclass::PrintSelf(os, indent); ImageRegistrationAlgorithmBase::PrintSelf(os, indent); os << indent << "Current itertation count: " << _currentIterationCount << std::endl; os << indent << "Finalized registration: " << _spFinalizedRegistration << std::endl; }; } // end namespace boxed } // end namespace algorithm } // end namespace map #endif diff --git a/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.tpp b/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.tpp index 6e8a1d4..aa8961a 100644 --- a/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.tpp +++ b/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.tpp @@ -1,1116 +1,1116 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) // Subversion HeadURL: $HeadURL$ */ #ifndef __MAP_ITK_IMAGE_REGISTRATION_ALGORITHM_TPP #define __MAP_ITK_IMAGE_REGISTRATION_ALGORITHM_TPP -#include "itkMutexLockHolder.h" +#include #include "itkExtractImageFilter.h" #include "mapAlgorithmException.h" #include "mapPreCachedRegistrationKernel.h" #include "mapInverseRegistrationKernelGenerator.h" #include "mapRegistrationManipulator.h" #include "mapAlgorithmWrapperEvent.h" #include "mapITKMVNLOptimizerControlInterface.h" #include "mapITKSVNLOptimizerControlInterface.h" #include "mapMaskBoundingBoxHelper.h" namespace map { namespace algorithm { namespace itk { template typename ITKImageRegistrationAlgorithm::FieldRepRequirement::Type ITKImageRegistrationAlgorithm:: isMovingRepresentationRequired() const { return FieldRepRequirement::No; }; template typename ITKImageRegistrationAlgorithm::FieldRepRequirement::Type ITKImageRegistrationAlgorithm:: isTargetRepresentationRequired() const { return FieldRepRequirement::No; }; template bool ITKImageRegistrationAlgorithm:: isStoppable() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->isStoppable(); } return result; }; template typename ITKImageRegistrationAlgorithm::IterationCountType ITKImageRegistrationAlgorithm:: doGetCurrentIteration() const { return this->_currentIterationCount; }; template typename ITKImageRegistrationAlgorithm::IterationCountType ITKImageRegistrationAlgorithm:: doGetMaxIterations() const { IterationCountType result = 0; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->getMaxIterations(); } return result; }; template bool ITKImageRegistrationAlgorithm:: hasIterationCount() const { return true; }; template bool ITKImageRegistrationAlgorithm:: hasMaxIterationCount() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->hasMaxIterationCount(); } return result; }; template bool ITKImageRegistrationAlgorithm:: hasCurrentOptimizerValue() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->hasCurrentValue(); } return result; }; template bool ITKImageRegistrationAlgorithm:: isReusable() const { return true; } template ITKImageRegistrationAlgorithm:: ITKImageRegistrationAlgorithm() { _finalizedTransformParameters.clear(); _currentTransformParameters.clear(); _currentIterationCount = 0; _spInternalMovingImage = NULL; _spInternalTargetImage = NULL; _CropInputImagesByMask = true; //now set the policy event slots typedef ::itk::ReceptorMemberCommand AlgorithmCommandType; typename AlgorithmCommandType::Pointer spInterpolatorCmd = AlgorithmCommandType::New(); spInterpolatorCmd->SetCallbackFunction(this, &Self::onInterpolatorChange); InterpolatorPolicyType::_spOnChange = spInterpolatorCmd; typename AlgorithmCommandType::Pointer spOptimizerCmd = AlgorithmCommandType::New(); spOptimizerCmd->SetCallbackFunction(this, &Self::onOptimizerChange); OptimizerPolicyType::_spOnChange = spOptimizerCmd; typename AlgorithmCommandType::Pointer spMetricCmd = AlgorithmCommandType::New(); spMetricCmd->SetCallbackFunction(this, &Self::onMetricChange); MetricPolicyType::_spOnChange = spMetricCmd; typename AlgorithmCommandType::Pointer spTransformCmd = AlgorithmCommandType::New(); spTransformCmd->SetCallbackFunction(this, &Self::onTransformChange); TransformPolicyType::_spOnChange = spTransformCmd; }; template ITKImageRegistrationAlgorithm:: ~ITKImageRegistrationAlgorithm() { }; template void ITKImageRegistrationAlgorithm:: configureAlgorithm() { //default implementation does nothing; } template typename ITKImageRegistrationAlgorithm::TransformParametersType ITKImageRegistrationAlgorithm:: getCurrentTransformParameters() const { - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock> LockHolderType; + typedef std::lock_guard LockHolderType; LockHolderType holder(this->_currentIterationLock); return this->_currentTransformParameters; }; template void ITKImageRegistrationAlgorithm:: setCurrentTransformParameters(const TransformParametersType& param) { - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock> LockHolderType; + typedef std::lock_guard LockHolderType; LockHolderType holder(this->_currentIterationLock); this->_currentTransformParameters = param; }; template typename ITKImageRegistrationAlgorithm::InterimRegistrationPointer ITKImageRegistrationAlgorithm:: determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const { - InterimRegistrationPointer spResult = NULL; + InterimRegistrationPointer spResult; if (this->_currentIterationCount > 0) { //the algorithm has iterated at least once so we can determin an interim registration const TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. No transform model present on internal level (getTransformInternal(). Pleas ensure proper setup of algorithm."); } //clone the transform model typename TransformBaseType::Pointer spInterimTransformModel = pTransformModel->Clone(); if (spInterimTransformModel.IsNull()) { std::ostringstream modelStrm; pTransformModel->Print(modelStrm); mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. Unable to clone transform model. Current model: "); //<< modelStrm); } //set the parameter of the interim transform model to the current transform parameters of the algorithm //We set the parameter by Value and not by using SetParameter() because otherwise //it could cause errors with itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). //This transforms would be invalid as soon as we leave this method. spInterimTransformModel->SetParametersByValue( this->getCurrentTransformParameters()); //now build the inverse kernel (main kernel of a image based registration algorithm) typedef core::PreCachedRegistrationKernel InverseKernelType; typename InverseKernelType::Pointer spIKernel = InverseKernelType::New(); spIKernel->setTransformModel(spInterimTransformModel); //now build the direct kernel via inversion of the inverse kernel typedef core::InverseRegistrationKernelGenerator GeneratorType; typename GeneratorType::Pointer spGenerator = GeneratorType::New(); typedef typename GeneratorType::InverseKernelBaseType DirectKernelType; typename DirectKernelType::Pointer spDKernel = spGenerator->generateInverse(* (spIKernel.GetPointer()), pMovingRepresentation); if (spDKernel.IsNull()) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine direct mapping kernel of interim registration. Current inverse kernel: " << spIKernel); } //now create the registration an set the kernels spResult = InterimRegistrationType::New(); ::map::core::RegistrationManipulator manipulator(spResult); manipulator.setDirectMapping(spDKernel); manipulator.setInverseMapping(spIKernel); manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); } return spResult; }; template bool ITKImageRegistrationAlgorithm:: doStopAlgorithm() { bool result = false; OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->stop(); } return result; }; template void ITKImageRegistrationAlgorithm:: prepCheckValidity() { if (!this->getTransformInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no transformation model available."); } if (!this->getInterpolatorInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no interpolator available."); } if (!this->getOptimizerInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no optimizer available."); } if (!this->getMetricInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no metric available."); } if (!this->getMovingImage()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no moving image."); } if (!this->getTargetImage()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no target image."); } } template void ITKImageRegistrationAlgorithm:: prepPrepareSubComponents() { this->prepareTransform(); this->prepareInterpolator(); this->prepareMetric(); this->prepareOptimizer(); } template void ITKImageRegistrationAlgorithm:: prepAssembleSubComponents() { this->_internalRegistrationMethod->SetMetric(this->getMetricInternal()->getImageToImageMetric()); this->_internalRegistrationMethod->SetOptimizer(this->getOptimizerInternal()->getSVNLOptimizer()); this->_internalRegistrationMethod->SetTransform(this->getTransformInternal()); this->_internalRegistrationMethod->SetInterpolator(this->getInterpolatorInternal()); } template void ITKImageRegistrationAlgorithm:: prepPerpareInternalInputData() { typedef ::itk::ExtractImageFilter MovingExtractFilterType; typedef ::itk::ExtractImageFilter TargetExtractFilterType; typename MovingExtractFilterType::Pointer movingFilter = MovingExtractFilterType::New(); ::map::core::OStringStream os; ::map::core::OStringStream os2; if (this->getCropInputImagesByMask()) { if (this->getInternalTargetMask().IsNotNull()) { //we have a mask -> so construct the image region typename TargetImageType::RegionType boundedRegion; if (::map::algorithm::MaskBoundingBoxHelper::computeBoundingImageRegion( this->getInternalTargetMask(), this->getInternalTargetImage(), boundedRegion)) { if (boundedRegion.Crop(this->getInternalTargetImage()->GetLargestPossibleRegion())) { os << "Target mask: set -> target image space region is set to: " << ::std::endl << boundedRegion; typename TargetExtractFilterType::Pointer targetFilter = TargetExtractFilterType::New(); targetFilter->SetExtractionRegion(boundedRegion); targetFilter->SetInput(this->getInternalTargetImage()); targetFilter->Update(); typename TargetImageType::Pointer newTarget = targetFilter->GetOutput(); newTarget->DisconnectPipeline(); this->setInternalTargetImage(newTarget); } else { os << "Target mask: set, but invalid (not within the bufferd target image) -> use complete target image."; } } else { os << "Target mask: set, but invalid (cannot compute bounding box) -> use complete target image."; } } else { os << "Target mask: none -> use complete target image."; } this->InvokeEvent(::map::events::AlgorithmEvent(this, os.str())); if (this->getInternalMovingMask().IsNotNull()) { //we have a mask -> so construct the image region typename MovingImageType::RegionType boundedRegion; if (::map::algorithm::MaskBoundingBoxHelper::computeBoundingImageRegion( this->getInternalMovingMask(), this->getInternalMovingImage(), boundedRegion)) { if (boundedRegion.Crop(this->getInternalMovingImage()->GetLargestPossibleRegion())) { os2 << "Moving mask: set -> moving image space region is set to: " << ::std::endl << boundedRegion; typename MovingExtractFilterType::Pointer movingFilter = MovingExtractFilterType::New(); movingFilter->SetExtractionRegion(boundedRegion); movingFilter->SetInput(this->getInternalMovingImage()); movingFilter->Update(); typename MovingImageType::Pointer newMoving = movingFilter->GetOutput(); newMoving->DisconnectPipeline(); this->setInternalMovingImage(newMoving); } else { os2 << "Moving mask: set, but invalid (not within the bufferd moving image) -> use complete moving image."; } } else { os2 << "Moving mask: set, but invalid (cannot compute bounding box) -> use complete moving image."; } } else { os2 << "Moving mask: none -> use complete moving image."; } this->InvokeEvent(::map::events::AlgorithmEvent(this, os2.str())); } } template void ITKImageRegistrationAlgorithm:: prepSetInternalInputData() { //Connect images this->InvokeEvent(::map::events::AlgorithmEvent(this, "Connect images to itk registration method.")); this->_internalRegistrationMethod->SetFixedImage(this->getInternalTargetImage()); this->_internalRegistrationMethod->SetMovingImage(this->getInternalMovingImage()); //Connect masks if present this->InvokeEvent(::map::events::AlgorithmEvent(this, "Connect masks to registration metric.")); if (this->getInternalMovingMask().IsNotNull()) { //add moving mask this->getMetricInternal()->getImageToImageMetric()->SetMovingImageMask(this->getInternalMovingMask()); } if (this->getInternalTargetMask().IsNotNull()) { //add target mask this->getMetricInternal()->getImageToImageMetric()->SetFixedImageMask(this->getInternalTargetMask()); } this->_internalRegistrationMethod->SetFixedImageRegion( this->getInternalTargetImage()->GetLargestPossibleRegion()); } template void ITKImageRegistrationAlgorithm:: prepInitializeTransformation() { const TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. No transform model present on internal level (getTransformInternal(). Pleas ensure proper setup of algorithm."); } ::map::core::OStringStream os; os << "Set start transformation parameters to: " << pTransformModel->GetParameters(); //set the parameter of the transform model to the current transform parameters of the algorithm this->setCurrentTransformParameters(pTransformModel->GetParameters()); this->_internalRegistrationMethod->SetInitialTransformParameters( pTransformModel->GetParameters()); this->InvokeEvent(::map::events::AlgorithmEvent(this, os.str())); }; template void ITKImageRegistrationAlgorithm:: prepFinalizePreparation() { //initialize registration components after assembly this->prepareTransformAfterAssembly(); this->prepareInterpolatorAfterAssembly(); this->prepareMetricAfterAssembly(); this->prepareOptimizerAfterAssembly(this->getMetricInternal()->getMinimizeToOptimize()); }; template void ITKImageRegistrationAlgorithm:: prepareAlgorithm() { this->prepCheckValidity(); this->_currentIterationCount = 0; this->_spFinalizedRegistration = NULL; this->_spInternalMovingImage = NULL; this->_spInternalTargetImage = NULL; this->_finalizedTransformParameters.Fill(0); //create method this->_internalRegistrationMethod = InternalRegistrationMethodType::New(); //initialize registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Transfer cached MetaProperties.")); this->configureAlgorithmByMetaProperties(); //initialize registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing registration components.")); this->prepPrepareSubComponents(); //assemble registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing itk multi resolution registration method.")); this->prepAssembleSubComponents(); this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing/Preparing input data.")); this->prepPerpareInternalInputData(); this->InvokeEvent(::map::events::AlgorithmEvent(this, "Passing input data to internal algorithm.")); this->prepSetInternalInputData(); //possibility to initialize internal registration method after assembly this->prepInitializeTransformation(); //initialize registration components after assembly this->InvokeEvent(::map::events::AlgorithmEvent(this, "Finalizing initialization...")); this->prepFinalizePreparation(); //Register observers if (_onIterationObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onIterationEvent); _onIterationObserver = core::ObserverSentinel::New(this->getOptimizerInternal()->getSVNLOptimizer(), ::itk::IterationEvent(), spCommand); } if (_onGeneralOptimizerObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralOptimizerEvent); _onGeneralOptimizerObserver = core::ObserverSentinel::New( this->getOptimizerInternal()->getSVNLOptimizer(), ::itk::AnyEvent(), spCommand); } if (_onGeneralMetricObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralMetricEvent); _onGeneralMetricObserver = core::ObserverSentinel::New( this->getMetricInternal()->getImageToImageMetric(), ::itk::AnyEvent(), spCommand); } if (_onGeneralInterpolatorObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralInterpolatorEvent); _onGeneralInterpolatorObserver = core::ObserverSentinel::New(this->getInterpolatorInternal(), ::itk::AnyEvent(), spCommand); } if (_onGeneralTransformObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralTransformEvent); _onGeneralTransformObserver = core::ObserverSentinel::New( this->getTransformInternal(), ::itk::AnyEvent(), spCommand); } typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralRegistrationMethodEvent); this->_internalRegistrationMethod->AddObserver(::itk::AnyEvent(), spCommand); }; template bool ITKImageRegistrationAlgorithm:: runAlgorithm() { this->_internalRegistrationMethod->Update(); this->_stopConditionDescription = this->getOptimizerInternal()->getStopConditionDescription(); return true; }; template void ITKImageRegistrationAlgorithm:: finalizeAlgorithm() { - RegistrationPointer spResult = NULL; + RegistrationPointer spResult; //touch the sub component to ensure an actualzed modification time, //this is needed because in case of arbitrary policies and dll deployment //the components could come out of another context. So a //ModificationTimeValidator is needed in it could produce //false positives in this constellation. OptimizerPolicyType::GetMTime(); MetricPolicyType::GetMTime(); TransformPolicyType::GetMTime(); TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine final registration. No transform model present on internal level (getTransformInternal()). Please ensure proper setup of algorithm."); } //clone the transform model typename TransformBaseType::Pointer spFinalTransformModel = pTransformModel->Clone(); if (spFinalTransformModel.IsNull()) { std::ostringstream modelStrm; pTransformModel->Print(modelStrm); mapExceptionMacro(AlgorithmException, << "Error. Cannot determine final registration. Unable to clone transform model. Current model: " << modelStrm.str()); } TransformParametersType lastTransformParameters = this->_internalRegistrationMethod->GetLastTransformParameters(); //set the parameter of the final transform model to the final transform parameters of the algorithm spFinalTransformModel->SetParametersByValue( lastTransformParameters); //this line is need to ensure correct cloning for //itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). //Thoose transforms can cause problems with optimizers that only keep the parameters localy (e.g. itk::LBFGSOptimizer). //Excplicit resetting the parameters is a work arround to this problem. //now build the inverse kernel (main kernel of a image based registration algorithm) typedef core::PreCachedRegistrationKernel InverseKernelType; typename InverseKernelType::Pointer spIKernel = InverseKernelType::New(); spIKernel->setTransformModel(spFinalTransformModel); //now build the direct kernel via inversion of the inverse kernel typedef core::InverseRegistrationKernelGenerator GeneratorType; typename GeneratorType::Pointer spGenerator = GeneratorType::New(); typedef typename GeneratorType::InverseKernelBaseType DirectKernelType; typename DirectKernelType::Pointer spDKernel = spGenerator->generateInverse(* (spIKernel.GetPointer()), this->getMovingRepresentation()); if (spDKernel.IsNull()) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine direct mapping kernel of final registration. Current inverse kernel: " << spIKernel); } //ensure that settings changed to the registration determination process are reseted to default this->configureAlgorithm(); //now create the registration an set the kernels spResult = RegistrationType::New(); ::map::core::RegistrationManipulator manipulator(spResult); manipulator.setDirectMapping(spDKernel); manipulator.setInverseMapping(spIKernel); manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); //store the final results _spFinalizedRegistration = spResult; _finalizedTransformParameters = lastTransformParameters; }; template typename ITKImageRegistrationAlgorithm::RegistrationPointer ITKImageRegistrationAlgorithm:: doGetRegistration() const { return _spFinalizedRegistration; }; template void ITKImageRegistrationAlgorithm:: onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::core::OStringStream os; TransformParametersType currentParams = this->getTransformInternal()->GetParameters(); bool hasCurrentPosition = this->getOptimizerInternal()->hasCurrentPosition(); typename OptimizerBaseType::OptimizerPositionType currentPosition = this->getOptimizerInternal()->getCurrentPosition(); bool hasCurrentValue = this->getOptimizerInternal()->hasCurrentValue(); typename OptimizerBaseType::SVNLMeasureType currentValue = this->getOptimizerInternal()->getCurrentMeasure(); - this->_currentIterationLock.Lock(); + this->_currentIterationLock.lock(); ++_currentIterationCount; _currentTransformParameters = currentParams; os << "Iteration #" << _currentIterationCount << "; params: "; os << currentParams << "; optimizer position: "; if (hasCurrentPosition) { os << currentPosition; } else { os << "unkown"; } os << "; metric value: "; if (hasCurrentValue) { os << currentValue; } else { os << "unkown"; } - this->_currentIterationLock.Unlock(); + this->_currentIterationLock.unlock(); this->InvokeEvent(::map::events::AlgorithmIterationEvent(this, os.str())); }; template void ITKImageRegistrationAlgorithm:: onGeneralOptimizerEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal optimizer event"); this->InvokeEvent(wrappedEvent); }; template void ITKImageRegistrationAlgorithm:: onGeneralMetricEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal metric event"); this->InvokeEvent(wrappedEvent); }; template void ITKImageRegistrationAlgorithm:: onGeneralInterpolatorEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal interpolator event"); this->InvokeEvent(wrappedEvent); }; template void ITKImageRegistrationAlgorithm:: onGeneralTransformEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal transform event"); this->InvokeEvent(wrappedEvent); }; template void ITKImageRegistrationAlgorithm:: onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal registration method event"); this->InvokeEvent(wrappedEvent); }; template void ITKImageRegistrationAlgorithm:: onOptimizerChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { // we can directly reset the observer sentinel befor the optimizer will be unregistered this->_onGeneralOptimizerObserver = NULL; } }; template void ITKImageRegistrationAlgorithm:: onMetricChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the metric will be unregistered this->_onGeneralMetricObserver = NULL; } }; template void ITKImageRegistrationAlgorithm:: onInterpolatorChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the interpolator will be unregistered this->_onGeneralInterpolatorObserver = NULL; } }; template void ITKImageRegistrationAlgorithm:: onTransformChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the transform will be unregistered this->_onGeneralTransformObserver = NULL; } }; template bool ITKImageRegistrationAlgorithm:: registrationIsOutdated() const { bool outdated = _spFinalizedRegistration.IsNull(); if (_spFinalizedRegistration.IsNotNull()) { if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < MetaPropertyAlgorithmBase::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < InterpolatorPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < OptimizerPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < MetricPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < TransformPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < this->getMovingImageMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < this->getTargetImageMTime(); } if (!outdated) { //check if the target mask has been changed outdated = _spFinalizedRegistration->GetMTime() < this->getTargetMaskMTime(); } if (!outdated) { //check if the moving mask has been changed outdated = _spFinalizedRegistration->GetMTime() < this->getMovingMaskMTime(); } } return outdated; }; template typename ITKImageRegistrationAlgorithm::OptimizerMeasureType ITKImageRegistrationAlgorithm:: doGetCurrentOptimizerValue() const { OptimizerMeasureType result; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { if (pOptimizer->hasCurrentValue()) { result = pOptimizer->getCurrentValue(); } } return result; }; template typename ITKImageRegistrationAlgorithm::InternalRegistrationMethodType& ITKImageRegistrationAlgorithm:: getInternalRegistrationMethod() { return *(this->_internalRegistrationMethod.GetPointer()); }; template void ITKImageRegistrationAlgorithm:: PrintSelf(std::ostream& os, ::itk::Indent indent) const { Superclass::PrintSelf(os, indent); ImageRegistrationAlgorithmBase::PrintSelf(os, indent); MaskedRegistrationAlgorithmBase::PrintSelf( os, indent); os << indent << "Current itertation count: " << _currentIterationCount << std::endl; os << indent << "Current transform parameters: " << _currentTransformParameters << std::endl; os << indent << "Finalized transform parameters: " << _finalizedTransformParameters << std::endl; os << indent << "Finalized registration: " << _spFinalizedRegistration << std::endl; }; template void ITKImageRegistrationAlgorithm:: compileInfos(MetaPropertyVectorType& infos) const { #ifndef MAP_SEAL_ALGORITHMS infos.push_back(::map::algorithm::MetaPropertyInfo::New("CropInputImagesByMasks", typeid(bool), true, true)); #endif }; template typename ITKImageRegistrationAlgorithm::MetaPropertyPointer ITKImageRegistrationAlgorithm:: doGetProperty(const MetaPropertyNameType& name) const { MetaPropertyPointer spResult; if (name == "CropInputImagesByMasks") { spResult = ::map::core::MetaProperty::New(this->_CropInputImagesByMask); } return spResult; }; template void ITKImageRegistrationAlgorithm:: doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty) { if (name == "CropInputImagesByMasks") { bool crop; ::map::core::unwrapMetaProperty(pProperty, crop); this->_CropInputImagesByMask = crop; } else { assert(false); //any other property name should have been excluded or allready handled by the calling function. } }; template typename ITKImageRegistrationAlgorithm::MovingImageConstPointer ITKImageRegistrationAlgorithm:: getInternalMovingImage() const { MovingImageConstPointer result = this->getMovingImage(); if (this->_spInternalMovingImage.IsNotNull()) { result = _spInternalMovingImage; } return result; }; template typename ITKImageRegistrationAlgorithm::TargetImageConstPointer ITKImageRegistrationAlgorithm:: getInternalTargetImage() const { TargetImageConstPointer result = this->getTargetImage(); if (this->_spInternalTargetImage.IsNotNull()) { result = _spInternalTargetImage; } return result; }; template void ITKImageRegistrationAlgorithm:: setInternalMovingImage(MovingImageType* image) { _spInternalMovingImage = image; }; template void ITKImageRegistrationAlgorithm:: setInternalTargetImage(TargetImageType* image) { _spInternalTargetImage = image; }; template typename ITKImageRegistrationAlgorithm::MovingMaskBaseConstPointer ITKImageRegistrationAlgorithm:: getInternalMovingMask() const { MovingMaskBaseConstPointer result = this->getMovingMask(); if (this->_spInternalMovingMask.IsNotNull()) { result = _spInternalMovingMask; } return result; } template typename ITKImageRegistrationAlgorithm::TargetMaskBaseConstPointer ITKImageRegistrationAlgorithm:: getInternalTargetMask() const { TargetMaskBaseConstPointer result = this->getTargetMask(); if (this->_spInternalTargetMask.IsNotNull()) { result = _spInternalTargetMask; } return result; } template void ITKImageRegistrationAlgorithm:: setInternalMovingMask(MovingMaskBaseType* mask) { _spInternalMovingMask = mask; } template void ITKImageRegistrationAlgorithm:: setInternalTargetMask(TargetMaskBaseType* mask) { _spInternalTargetMask = mask; } } // end namespace itk } // end namespace algorithm } // end namespace map #endif diff --git a/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.tpp b/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.tpp index 105ba90..87c0cac 100644 --- a/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.tpp +++ b/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.tpp @@ -1,313 +1,313 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) // Subversion HeadURL: $HeadURL$ */ #ifndef __ITK_MULTI_RES_IMAGE_REGISTRATION_ALGORITHM_TPP #define __ITK_MULTI_RES_IMAGE_REGISTRATION_ALGORITHM_TPP #include "mapAlgorithmException.h" #include "mapPreCachedRegistrationKernel.h" #include "mapInverseRegistrationKernelGenerator.h" #include "mapRegistrationManipulator.h" #include "mapAlgorithmWrapperEvent.h" #include "mapITKMVNLOptimizerControlInterface.h" #include "mapITKSVNLOptimizerControlInterface.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace algorithm { namespace itk { template typename ITKMultiResImageRegistrationAlgorithm::ResolutionLevelCountType ITKMultiResImageRegistrationAlgorithm:: doGetCurrentLevel() const { return this->_currentLevelCount; }; template bool ITKMultiResImageRegistrationAlgorithm:: hasLevelCount() const { return true; }; template ITKMultiResImageRegistrationAlgorithm:: ITKMultiResImageRegistrationAlgorithm() { _currentLevelCount = 0; _firstLevelEvent = true; }; template ITKMultiResImageRegistrationAlgorithm:: ~ITKMultiResImageRegistrationAlgorithm() { }; template void ITKMultiResImageRegistrationAlgorithm:: prepCheckValidity() { Superclass::prepCheckValidity(); if (!this->getMovingPyramideInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no moving image pyramide available."); } if (!this->getTargetPyramideInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no target image pyramide available."); } } template void ITKMultiResImageRegistrationAlgorithm:: prepPrepareSubComponents() { Superclass::prepPrepareSubComponents(); this->preparePyramides(); } template void ITKMultiResImageRegistrationAlgorithm:: prepAssembleSubComponents() { Superclass::prepAssembleSubComponents(); this->getInternalRegistrationMethod().SetMovingImagePyramid(this->getMovingPyramideInternal()); this->getInternalRegistrationMethod().SetFixedImagePyramid(this->getTargetPyramideInternal()); } template void ITKMultiResImageRegistrationAlgorithm:: prepSetInternalInputData() { Superclass::prepSetInternalInputData(); this->InvokeEvent(::map::events::AlgorithmEvent(this, "Pass resolution schedules to itk registration method.")); this->getInternalRegistrationMethod().SetSchedules(this->getTargetSchedule(), this->getMovingSchedule()); } template void ITKMultiResImageRegistrationAlgorithm:: prepFinalizePreparation() { Superclass::prepFinalizePreparation(); this->preparePyramidesAfterAssembly(); }; template void ITKMultiResImageRegistrationAlgorithm:: prepareAlgorithm() { /*check once before start to change internal state*/ this->prepCheckValidity(); this->_firstLevelEvent = true; this->_currentLevelCount = 0; Superclass::prepareAlgorithm(); //Register level observers typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onLevelEvent); this->getInternalRegistrationMethod().AddObserver(::itk::IterationEvent(), spCommand); }; template void ITKMultiResImageRegistrationAlgorithm:: onLevelEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { if (!(::itk::IterationEvent().CheckEvent(&eventObject))) { return; } - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock > LockHolderType; + typedef std::lock_guard LockHolderType; - this->_currentIterationLock.Lock(); - this->_currentLevelLock.Lock(); + this->_currentIterationLock.lock(); + this->_currentLevelLock.lock(); ::map::core::OStringStream os; if (!this->_firstLevelEvent) { TransformParametersType currentParams = this->getTransformInternal()->GetParameters(); bool hasCurrentPosition = this->getOptimizerInternal()->hasCurrentPosition(); typename OptimizerBaseType::OptimizerPositionType currentPosition = this->getOptimizerInternal()->getCurrentPosition(); bool hasCurrentValue = this->getOptimizerInternal()->hasCurrentValue(); typename OptimizerBaseType::SVNLMeasureType currentValue = this->getOptimizerInternal()->getCurrentMeasure(); ++_currentLevelCount; this->_currentIterationCount = 0; this->_currentTransformParameters = currentParams; os << "Resolution level finished: final level params: "; if (hasCurrentPosition) { os << currentParams; } else { os << "unkown"; } os << "; final level metric value: "; if (hasCurrentValue) { os << currentValue; } else { os << "unkown"; } os << std::endl; } else { this->_firstLevelEvent = false; } os << "New Level #" << _currentLevelCount; - this->_currentIterationLock.Unlock(); - this->_currentLevelLock.Unlock(); + this->_currentIterationLock.unlock(); + this->_currentLevelLock.unlock(); this->InvokeEvent(::map::events::AlgorithmResolutionLevelEvent(this, os.str())); this->doInterLevelSetup(); }; template void ITKMultiResImageRegistrationAlgorithm:: doInterLevelSetup() { //default implementation does nothing } template void ITKMultiResImageRegistrationAlgorithm:: onTargetImagePyramideChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the target pyramide will be unregistered this->_onGeneralTargePyramideObserver = NULL; } }; template void ITKMultiResImageRegistrationAlgorithm:: onMovingImagePyramideChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the moving pyramide will be unregistered this->_onGeneralMovingPyramideObserver = NULL; } }; template bool ITKMultiResImageRegistrationAlgorithm:: registrationIsOutdated() const { bool outdated = Superclass::registrationIsOutdated(); if (!outdated) { outdated = this->_spFinalizedRegistration->GetMTime() < this->getTargetPyramideMTime(); } if (!outdated) { outdated = this->_spFinalizedRegistration->GetMTime() < this->getMovingPyramideMTime(); } return outdated; }; template void ITKMultiResImageRegistrationAlgorithm:: PrintSelf(std::ostream& os, ::itk::Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Current level count: " << _currentLevelCount << std::endl; }; template bool ITKMultiResImageRegistrationAlgorithm:: doStopAlgorithm() { this->getInternalRegistrationMethod().StopRegistration(); Superclass::doStopAlgorithm(); return true; }; } // end namespace itk } // end namespace algorithm } // end namespace map #endif diff --git a/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.tpp b/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.tpp index f141c1e..9942db5 100644 --- a/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.tpp +++ b/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.tpp @@ -1,766 +1,766 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) // Subversion HeadURL: $HeadURL$ */ #ifndef __ITK_POINT_SET_REGISTRATION_ALGORITHM_TPP #define __ITK_POINT_SET_REGISTRATION_ALGORITHM_TPP #include "mapAlgorithmException.h" #include "mapPreCachedRegistrationKernel.h" #include "mapInverseRegistrationKernelGenerator.h" #include "mapRegistrationManipulator.h" #include "mapAlgorithmWrapperEvent.h" #include "mapITKMVNLOptimizerControlInterface.h" #include "mapITKSVNLOptimizerControlInterface.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace algorithm { namespace itk { template bool ITKPointSetRegistrationAlgorithm:: isStoppable() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->isStoppable(); } return result; }; template typename ITKPointSetRegistrationAlgorithm::IterationCountType ITKPointSetRegistrationAlgorithm:: doGetCurrentIteration() const { return this->_currentIterationCount; }; template typename ITKPointSetRegistrationAlgorithm::IterationCountType ITKPointSetRegistrationAlgorithm:: doGetMaxIterations() const { IterationCountType result = 0; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->getMaxIterations(); } return result; }; template bool ITKPointSetRegistrationAlgorithm:: hasIterationCount() const { return true; }; template bool ITKPointSetRegistrationAlgorithm:: hasMaxIterationCount() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->hasMaxIterationCount(); } return result; }; template bool ITKPointSetRegistrationAlgorithm:: hasCurrentOptimizerValue() const { bool result = false; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->hasCurrentValue(); } return result; }; template typename ITKPointSetRegistrationAlgorithm::FieldRepRequirement::Type ITKPointSetRegistrationAlgorithm:: isMovingRepresentationRequired() const { return FieldRepRequirement::No; }; template typename ITKPointSetRegistrationAlgorithm::FieldRepRequirement::Type ITKPointSetRegistrationAlgorithm:: isTargetRepresentationRequired() const { typename TransformBaseType::InverseTransformBasePointer spInverseModel = this->getTransformModel()->GetInverseTransform(); if (spInverseModel.IsNotNull()) { // you can invert it thus no rep is needed return FieldRepRequirement::No; } else { return FieldRepRequirement::Unkown; } }; template bool ITKPointSetRegistrationAlgorithm:: isReusable() const { return true; } template ITKPointSetRegistrationAlgorithm:: ITKPointSetRegistrationAlgorithm() { _finalizedTransformParameters.clear(); _currentTransformParameters.clear(); _currentIterationCount = 0; //now set the policy event slots typedef ::itk::ReceptorMemberCommand AlgorithmCommandType; typename AlgorithmCommandType::Pointer spOptimizerCmd = AlgorithmCommandType::New(); spOptimizerCmd->SetCallbackFunction(this, &Self::onOptimizerChange); OptimizerPolicyType::_spOnChange = spOptimizerCmd; typename AlgorithmCommandType::Pointer spMetricCmd = AlgorithmCommandType::New(); spMetricCmd->SetCallbackFunction(this, &Self::onMetricChange); MetricPolicyType::_spOnChange = spMetricCmd; typename AlgorithmCommandType::Pointer spTransformCmd = AlgorithmCommandType::New(); spTransformCmd->SetCallbackFunction(this, &Self::onTransformChange); TransformPolicyType::_spOnChange = spTransformCmd; }; template ITKPointSetRegistrationAlgorithm:: ~ITKPointSetRegistrationAlgorithm() { }; template void ITKPointSetRegistrationAlgorithm:: configureAlgorithm() { //default implementation does nothing; } template typename ITKPointSetRegistrationAlgorithm::TransformParametersType ITKPointSetRegistrationAlgorithm:: getCurrentTransformParameters() const { - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock> LockHolderType; + typedef std::lock_guard LockHolderType; LockHolderType holder(this->_currentIterationLock); return this->_currentTransformParameters; }; template void ITKPointSetRegistrationAlgorithm:: setCurrentTransformParameters(const TransformParametersType& param) { - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock> LockHolderType; + typedef std::lock_guard LockHolderType; LockHolderType holder(this->_currentIterationLock); this->_currentTransformParameters = param; }; template typename ITKPointSetRegistrationAlgorithm::InterimRegistrationPointer ITKPointSetRegistrationAlgorithm:: determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const { - InterimRegistrationPointer spResult = NULL; + InterimRegistrationPointer spResult; if (this->_currentIterationCount > 0) { //the algorithm has iterated at least once so we can determin an interim registration const TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. No transform model present on internal level (getTransformInternal(). Pleas ensure proper setup of algorithm."); } //clone the transform model typename TransformBaseType::Pointer spInterimTransformModel = pTransformModel->Clone(); if (spInterimTransformModel.IsNull()) { std::ostringstream modelStrm; pTransformModel->Print(modelStrm); mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. Unable to clone transform model. Current model: " << modelStrm.str()); } //set the parameter of the interim transform model to the current transform parameters of the algorithm //We set the parameter by Value and not by using SetParameter() because otherwise //it could cause errors with itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). //This transforms would be invalid as soon as we leave this method. spInterimTransformModel->SetParametersByValue( this->getCurrentTransformParameters()); //now build the direct kernel (main kernel of a point set based registration algorithm) typedef core::PreCachedRegistrationKernel DirectKernelType; typename DirectKernelType::Pointer spDKernel = DirectKernelType::New(); spDKernel->setTransformModel(spInterimTransformModel); //now build the inverse kernel via inversion of the direct kernel typedef core::InverseRegistrationKernelGenerator GeneratorType; typename GeneratorType::Pointer spGenerator = GeneratorType::New(); typedef typename GeneratorType::InverseKernelBaseType InverseKernelType; typename InverseKernelType::Pointer spIKernel = spGenerator->generateInverse(* (spDKernel.GetPointer()), this->getTargetRepresentation()); if (spIKernel.IsNull()) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine inverse mapping kernel of interim registration. Current direct kernel: " << spDKernel); } //now create the registration an set the kernels spResult = InterimRegistrationType::New(); ::map::core::RegistrationManipulator manipulator(spResult); manipulator.setDirectMapping(spDKernel); manipulator.setInverseMapping(spIKernel); manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); } return spResult; }; template bool ITKPointSetRegistrationAlgorithm:: doStopAlgorithm() { bool result = false; OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { result = pOptimizer->stop(); } return result; }; template void ITKPointSetRegistrationAlgorithm:: prepareAlgorithm() { if (!this->getTransformInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no transformation model available."); } if (!this->getOptimizerInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no optimizer available."); } if (!this->getMetricInternal()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no metric available."); } if (!this->getMovingPointSet()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no moving point set."); } if (!this->getTargetPointSet()) { mapExceptionMacro(AlgorithmException, << "Cannot start algorithm; no target point set."); } this->_currentIterationCount = 0; this->_spFinalizedRegistration = NULL; //create method this->_internalRegistrationMethod = InternalRegistrationMethodType::New(); //initialize registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Transfer cached MetaProperties.")); this->configureAlgorithmByMetaProperties(); //initialize registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing registration components.")); this->prepareTransform(); this->prepareMetric(); this->prepareOptimizer(); //assemble registration components this->InvokeEvent(::map::events::AlgorithmEvent(this, "Initializing itk registration method.")); this->_internalRegistrationMethod->SetMetric( this->getMetricInternal()->getPointSetToPointSetMetric()); this->_internalRegistrationMethod->SetOptimizer(this->getOptimizerInternal()->getMVNLOptimizer()); this->_internalRegistrationMethod->SetTransform(this->getTransformInternal()); this->prepInitializeTransformation(); //Connect point sets this->InvokeEvent(::map::events::AlgorithmEvent(this, "Connect point sets to itk registration method.")); this->_internalRegistrationMethod->SetFixedPointSet(this->getTargetPointSet()); this->_internalRegistrationMethod->SetMovingPointSet(this->getMovingPointSet()); //initialize registration components after assembly this->prepareTransformAfterAssembly(); this->prepareMetricAfterAssembly(); this->prepareOptimizerAfterAssembly(this->getMetricInternal()->getMinimizeToOptimize()); //Register observers if (_onIterationObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onIterationEvent); _onIterationObserver = core::ObserverSentinel::New(this->getOptimizerInternal()->getMVNLOptimizer(), ::itk::IterationEvent(), spCommand); } if (_onGeneralOptimizerObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralOptimizerEvent); _onGeneralOptimizerObserver = core::ObserverSentinel::New( this->getOptimizerInternal()->getMVNLOptimizer(), ::itk::AnyEvent(), spCommand); } if (_onGeneralMetricObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralMetricEvent); _onGeneralMetricObserver = core::ObserverSentinel::New( this->getMetricInternal()->getPointSetToPointSetMetric(), ::itk::AnyEvent(), spCommand); } if (_onGeneralTransformObserver.IsNull()) { typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralTransformEvent); _onGeneralTransformObserver = core::ObserverSentinel::New( this->getTransformInternal(), ::itk::AnyEvent(), spCommand); } typename ::itk::MemberCommand::Pointer spCommand = ::itk::MemberCommand::New(); spCommand->SetCallbackFunction(this, &Self::onGeneralRegistrationMethodEvent); this->_internalRegistrationMethod->AddObserver(::itk::AnyEvent(), spCommand); }; template bool ITKPointSetRegistrationAlgorithm:: runAlgorithm() { this->_internalRegistrationMethod->Update(); this->_stopConditionDescription = this->getOptimizerInternal()->getStopConditionDescription(); return true; }; template void ITKPointSetRegistrationAlgorithm:: finalizeAlgorithm() { - RegistrationPointer spResult = NULL; + RegistrationPointer spResult; //touch the sub component to ensure an actualzed modification time, //this is needed because in case of arbitrary policies and dll deployment //the components could come out of another context. So a //ModificationTimeValidator is needed in it could produce //false positives in this constellation. OptimizerPolicyType::GetMTime(); MetricPolicyType::GetMTime(); TransformPolicyType::GetMTime(); TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine final registration. No transform model present on internal level (getTransformInternal()). Please ensure proper setup of algorithm."); } TransformParametersType lastTransformParameters = this->_internalRegistrationMethod->GetLastTransformParameters(); //clone the transform model pTransformModel->SetParametersByValue( lastTransformParameters); //this line is need to ensure correct cloning for //itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). //Thoose transforms can cause problems with optimizers that only keep the parameters localy (e.g. itk::LBFGSOptimizer). //Excplicit resetting the parameters is a work arround to this problem. typename TransformBaseType::Pointer spFinalTransformModel = pTransformModel->Clone(); if (spFinalTransformModel.IsNull()) { std::ostringstream modelStrm; pTransformModel->Print(modelStrm); mapExceptionMacro(AlgorithmException, << "Error. Cannot determine final registration. Unable to clone transform model. Current model: " << modelStrm.str()); } //set the parameter of the final transform model to the final transform parameters of the algorithm //We set the parameter by Value and not by using SetParameter() because otherwise //it could cause errors with itk transforms that only keep a pointer to their parameters (e.g. itk::BSplineDeformableTransform). //This transforms would be invalid as soon as we leave this method. spFinalTransformModel->SetParametersByValue(lastTransformParameters); //now build the direct kernel (main kernel of a point set based registration algorithm) typedef core::PreCachedRegistrationKernel DirectKernelType; typename DirectKernelType::Pointer spDKernel = DirectKernelType::New(); spDKernel->setTransformModel(spFinalTransformModel); //now build the inverse kernel via inversion of the direct kernel typedef core::InverseRegistrationKernelGenerator GeneratorType; typename GeneratorType::Pointer spGenerator = GeneratorType::New(); typedef typename GeneratorType::InverseKernelBaseType InverseKernelType; typename InverseKernelType::Pointer spIKernel = spGenerator->generateInverse(* (spDKernel.GetPointer()), this->getTargetRepresentation()); if (spIKernel.IsNull()) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine inverse mapping kernel of final registration. Current direct kernel: " << spDKernel); } //ensure that settings changed to the registration determination process are reseted to default this->configureAlgorithm(); //now create the registration an set the kernels spResult = RegistrationType::New(); ::map::core::RegistrationManipulator manipulator(spResult); manipulator.setDirectMapping(spDKernel); manipulator.setInverseMapping(spIKernel); manipulator.getTagValues()[tags::AlgorithmUID] = this->getUID()->toStr(); //store the final results _spFinalizedRegistration = spResult; _finalizedTransformParameters = lastTransformParameters; }; template void ITKPointSetRegistrationAlgorithm:: prepInitializeTransformation() { const TransformBaseType* pTransformModel = this->getTransformInternal(); if (!pTransformModel) { mapExceptionMacro(AlgorithmException, << "Error. Cannot determine interim registration. No transform model present on internal level (getTransformInternal(). Pleas ensure proper setup of algorithm."); } ::map::core::OStringStream os; os << "Set start transformation parameters to: " << pTransformModel->GetParameters(); //set the parameter of the transform model to the current transform parameters of the algorithm this->setCurrentTransformParameters(pTransformModel->GetParameters()); this->_internalRegistrationMethod->SetInitialTransformParameters( pTransformModel->GetParameters()); this->InvokeEvent(::map::events::AlgorithmEvent(this, os.str())); }; template typename ITKPointSetRegistrationAlgorithm::RegistrationPointer ITKPointSetRegistrationAlgorithm:: doGetRegistration() const { return _spFinalizedRegistration; }; template void ITKPointSetRegistrationAlgorithm:: onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::core::OStringStream os; TransformParametersType currentParams = this->getTransformInternal()->GetParameters(); bool hasCurrentValue = this->getOptimizerInternal()->hasCurrentValue(); typename OptimizerBaseType::MVNLMeasureType currentValue = this->getOptimizerInternal()->getCurrentMeasure(); - this->_currentIterationLock.Lock(); + this->_currentIterationLock.lock(); ++_currentIterationCount; _currentTransformParameters = currentParams; os << "Iteration #" << _currentIterationCount << "; params: " << currentParams << "; metric value: "; if (hasCurrentValue) { os << currentValue; } else { os << "unkown"; } - this->_currentIterationLock.Unlock(); + this->_currentIterationLock.unlock(); this->InvokeEvent(::map::events::AlgorithmIterationEvent(this, os.str())); }; template void ITKPointSetRegistrationAlgorithm:: onGeneralOptimizerEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal optimizer event"); this->InvokeEvent(wrappedEvent); }; template void ITKPointSetRegistrationAlgorithm:: onGeneralMetricEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal metric event"); this->InvokeEvent(wrappedEvent); }; template void ITKPointSetRegistrationAlgorithm:: onGeneralTransformEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal transform event"); this->InvokeEvent(wrappedEvent); }; template void ITKPointSetRegistrationAlgorithm:: onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject) { ::map::events::AlgorithmWrapperEvent wrappedEvent(eventObject, caller, "internal registration method event"); this->InvokeEvent(wrappedEvent); }; template void ITKPointSetRegistrationAlgorithm:: onOptimizerChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { // we can directly reset the observer sentinel befor the optimizer will be unregistered this->_onGeneralOptimizerObserver = NULL; } }; template void ITKPointSetRegistrationAlgorithm:: onMetricChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the metric will be unregistered this->_onGeneralMetricObserver = NULL; } }; template void ITKPointSetRegistrationAlgorithm:: onTransformChange(const ::itk::EventObject& eventObject) { map::events::UnregisterAlgorithmComponentEvent unregEvent; if (unregEvent.CheckEvent(&eventObject)) { //we can directly reset the observer sentinel befor the transform will be unregistered this->_onGeneralTransformObserver = NULL; } }; template bool ITKPointSetRegistrationAlgorithm:: registrationIsOutdated() const { bool outdated = _spFinalizedRegistration.IsNull(); if (_spFinalizedRegistration.IsNotNull()) { if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < MetaPropertyAlgorithmBase::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < OptimizerPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < MetricPolicyType::GetMTime(); } if (!outdated) { outdated = _spFinalizedRegistration->GetMTime() < TransformPolicyType::GetMTime(); } if (!outdated) { //check if the inputs have been changed outdated = _internalRegistrationMethod->GetMovingPointSet() != this->getMovingPointSet(); } if (!outdated) { //check if the inputs have been changed outdated = _internalRegistrationMethod->GetFixedPointSet() != this->getTargetPointSet(); } } return outdated; }; template typename ITKPointSetRegistrationAlgorithm::OptimizerMeasureType ITKPointSetRegistrationAlgorithm:: doGetCurrentOptimizerValue() const { OptimizerMeasureType result; const OptimizerBaseType* pOptimizer = this->getOptimizerInternal(); if (pOptimizer) { if (pOptimizer->hasCurrentValue()) { result = pOptimizer->getCurrentValue(); } } return result; }; template void ITKPointSetRegistrationAlgorithm:: PrintSelf(std::ostream& os, ::itk::Indent indent) const { Superclass::PrintSelf(os, indent); PointSetRegistrationAlgorithmBase::PrintSelf(os, indent); os << indent << "Current itertation count: " << _currentIterationCount << std::endl; os << indent << "Current transform parameters: " << _currentTransformParameters << std::endl; os << indent << "Finalized transform parameters: " << _finalizedTransformParameters << std::endl; os << indent << "Finalized registration: " << _spFinalizedRegistration << std::endl; }; template void ITKPointSetRegistrationAlgorithm:: compileInfos(MetaPropertyVectorType& infos) const { //default implementation does nothing. }; template typename ITKPointSetRegistrationAlgorithm::MetaPropertyPointer ITKPointSetRegistrationAlgorithm:: doGetProperty(const MetaPropertyNameType& name) const { //default implementation does nothing. MetaPropertyPointer spDummy; return spDummy; }; template void ITKPointSetRegistrationAlgorithm:: doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty) { //default implementation does nothing. }; } // end namespace itk } // end namespace algorithm } // end namespace map #endif diff --git a/Code/Core/include/mapLazyRegistrationKernel.tpp b/Code/Core/include/mapLazyRegistrationKernel.tpp index 3253321..c8eeb13 100644 --- a/Code/Core/include/mapLazyRegistrationKernel.tpp +++ b/Code/Core/include/mapLazyRegistrationKernel.tpp @@ -1,199 +1,199 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1285 $ (last changed revision) // @date $Date: 2016-03-30 17:47:52 +0200 (Mi, 30 Mrz 2016) $ (last change date) // @author $Author: floca $ (last changed by) // Subversion HeadURL: $HeadURL: https://svn/sbr/Sources/SBR-Projects/MatchPoint/branches/Issue-1505/Code/Core/include/mapLazyRegistrationKernel.tpp $ */ #ifndef __LAZY_REGISTRATION_KERNEL_TPP #define __LAZY_REGISTRATION_KERNEL_TPP #include "mapExceptionObjectMacros.h" #include "mapPointVectorCombinationPolicy.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace core { template void LazyRegistrationKernel:: setTransformFunctor(const TransformGenerationFunctorType* functor) { assert(functor); if (!functor) { mapDefaultExceptionMacro(<< "Error. Cannot set functor. Functor points to NULL."); } - ::itk::MutexLockHolder mutexHolder(_generateMutex); + std::lock_guard mutexHolder(_generateMutex); _spGenerationFunctor = functor; }; template const typename LazyRegistrationKernel::TransformGenerationFunctorType* LazyRegistrationKernel:: getTransformFunctor() const { return _spGenerationFunctor; }; template bool LazyRegistrationKernel:: transformExists() const { return _spTransform.IsNotNull(); }; template typename LazyRegistrationKernel::RepresentationDescriptorConstPointer LazyRegistrationKernel:: getLargestPossibleRepresentation() const { RepresentationDescriptorConstPointer spRep; if (_spGenerationFunctor.IsNotNull()) { spRep = _spGenerationFunctor->getInFieldRepresentation(); } return spRep; }; template const typename LazyRegistrationKernel::TransformType* LazyRegistrationKernel:: getTransformModel() const { if (!this->checkAndPrepareTransform()) { mapDefaultExceptionMacro(<< "Error. Cannot return field. checkAndPrepareField() failed."); } return _spTransform; }; template bool LazyRegistrationKernel:: checkAndPrepareTransform() const { - ::itk::MutexLockHolder mutexHolder(_checkMutex); + std::lock_guard mutexHolder(_checkMutex); if (_spTransform.IsNull()) { //create field mapLogInfoObjMacro(<< "Lazy field kernel needs to generate the field"); - ::itk::MutexLockHolder mutexHolder(_generateMutex); + std::lock_guard mutexHolder(_generateMutex); assert(_spGenerationFunctor.IsNotNull()); _spTransform = _spGenerationFunctor->generateTransform(); mapLogInfoObjMacro(<< "Lazy field kernel has generated the field"); } return true; }; template LazyRegistrationKernel:: - LazyRegistrationKernel() : _spGenerationFunctor(NULL), _spTransform(NULL) + LazyRegistrationKernel() { }; template LazyRegistrationKernel:: ~LazyRegistrationKernel() { }; template const typename LazyRegistrationKernel::OutputPointType LazyRegistrationKernel:: getNullPoint() const { OutputPointType result; if (_spGenerationFunctor.IsNotNull()) { result = _spGenerationFunctor->getNullPoint(); } return result; }; template bool LazyRegistrationKernel:: usesNullPoint() const { bool result = false; if (_spGenerationFunctor.IsNotNull()) { result = _spGenerationFunctor->getNullPointUsage(); } return result; }; template ::itk::LightObject::Pointer LazyRegistrationKernel:: InternalClone() const { Pointer clone = Self::New(); clone->_spTransform = this->_spTransform; clone->_spGenerationFunctor = this->_spGenerationFunctor; return clone.GetPointer(); }; template void LazyRegistrationKernel:: PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); if (_spGenerationFunctor.IsNotNull()) { os << indent << "Generation functor : " << std::endl << _spGenerationFunctor << std::endl; } else { os << indent << "Generation functor : NULL" << std::endl; } if (_spTransform.IsNotNull()) { os << indent << "Transform : " << std::endl << _spTransform << std::endl; } else { os << indent << "Transform : NULL" << std::endl; } os << indent << "Use null vector: " << this->usesNullPoint() << std::endl; os << indent << "Null vector: " << this->getNullPoint() << std::endl; }; } // end namespace core } // end namespace map #endif