diff --git a/Code/Algorithms/Common/include/mapIterativeAlgorithmInterface.h b/Code/Algorithms/Common/include/mapIterativeAlgorithmInterface.h index af87547..32d76d9 100644 --- a/Code/Algorithms/Common/include/mapIterativeAlgorithmInterface.h +++ b/Code/Algorithms/Common/include/mapIterativeAlgorithmInterface.h @@ -1,99 +1,98 @@ // ----------------------------------------------------------------------- // 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 __ITERATIVE_ALGORITHM_INTERFACE_H #define __ITERATIVE_ALGORITHM_INTERFACE_H -#include "itkSimpleFastMutexLock.h" -#include "itkMutexLockHolder.h" +#include #include "mapMacros.h" #include "mapMAPAlgorithmsExports.h" /*! @namespace map The namespace map is used throughout the MatchPoint project to mark code as components of this project */ namespace map { namespace algorithm { namespace facet { /*! @class IterativeAlgorithmInterface @brief This is the interface for iterative algorithms @ingroup AlgorithmFacets @remark Algorithms that want to support iteration events and implement this interface should use the AlgorithmIterationEvent to indicate the begining of the next iteration @see map::events::AlgorithmIterationEvent */ class MAPAlgorithms_EXPORT IterativeAlgorithmInterface { public: using Self = IterativeAlgorithmInterface; using IterationCountType = unsigned long; /*! has the optimizer an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const = 0; /*! @brief gets the number of the algorithm's current iteration @eguarantee strong @return returns the algorithm's current iteration. If the optimizer has no iteration count (hasIterationCount()==false), return is always 0. @retval an IterationCountType specifying the current iteration @sa IterationCountType */ virtual IterationCountType getCurrentIteration() const = 0; /*! has the optimizer an maximum iteration count for the current level/stage? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const = 0; /*! @brief gets the maximum number of the algorithm's iterations in the current resolution level/stage @eguarantee strong @return returns the algorithm's maximum iterations count. If the optimizer has no iteration count (hasMaxIterationCount()==false), return is always 0. */ virtual IterationCountType getMaxIterations() const = 0; protected: IterativeAlgorithmInterface() = default; virtual ~IterativeAlgorithmInterface() = default; private: //No copy constructor allowed IterativeAlgorithmInterface(const Self& source) = delete; //purposely not implemented void operator=(const Self&) = delete; //purposely not implemented }; } // namespace facet } // namespace algorithm } // namespace map #endif diff --git a/Code/Algorithms/Common/include/mapRegistrationAlgorithm.h b/Code/Algorithms/Common/include/mapRegistrationAlgorithm.h index 1f727e4..18155df 100644 --- a/Code/Algorithms/Common/include/mapRegistrationAlgorithm.h +++ b/Code/Algorithms/Common/include/mapRegistrationAlgorithm.h @@ -1,175 +1,175 @@ // ----------------------------------------------------------------------- // 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_H #define __REGISTRATION_ALGORITHM_H #include "mapRegistrationAlgorithmBase.h" #include "mapRegistrationAlgorithmInterface.h" -#include "itkSimpleFastMutexLock.h" +#include namespace map { namespace algorithm { /*! @class RegistrationAlgorithm @brief Template class for registration algorithms. Has input and output dimensions. This class is the abstract class for generating registration algorithms, inherited from RegistrationAlgorithmBase and extended with InputDimensions and OutputDimensions. The different concrete RegistrationAlgorithm implementations inherit from this. @ingroup Algorithms */ template class RegistrationAlgorithm: public RegistrationAlgorithmBase, public facet::RegistrationAlgorithmInterface { public: typedef RegistrationAlgorithm Self; using Superclass = RegistrationAlgorithmBase; using Pointer = ::itk::SmartPointer; using ConstPointer = ::itk::SmartPointer; itkTypeMacro(RegistrationAlgorithm, RegistrationAlgorithmBase); /** Dimension of the algorithm */ itkStaticConstMacro(MovingDimensions, unsigned int, VMovingDimensions); itkStaticConstMacro(TargetDimensions, unsigned int, VTargetDimensions); typedef facet::RegistrationAlgorithmInterface RegistrationAlgorithmInterfaceType; using RegistrationType = typename RegistrationAlgorithmInterfaceType::RegistrationType; using RegistrationPointer = typename RegistrationAlgorithmInterfaceType::RegistrationPointer; using ConstRegistrationPointer = typename RegistrationAlgorithmInterfaceType::ConstRegistrationPointer; /*! @brief Gets the number of moving dimensions for this registration algorithm @eguarantee strong @return The number of moving dimensions @sa getTargetDimensions() */ unsigned int getMovingDimensions() const override; /*! @brief Gets the number of target dimensions for this registration algorithm @eguarantee strong @return The number of target dimensions @sa getMovingDimensions() */ unsigned int getTargetDimensions() const override; /*! Checks if the registration is uptodate. If not the registration becomes (re)computed * the valid registration will be returned. @eguarantee strong @return Smart pointer to the registration instance. May be null if no registration could be computed (determineRegistration returned false). @retval an ITK smart pointer on a specific RegistrationType object */ RegistrationPointer getRegistration() override; using MovingRepresentationDescriptorType = core::FieldRepresentationDescriptor; using TargetRepresentationDescriptorType = core::FieldRepresentationDescriptor; const MovingRepresentationDescriptorType* getMovingRepresentation() const override; void setMovingRepresentation(const MovingRepresentationDescriptorType* pDescriptor) override; const TargetRepresentationDescriptorType* getTargetRepresentation() const override; void setTargetRepresentation(const TargetRepresentationDescriptorType* pDescriptor) override; protected: /*! @brief returns if the registration should be computed. This default implementation returns true * if the doGetRegistration() returns a null pointer. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; /*! @brief internal virtual method that gets the precomputed registration @remark This method does not compute a registration, the computation is done by doDetermineRegistration() @eguarantee strong @return the registration @retval an ITK smart pointer on a specific RegistrationType object */ virtual RegistrationPointer doGetRegistration() const = 0; /*! Indicates the support region in the moving space required by the algorithm user. Thus, every object covered by the representation descriptor should be mapable by the direct kernel. If set to null, the support region should not be limited.*/ typename MovingRepresentationDescriptorType::ConstPointer _spMovingRepresentation; /*! Indicates the support region in the target space required by the algorithm user. Thus, every object covered by the representation descriptor should be mapable by the inverse kernel. If set to null, the support region should not be limited.*/ typename TargetRepresentationDescriptorType::ConstPointer _spTargetRepresentation; /*! This method is called by setMovingRepresentation() before the new representation is set. * This default implementation does nothing. * @param [in] pMovingRepresentation Pointer to the new representation.*/ virtual void doBeforeSetMovingRepresentation(const MovingRepresentationDescriptorType* pMovingRepresentation); /*! This method is called by setMovingRepresentation() after the new representation is set. * This default implementation does nothing.*/ virtual void doAfterSetMovingRepresentation(); /*! This method is called by setTargetRepresentation() before the new representation is set. * This default implementation does nothing. * @param [in] pTargetRepresentation Pointer to the new representation.*/ virtual void doBeforeSetTargetRepresentation(const TargetRepresentationDescriptorType* pTargetRepresentation); /*! This method is called by setTargetRepresentation() after the new representation is set. * This default implementation does nothing.*/ virtual void doAfterSetTargetRepresentation(); /*! This method is called by getMovingRepresentation() before the representation is returned. * This default implementation does nothing.*/ virtual void doBeforeGetMovingRepresentation() const; /*! This method is called by getTargetRepresentation() after the representation is returned. * This default implementation does nothing.*/ virtual void doBeforeGetTargetRepresentation() const; /*! The lock is used to manage the access to determination of a registration * and write acces to all members that are relevant for determination of a registration */ - mutable ::itk::SimpleFastMutexLock _determinationLock; + mutable ::std::mutex _determinationLock; RegistrationAlgorithm(); ~RegistrationAlgorithm() override; private: RegistrationAlgorithm(const Self& source) = delete; //purposely not implemented void operator=(const Self&) = delete; //purposely not implemented }; } // namespace algorithm } // namespace map #ifndef MatchPoint_MANUAL_TPP #include "mapRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/Common/include/mapRegistrationAlgorithmBase.h b/Code/Algorithms/Common/include/mapRegistrationAlgorithmBase.h index 27a82e2..e6ea3b4 100644 --- a/Code/Algorithms/Common/include/mapRegistrationAlgorithmBase.h +++ b/Code/Algorithms/Common/include/mapRegistrationAlgorithmBase.h @@ -1,217 +1,216 @@ // ----------------------------------------------------------------------- // 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_BASE_H #define __REGISTRATION_ALGORITHM_BASE_H #include "itkObject.h" -#include "itkSimpleFastMutexLock.h" -#include "itkMutexLockHolder.h" +#include #include "mapAlgorithmIdentificationInterface.h" #include "mapMacros.h" #include "mapMAPAlgorithmsExports.h" #define mapNewAlgorithmMacro(classname) \ static Pointer New() \ { \ Pointer smartPtr = new classname (); \ smartPtr->UnRegister(); \ smartPtr->configureAlgorithm();\ smartPtr->doneFirstConfiguration();\ return smartPtr; \ } namespace map { namespace algorithm { /*! @class RegistrationAlgorithmBase @brief Base class for registration algorithms. Does not have input and output dimensions. This class is the base class for generating registration algorithms. Only RegistrationAlgorithm inherits from this. @ingroup Algorithms */ class MAPAlgorithms_EXPORT RegistrationAlgorithmBase: public ::itk::Object, public facet::AlgorithmIdentificationInterface { public: using Self = RegistrationAlgorithmBase; using Superclass = ::itk::Object; using Pointer = ::itk::SmartPointer; using ConstPointer = ::itk::SmartPointer; itkTypeMacro(RegistrationAlgorithmBase, ::itk::Object); /*! @brief There are two algorithm types, analytic and iterative ones, which differ from the approach of obtaining the registration. */ enum AlgorithmType { ATAnalytic /*!< analytic algorithm type */, ATIterative /*!< iterative algorithm type */ }; /*! @brief Defines the state the algorithm is in */ struct AlgorithmState { enum Type { Pending /*!< the algorithm has been instanziated and is waiting. */, Initializing /*!< the algorithm is about to be initialized, but not yet started*/, Running /*!< the algorithm has been started and is running */, Stopping /*!< the algorithm is ordered to stop */, Stopped /*!< the algorithm has been stopped or is done with its processing */, Finalizing /*!< the algorithm has been is done with its processing and and about to generate the results*/, Finalized /*!< the algorithm has been is done with its processing and has a result*/, }; }; /*! @brief gets the algorithm's current state @eguarantee no fail @return returns the state of the algorithm */ virtual AlgorithmState::Type getCurrentState() const; /*! @brief Gets the number of moving dimensions for this registration algorithm @eguarantee no fail @return The number of moving dimensions @sa getTargetDimensions() */ virtual unsigned int getMovingDimensions() const = 0; /*! @brief Gets the number of target dimensions for this registration algorithm @eguarantee no fail @return The number of target dimensions @sa getMovingDimensions() */ virtual unsigned int getTargetDimensions() const = 0; /*! @brief Returns the algorithm type for this registration algorithm @eguarantee no fail @return The algorithm type @sa AlgorithmType */ virtual AlgorithmType getAlgorithmType() const = 0; /*! @brief Enforces the (re)computation of the registration and starts it. @return Indicates of the registration was successfully determined (e.g. could be false if an iterative algorithm was stopped prematurely by the user). @eguarantee strong @post If algorithm is indicated as reusable he is configured identically to its state before this function is called. */ bool determineRegistration(); /*! @brief Indicates if the algorithm is designed to be reused. Thus if * it is possible to use one instance to determine several registrations * with the same settings. @eguarantee no fail @retval true An instance can be used several times to determine registrations with the same algorithmic settings. @retval false The algorithm does not guarentee that in the case of several executions the algorithm is correctly initialized for later executions except the first. In this case it is normally necessary to generate an algorithm instance per registration task. Or reset the settings of the algorithm manually.*/ virtual bool isReusable() const = 0; protected: /*! @brief sets the algorithm's current state and calls onStateChange before; @eguarantee strong */ virtual void setCurrentState(const AlgorithmState::Type& state); /*! Method is called when state is going to be changed via setAlgorithmState(). Overwrite this method to create special algorithmic behavior. The default implementation does nothing. @eguarantee strong @return returns the success of stopping @retval true if algorithm has been successfully stopped @retval false otherwise */ virtual void onStateChange(AlgorithmState::Type oldState, AlgorithmState::Type newState) const; /*! @brief starts the computation of the registration @eguarantee strong @return Indicates of the registration was successfully determined (e.g. could be false if an iterative algorithm was stopped prematurely by the user). */ virtual bool doDetermineRegistration() = 0; /*! This member is used to implement the basic setup of the algorithm or * of its. properties (e.g. step size, resolution schedule). * @remark this function is called by mapNewAlgorithmMacro() to configure the * basic settings of an algorithm after instance creation. * @remark If an implemented algorithm is specified as reusable, this function * should also ensure the reusability of an algorithm. Thus it is called after algorithm * usage to ensure reasonable settings (default or set by user) for the next execution. * @eguarantee strong * @post Algorithm is configured with default settings or the user settings, if provided (and * he is reusable). * @sa mapNewAlgorithmMacro*/ virtual void configureAlgorithm() = 0; /*! Method returns the current value of _firstConfiguration. It is true within the call of mapNewAlgorithmMacro.*/ bool isFirstConfiguration() const; /*! Internal helper function (used by mapNewAlgorithmMacro) to set _firstConfiguration to false.*/ void doneFirstConfiguration(); RegistrationAlgorithmBase(); ~RegistrationAlgorithmBase() override; /*! Methods invoked by ::itk::LightObject::Print(). */ void PrintSelf(std::ostream& os, ::itk::Indent indent) const override; /*! mutex used to secure all state changes. */ - ::itk::SimpleFastMutexLock _stateLock; + ::std::mutex _stateLock; - using StateLockHolderType = ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock>; + using StateLockHolderType = ::std::lock_guard<::std::mutex>; private: /*! the current state of the algorithm (initialized, pausing, ...) */ AlgorithmState::Type _currentState{AlgorithmState::Pending}; /*! This member is used to indicate if a algorithm instance is configured the first time. * it is set by mapNewAlgorithmMacro()*/ bool _firstConfiguration{true}; //No copy constructor allowed RegistrationAlgorithmBase(const Self& source) = delete; void operator=(const Self&) = delete; //purposely not implemented }; } // namespace algorithm } // namespace map #endif diff --git a/Code/Algorithms/Elastix/include/mapElxCLIRegistrationAlgorithmBase.h b/Code/Algorithms/Elastix/include/mapElxCLIRegistrationAlgorithmBase.h index 3825ab4..59c6227 100644 --- a/Code/Algorithms/Elastix/include/mapElxCLIRegistrationAlgorithmBase.h +++ b/Code/Algorithms/Elastix/include/mapElxCLIRegistrationAlgorithmBase.h @@ -1,364 +1,364 @@ // ----------------------------------------------------------------------- // 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_ELX_CLI_REGISTRATION_ALGORITHM_BASE_H #define __MAP_ELX_CLI_REGISTRATION_ALGORITHM_BASE_H //MatchPoint #include "mapContinuous.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapClassMacros.h" #include "mapElxAlgorithmHelper.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapMaskedRegistrationAlgorithmBase.h" #include "mapGenericVectorFieldTransform.h" namespace map { namespace algorithm { namespace elastix { /*! @class CLIRegistrationAlgorithmBase @brief This is the base class for algorithms that serve as a wrapper for the registration tool "elastix". The algorithm is a very simple wrapper using a command line interface to facilitate elastix. For a registration task a temporary working directory is generated, where the algorithm stores the given moving and target image. Then the algorithms calls 'elastix' with appropriated command line arguments to trigger the registration as an external process. After elastix transformix will be used to generate a deformation field as result. This field will be loaded and converted into a MatchPoint registration object and returned. After the registration job is done, the temporary directory will be deleted by the algorithm. @remark @ingroup Algorithms @ingroup Elastix */ template class CLIRegistrationAlgorithmBase : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public MaskedRegistrationAlgorithmBase, public TIdentificationPolicy { public: typedef CLIRegistrationAlgorithmBase Self; typedef IterativeRegistrationAlgorithm Superclass; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(CLIRegistrationAlgorithmBase, IterativeRegistrationAlgorithm); typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageType TargetImageType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageType MovingImageType; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename MetaPropertyAlgorithmBase::MetaPropertyType MetaPropertyType; typedef typename MetaPropertyAlgorithmBase::MetaPropertyPointer MetaPropertyPointer; typedef typename MetaPropertyAlgorithmBase::MetaPropertyNameType MetaPropertyNameType; mapDefineAlgorithmIdentificationByPolicyMacro; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates if the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its curent value. */ virtual bool hasCurrentOptimizerValue() const; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; /*! @reimplemented */ virtual bool isReusable() const; mapGetMetaMacro(WorkingDirectory, core::String); mapSetMetaMacro(WorkingDirectory, core::String); mapGetMetaMacro(ElastixDirectory, core::String); mapSetMetaMacro(ElastixDirectory, core::String); mapGetMetaMacro(DeleteTempDirectory, bool); mapSetMetaMacro(DeleteTempDirectory, bool); protected: CLIRegistrationAlgorithmBase(); virtual ~CLIRegistrationAlgorithmBase(); typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; typedef typename Superclass::IterationCountType IterationCountType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer MovingImageConstPointer; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer TargetImageConstPointer; typedef ::itk::GenericVectorFieldTransform< ::map::core::continuous::ScalarType, TTargetImage::ImageDimension, TTargetImage::ImageDimension> FieldTransformType; typedef typename map::core::RegistrationTopology::InverseFieldType FinalFieldType; typedef typename FinalFieldType::Pointer FinalFieldPointer; typedef std::vector ParameterMapVectorType; /* @reimplemented*/ virtual void configureAlgorithm(); // MetaPropertyAlgorithmBase /*! @reimplemented*/ virtual void compileInfos(MetaPropertyVectorType& infos) const; /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by the passed region descriptors (pMovingRepresentation, pTargetRepresentation). @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification time of at least one sub component is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preparation tasks right before the algorithm is executed. At the end of this method the algorithm should be set up and ready to use.\n The method delegates the main work of initialization to several sub methods. These sub methods serve as slots that can be rewritten by an algorithm developer to alter certain aspects and keep the rest untouched.\n The sequence of slot calls is: \n - prepCheckValidity - prepPerpareInternalInputData - prepSaveElastixInputData - prepParameterMaps - prepFinalizePreparation @remark If you want to change the execution style, then overwrite runAlgorithm(). @eguarantee strong*/ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. @remark The default implementation checks the moving and target image. Overload this method to alter the validity check. @remark It is assumed that the implementation of this method throws an exception if the algorithm is not configured correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot for internal preprocessing of input data. This method should be reimplemented if you want to prepare the input data before they go into the internal registration method. E.g. blurring or normalizing the moving and target image before registration. @remark The default implementation does nothing. Thus the public input data will be the data used by the internal algorithm. @remark Implementations of this method should work on _spInternalMoving and _spInternalTargetImage. In the default implementation of prepSetInternalInputData() these member will be passed to the internal algorithm. @eguarantee strong*/ virtual void prepPerpareInternalInputData(); /*! This method is the slot for storing the relevant input data to the working directory of elastix. * @remark The default implementation stores _spInternalMoving and _spInternalTargetImage and the masks if set. @eguarantee strong */ virtual void prepSaveElastixInputData(); /*! This method is the slot for the generation of the parameter maps that should be passed to elastix. The base class assumes that after calling this methods the member _parameterMaps contains all parameters for all stages. @eguarantee strong */ virtual void prepParameterMaps() = 0; /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareIteration() or finalizeAlgorithm(). * @return Indicates if the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareIteration() or iterateAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). * @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). @eguarantee strong */ virtual IterationCountType doGetMaxIterations() const; /*! This method generates a unique and random subdirectory contained by _workingDir. * The path to this directory is stored in _currentTempDir. * @eguarantee strong */ void initializeCurrentTempDir(); /*! Helper function that uses transformix to generate a deformation file. The generated file is loaded and returned by the function.*/ FinalFieldPointer generateField() const; /*! Helper function that generates the file path to the parameter file for a certain stage (passed by parameter) regarding the current settings of the instance. @remark This function does not check if the passed stage NR is out of bound.*/ core::String getParameterFilePath(unsigned int stageNr) const; /*! Helper function that generates the file path to the result parameters for the final(last stage) transform. @pre Algorithm must have at least one stage.*/ core::String getFinalTransformFilePath() const; /*!Pointer to the moving image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving image without changing the public moving image pointer. * The variable is set by prepareIteration() to _spMovingImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalMovingImage before it is used by prepareIteration() to set the internal algorithm)*/ MovingImageConstPointer _spInternalMovingImage; /*!Pointer to the target image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target image with out changing the public target image pointer. * The variable is set by prepareIteration() to _spTargetImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalTargetImage before it is used by prepareIteration() to set the internal algorithm)*/ TargetImageConstPointer _spInternalTargetImage; /*!Directory that can be used to store temporary data. Process must have write access to this directory*/ core::String _workingDir; /*!Directory where the elastix tools 'elastix' and 'transformix' are located.*/ core::String _elastixDir; /*!Directory that is used to store temporary data on the current run*/ core::String _currentTempDir; /*!Vector with elastix parameter maps, each element of the vector is the parameter map for one registration stage of elastix*/ ParameterMapVectorType _parameterMaps; core::String _movingImageTempPath; core::String _targetImageTempPath; core::String _finalFieldTempPath; core::String _movingMaskTempPath; core::String _targetMaskTempPath; bool _deleteTempDirectory; /*! This member function is called by the process executer, whenever Elastix generates an output on stdout.*/ void onElxOutputEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! Helper method that removes the current temp dir (if it exists and _deleteTempDirectory is true). * @eguarantee no throw*/ void cleanTempDir() const; private: /*! The parameters of the registration field generated by transformix by using the results of elastix.*/ typename FinalFieldPointer _spFinalizedField; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; CLIRegistrationAlgorithmBase(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapElxCLIRegistrationAlgorithmBase.tpp" #endif #endif diff --git a/Code/Algorithms/FSL/include/mapFSLRegistrationAlgorithm.h b/Code/Algorithms/FSL/include/mapFSLRegistrationAlgorithm.h index 5964a98..4f6042e 100644 --- a/Code/Algorithms/FSL/include/mapFSLRegistrationAlgorithm.h +++ b/Code/Algorithms/FSL/include/mapFSLRegistrationAlgorithm.h @@ -1,343 +1,343 @@ // ----------------------------------------------------------------------- // 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_FSL_REGISTRATION_ALGORITHM_H #define __MAP_FSL_REGISTRATION_ALGORITHM_H #include "itkAffineTransform.h" #include "mapContinuous.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapClassMacros.h" #include "mapMetaPropertyAlgorithmBase.h" /*! @namespace map The namespace map is used throughout the MatchPoint project to mark code as components of this project */ namespace map { namespace algorithm { namespace fsl { struct DegreesOfFreedom { enum Type { DoF6 = 6, DoF7 = 7, DoF9 = 9, DoF12 = 12, DoF2D = 2 }; }; struct CostFunction { enum Type { LeastSquares, NormalisedCorrelation, CorrelationRatio, MutualInformation, NormalisedMutualInformation }; }; /*! @class FSLRegistrationAlgorithm @brief The class is an algorithm that serves as a wrapper for the FSL registration tool "flirt". The algorithm generates a temporary working directory, where it stores the given moving and target image. Then the algorithms calls 'flirt' with appropriated command line arguments to trigger the registration as an external process. After flirt is finished the result transformation will be converted into an MatchPoint registration object and returned. After the registration job is done, the temporary directory will be deleted by the algorithm. @ingroup Algorithms @ingroup FSL */ template class FSLRegistrationAlgorithm : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public TIdentificationPolicy { public: typedef FSLRegistrationAlgorithm Self; typedef IterativeRegistrationAlgorithm Superclass; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(FSLRegistrationAlgorithm, IterativeRegistrationAlgorithm); mapNewAlgorithmMacro(Self); typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageType TargetImageType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageType MovingImageType; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename MetaPropertyAlgorithmBase::MetaPropertyPointer MetaPropertyPointer; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates if the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its current value. */ virtual bool hasCurrentOptimizerValue() const; virtual UIDPointer getUID() const; virtual map::core::String getAlgorithmProfile() const; virtual map::core::String getAlgorithmDescription() const; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; /*! @reimplemented */ virtual bool isReusable() const; mapGetMetaMacro(WorkingDirectory, core::String); mapSetMetaMacro(WorkingDirectory, core::String); mapGetMetaMacro(FlirtDirectory, core::String); mapSetMetaMacro(FlirtDirectory, core::String); mapGetMetaMacro(DeleteTempDirectory, bool); mapSetMetaMacro(DeleteTempDirectory, bool); mapGetMetaMacro(CostFunction, CostFunction::Type); mapSetMetaMacro(CostFunction, CostFunction::Type); mapGetMetaMacro(DegreesOfFreedom, DegreesOfFreedom::Type); mapSetMetaMacro(DegreesOfFreedom, DegreesOfFreedom::Type); protected: FSLRegistrationAlgorithm(); virtual ~FSLRegistrationAlgorithm(); typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; typedef typename Superclass::IterationCountType IterationCountType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer MovingImageConstPointer; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer TargetImageConstPointer; typedef ::itk::AffineTransform ModelType; /* @reimplemented*/ virtual void configureAlgorithm(); // MetaPropertyAlgorithmBase /*! @reimplemented*/ virtual void compileInfos(MetaPropertyVectorType& infos) const; /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by the passed region descriptors (pMovingRepresentation, pTargetRepresentation). @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preparation tasks right before the algorithms execution. At the end of this method * the algorithm should be set up and ready to use. * @remark If you want to change the execution style, then overwrite iterateAlgorithm(). @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method should be reimplemented if you want to prepare the input data before they go into the internal * registration method. E.g. blurring or normalizing the moving and target image before registration. * @remark The default implementation does nothing. Thus the public input data will be the data used by the * internal algorithm. @eguarantee strong */ virtual void prepPerpareInternalInputData(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareIteration() or finalizeAlgorithm(). * @return Indicates if the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareIteration() or iterateAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). * @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). @eguarantee strong */ virtual IterationCountType doGetMaxIterations() const; /*! This method generates a unique and random subdirectory contained by _workingDir. * The path to this directory is stored in _currentTempDir. * @eguarantee strong */ void initializeCurrentTempDir(); /*!Pointer to the moving image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving image with out changing the public moving image pointer. * The variable is set by prepareAlgorithm() to _spMovingImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalMovingImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ MovingImageConstPointer _spInternalMovingImage; /*!Pointer to the target image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target image with out changing the public target image pointer. * The variable is set by prepareAlgorithm() to _spTargetImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalTargetImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ TargetImageConstPointer _spInternalTargetImage; /*!Directory that can be used to store temporary data. Process must have write access to this directory*/ core::String _workingDir; /*!Directory where the FSL tool 'flirt' is located.*/ core::String _flirtDir; /*!Directory that is used to store temporary data on the current run*/ core::String _currentTempDir; core::String _movingImageTempPath; core::String _targetImageTempPath; core::String _resultMatrixTempPath; /*!Cost function that should be used by flirt (default is CorrelationRatio).*/ CostFunction::Type _costFnc; /*!Degrees of freedom that should be used by flirt (default is 12).*/ DegreesOfFreedom::Type _dof; bool _deleteTempDirectory; /*! This member function is called by the process executer, when ever fsl generates an output on stdout.*/ void onFSLOutputEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! Helper method that removes the current temp dir (if it exists and _deleteTempDirectory is true). * @eguarantee no throw*/ void cleanTempDir() const; private: /*! The parameters of the registration transform of the last successfull registration determiniation. Will be set by finalizeAlgorithm()*/ typename ModelType::ParametersType _finalizedTransformParameters; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; FSLRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapFSLRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.h b/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.h index 180483f..cc12951 100644 --- a/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.h +++ b/Code/Algorithms/ITK/boxed/mapITKDemonsRegistrationAlgorithm.h @@ -1,235 +1,235 @@ // ----------------------------------------------------------------------- // 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_DEMONS_REGISTRATION_ALGORITHM_H #define __MAP_DEMONS_REGISTRATION_ALGORITHM_H #include "itkDemonsRegistrationFilter.h" #include "mapContinuous.h" #include "mapDiscreteElements.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapGenericVectorFieldTransform.h" /*! @namespace map The namespace map is used throughout the MatchPoint project to mark code as components of this project */ namespace map { namespace algorithm { namespace boxed { mapGenerateAlgorithmUIDPolicyMacro(ITKDemonsRegistationUIDPolicy, "de.dkfz.matchpoint", "ITKDemonsRegistrationAlgorithm", "1.0.0", ""); /*! @class ITKDemonsRegistrationAlgorithm @brief The class wraps the itk::DemonsRegistrationFilter as MatchPoint algorithm @ingroup Boxed */ template < class TMovingImage, class TTargetImage, class TIdentificationPolicy = ITKDemonsRegistationUIDPolicy > class ITKDemonsRegistrationAlgorithm : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public TIdentificationPolicy, public MetaPropertyAlgorithmBase { public: typedef ITKDemonsRegistrationAlgorithm Self; typedef IterativeRegistrationAlgorithm Superclass; typedef TIdentificationPolicy IdentificationPolicyType; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(ITKDemonsRegistrationAlgorithm, IterativeRegistrationAlgorithm); mapNewAlgorithmMacro(Self); typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef typename RegistrationAlgorithmBase::AlgorithmType AlgorithmType; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; typedef typename Superclass::IterationCountType IterationCountType; mapDefineAlgorithmIdentificationByPolicyMacro; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determine its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determine its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates of the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determine its current value. */ virtual bool hasCurrentOptimizerValue() const; protected: ITKDemonsRegistrationAlgorithm(); virtual ~ITKDemonsRegistrationAlgorithm(); typedef ::itk::GenericVectorFieldTransform< ::map::core::continuous::ScalarType, TTargetImage::ImageDimension, TTargetImage::ImageDimension> FieldTransformType; typedef typename ::map::core::discrete::Elements< Superclass::TargetDimensions >::VectorFieldType DisplacementFieldType; typedef ::itk::DemonsRegistrationFilter InternalRegistrationMethodType; // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by a region @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preperation tasks right befor the algorithms execution. At the and of this method * the algorithm should be set up and ready to use. * @remark If you want to change the execution style, then overwrite runAlgorithm(). @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareAlgorithm() or finalizeAlgorithm(). * @return Indicates of the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareAlgorithm() or runAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! This method should do all the special initialization work of the internal registration method. * By default it just sets the initial transformation parameter for the methods to the values of the transform * and sets the fixed image region if a target mask is set. @eguarantee strong */ virtual void prepInitializeTransformation(); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! @brief gets the maximum number of the algorithm's iterations @eguarantee strong @return returns the algorithm's maximum iterations count */ virtual IterationCountType doGetMaxIterations() const; typename InternalRegistrationMethodType::Pointer _internalRegistrationMethod; private: /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! The count if the iterations, since starting the registration algorithm the last time. * 0 indicates that no iteration has been processed yet.*/ IterationCountType _currentIterationCount; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; /*! This member function is called by the observer of the optimizer, when ever a IterationEvent is invoked.*/ void onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); ITKDemonsRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapITKDemonsRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.h b/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.h index 8ad02b6..7de2e37 100644 --- a/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.h +++ b/Code/Algorithms/ITK/include/mapITKImageRegistrationAlgorithm.h @@ -1,466 +1,466 @@ // ----------------------------------------------------------------------- // 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_H #define __MAP_ITK_IMAGE_REGISTRATION_ALGORITHM_H #include "mapContinuous.h" #include "mapClassMacros.h" #include "mapArbitraryTransformPolicy.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapMaskedRegistrationAlgorithmBase.h" #include "mapITKImageRegistrationAlgorithmInterface.h" #include "mapArbitraryInterpolatorPolicy.h" #include "mapArbitraryImageToImageMetricPolicy.h" #include "mapArbitrarySVNLOptimizerPolicy.h" #include "mapArbitraryTransformPolicy.h" #include "mapObserverSentinel.h" #include "mapModificationTimeValidator.h" #include "itkImageRegistrationMethod.h" -#include "itkSimpleFastMutexLock.h" +#include /*! @namespace map The namespace map is used throughout the MatchPoint project to mark code as components of this project */ namespace map { namespace algorithm { namespace itk { /*! @class ITKImageRegistrationAlgorithm @brief The class for an image registration algorithm based on ITK @ingroup Algorithms @ingroup ITK */ template < class TMovingImage, class TTargetImage, class TIdentificationPolicy, class TInterpolatorPolicy = ArbitraryInterpolatorPolicy, class TMetricPolicy = ArbitraryImageToImageMetricPolicy, class TOptimizerPolicy = ArbitrarySVNLOptimizerPolicy, class TTransformPolicy = ArbitraryTransformPolicy< ::map::core::continuous::ScalarType, TMovingImage::ImageDimension, TTargetImage::ImageDimension>, class TInternalRegistrationMethod = ::itk::ImageRegistrationMethod > class ITKImageRegistrationAlgorithm : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public MaskedRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public ITKImageRegistrationAlgorithmInterface, public TIdentificationPolicy, public TInterpolatorPolicy, public TMetricPolicy, public TOptimizerPolicy, public TTransformPolicy { public: typedef ITKImageRegistrationAlgorithm < TMovingImage, TTargetImage, TIdentificationPolicy, TInterpolatorPolicy, TMetricPolicy, TOptimizerPolicy, TTransformPolicy, TInternalRegistrationMethod > Self; typedef IterativeRegistrationAlgorithm Superclass; typedef ITKImageRegistrationAlgorithmInterface ITKRegistrationType; using Pointer = ::itk::SmartPointer; using ConstPointer = ::itk::SmartPointer; itkTypeMacro(ITKImageRegistrationAlgorithm, IterativeRegistrationAlgorithm); mapNewAlgorithmMacro(Self); using UIDType = typename Superclass::UIDType; using UIDPointer = typename Superclass::UIDPointer; using InterpolatorPolicyType = TInterpolatorPolicy; using MetricPolicyType = TMetricPolicy; using OptimizerPolicyType = TOptimizerPolicy; using TransformPolicyType = TTransformPolicy; using IdentificationPolicyType = TIdentificationPolicy; using OptimizerBaseType = typename ITKRegistrationType::OptimizerBaseType; using MetricBaseType = typename ITKRegistrationType::MetricBaseType; using TransformBaseType = typename ITKRegistrationType::TransformBaseType; using InterpolatorBaseType = typename ITKRegistrationType::InterpolatorBaseType; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; using MaskRegistrationAlgorithmBaseType = MaskedRegistrationAlgorithmBase; using TargetImageType = typename ImageRegistrationAlgorithmBaseType::TargetImageType; using MovingImageType = typename ImageRegistrationAlgorithmBaseType::MovingImageType; using MovingImageConstPointer = typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer; using TargetImageConstPointer = typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer; using MovingMaskBaseType = typename MaskRegistrationAlgorithmBaseType::MovingMaskBaseType; using TargetMaskBaseType = typename MaskRegistrationAlgorithmBaseType::TargetMaskBaseType; using MovingMaskBaseConstPointer = typename MaskRegistrationAlgorithmBaseType::MovingMaskBaseConstPointer; using TargetMaskBaseConstPointer = typename MaskRegistrationAlgorithmBaseType::TargetMaskBaseConstPointer; using MovingRepresentationDescriptorType = typename Superclass::MovingRepresentationDescriptorType; using TargetRepresentationDescriptorType = typename Superclass::TargetRepresentationDescriptorType; using RegistrationPointer = typename Superclass::RegistrationPointer; using RegistrationType = typename Superclass::RegistrationType; using FieldRepRequirement = typename Superclass::FieldRepRequirement; using IterationCountType = typename Superclass::IterationCountType; using MetaPropertyPointer = typename MetaPropertyAlgorithmBase::MetaPropertyPointer; using MetaPropertyNameType = typename MetaPropertyAlgorithmBase::MetaPropertyNameType; using MetaPropertyVectorType = typename MetaPropertyAlgorithmBase::MetaPropertyVectorType; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates of the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its curent value. */ virtual bool hasCurrentOptimizerValue() const; mapDefineAlgorithmIdentificationByPolicyMacro; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; virtual bool isReusable() const; mapSetMacro(CropInputImagesByMask, bool); mapGetMacro(CropInputImagesByMask, bool); protected: ITKImageRegistrationAlgorithm(); ~ITKImageRegistrationAlgorithm() override; using InternalRegistrationMethodType = TInternalRegistrationMethod; using InterimRegistrationType = typename Superclass::InterimRegistrationType; using InterimRegistrationPointer = typename Superclass::InterimRegistrationPointer; /*! @overwrite * This default implementation does nothing.*/ virtual void configureAlgorithm(); // MetaPropertyAlgorithmBase /*! @reimplemented*/ void compileInfos(MetaPropertyVectorType& infos) const override; /*! @reimplemented*/ MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const override; /*! @reimplemented*/ void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty) override; // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by a region @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preparation tasks right before the algorithms execution. At the and of this method * the algorithm should be set up and ready to use.\n * The method delegates the main work of initialization to several sub methods. This sub methods serves as slots * that can be rewritten by a algorithm developer to alter certain aspects and keep the rest untouched.\n * The sequence of slot calls is: \n * - prepCheckValidity * - prepPrepareSubComponents * - prepAssembleSubComponents * - prepPerpareInternalInputData * - prepSetInternalInputData * - prepInitializeTransformation * - prepFinalizePreparation * @remark If you want to change the execution style, then overwrite runAlgorithm(). @remark If you want to alter settings of optimzer, metric or interpolator depending on the resolution level use the method doInterLevelSetup() @remark configureAlgorithmByMetaProperties is called after preCheckValidity and before prepPerpareSubComponent. @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. * @remark The default implementation checks transform, interpolator, optimizer, metric, pyramides, moving and target image. * overload this method to alter the validity check. * @remark It is assumed that the implementation of this method throws an exception if the algorithm is not be configured * correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot where sub components can be configured before(!) they are set to the * internal registration method. * @remark The default implementation just calls the preparation methods of the component policies.*/ virtual void prepPrepareSubComponents(); /*! This method is the slot where sub components are set to the internal registration method. * @remark The default implementation just calls the preparation methods of the component policies.*/ virtual void prepAssembleSubComponents(); /*! This method is the slot for internal preprocessing of input data. This method should * be reimplemented if you want to prepare the input data before they go into the internal * registration method. E.g. blurring or normalizing the moving and target image before registration. * @remark The default implementation does nothing. Thus the public input data will be the data used by the * internal algorithm. * @remark Implementations of this method should work with getInternalTargetImage()/getInternalMovingImage() and * set there results via setInternalTargetImage()/setInternalMovingImage() to allow the correct handling. @eguarantee strong */ virtual void prepPerpareInternalInputData(); /*! This method is the slot for passing relevant input data to the internal algorithm or its components. * @remark The default implementation passes getInternalTargetImage and getInternalMovingImage, sets the schedules, the fixed image region of the registration and the metric masks. * @remark If you need to access the images use getInternalTargetImage()/getInternalMovingImage(). @eguarantee strong */ virtual void prepSetInternalInputData(); /*! This method is a slot that is used for the initialization of the transformation model used * by the internal registration algorithm. * @remark By default it just sets the initial transformation parameter for the internal registration methods to the current values of the transform. * @remark If you need to access the images use getInternalTargetImage()/getInternalMovingImage(). @eguarantee strong */ virtual void prepInitializeTransformation(); /*! This method is the slot for final steps in the preparation process * @remark The default implementation calls the prepareAfterAssembly methods of the sub component policies. * @remark If you need to access the images use getInternalTargetImage()/getInternalMovingImage(). @eguarantee strong */ virtual void prepFinalizePreparation(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareAlgorithm() or finalizeAlgorithm(). * @return Indicates of the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareAlgorithm() or runAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); using TransformParametersType = typename TransformPolicyType::TransformType::ParametersType; /*! Gets the member variable _currentTransformParameters secured via _currentIterationLock. @return Copy of the current transform parameters. */ TransformParametersType getCurrentTransformParameters() const; /*! Sets the member variable _currentTransformParameters secured via _currentIterationLock. @param [in] Reference to the new current parameters. */ void setCurrentTransformParameters(const TransformParametersType& param); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! @brief gets the maximum number of the algorithm's iterations @eguarantee strong @return returns the algorithm's maximum iterations count */ virtual IterationCountType doGetMaxIterations() const; /*! Offers access to the internal registration method */ InternalRegistrationMethodType& getInternalRegistrationMethod(); /*! The count if the iterations, since starting the registration algorithm the last time. * 0 indicates that no iteration has been processed yet.*/ IterationCountType _currentIterationCount; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; /*! The current parameters of the registration transform. Will be set in every iteration step*/ TransformParametersType _currentTransformParameters; /*! The parameters of the registration transform of the last successfull registration determiniation. Will be set by finalizeAlgorithm()*/ TransformParametersType _finalizedTransformParameters; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! Method returns pointer to the moving image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving image with out changing the public moving image pointer. * It returns _spMovingImage if setInternalMovingImage was never called (thus no special internal image was defined). * Otherwise it will return _spInternalMovingImage. * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate the internal moving image before it is used by prepareAlgorithm() to set the internal algorithm)*/ MovingImageConstPointer getInternalMovingImage() const; /*! Method returns pointer to the target image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target image with out changing the public target image pointer. * It returns _spTargetImage if setInternalTargetImage was never called (thus no special internal image was defined). * Otherwise it will return _spInternalTargetImage. * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate the internal target image before it is used by prepareAlgorithm() to set the internal algorithm)*/ TargetImageConstPointer getInternalTargetImage() const; /*!Method sets _spInternalMovingImage to the passed image and therefore overrides the target which is internally used by the algorithm.*/ void setInternalMovingImage(MovingImageType* image); /*!Method sets _spInternalTargetImage to the passed image and therefore overrides the target which is internally used by the algorithm.*/ void setInternalTargetImage(TargetImageType* image); /*! Method returns pointer to the moving mask used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving mask with out changing the public moving mask pointer. * It returns _spMovingMask if setInternalMovingMask was never called (thus no special internal mask was defined). * Otherwise it will return _spInternalMovingMask.*/ MovingMaskBaseConstPointer getInternalMovingMask() const; /*! Method returns pointer to the target mask used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target mask with out changing the public target mask pointer. * It returns _spTargetMask if setInternalTargetMask was never called (thus no special internal mask was defined). * Otherwise it will return _spInternalTargetMask.*/ TargetMaskBaseConstPointer getInternalTargetMask() const; /*!Method sets _spInternalMovingMask to the passed mask and therefore overrides the target which is internally used by the algorithm.*/ void setInternalMovingMask(MovingMaskBaseType* mask); /*!Method sets _spInternalTargetMask to the passed mask and therefore overrides the target which is internally used by the algorithm.*/ void setInternalTargetMask(TargetMaskBaseType* mask); bool _CropInputImagesByMask; private: typename InternalRegistrationMethodType::Pointer _internalRegistrationMethod; /*!Pointer to the moving image used by the algorithm internally if it was changed by setInternalMovingImage(). * This is used to allow the algorithm or its derived classes to modify the moving image with out changing the public moving image pointer. * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate _spInternalMovingImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ typename MovingImageType::Pointer _spInternalMovingImage; /*!Pointer to the target image used by the algorithm internally if it was changed by setInternalTargetImage(). * This is used to allow the algorithm or its derived classes to modify the target image with out changing the public target image pointer. * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate _spInternalTargetImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ typename TargetImageType::Pointer _spInternalTargetImage; /*!Pointer to the moving mask used by the algorithm internally if it was changed by setInternalMovingMask(). * This is used to allow the algorithm or its derived classes to modify the moving mask with out changing the public moving mask pointer.*/ typename MovingMaskBaseType::Pointer _spInternalMovingMask; /*!Pointer to the target mask used by the algorithm internally if it was changed by setInternaltargetMask(). * This is used to allow the algorithm or its derived classes to modify the target mask with out changing the public target mask pointer.*/ typename TargetMaskBaseType::Pointer _spInternalTargetMask; mutable core::ObserverSentinel::Pointer _onIterationObserver; mutable core::ObserverSentinel::Pointer _onGeneralOptimizerObserver; mutable core::ObserverSentinel::Pointer _onGeneralMetricObserver; mutable core::ObserverSentinel::Pointer _onGeneralInterpolatorObserver; mutable core::ObserverSentinel::Pointer _onGeneralTransformObserver; /*! This member function is called by the observer of the optimizer, when ever a IterationEvent is invoked.*/ void onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the optimizer for all kind of events. It serves as a pass through.*/ void onGeneralOptimizerEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the metric for all kind of events. It serves as a pass through.*/ void onGeneralMetricEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the interpolator for all kind of events. It serves as a pass through.*/ void onGeneralInterpolatorEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralTransformEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the optimizer policy if the optimizer instance changes.*/ void onOptimizerChange(const ::itk::EventObject& eventObject); /*! This member function is called by the metric policy if the metric instance changes.*/ void onMetricChange(const ::itk::EventObject& eventObject); /*! This member function is called by the interpolator policy if the interpolator instance changes.*/ void onInterpolatorChange(const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onTransformChange(const ::itk::EventObject& eventObject); ITKImageRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } // namespace itk } // namespace algorithm } // namespace map #ifndef MatchPoint_MANUAL_TPP #include "mapITKImageRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.h b/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.h index fcb0645..47abd16 100644 --- a/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.h +++ b/Code/Algorithms/ITK/include/mapITKMultiResImageRegistrationAlgorithm.h @@ -1,251 +1,251 @@ // ----------------------------------------------------------------------- // 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_H #define __ITK_MULTI_RES_IMAGE_REGISTRATION_ALGORITHM_H #include "mapContinuous.h" #include "mapITKImageRegistrationAlgorithm.h" #include "mapArbitraryImagePyramidesPolicy.h" #include "mapModifiableMultiResImageRegistrationAlgorithmBase.h" #include "itkMultiResolutionImageRegistrationMethod.h" -#include "itkSimpleFastMutexLock.h" +#include namespace map { namespace algorithm { namespace itk { /*! @class ITKMultiResImageRegistrationAlgorithm @brief The class is used for image registration algorithm based on ITK and using a multi resolution approach. If you need to react on level changes (e.g. to adapt certain algorithm parameters) you can observe the object for AlgorithmResolutionLevelEvent. If you derive from this class you may also reimplement the method doInterLevelSetup to directly react on level changes within the class implementation. @ingroup Algorithms */ template < class TMovingImage, class TTargetImage, class TIdentificationPolicy, class TInterpolatorPolicy = ArbitraryInterpolatorPolicy, class TMetricPolicy = ArbitraryImageToImageMetricPolicy, class TOptimizerPolicy = ArbitrarySVNLOptimizerPolicy, class TTransformPolicy = ArbitraryTransformPolicy< ::map::core::continuous::ScalarType, TMovingImage::ImageDimension, TTargetImage::ImageDimension>, class TPyramidesPolicy = ArbitraryImagePyramidesPolicy, class TInternalRegistrationMethod = ::itk::MultiResolutionImageRegistrationMethod > class ITKMultiResImageRegistrationAlgorithm : public ITKImageRegistrationAlgorithm, public ModifiableMultiResImageRegistrationAlgorithmBase { public: typedef ITKMultiResImageRegistrationAlgorithm < TMovingImage, TTargetImage, TIdentificationPolicy, TInterpolatorPolicy, TMetricPolicy, TOptimizerPolicy, TTransformPolicy, TPyramidesPolicy, TInternalRegistrationMethod > Self; typedef ITKImageRegistrationAlgorithm Superclass; typedef ITKImageRegistrationAlgorithmInterface ITKRegistrationType; typedef ModifiableMultiResImageRegistrationAlgorithmBase MultiResRegistrationAlgorithmType; using Pointer = ::itk::SmartPointer; using ConstPointer = ::itk::SmartPointer; itkTypeMacro(ITKMultiResImageRegistrationAlgorithm, ITKImageRegistrationAlgorithm); mapNewAlgorithmMacro(Self); using UIDType = typename Superclass::UIDType; using UIDPointer = typename Superclass::UIDPointer; using MovingImageType = TMovingImage; using TargetImageType = TTargetImage; using InterpolatorPolicyType = TInterpolatorPolicy; using MetricPolicyType = TMetricPolicy; using OptimizerPolicyType = TOptimizerPolicy; using TransformPolicyType = TTransformPolicy; using IdentificationPolicyType = TIdentificationPolicy; using PyramidesPolicyType = TPyramidesPolicy; using OptimizerBaseType = typename ITKRegistrationType::OptimizerBaseType; using MetricBaseType = typename ITKRegistrationType::MetricBaseType; using TransformBaseType = typename ITKRegistrationType::TransformBaseType; using InterpolatorBaseType = typename ITKRegistrationType::InterpolatorBaseType; using ScheduleType = typename MultiResRegistrationAlgorithmType::ScheduleType; using ResolutionLevelCountType = typename MultiResRegistrationAlgorithmType::ResolutionLevelCountType; using TargetImagePyramideBaseType = typename MultiResRegistrationAlgorithmType::TargetImagePyramideBaseType; using MovingImagePyramideBaseType = typename MultiResRegistrationAlgorithmType::MovingImagePyramideBaseType; using TargetImagePyramideBasePointer = typename MultiResRegistrationAlgorithmType::TargetImagePyramideBasePointer; using MovingImagePyramideBasePointer = typename MultiResRegistrationAlgorithmType::MovingImagePyramideBasePointer; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; using MovingRepresentationDescriptorType = typename Superclass::MovingRepresentationDescriptorType; using TargetRepresentationDescriptorType = typename Superclass::TargetRepresentationDescriptorType; using RegistrationPointer = typename Superclass::RegistrationPointer; using RegistrationType = typename Superclass::RegistrationType; using IterationCountType = typename Superclass::IterationCountType; using FieldRepRequirement = typename Superclass::FieldRepRequirement; using MovingImageConstPointer = typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer; using TargetImageConstPointer = typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer; /*! Indicates if the current processed level can be deduced @eguarantee no fail */ virtual bool hasLevelCount() const; protected: ITKMultiResImageRegistrationAlgorithm(); virtual ~ITKMultiResImageRegistrationAlgorithm(); using InternalRegistrationMethodType = typename Superclass::InternalRegistrationMethodType; using InterimRegistrationType = typename Superclass::InterimRegistrationType; using InterimRegistrationPointer = typename Superclass::InterimRegistrationPointer; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; /*! This method should do all preparation tasks right before the algorithms execution. At the and of this method * the algorithm should be set up and ready to use.\n * The method delegates the main work of initialization to several sub methods. This sub methods serves as slots * that can be rewritten by a algorithm developer to alter certain aspects and keep the rest untouched.\n * The sequence of slot calls is: \n * - prepCheckValidity * - prepPrepareSubComponents * - prepAssembleSubComponents * - prepPerpareInternalInputData * - prepSetInternalInputData * - prepInitializeTransformation * - prepFinalizePreparation * @remark If you want to change the execution style, then overwrite runAlgorithm(). @remark If you want to alter settings of optimzer, metric or interpolator depending on the resolution level use the method doInterLevelSetup() @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. * @remark The default implementation checks transform, interpolator, optimizer, metric, pyramides, moving and target image. * overload this method to alter the validity check. * @remark It is assumed that the implementation of this method throws an exception if the algorithm is not be configured * correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot where sub components can be configured before(!) they are set to the * internal registration method. * @remark The default implementation just calls the preparation methods of the component policies.*/ virtual void prepPrepareSubComponents(); /*! This method is the slot where sub components are set to the internal registration method. * @remark The default implementation just calls the preparation methods of the component policies.*/ virtual void prepAssembleSubComponents(); /*! This method is the slot for passing relevant input data to the internal algorithm or its components. * @remark The default implementation passes _spInternalMoving and _spInternalTargetImage, sets the schedules, the fixed image region of the registration and the metric masks. @eguarantee strong */ virtual void prepSetInternalInputData(); /*! This method is the slot for final steps in the preperation process * @remark The default implementation calls the prepareAfterAssembly methods of the sub component policies. @eguarantee strong */ virtual void prepFinalizePreparation(); using TransformParametersType = typename TransformPolicyType::TransformType::ParametersType; /*! return the current resolution level number. Will be called by getCurrentLevel() if hasLevelCount() returns true. @eguarantee strong @return level count */ virtual ResolutionLevelCountType doGetCurrentLevel() const; /*! This member is called by onLevelEvent() after the envent is invoked. The default implementation does nothing. It can be used in derivated classes to directly implement any initialization or setup strategies between level changes (e.g. adjusting the stepsize of the optimizer. */ virtual void doInterLevelSetup(); /*! Overloaded member that also stops on the registration method * level */ virtual bool doStopAlgorithm(); /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; private: /*! The count of the levels, since starting the registration algorithm the last time. * 0 indicates that no level has been processed yet.*/ ResolutionLevelCountType _currentLevelCount; /*!Indicates if there was any level event before*/ bool _firstLevelEvent; /*! The lock is used to manage the access to the member variable _currentLevelCount.*/ - mutable ::itk::SimpleFastMutexLock _currentLevelLock; + mutable ::std::mutex _currentLevelLock; mutable core::ObserverSentinel::Pointer _onLevelObserver; mutable core::ObserverSentinel::Pointer _onGeneralTargePyramideObserver; mutable core::ObserverSentinel::Pointer _onGeneralMovingPyramideObserver; /*! This member function is called by the observer of the optimizer, when ever a LevelEvent is invoked.*/ void onLevelEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onTargetImagePyramideChange(const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onMovingImagePyramideChange(const ::itk::EventObject& eventObject); ITKMultiResImageRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } // namespace itk } // namespace algorithm } // namespace map #ifndef MatchPoint_MANUAL_TPP #include "mapITKMultiResImageRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/include/mapITKMultiResPDEDeformableRegistrationAlgorithm.h b/Code/Algorithms/ITK/include/mapITKMultiResPDEDeformableRegistrationAlgorithm.h index 044c7de..1515539 100644 --- a/Code/Algorithms/ITK/include/mapITKMultiResPDEDeformableRegistrationAlgorithm.h +++ b/Code/Algorithms/ITK/include/mapITKMultiResPDEDeformableRegistrationAlgorithm.h @@ -1,290 +1,290 @@ // ----------------------------------------------------------------------- // 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_PDE_DEFORMABLE_REGISTRATION_ALGORITHM_H #define __ITK_MULTI_RES_PDE_DEFORMABLE_REGISTRATION_ALGORITHM_H #include "mapContinuous.h" #include "mapDiscreteElements.h" #include "mapITKPDEDeformableRegistrationAlgorithmBase.h" #include "mapObserverSentinel.h" #include "mapModificationTimeValidator.h" #include "mapMultiResImageRegistrationAlgorithmBase.h" #include "mapArbitraryImagePyramidesPolicy.h" #include "itkMultiResolutionPDEDeformableRegistration.h" -#include "itkSimpleFastMutexLock.h" +#include namespace map { namespace algorithm { namespace itk { /*! @class ITKMultiResPDEDeformableRegistrationAlgorithm @brief The class for an image registration algorithm based on ITK @ingroup Algorithms @ingroup ITK */ template < class TImageType, class TIdentificationPolicy, class TInternalRegistrationFilter, class TDisplacementField = typename core::discrete::Elements::VectorFieldType , class TPyramidesPolicy = ArbitraryImagePyramidesPolicy > class ITKMultiResPDEDeformableRegistrationAlgorithm : public ITKPDEDeformableRegistrationAlgorithmBase< TImageType, TIdentificationPolicy, TDisplacementField, TInternalRegistrationFilter >, public MultiResImageRegistrationAlgorithmBase { public: typedef ITKMultiResPDEDeformableRegistrationAlgorithm < TImageType, TIdentificationPolicy, TInternalRegistrationFilter, TDisplacementField, TPyramidesPolicy > Self; typedef ITKPDEDeformableRegistrationAlgorithmBase < TImageType, TIdentificationPolicy, TDisplacementField, TInternalRegistrationFilter > Superclass; typedef MultiResImageRegistrationAlgorithmBase MultiResRegistrationAlgorithmType; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(ITKMultiResPDEDeformableRegistrationAlgorithm, ITKPDEDeformableRegistrationAlgorithm); mapNewAlgorithmMacro(Self); typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef TIdentificationPolicy IdentificationPolicyType; typedef TPyramidesPolicy PyramidesPolicyType; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; typedef typename Superclass::TargetImageType TargetImageType; typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImageConstPointer MovingImageConstPointer; typedef typename Superclass::TargetImageConstPointer TargetImageConstPointer; typedef typename MultiResRegistrationAlgorithmType::ScheduleType ScheduleType; typedef typename MultiResRegistrationAlgorithmType::ResolutionLevelCountType ResolutionLevelCountType; typedef typename MultiResRegistrationAlgorithmType::TargetImagePyramideBaseType TargetImagePyramideBaseType; typedef typename MultiResRegistrationAlgorithmType::MovingImagePyramideBaseType MovingImagePyramideBaseType; typedef typename MultiResRegistrationAlgorithmType::TargetImagePyramideBasePointer TargetImagePyramideBasePointer; typedef typename MultiResRegistrationAlgorithmType::MovingImagePyramideBasePointer MovingImagePyramideBasePointer; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename Superclass::IterationCountType IterationCountType; typedef typename Superclass::MetaPropertyPointer MetaPropertyPointer; typedef typename Superclass::MetaPropertyNameType MetaPropertyNameType; typedef typename Superclass::MetaPropertyVectorType MetaPropertyVectorType; typedef typename Superclass::MetaPropertyType MetaPropertyType; /*! Indicates if the current processed level can be deduced @eguarantee no fail */ virtual bool hasLevelCount() const; protected: ITKMultiResPDEDeformableRegistrationAlgorithm(); virtual ~ITKMultiResPDEDeformableRegistrationAlgorithm(); typedef TInternalRegistrationFilter InternalRegistrationMethodType; typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; /*! @reimplemented*/ virtual void configureAlgorithm(); /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); virtual bool doStopAlgorithm(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareAlgorithm() or finalizeAlgorithm(). * @return Indicates of the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; /*! This method should do all preparation tasks right before the algorithms execution. At the and of this method * the algorithm should be set up and ready to use.\n * The method delegates the main work of initialization to several sub methods. This sub methods serves as slots * that can be rewritten by a algorithm developer to alter certain aspects and keep the rest untouched.\n * The sequence of slot calls is: \n * - prepCheckValidity * - prepPrepareSubComponents * - prepAssembleSubComponents * - prepPerpareInternalInputData * - prepSetInternalInputData * - prepInitializeTransformation * - prepFinalizePreparation * @remark If you want to change the execution style, then overwrite runAlgorithm(). @remark If you want to alter settings depending on the resolution level use the method doInterLevelSetup() @remark configureAlgorithmByMetaProperties is called after preCheckValidity and before prepPerpareSubComponent. @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. * @remark The default implementation checks transform, interpolator, optimizer, metric, pyramides, moving and target image. * overload this method to alter the validity check. * @remark It is assumed that the implementation of this method throws an exception if the algorithm is not be configured * correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot where sub components can be configured before(!) they are set to the * internal registration method. * @remark The default implementation does nothing.*/ virtual void prepPrepareSubComponents(); /*! This method is the slot where sub components are set to the internal registration method. * @remark The default implementation does nothing.*/ virtual void prepAssembleSubComponents(); /*! This method is the slot for internal preprocessing of input data. This method should * be reimplemented if you want to prepare the input data before they go into the internal * registration method. E.g. blurring or normalizing the moving and target image before registration. * @remark The default implementation uses an itk::HistogrammMatchingFilter to normalize the gray values of the input image. * @remark Implementations of this method should work on _spInternalMoving and _spInternalTargetImage. In the default * implementation of prepSetInternalInputData() these member will be passed to the internal algorithm. @eguarantee strong */ virtual void prepPerpareInternalInputData(); /*! This method is the slot for passing relevant input data to the internal algorithm or its components. * @remark The default implementation passes _spInternalMoving and _spInternalTargetImage, sets the schedules, the fixed image region of the registration and the metric masks. @eguarantee strong */ virtual void prepSetInternalInputData(); /*! This method is a slot that is used for the initialization of the transformation model used * by the internal registration algorithm. * @remark By default it just sets the initial transformation parameter for the internal registration methods to the current values of the transform. @eguarantee strong */ virtual void prepInitializeTransformation(); /*! This method is the slot for final steps in the preparation process * @remark The default implementation calls the prepareAfterAssembly methods of the sub component policies. @eguarantee strong */ virtual void prepFinalizePreparation(); /*! return the current resolution level number. Will be called by getCurrentLevel() if hasLevelCount() returns true. @eguarantee strong @return level count */ virtual ResolutionLevelCountType doGetCurrentLevel() const; /*! This member is called by onLevelEvent() after the envent is invoked. The default implementation does nothing. It can be used in derivated classes to directly implement any initialization or setup strategies between level changes (e.g. adjusting the stepsize of the optimizer. */ virtual void doInterLevelSetup(); /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! @brief gets the maximum number of the algorithm's iterations @eguarantee strong @return returns the algorithm's maximum iterations count */ virtual IterationCountType doGetMaxIterations() const; virtual typename TDisplacementField::Pointer getFinalDisplacementField(); private: typedef ::itk::MultiResolutionPDEDeformableRegistration InternalMultiResRegFilterType; /*! Wrapping class that manage the multi resolution approach with PDEDeformable filter*/ typename InternalMultiResRegFilterType::Pointer _multiResFilter; /*! The count of the levels, since starting the registration algorithm the last time. * 0 indicates that no level has been processed yet.*/ ResolutionLevelCountType _currentLevelCount; /*! Cache for the number of iterations, defined by the user/developer.*/ unsigned long _numberOfIterations; /*! The lock is used to manage the access to the member variable _currentLevelCount.*/ - mutable ::itk::SimpleFastMutexLock _currentLevelLock; + mutable ::std::mutex _currentLevelLock; mutable core::ObserverSentinel::Pointer _onLevelObserver; mutable core::ObserverSentinel::Pointer _onGeneralTargePyramideObserver; mutable core::ObserverSentinel::Pointer _onGeneralMovingPyramideObserver; /*! This member function is called by the observer of the optimizer, when ever a LevelEvent is invoked.*/ void onLevelEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onTargetImagePyramideChange(const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onMovingImagePyramideChange(const ::itk::EventObject& eventObject); ITKMultiResPDEDeformableRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapITKMultiResPDEDeformableRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/include/mapITKPDEDeformableRegistrationAlgorithmBase.h b/Code/Algorithms/ITK/include/mapITKPDEDeformableRegistrationAlgorithmBase.h index 5ff2fa6..03f4a35 100644 --- a/Code/Algorithms/ITK/include/mapITKPDEDeformableRegistrationAlgorithmBase.h +++ b/Code/Algorithms/ITK/include/mapITKPDEDeformableRegistrationAlgorithmBase.h @@ -1,336 +1,336 @@ // ----------------------------------------------------------------------- // 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_PDE_DEFORMABLE_REGISTRATION_ALGORITHM_BASE_H #define __ITK_PDE_DEFORMABLE_REGISTRATION_ALGORITHM_BASE_H -#include "itkSimpleFastMutexLock.h" +#include #include "itkPDEDeformableRegistrationFilter.h" #include "mapGenericVectorFieldTransform.h" #include "mapContinuous.h" #include "mapDiscreteElements.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapObserverSentinel.h" #include "mapModificationTimeValidator.h" namespace map { namespace algorithm { namespace itk { /*! @class ITKPDEDeformableRegistrationAlgorithmBase @brief base class for algorithms based on the itk PDE deformable registration filters @ingroup Algorithms @ingroup ITK */ template < class TImageType, class TIdentificationPolicy, class TDisplacementField = typename core::discrete::Elements::VectorFieldType, class TInternalRegistrationFilter = typename ::itk::PDEDeformableRegistrationFilter< TImageType, TImageType, TDisplacementField> > class ITKPDEDeformableRegistrationAlgorithmBase : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public TIdentificationPolicy { public: typedef ITKPDEDeformableRegistrationAlgorithmBase < TImageType, TIdentificationPolicy, TDisplacementField, TInternalRegistrationFilter > Self; typedef IterativeRegistrationAlgorithm < TImageType::ImageDimension, TImageType::ImageDimension > Superclass; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(ITKPDEDeformableRegistrationAlgorithmBase, IterativeRegistrationAlgorithm); typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef TIdentificationPolicy IdentificationPolicyType; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageType TargetImageType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageType MovingImageType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer MovingImageConstPointer; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer TargetImageConstPointer; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename Superclass::IterationCountType IterationCountType; typedef typename MetaPropertyAlgorithmBase::MetaPropertyPointer MetaPropertyPointer; typedef typename MetaPropertyAlgorithmBase::MetaPropertyNameType MetaPropertyNameType; typedef typename MetaPropertyAlgorithmBase::MetaPropertyVectorType MetaPropertyVectorType; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates of the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its curent value. */ virtual bool hasCurrentOptimizerValue() const; mapDefineAlgorithmIdentificationByPolicyMacro; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; virtual bool isReusable() const; protected: ITKPDEDeformableRegistrationAlgorithmBase(); virtual ~ITKPDEDeformableRegistrationAlgorithmBase(); typedef TInternalRegistrationFilter InternalRegistrationMethodType; typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; typedef ::itk::GenericVectorFieldTransform< ::map::core::continuous::ScalarType, TImageType::ImageDimension, TImageType::ImageDimension> FieldTransformType; /*! @overwrite * This default implementation does nothing.*/ virtual void configureAlgorithm(); // MetaPropertyAlgorithmBase /*! @reimplemented*/ virtual void compileInfos(MetaPropertyVectorType& infos) const; /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by a region @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; /*! This method should do all preparation tasks right before the algorithms execution. At the and of this method * the algorithm should be set up and ready to use.\n * The method delegates the main work of initialization to several sub methods. This sub methods serves as slots * that can be rewritten by a algorithm developer to alter certain aspects and keep the rest untouched.\n * The sequence of slot calls is: \n * - prepCheckValidity * - prepPrepareSubComponents * - prepAssembleSubComponents * - prepPerpareInternalInputData * - prepSetInternalInputData * - prepInitializeTransformation * - prepFinalizePreparation * @remark If you want to change the execution style, then overwrite runAlgorithm(). @remark If you want to alter settings depending on the resolution level use the method doInterLevelSetup() @remark configureAlgorithmByMetaProperties is called after preCheckValidity and before prepPerpareSubComponent. @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. * @remark The default implementation checks transform, interpolator, optimizer, metric, pyramides, moving and target image. * overload this method to alter the validity check. * @remark It is assumed that the implementation of this method throws an exception if the algorithm is not be configured * correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot where sub components can be configured before(!) they are set to the * internal registration method. * @remark The default implementation does nothing.*/ virtual void prepPrepareSubComponents(); /*! This method is the slot where sub components are set to the internal registration method. * @remark The default implementation does nothing.*/ virtual void prepAssembleSubComponents(); /*! This method is the slot for internal preprocessing of input data. This method should * be reimplemented if you want to prepare the input data before they go into the internal * registration method. E.g. blurring or normalizing the moving and target image before registration. * @remark The default implementation uses an itk::HistogrammMatchingFilter to normalize the gray values of the input image. * @remark Implementations of this method should work on _spInternalMoving and _spInternalTargetImage. In the default * implementation of prepSetInternalInputData() these member will be passed to the internal algorithm. @eguarantee strong */ virtual void prepPerpareInternalInputData(); /*! This method is the slot for passing relevant input data to the internal algorithm or its components. * (e.g. passing _spInternalMoving and _spInternalTargetImage, setting the schedules and ,masks. @eguarantee strong */ virtual void prepSetInternalInputData() = 0; /*! This method is a slot that is used for the initialization of the transformation model used * by the internal registration algorithm. * @remark By default it just sets the initial transformation parameter for the internal registration methods to the current values of the transform. @eguarantee strong */ virtual void prepInitializeTransformation(); /*! This method is the slot for final steps in the preparation process * @remark The default implementation calls the prepareAfterAssembly methods of the sub component policies. @eguarantee strong */ virtual void prepFinalizePreparation(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareAlgorithm() or runAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! @brief gets the maximum number of the algorithm's iterations @eguarantee strong @return returns the algorithm's maximum iterations count */ virtual IterationCountType doGetMaxIterations() const; /*! Offers access to the internal registration method */ InternalRegistrationMethodType& getInternalRegistrationMethod(); /*! Helper function used by finalizeAlgorithm to access the final displacement field. * implemented by derived classes regarding there implementation.*/ virtual typename TDisplacementField::Pointer getFinalDisplacementField() = 0; /*!Pointer to the moving image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving image with out changing the public moving image pointer. * The variable is set by prepareAlgorithm() to _spMovingImage before calling prepPerpareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate _spInternalMovingImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ MovingImageConstPointer _spInternalMovingImage; /*!Pointer to the target image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target image with out changing the public target image pointer. * The variable is set by prepareAlgorithm() to _spTargetImage before calling prepPerpareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepPerpareInternalInputData() * function to manipulate _spInternalTargetImage before it is used by prepareAlgorithm() to set the internal algorithm)*/ TargetImageConstPointer _spInternalTargetImage; /*! The count if the iterations, since starting the registration algorithm the last time. * 0 indicates that no iteration has been processed yet.*/ IterationCountType _currentIterationCount; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; private: typename InternalRegistrationMethodType::Pointer _internalRegistrationMethod; bool _matchHistograms; bool _thresholdAtMeanIntensity; unsigned int _numberOfHistogramLevels; unsigned int _numberOfHistogramMatchPoints; mutable core::ObserverSentinel::Pointer _onIterationObserver; /*! This member function is called by the observer of the optimizer, when ever a IterationEvent is invoked.*/ void onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); ITKPDEDeformableRegistrationAlgorithmBase(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapITKPDEDeformableRegistrationAlgorithmBase.tpp" #endif #endif diff --git a/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.h b/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.h index 4bd85d7..1036064 100644 --- a/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.h +++ b/Code/Algorithms/ITK/include/mapITKPointSetRegistrationAlgorithm.h @@ -1,322 +1,322 @@ // ----------------------------------------------------------------------- // 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_H #define __ITK_POINT_SET_REGISTRATION_ALGORITHM_H #include "mapContinuous.h" #include "mapArbitraryTransformPolicy.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapPointSetRegistrationAlgorithmBase.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapITKPointSetRegistrationAlgorithmInterface.h" #include "mapArbitraryPointSetToPointSetMetricPolicy.h" #include "mapArbitraryMVNLOptimizerPolicy.h" #include "mapArbitraryTransformPolicy.h" #include "mapObserverSentinel.h" #include "itkPointSetToPointSetRegistrationMethod.h" -#include "itkSimpleFastMutexLock.h" +#include /*! @namespace map The namespace map is used throughout the MatchPoint project to mark code as components of this project */ namespace map { namespace algorithm { namespace itk { /*! @class ITKPointSetRegistrationAlgorithm @brief The class for a point set image registration algorithm based on ITK (PointSetToPointSetRegistrationMethod) It implements a MetaPropertyAlgorithmInterface, but has by default no properties defined. @ingroup Algorithms */ template < class TMovingPointSet, class TTargetPointSet, class TIdentificationPolicy, class TMetricPolicy = ArbitraryPointSetToPointSetMetricPolicy, class TOptimizerPolicy = ArbitraryMVNLOptimizerPolicy, class TTransformPolicy = ArbitraryTransformPolicy< ::map::core::continuous::ScalarType, TMovingPointSet::PointDimension, TTargetPointSet::PointDimension> > class ITKPointSetRegistrationAlgorithm : public IterativeRegistrationAlgorithm, public PointSetRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public ITKPointSetRegistrationAlgorithmInterface, public TIdentificationPolicy, public TMetricPolicy, public TOptimizerPolicy, public TTransformPolicy { public: typedef ITKPointSetRegistrationAlgorithm < TMovingPointSet, TTargetPointSet, TIdentificationPolicy, TMetricPolicy, TOptimizerPolicy, TTransformPolicy > Self; typedef IterativeRegistrationAlgorithm Superclass; typedef ITKPointSetRegistrationAlgorithmInterface ITKRegistrationType; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(ITKPointSetRegistrationAlgorithm, IterativeRegistrationAlgorithm); mapNewAlgorithmMacro(Self); typedef TMetricPolicy MetricPolicyType; typedef TOptimizerPolicy OptimizerPolicyType; typedef TTransformPolicy TransformPolicyType; typedef TIdentificationPolicy IdentificationPolicyType; typedef typename ITKRegistrationType::OptimizerBaseType OptimizerBaseType; typedef typename ITKRegistrationType::MetricBaseType MetricBaseType; typedef typename ITKRegistrationType::TransformBaseType TransformBaseType; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef PointSetRegistrationAlgorithmBase PointSetRegistrationAlgorithmBaseType; typedef typename PointSetRegistrationAlgorithmBaseType::TargetPointSetType TargetPointSetType; typedef typename PointSetRegistrationAlgorithmBaseType::MovingPointSetType MovingPointSetType; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::IterationCountType IterationCountType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef typename MetaPropertyAlgorithmBase::MetaPropertyPointer MetaPropertyPointer; typedef typename MetaPropertyAlgorithmBase::MetaPropertyNameType MetaPropertyNameType; mapDefineAlgorithmIdentificationByPolicyMacro; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates of the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its curent value. */ virtual bool hasCurrentOptimizerValue() const; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; virtual bool isReusable() const; protected: ITKPointSetRegistrationAlgorithm(); virtual ~ITKPointSetRegistrationAlgorithm(); typedef ::itk::PointSetToPointSetRegistrationMethod InternalRegistrationMethodType; typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; virtual void configureAlgorithm(); // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by a region @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification times of at least one policy is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preperation tasks right befor the algorithms execution. At the and of this method * the algorithm should be set up and ready to use. * @remark If you want to change the execution style, then overwrite runAlgorithm(). @eguarantee strong */ virtual void prepareAlgorithm(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareAlgorithm() or finalizeAlgorithm(). * @return Indicates of the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareAlgorithm() or runAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! This method should do all the special inizialization work of the internal registration method. * By default it just sets the initial transformation parameter for the methods to the values of the transform. @eguarantee strong */ virtual void prepInitializeTransformation(); typedef typename TransformPolicyType::TransformType::ParametersType TransformParametersType; /*! Gets the member variable _currentTransformParameters secured via _currentIterationLock. @return Copy of the current transform parameters. */ TransformParametersType getCurrentTransformParameters() const; /*! Sets the member variable _currentTransformParameters secured via _currentIterationLock. @param [in] Reference to the new current parameters. */ void setCurrentTransformParameters(const TransformParametersType& param); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! @brief gets the maximum number of the algorithm's iterations @eguarantee strong @return returns the algorithm's maximum iterations count */ virtual IterationCountType doGetMaxIterations() const; // MetaPropertyAlgorithmBase /*! @reimplemented*/ virtual void compileInfos(MetaPropertyVectorType& infos) const; /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); private: typename InternalRegistrationMethodType::Pointer _internalRegistrationMethod; /*! The current parameters of the registration transform. Will be set in every iteration step*/ TransformParametersType _currentTransformParameters; /*! The parameters of the registration transform of the last successfull registration determiniation. Will be set by finalizeAlgorithm()*/ TransformParametersType _finalizedTransformParameters; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! The count if the iterations, since starting the registration algorithm the last time. * 0 indicates that no iteration has been processed yet.*/ IterationCountType _currentIterationCount; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; mutable core::ObserverSentinel::Pointer _onIterationObserver; mutable core::ObserverSentinel::Pointer _onGeneralOptimizerObserver; mutable core::ObserverSentinel::Pointer _onGeneralMetricObserver; mutable core::ObserverSentinel::Pointer _onGeneralTransformObserver; /*! This member function is called by the observer of the optimizer, when ever a IterationEvent is invoked.*/ void onIterationEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the optimizer for all kind of events. It serves as a pass through.*/ void onGeneralOptimizerEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the metric for all kind of events. It serves as a pass through.*/ void onGeneralMetricEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralTransformEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the observer of the transform for all kind of events. It serves as a pass through.*/ void onGeneralRegistrationMethodEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! This member function is called by the optimizer policy if the optimizer instance changes.*/ void onOptimizerChange(const ::itk::EventObject& eventObject); /*! This member function is called by the metric policy if the metric instance changes.*/ void onMetricChange(const ::itk::EventObject& eventObject); /*! This member function is called by the transform policy if the transform model instance changes.*/ void onTransformChange(const ::itk::EventObject& eventObject); ITKPointSetRegistrationAlgorithm(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapITKPointSetRegistrationAlgorithm.tpp" #endif #endif diff --git a/Code/Algorithms/Plastimatch/include/mapPlmCLIRegistrationAlgorithmBase.h b/Code/Algorithms/Plastimatch/include/mapPlmCLIRegistrationAlgorithmBase.h index a048b43..a6e17b7 100644 --- a/Code/Algorithms/Plastimatch/include/mapPlmCLIRegistrationAlgorithmBase.h +++ b/Code/Algorithms/Plastimatch/include/mapPlmCLIRegistrationAlgorithmBase.h @@ -1,425 +1,425 @@ // ----------------------------------------------------------------------- // 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_PLM_CLI_REGISTRATION_ALGORITHM_BASE_H #define __MAP_PLM_CLI_REGISTRATION_ALGORITHM_BASE_H //MatchPoint #include "mapContinuous.h" #include "mapIterativeRegistrationAlgorithm.h" #include "mapImageRegistrationAlgorithmBase.h" #include "mapClassMacros.h" #include "mapPlmAlgorithmHelper.h" #include "mapMetaPropertyAlgorithmBase.h" #include "mapMaskedRegistrationAlgorithmBase.h" #include "mapPointSetRegistrationAlgorithmInterfaceV2.h" #include "mapGenericVectorFieldTransform.h" namespace map { namespace algorithm { namespace plastimatch { /*! @class CLIRegistrationAlgorithmBase @brief This is the base class for algorithms that serve as a wrapper for the registration tool "plastimatch". The algorithm is a very simple wrapper using a command line interface to facilitate plastimatch. For a registration task a temporary working directory is generated, where the algorithm stores the given moving and target image. Then the algorithms calls 'plastimatch' with appropriated command line arguments to trigger the registration as an external process and to produce a deformation field as output. This field will be loaded, converted into a MatchPoint registration object and returned. After the registration job is done, the temporary directory will be deleted by the algorithm. @remark @ingroup Algorithms @ingroup Plastimatch */ template class CLIRegistrationAlgorithmBase : public IterativeRegistrationAlgorithm, public ImageRegistrationAlgorithmBase, public MetaPropertyAlgorithmBase, public MaskedRegistrationAlgorithmBase, public facet::PointSetRegistrationAlgorithmInterfaceV2, public TIdentificationPolicy { public: typedef CLIRegistrationAlgorithmBase Self; typedef IterativeRegistrationAlgorithm Superclass; typedef ::itk::SmartPointer Pointer; typedef ::itk::SmartPointer ConstPointer; itkTypeMacro(CLIRegistrationAlgorithmBase, IterativeRegistrationAlgorithm); typedef typename Superclass::UIDType UIDType; typedef typename Superclass::UIDPointer UIDPointer; typedef typename IterativeRegistrationAlgorithm::OptimizerMeasureType OptimizerMeasureType; typedef ImageRegistrationAlgorithmBase ImageRegistrationAlgorithmBaseType; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageType TargetImageType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageType MovingImageType; typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; typedef typename Superclass::RegistrationPointer RegistrationPointer; typedef typename Superclass::RegistrationType RegistrationType; typedef typename Superclass::FieldRepRequirement FieldRepRequirement; typedef facet::PointSetRegistrationAlgorithmInterfaceV2 PointSetInterfaceType; typedef typename PointSetInterfaceType::MovingPointSetConstPointer MovingPointSetConstPointer; typedef typename PointSetInterfaceType::TargetPointSetConstPointer TargetPointSetConstPointer; typedef typename PointSetInterfaceType::SlotIndexType SlotIndexType; typedef typename PointSetInterfaceType::MovingPointSetType MovingPointSetType; typedef typename PointSetInterfaceType::TargetPointSetType TargetPointSetType; typedef typename MetaPropertyAlgorithmBase::MetaPropertyType MetaPropertyType; typedef typename MetaPropertyAlgorithmBase::MetaPropertyPointer MetaPropertyPointer; typedef typename MetaPropertyAlgorithmBase::MetaPropertyNameType MetaPropertyNameType; mapDefineAlgorithmIdentificationByPolicyMacro; // IterativeRegistrationAlgorithm /*! @eguarantee strong*/ virtual bool isStoppable() const; /*! has the algorithm an iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its current iteration count */ virtual bool hasIterationCount() const; /*! has the algorithm an maximum iteration count? @eguarantee no fail @return Indicates if the algorithm can determin its maximum iteration count */ virtual bool hasMaxIterationCount() const; /*! This function indicates if the optimizer of the iterative registration algorithm is * able to return its current metric/optimizer value(s)? @eguarantee no fail @return Indicates if the algorithm can determin its curent value. */ virtual bool hasCurrentOptimizerValue() const; virtual typename FieldRepRequirement::Type isMovingRepresentationRequired() const; virtual typename FieldRepRequirement::Type isTargetRepresentationRequired() const; /*! @reimplemented */ virtual bool isReusable() const; mapGetMetaMacro(WorkingDirectory, core::String); mapSetMetaMacro(WorkingDirectory, core::String); mapGetMetaMacro(PlastimatchDirectory, core::String); mapSetMetaMacro(PlastimatchDirectory, core::String); mapGetMetaMacro(DeleteTempDirectory, bool); mapSetMetaMacro(DeleteTempDirectory, bool); virtual bool hasCoupledPointSetInputs() const override { return true; }; virtual bool isOptionalTargetPointSet(SlotIndexType index) const override { return true; }; virtual bool isOptionalMovingPointSet(SlotIndexType index) const override { return true; }; virtual SlotIndexType getTargetPointSetCount(bool onlyMandatory = false) const override { if (onlyMandatory) return 0; return 1; }; virtual SlotIndexType getMovingPointSetCount(bool onlyMandatory = false) const override { if (onlyMandatory) return 0; return 1; }; virtual unsigned long getNthTargetPointSetMTime(SlotIndexType index) const override; virtual unsigned long getNthMovingPointSetMTime(SlotIndexType index) const override; protected: CLIRegistrationAlgorithmBase(); virtual ~CLIRegistrationAlgorithmBase(); typedef typename Superclass::InterimRegistrationType InterimRegistrationType; typedef typename Superclass::InterimRegistrationPointer InterimRegistrationPointer; typedef typename Superclass::IterationCountType IterationCountType; typedef typename ImageRegistrationAlgorithmBaseType::MovingImageConstPointer MovingImageConstPointer; typedef typename ImageRegistrationAlgorithmBaseType::TargetImageConstPointer TargetImageConstPointer; typedef ::itk::GenericVectorFieldTransform< ::map::core::continuous::ScalarType, TTargetImage::ImageDimension, TTargetImage::ImageDimension> FieldTransformType; typedef typename map::core::RegistrationTopology::InverseFieldType FinalFieldType; typedef typename FinalFieldType::Pointer FinalFieldPointer; /* @reimplemented*/ virtual void configureAlgorithm(); // MetaPropertyAlgorithmBase /*! @reimplemented*/ virtual void compileInfos(MetaPropertyVectorType& infos) const; /*! @reimplemented*/ virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; /*! @reimplemented*/ virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); // IterativeRegistrationAlgorithmInterface /*! @brief gets the registration result that has been computed in the last iteration. This result is limited by the passed region descriptors (pMovingRepresentation, pTargetRepresentation). @pre pMovingRepresentation and pTargetRepresentation must not be null. @param [in] pMovingRepresentation Pointer to @eguarantee strong @return the interim registration result as smart pointer @retval a Registration object @sa Registration */ virtual InterimRegistrationPointer determineInterimRegistration(const MovingRepresentationDescriptorType* pMovingRepresentation, const TargetRepresentationDescriptorType* pTargetRepresentation) const; /*! * Returns the final registration @eguarantee strong */ virtual RegistrationPointer doGetRegistration() const; /*! Returns if the registration should be computed. The registration is outdated if doGetRegistration returns null * or the modification time of at least one sub component is newer then the modification time of the registration. @eguarantee strong @return true if the registration should be (re)computed. False if the registration is uptodate. */ virtual bool registrationIsOutdated() const; virtual bool doStopAlgorithm(); /*! This method should do all preparation tasks right before the algorithm is executed. At the end of this method the algorithm should be set up and ready to use.\n The method delegates the main work of initialization to several sub methods. These sub methods serve as slots that can be rewritten by an algorithm developer to alter certain aspects and keep the rest untouched.\n The sequence of slot calls is: \n - prepCheckValidity - prepPerpareInternalInputData - prepSavePlastimatchInputData - prepParameterMaps - prepFinalizePreparation @remark If you want to change the execution style, then overwrite runAlgorithm(). @eguarantee strong*/ virtual void prepareAlgorithm(); /*! This method is the slot to check if all internal components and input data are properly set. @remark The default implementation checks the moving and target image. Overload this method to alter the validity check. @remark It is assumed that the implementation of this method throws an exception if the algorithm is not configured correctly.*/ virtual void prepCheckValidity(); /*! This method is the slot for internal preprocessing of input data. This method should be reimplemented if you want to prepare the input data before they go into the internal registration method. E.g. blurring or normalizing the moving and target image before registration. @remark The default implementation does nothing. Thus the public input data will be the data used by the internal algorithm. @remark Implementations of this method should work on _spInternalMoving and _spInternalTargetImage. In the default implementation of prepSetInternalInputData() these member will be passed to the internal algorithm. @eguarantee strong*/ virtual void prepPerpareInternalInputData(); /*! This method is the slot for storing the relevant input data to the working directory of plastimatch. * @remark The default implementation stores _spInternalMoving and _spInternalTargetImage and the masks if set. @eguarantee strong */ virtual void prepSavePlastimatchInputData(); /*! This method is the slot for the generation of the configuration that should be passed to plastimatch. The base class assumes that after calling this methods the member _configurationPLM contains all parameters for all stages. @eguarantee strong */ virtual void prepConfigurationPLM() = 0; /*! This method is used after preConfifurationPLM() to ensure that parameters for input images, masks and resulting vector field are correctly set. If the parameters are already set, they will be overwritten. In addition the function removes all settings for the output of result images or xform (they are deactivated). @eguarantee strong */ void ensureCorrectGlobalConfigSettings(); /*! This method should just execute the iteration loop. * @remark If you want to change the initialization or the finalization, then overwrite prepareIteration() or finalizeAlgorithm(). * @return Indicates if the registration was successfully determined (e.g. could be * false if an iterative algorithm was stopped prematurely by the user). * @eguarantee strong */ virtual bool runAlgorithm(); /*! This method should do all the finalization work (e.g. generating the registration based on the iteration results). * @remark If you want to change the initialization or the iteration, then overwrite prepareIteration() or iterateAlgorithm(). @eguarantee strong */ virtual void finalizeAlgorithm(); /*! return the optimizer value(s) of the current iteration step. Will be called by getCurrentOptimizerValue() if hasCurrentValue() returns true. @eguarantee strong @return current measure */ virtual OptimizerMeasureType doGetCurrentOptimizerValue() const; /*! Methods invoked by derivated classes. */ virtual void PrintSelf(std::ostream& os, ::itk::Indent indent) const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). * @eguarantee strong*/ virtual IterationCountType doGetCurrentIteration() const; /*! Feature is not supported by this wrapper. Therefore the methods returns only a dummy value (0). @eguarantee strong */ virtual IterationCountType doGetMaxIterations() const; /*! This method generates a unique and random subdirectory contained by _workingDir. * The path to this directory is stored in _currentTempDir. * @eguarantee strong */ void initializeCurrentTempDir(); /*! Helper function that loads the deformation file generated by plastimatch. The generated file is loaded and returned by the function.*/ FinalFieldPointer generateField() const; /*! Helper function that generates the file path to the parameter file.*/ ::map::core::String getParameterFilePath() const; /*! Helper function that generates the file path to the result parameters for the final(last stage) transform. @pre Algorithm must have at least one stage.*/ ::map::core::String getFinalTransformFilePath() const; /*!Pointer to the moving image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the moving image without changing the public moving image pointer. * The variable is set by prepareIteration() to _spMovingImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalMovingImage before it is used by prepareIteration() to set the internal algorithm)*/ MovingImageConstPointer _spInternalMovingImage; /*!Pointer to the target image used by the algorithm internally. This is used to allow the algorithm * or its derived classes to modify the target image with out changing the public target image pointer. * The variable is set by prepareIteration() to _spTargetImage before calling prepareInternalInputData(). * (e.g.: An algorithm always normalizes an image before registration. Then the algorithm can use the prepareInternalInputData() * function to manipulate _spInternalTargetImage before it is used by prepareIteration() to set the internal algorithm)*/ TargetImageConstPointer _spInternalTargetImage; /*!Directory that can be used to store temporary data. Process must have write access to this directory*/ ::map::core::String _workingDir; /*!Directory where the plastimatch tool 'plastimatch' is located.*/ ::map::core::String _plastimatchDir; /*!Directory that is used to store temporary data on the current run*/ ::map::core::String _currentTempDir; /*!Vector with plastimatch parameter maps, each element of the vector is the parameter map for one registration stage of plastimatch*/ ConfigurationType _configurationPLM; ::map::core::String _movingImageTempPath; ::map::core::String _targetImageTempPath; ::map::core::String _finalFieldTempPath; ::map::core::String _movingMaskTempPath; ::map::core::String _targetMaskTempPath; ::map::core::String _movingPointSetTempPath; ::map::core::String _targetPointSetTempPath; bool _deleteTempDirectory; /*! This member function is called by the process executer, whenever Plastimatch generates an output on stdout.*/ void onPlmOutputEvent(::itk::Object* caller, const ::itk::EventObject& eventObject); /*! Helper method that removes the current temp dir (if it exists and _deleteTempDirectory is true). * @eguarantee no throw*/ void cleanTempDir() const; ::map::core::String _parameterFilePath; virtual MovingPointSetConstPointer doGetNthMovingPointSet(SlotIndexType index) const override; virtual TargetPointSetConstPointer doGetNthTargetPointSet(SlotIndexType index) const override; virtual void doSetNthMovingPointSet(SlotIndexType index, const MovingPointSetType* pMovingPointSet) override; virtual void doSetNthTargetPointSet(SlotIndexType index, const TargetPointSetType* pTargetPointSet) override; ::map::core::ModificationTimeValidator _targetPSMTime; ::map::core::ModificationTimeValidator _movingPSMTime; MovingPointSetConstPointer _spMovingPointSet; TargetPointSetConstPointer _spTargetPointSet; private: /*! The parameters of the registration field generated by plastimatch.*/ FinalFieldPointer _spFinalizedField; /*! Smartpointer to the finalized registration. Will be set by finalizeAlgorithm()*/ typename RegistrationType::Pointer _spFinalizedRegistration; /*! The lock is used to manage the access to the member variable _currentIterationCount.*/ - mutable ::itk::SimpleFastMutexLock _currentIterationLock; + mutable ::std::mutex _currentIterationLock; CLIRegistrationAlgorithmBase(const Self& source); void operator=(const Self&); //purposely not implemented }; } } } #ifndef MatchPoint_MANUAL_TPP #include "mapPlmCLIRegistrationAlgorithmBase.tpp" #endif #endif diff --git a/Code/Core/include/mapFastLockedThreadingPolicy.h b/Code/Core/include/mapFastLockedThreadingPolicy.h index 2e581b0..5b4c1a6 100644 --- a/Code/Core/include/mapFastLockedThreadingPolicy.h +++ b/Code/Core/include/mapFastLockedThreadingPolicy.h @@ -1,78 +1,78 @@ // ----------------------------------------------------------------------- // 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_FAST_LOCKED_THREADING_POLICY_H #define __MAP_FAST_LOCKED_THREADING_POLICY_H -#include "itkSimpleFastMutexLock.h" +#include #include "mapFastMutexLockSentinel.h" #include "mapMAPCoreExports.h" namespace map { namespace core { namespace services { /*! @class FastLockedThreadingPolicy * @brief Policy is used to handle critical code via a mutex lock. * * @ingroup ThreadingPolicies */ class MAPCore_EXPORT FastLockedThreadingPolicy { protected: - using MutexType = itk::SimpleFastMutexLock; + using MutexType = std::mutex; using SentinelType = FastMutexLockSentinel; /*! Initialize a sentinel and implicitly lock the mutex. * @eguarantee strong */ void activateSentinel(SentinelType& sentinel) const; /*! Used by the policy owner to lock part of its code. * @eguarantee strong */ void lock() const; /*! Used by the policy owner to unlock critical code. * @eguarantee strong */ void unlock() const; FastLockedThreadingPolicy(); ~FastLockedThreadingPolicy(); private: /*! This policy uses this mutex to lock critical code by the policy user.*/ mutable MutexType _mutex; FastLockedThreadingPolicy(const FastLockedThreadingPolicy&) = delete; //purposely not implemented void operator=(const FastLockedThreadingPolicy&) = delete; //purposely not implemented }; } // end namespace services } // end namespace core } // end namespace map #endif diff --git a/Code/Core/include/mapFastLockedThreadingStaticPolicy.h b/Code/Core/include/mapFastLockedThreadingStaticPolicy.h index 07e870f..ccdd21b 100644 --- a/Code/Core/include/mapFastLockedThreadingStaticPolicy.h +++ b/Code/Core/include/mapFastLockedThreadingStaticPolicy.h @@ -1,81 +1,81 @@ // ----------------------------------------------------------------------- // 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_FAST_LOCKED_THREADING_STATIC_POLICY_H #define __MAP_FAST_LOCKED_THREADING_STATIC_POLICY_H -#include "itkSimpleFastMutexLock.h" +#include #include "mapFastMutexLockSentinel.h" #include "mapMAPCoreExports.h" namespace map { namespace core { namespace services { /*! @class FastLockedThreadingStaticPolicy * @brief Policy is used to handle critical code via a mutex lock. * * It is used as normally used by StaticServiceStack * @ingroup ThreadingPolicies */ class MAPCore_EXPORT FastLockedThreadingStaticPolicy { protected: - using MutexType = itk::SimpleFastMutexLock; + using MutexType = std::mutex; using SentinelType = FastMutexLockSentinel; /*! Initialize a sentinel and implicitly lock the mutex. * @eguarantee strong */ static void activateSentinel(SentinelType& sentinel); /*! Used by the policy owner to lock part of its code. * @eguarantee strong */ static void lock(); /*! Used by the policy owner to unlock critical code. * @eguarantee strong */ static void unlock(); FastLockedThreadingStaticPolicy(); ~FastLockedThreadingStaticPolicy(); private: /*! This policy uses this mutex to lock critical code by the policy user.*/ static MutexType _mutex; FastLockedThreadingStaticPolicy(const FastLockedThreadingStaticPolicy&) = delete; //purposely not implemented void operator=(const FastLockedThreadingStaticPolicy&) = delete; //purposely not implemented }; } // end namespace services } // end namespace core } // end namespace map #endif diff --git a/Code/Core/include/mapFastMutexLockSentinel.h b/Code/Core/include/mapFastMutexLockSentinel.h index ed27195..d9b7f9e 100644 --- a/Code/Core/include/mapFastMutexLockSentinel.h +++ b/Code/Core/include/mapFastMutexLockSentinel.h @@ -1,68 +1,68 @@ // ----------------------------------------------------------------------- // 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_FAST_MUTEX_LOCK_SENTINEL_H #define __MAP_FAST_MUTEX_LOCK_SENTINEL_H -#include "itkSimpleFastMutexLock.h" +#include #include "mapMacros.h" #include "mapMAPCoreExports.h" namespace map { namespace core { namespace services { /*! @class FastMutexLockSentinel * @brief Helper class for fast locked threadding policies. * Used as their sentinel class. Locks the mutex when calling InitializeSentinel() * unlocks the mutex when the destructor of the sentinel is called. * * @ingroup ThreadingPolicies */ class MAPCore_EXPORT FastMutexLockSentinel { public: - using MutexType = itk::SimpleFastMutexLock; + using MutexType = std::mutex; void initializeSentinel(MutexType* pMutex); FastMutexLockSentinel(); ~FastMutexLockSentinel(); private: /*! This policy uses this mutex to lock critical code by the policy user.*/ MutexType* _pMutex{nullptr}; FastMutexLockSentinel(const FastMutexLockSentinel&) = delete; //purposely not implemented void operator=(const FastMutexLockSentinel&) = delete; //purposely not implemented }; } // end namespace services } // end namespace core } // end namespace map #endif \ No newline at end of file diff --git a/Code/Core/include/mapLazyRegistrationKernel.h b/Code/Core/include/mapLazyRegistrationKernel.h index 0e80c76..acfcb5d 100644 --- a/Code/Core/include/mapLazyRegistrationKernel.h +++ b/Code/Core/include/mapLazyRegistrationKernel.h @@ -1,149 +1,149 @@ // ----------------------------------------------------------------------- // 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/mapRegistrationKernel.h $ */ #ifndef __LAZY_REGISTRATION_KERNEL_H #define __LAZY_REGISTRATION_KERNEL_H #include "mapRegistrationKernel.h" #include "mapLazyRegistrationKernelInterface.h" -#include "itkSimpleFastMutexLock.h" +#include /*! @namespace map The namespace map::core is for the library of MatchPoint */ namespace map { namespace core { /*! This class is the implementation of a lazy kernel. The lazy kernel * establishes its internal transformation when it is needed the first time * on the fly by using its generation functor. * @ingroup RegKernel */ template class LazyRegistrationKernel : public RegistrationKernel, public LazyRegistrationKernelInterface < VInputDimensions, VOutputDimensions > { public: typedef LazyRegistrationKernel Self; typedef RegistrationKernel Superclass; using Pointer = itk::SmartPointer; using ConstPointer = itk::SmartPointer; itkNewMacro(Self); itkTypeMacro(LazyRegistrationKernel, RegistrationKernel); using TransformType = typename Superclass::TransformType; using RepresentationDescriptorType = typename Superclass::RepresentationDescriptorType; using RepresentationDescriptorPointer = typename Superclass::RepresentationDescriptorPointer; using RepresentationDescriptorConstPointer = typename Superclass::RepresentationDescriptorConstPointer; using InputPointType = typename Superclass::InputPointType; using OutputPointType = typename Superclass::OutputPointType; using MappingVectorType = typename Superclass::MappingVectorType; typedef functors::TransformGenerationFunctor < VInputDimensions, VOutputDimensions > TransformGenerationFunctorType; using TransformGenerationFunctorConstPointer = typename TransformGenerationFunctorType::ConstPointer; /*! sets the field's functor @eguarantee no fail @param functor Pointer to the functor that is responsible for generating the field @pre functor must point to a valid instance. */ void setTransformFunctor(const TransformGenerationFunctorType* functor) override; /*! gets the field's functor @eguarantee no fail @return Pointer to the field functor that is used to generate the field on demand. */ const TransformGenerationFunctorType* getTransformFunctor() const override; /*! Returns if the transform was already created (true) or if the generation still is pending / wasn't necessary (false). @eguarantee strong */ bool transformExists() const override; /*! @brief gets the largest possible representation descriptor. The descriptor defines * the space the kernel guarantees to map. * @return Smart pointer to the descriptor (may be generated dynamicaly) * @retval NULL there is no descriptor. If hasLimitedRepresentation returns false, the kernel * has no mapping limitations and covers the total input space. * @eguarantee strong */ RepresentationDescriptorConstPointer getLargestPossibleRepresentation() const override; /*! Returns pointer to the transform model used by the kernel @eguarantee strong @return const pointer to the internal tranform model */ const TransformType* getTransformModel() const override; const OutputPointType getNullPoint() const override; bool usesNullPoint() const override; protected: LazyRegistrationKernel(); virtual ~LazyRegistrationKernel(); using TransformPointer = typename TransformType::Pointer; //is mutable because it is a cache for the functor result, thus it may be changed by checkAndPrepareTransform() mutable TransformPointer _spTransform; TransformGenerationFunctorConstPointer _spGenerationFunctor; /*! checks the transform that has been set for correctness and prepares it to be used @eguarantee strong @return the success of the operation */ bool checkAndPrepareTransform() const override; /*! Methods invoked by itk::LightObject::Print(). */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; /** @reimplementation Reimplementation of the itk::LightObject::InternalClone*/ virtual ::itk::LightObject::Pointer InternalClone() const; private: - using MutexType = ::itk::SimpleFastMutexLock; + using MutexType = ::std::mutex; /*!Mutex to make the checks of the policy thread safe*/ mutable MutexType _checkMutex; /*!Mutex to make the generation of the fields thread safe and to avoid paralel * generation of fields because of a racing condition of two checkAndPrepare calls*/ mutable MutexType _generateMutex; //No copy constructor allowed LazyRegistrationKernel(const Self& source); void operator=(const Self&); //purposely not implemented }; } // namespace core } // namespace map #ifndef MatchPoint_MANUAL_TPP #include "mapLazyRegistrationKernel.tpp" #endif #endif diff --git a/Code/Core/include/mapLogbook.h b/Code/Core/include/mapLogbook.h index 5c8e539..deb54b5 100644 --- a/Code/Core/include/mapLogbook.h +++ b/Code/Core/include/mapLogbook.h @@ -1,207 +1,207 @@ // ----------------------------------------------------------------------- // 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_LOGBOOK_H #define __MAP_LOGBOOK_H #include "itkLoggerBase.h" #include "itkLoggerOutput.h" -#include "itkSimpleFastMutexLock.h" +#include #include "mapXMLLogger.h" #include "mapString.h" #include "mapSyncObject.h" #include "mapMacros.h" #include "mapMAPCoreExports.h" namespace map { namespace core { //forward declarations class LogbookImplementation; /*! @class Logbook * @brief Helper class for centralized logging. * * This class offers a logger as singeltons and a centralized access to its * logging functionality. This class is used within MatchPoint for default logging purposes. By * default the logging will be saved in a xml file (matchpoint.log in the current working directory). * The file may be changed any time, also you may add additional outputs. You can also deactivate the * default file output by setting the default log output file to an empty string. * @ingroup Logging */ class MAPCore_EXPORT Logbook { public: using OutputType = itk::LoggerBase::OutputType; using PriorityLevelType = itk::LoggerBase::PriorityLevelType; /*! Passes the content to normal and error logger. * @eguarantee strong*/ static void write(PriorityLevelType level, const String& content); /*! Helper methods: Passes the content to normal and error logger with priority level "debug". */ static void debug(const String& message) { if (_currentPriorityLevel == itk::LoggerBase::DEBUG) { //only call the function and "risk" singelton checking and managing overhead //if the message will be logged anyway. write(itk::LoggerBase::DEBUG, message); } } /*! Helper methods: Passes the content to normal and error logger with priority level "info". */ static void info(const String& message) { if (_currentPriorityLevel != itk::LoggerBase::CRITICAL) { //only call the function and "risk" singelton checking and managing overhead //if the message will be logged anyway. write(itk::LoggerBase::INFO, message); } } /*! Helper methods: Passes the content to normal and error logger with priority level "warning". */ static void warning(const String& message) { if (_currentPriorityLevel != itk::LoggerBase::CRITICAL) { //only call the function and "risk" singelton checking and managing overhead //if the message will be logged anyway. write(itk::LoggerBase::WARNING, message); } } /*! Helper methods: Passes the content to normal and error logger with priority level "critical". */ static void critical(const String& message) { write(itk::LoggerBase::CRITICAL, message); } /*! Helper methods: Passes the content to normal and error logger with priority level "critical". */ static void error(const String& message) { write(itk::LoggerBase::CRITICAL, message); } /*! Helper methods: Passes the content to normal and error logger with priority level "fatal". */ static void fatal(const String& message) { write(itk::LoggerBase::FATAL, message); } /*! Flushes both loggers. */ static void flush(); /*! opens file stream to the new file. If it succeeds the the current default file stream will be closed and exchanged. * You can deactivate the default log out put by passing an empty string. * @eguarantee strong*/ static void setDefaultLogFileName(const String& fileName); /*! adds additional log outputs to the logbook. * @eguarantee strong * @pre pOuput must not be a NULL pointer.*/ static void addAdditionalLogOutput(OutputType* pOutput); /*! Attaches the central itk output window to the MatchPoint logging, by setting the OutputWindow to * a LoggerOutput using _spLogger.*/ static void attachITKOutputWindow(); /*!@eguarantee strong*/ static PriorityLevelType getLogbookMode(); /*! Calls sets _currentPriorityLevel and _spLogger PriorityLevel to itk::LoggerBase::DEBUG. Thus everything will be logged.*/ static void setLogbookToDebugMode(); /*! Calls sets _currentPriorityLevel and _spLogger PriorityLevel to itk::LoggerBase::INFO. Thus everything will be logged except of debug infos.*/ static void setLogbookToInfoMode(); /*! Calls sets _currentPriorityLevel and _spLogger PriorityLevel to itk::LoggerBase::CRITICAL. Thus only criticals, errors and fatals will be logged.*/ static void setLogbookToCriticalMode(); /*! Calls sets _currentPriorityLevel and _spLogger PriorityLevel to the passed level. * @remark The logbook must not be in deprecated sync mode. The mode can only be changed * by the host or in standalone logbooks. * @pre The logbook must not be in deprecated sync mode.*/ static void setLogbookMode(PriorityLevelType level); /*! Returns true if there is an valid pointer to a logbook implementation. Returns false if the * logbook wasn't used yet and isn't initialized. * @eguarantee no fail*/ static bool isInitialized(); /** This function is called to add all information to pSyncObject * that are needed to performe a synchronisation of an other instance*/ static void getSynchronization(deployment::SyncObject& pSyncObject); /** This function is called to synchronize the instance with * the information of pSyncObject.*/ static void setSynchronization(const deployment::SyncObject& pSyncObject); /** This function is called to desynchronize the instance.*/ static void deSynchronize(); protected: /*! Creates the implementation singelton if it doesn't exist.*/ static void initializeLogger(); /*!changes the own logbook implmentation with the passed one. * The exchange is secured by the mutex. * @eguarantee strong * @pre pImpl must be a valid pointer to an implmentation. * @param [in,out] pImpl Pointer to the new implementation.*/ static void swapImplementations(LogbookImplementation* pImpl); using LogImplPointer = itk::SmartPointer; static LogImplPointer _spLoggerImpl; - static itk::SimpleFastMutexLock _testMutex; - static itk::SimpleFastMutexLock _initMutex; + static std::mutex _testMutex; + static std::mutex _initMutex; /*! Indicates of the logbook is on its "own" or synced with an other host * logbook */ static bool _syncedAsDedicated; static PriorityLevelType _currentPriorityLevel; static String _defaultFilename; private: Logbook() = delete; //purposely not implemented virtual ~Logbook() = delete; //purposely not implemented Logbook(const Logbook&) = delete; //purposely not implemented void operator=(const Logbook&) = delete; //purposely not implemented }; } // end namespace core } // end namespace map #include "mapLogbookMacros.h" #endif diff --git a/Code/Core/include/mapMappingTaskBatch.h b/Code/Core/include/mapMappingTaskBatch.h index 424aa77..bfe6955 100644 --- a/Code/Core/include/mapMappingTaskBatch.h +++ b/Code/Core/include/mapMappingTaskBatch.h @@ -1,182 +1,182 @@ // ----------------------------------------------------------------------- // 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_MAPPING_TASK_BATCH_H #define __MAP_MAPPING_TASK_BATCH_H #include "mapMappingTaskBase.h" #include "mapMappingTaskBatchThread.h" #include "itkObject.h" #include "itkMultiThreader.h" #include #include namespace map { namespace core { /*! @class MappingTaskBatch * @brief Class realizes a task batch, that performs mapping on different data in on run. * * You can add an arbitrarily number of tasks to the batch. by calling process(const RegistrationType*) all * tasks will be performed with the passed registration. * @ingroup MappingTask * @ingroup Registration * @tparam TRegistration the registration class, that should be used to perform the task. */ template class MappingTaskBatch: public itk::Object { public: /*! Standard class typedefs. */ typedef TRegistration RegistrationType; typedef MappingTaskBase MappingTaskBaseType; typedef typename MappingTaskBaseType::Pointer MappingTaskBasePointer; typedef std::deque TaskSelectionType; typedef std::vector TaskVectorType; typedef MappingTaskBatch Self; typedef itk::Object Superclass; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; typedef typename TaskVectorType::size_type ThreadCountType; itkTypeMacro(MappingTaskBatch, itk::Object); itkNewMacro(Self); /*! Removes all tasks from the batch. * @eguarantee: strong */ void clear(void); /*! Adds a task to the batch. * @param [in] Pointer to the task that should be added. * @eguarantee: strong * @pre pTask must not be NULL. */ void addTask(MappingTaskBaseType* pTask); /*! Adds the registration to every task in the batch and calls execute(). * @param [in] Pointer to the registration that should be used. * @eguarantee: basic * @pre pRegistration must not be NULL. */ bool process(const RegistrationType* pRegistration); /*! Calls execute() of every task. * @eguarantee: basic */ bool process(); const TaskSelectionType& getFailedTasks(void) const; const TaskVectorType& getTasks(void) const; /*! Sets the value of _maxThreadCount. * @eguarantee: strong */ void setMaxThreadCount(ThreadCountType count); /*! Returns the value of _maxThreadCount. * @eguarantee: strong * @return The number of thread that will be used. * @retval 0 Indicates that the thread count will equal the number of tasks. */ ThreadCountType getMaxThreadCount() const; /*! Checks if _maxThreadCount is 0. * @eguarantee: strong */ bool getOneThreadPerTask() const; /*! Sets the value of _maxThreadCount to 0. * @eguarantee: strong */ void activateOneThreadPerTask(); protected: MappingTaskBatch(); virtual ~MappingTaskBatch(); /*! Methods invoked by itk::LightObject::Print(). */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; private: TaskVectorType _tasks; /*! all tasks that are waiting to be processed*/ TaskSelectionType _pendingTasks; /*! all tasks that are assigned to threads*/ TaskSelectionType _assignedTasks; /*! all tasks that were successfully processed*/ TaskSelectionType _processedTasks; /*! all tasks that have failed*/ TaskSelectionType _failedTasks; /*! copys all tasks from _tasks to _pendingTasks * @eguarantee: strong */ void populatePendingTasks(); /*! Adds the registration to every task in the batch. * @param [in] Pointer to the registration that should be used. * @eguarantee: strong * @pre pRegistration must not be NULL. */ void setRegistration(const RegistrationType* pRegistration); typedef MappingTaskBatchThread ThreadType; typedef std::vector ThreadVectorType; /*! Indicate how many thread should be used to process the task. * A value of 0 indicates that the thread number should equal the task number (one task per thread).*/ ThreadCountType _maxThreadCount; ThreadVectorType _threads; /*! Indicates if a task has failed with an exception and was set exception neutral. Thus the batch won't processe * any further tasks and will wait for the threads to return and throw the exception afterwards.*/ const ExceptionObject* _pTerminatingException; static ITK_THREAD_RETURN_TYPE threadExecution(void* arg); void onNextTaskThreadEvent(::itk::Object* pCaller, const ::itk::EventObject& eventObject); void onProcessedTaskThreadEvent(::itk::Object* pCaller, const ::itk::EventObject& eventObject); void onFailedTaskThreadEvent(::itk::Object* pCaller, const ::itk::EventObject& eventObject); /** Responsible for locking the processing of thread callbacks.*/ - ::itk::SimpleFastMutexLock _threadMutex; - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock > MutexHolderType; + ::std::mutex _threadMutex; + typedef ::std::lock_guard< ::std::mutex > MutexHolderType; MappingTaskBatch(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace core } // end namespace map #ifndef MatchPoint_MANUAL_TPP # include "mapMappingTaskBatch.tpp" #endif #endif diff --git a/Code/Core/include/mapMappingTaskBatchThread.h b/Code/Core/include/mapMappingTaskBatchThread.h index cfabb0c..6abb6c5 100644 --- a/Code/Core/include/mapMappingTaskBatchThread.h +++ b/Code/Core/include/mapMappingTaskBatchThread.h @@ -1,111 +1,111 @@ // ----------------------------------------------------------------------- // 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_MAPPING_TASK_BATCH_THREAD_H #define __MAP_MAPPING_TASK_BATCH_THREAD_H #include "mapMappingTaskBase.h" #include "itkObject.h" -#include "itkMutexLockHolder.h" +#include namespace map { namespace core { /*! @class MappingTaskBatchThread * @brief Class realizes a thread of a task batch, that process mapping tasks give by the batch. * * To request a new task this class will invoke an NextTaskThreadEvent.\n * To signal a sucessfully processed task it will invoke a ProcessedTaskThreadEvent.\n * To signal a failed task it will invoke a FailedTaskThreadEvent. * @ingroup MappingTask * @ingroup Registration * @tparam TMappingTaskBase the registration task base class, that should be processed. */ template class MappingTaskBatchThread: public itk::Object { public: /*! Standard class typedefs. */ typedef MappingTaskBatchThread Self; typedef itk::Object Superclass; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; typedef TMappingTaskBase MappingTaskBaseType; typedef typename MappingTaskBaseType::Pointer MappingTaskBasePointer; itkNewMacro(Self); itkTypeMacro(MappingTaskBatchThread, itk::Object); typedef unsigned long ThreadIDType; ThreadIDType getThreadID() const; void setThreadID(const ThreadIDType& id); /** Executes the thread. The default handling requests a task via * invoking an NextTaskThreadEvent. The thread assumes that the next task is set * if the event returns. If the _pNewTask is NULL the thread asumes, * that all work is done and execute returns. If there is a new task, it will be processed. * After the processing the next task will be requested (and so on). */ void execute(); void setNewTask(MappingTaskBaseType* pTask); MappingTaskBaseType* getCurrentTask(); bool hasUnhandledExceptionOccured() const; protected: MappingTaskBatchThread(); virtual ~MappingTaskBatchThread(); private: ThreadIDType _threadID; bool _unhandledExceptionOccured; MappingTaskBaseType* _pNewTask; MappingTaskBaseType* _pCurrentProcessedTask; /** Responsible for locking the processing, to ensure no change of values * while thread is in Execution.*/ - ::itk::SimpleFastMutexLock _executionMutex; - typedef ::itk::MutexLockHolder< ::itk::SimpleFastMutexLock > MutexHolderType; + ::std::mutex _executionMutex; + typedef ::std::lock_guard< ::std::mutex > MutexHolderType; MappingTaskBatchThread(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace core } // end namespace map #ifndef MatchPoint_MANUAL_TPP # include "mapMappingTaskBatchThread.tpp" #endif #endif diff --git a/Code/Core/source/mapFastLockedThreadingPolicy.cpp b/Code/Core/source/mapFastLockedThreadingPolicy.cpp index 20154fa..fc39a81 100644 --- a/Code/Core/source/mapFastLockedThreadingPolicy.cpp +++ b/Code/Core/source/mapFastLockedThreadingPolicy.cpp @@ -1,63 +1,63 @@ // ----------------------------------------------------------------------- // 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$ */ #include "mapFastLockedThreadingPolicy.h" namespace map { namespace core { namespace services { void FastLockedThreadingPolicy:: lock() const { - _mutex.Lock(); + _mutex.lock(); } void FastLockedThreadingPolicy:: unlock() const { - _mutex.Unlock(); + _mutex.unlock(); }; void FastLockedThreadingPolicy:: activateSentinel(SentinelType& sentinel) const { sentinel.initializeSentinel(&_mutex); //lock will be done by initializeSentinel() }; FastLockedThreadingPolicy:: FastLockedThreadingPolicy() = default; FastLockedThreadingPolicy:: ~FastLockedThreadingPolicy() = default; } // end namespace services } // end namespace core } // end namespace map diff --git a/Code/Core/source/mapFastLockedThreadingStaticPolicy.cpp b/Code/Core/source/mapFastLockedThreadingStaticPolicy.cpp index a653b8a..8246cc5 100644 --- a/Code/Core/source/mapFastLockedThreadingStaticPolicy.cpp +++ b/Code/Core/source/mapFastLockedThreadingStaticPolicy.cpp @@ -1,67 +1,67 @@ // ----------------------------------------------------------------------- // 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$ */ #include "mapFastLockedThreadingStaticPolicy.h" namespace map { namespace core { namespace services { void FastLockedThreadingStaticPolicy:: activateSentinel(SentinelType& sentinel) { sentinel.initializeSentinel(&FastLockedThreadingStaticPolicy::_mutex); //lock will be done by initializeSentinel() }; void FastLockedThreadingStaticPolicy:: lock() { - FastLockedThreadingStaticPolicy::_mutex.Lock(); + FastLockedThreadingStaticPolicy::_mutex.lock(); }; void FastLockedThreadingStaticPolicy:: unlock() { - FastLockedThreadingStaticPolicy::_mutex.Unlock(); + FastLockedThreadingStaticPolicy::_mutex.unlock(); }; FastLockedThreadingStaticPolicy:: FastLockedThreadingStaticPolicy() = default; FastLockedThreadingStaticPolicy:: ~FastLockedThreadingStaticPolicy() = default; FastLockedThreadingStaticPolicy::MutexType FastLockedThreadingStaticPolicy::_mutex; } // end namespace services } // end namespace core } // end namespace map diff --git a/Code/Core/source/mapFastMutexLockSentinel.cpp b/Code/Core/source/mapFastMutexLockSentinel.cpp index 2d09a1c..4ed2248 100644 --- a/Code/Core/source/mapFastMutexLockSentinel.cpp +++ b/Code/Core/source/mapFastMutexLockSentinel.cpp @@ -1,57 +1,57 @@ // ----------------------------------------------------------------------- // 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$ */ #include "mapFastMutexLockSentinel.h" #include namespace map { namespace core { namespace services { void FastMutexLockSentinel:: initializeSentinel(MutexType* pMutex) { assert(_pMutex == nullptr); //must not be used before! _pMutex = pMutex; - _pMutex->Lock(); + _pMutex->lock(); } FastMutexLockSentinel:: FastMutexLockSentinel() {}; FastMutexLockSentinel:: ~FastMutexLockSentinel() { if (_pMutex != nullptr) { - _pMutex->Unlock(); + _pMutex->unlock(); } }; } // end namespace services } // end namespace core } // end namespace map diff --git a/Code/Core/source/mapLogbook.cpp b/Code/Core/source/mapLogbook.cpp index 8974cc0..1670500 100644 --- a/Code/Core/source/mapLogbook.cpp +++ b/Code/Core/source/mapLogbook.cpp @@ -1,264 +1,264 @@ // ----------------------------------------------------------------------- // 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$ */ #include "mapLogbook.h" #include "mapLogbookImplementation.h" #include "mapSmartMetaProperty.h" #include "mapMetaProperty.h" -#include "itkMutexLockHolder.h" +#include #include namespace map { namespace core { Logbook::LogImplPointer Logbook::_spLoggerImpl = nullptr; - itk::SimpleFastMutexLock Logbook::_testMutex; - itk::SimpleFastMutexLock Logbook::_initMutex; + std::mutex Logbook::_testMutex; + std::mutex Logbook::_initMutex; Logbook::PriorityLevelType Logbook::_currentPriorityLevel = itk::LoggerBase::INFO; bool Logbook::_syncedAsDedicated = false; String Logbook::_defaultFilename = "MatchPoint.log"; void Logbook:: write(PriorityLevelType level, const String& content) { if (_spLoggerImpl.IsNull()) { initializeLogger(); } _spLoggerImpl->getLogger().Write(level, content); }; void Logbook:: flush() { if (_spLoggerImpl.IsNotNull()) { _spLoggerImpl->getLogger().Flush(); } }; void Logbook:: setDefaultLogFileName(const String& fileName) { if (_spLoggerImpl.IsNotNull() && _defaultFilename != fileName) { //we need to exchange the implementation mapLogDebugStaticMacro( << "Attempt to change logbook default file. New file name: " << fileName); LogImplPointer spNewImpl = _spLoggerImpl->clone(fileName); //if we reached this point without exception the implementation //with the new file is open and established, thus swap the implmentations, //store the new default file and print the header. swapImplementations(spNewImpl); _defaultFilename = fileName; } else { _defaultFilename = fileName; } }; void Logbook:: addAdditionalLogOutput(OutputType* pOutput) { assert(pOutput); //must not be null if (_spLoggerImpl.IsNull()) { initializeLogger(); } mapLogDebugStaticMacro( << "Add output to logbook. Output: " << pOutput->GetNameOfClass()); LogImplPointer spNewImpl = _spLoggerImpl->clone(); spNewImpl->addAdditionalLogOutput(pOutput); swapImplementations(spNewImpl); }; void Logbook:: attachITKOutputWindow() { if (_spLoggerImpl.IsNull()) { initializeLogger(); } mapLogDebugStaticMacro( << "Attached itk ouput window to MatchPoint logbook"); - itk::MutexLockHolder testHolder(_testMutex); - itk::MutexLockHolder initHolder(_initMutex); + std::lock_guard testHolder(_testMutex); + std::lock_guard initHolder(_initMutex); if (_spLoggerImpl->_spItkOutputWindow.IsNull()) { itk::LoggerOutput::Pointer spNewLogger = itk::LoggerOutput::New(); itk::OutputWindow::SetInstance(spNewLogger); _spLoggerImpl->_spItkOutputWindow = spNewLogger; } _spLoggerImpl->_spItkOutputWindow->SetLogger(&(_spLoggerImpl->getLogger())); }; Logbook::PriorityLevelType Logbook:: getLogbookMode() { return _currentPriorityLevel; }; void Logbook:: setLogbookToDebugMode() { setLogbookMode(itk::LoggerBase::DEBUG); }; void Logbook:: setLogbookToInfoMode() { setLogbookMode(itk::LoggerBase::INFO); }; void Logbook:: setLogbookToCriticalMode() { setLogbookMode(itk::LoggerBase::CRITICAL); }; void Logbook:: setLogbookMode(PriorityLevelType level) { if (_spLoggerImpl.IsNotNull()) { _spLoggerImpl->getLogger().SetPriorityLevel(level); } _currentPriorityLevel = level; }; bool Logbook:: isInitialized() { return _spLoggerImpl.IsNotNull(); }; void Logbook:: initializeLogger() { - itk::MutexLockHolder testHolder(_testMutex); + std::lock_guard testHolder(_testMutex); if (_spLoggerImpl.IsNull()) { { //mutex lock holder scope - itk::MutexLockHolder initHolder(_initMutex); + std::lock_guard initHolder(_initMutex); LogImplPointer spNewImpl = LogbookImplementation::New(); spNewImpl->initializeOutputs(_defaultFilename); _spLoggerImpl = spNewImpl; } // end of mutex lock holder scope } }; void Logbook:: swapImplementations(LogbookImplementation* pImpl) { assert(pImpl); //must not be null; - _testMutex.Lock(); - _initMutex.Lock(); + _testMutex.lock(); + _initMutex.lock(); _spLoggerImpl = pImpl; - _initMutex.Unlock(); - _testMutex.Unlock(); + _initMutex.unlock(); + _testMutex.unlock(); }; void Logbook:: getSynchronization(deployment::SyncObject& syncObject) { core::MetaPropertyBase::Pointer prop = core::SmartMetaProperty::New(_spLoggerImpl).GetPointer(); deployment::SyncObject::SyncPropertyMapType::value_type valuePair("Logbook_Impl", prop); syncObject._map.insert(valuePair); prop = core::MetaProperty::New(_currentPriorityLevel).GetPointer(); deployment::SyncObject::SyncPropertyMapType::value_type valuePair2("Logbook_Priority", prop); syncObject._map.insert(valuePair2); }; void Logbook:: setSynchronization(const deployment::SyncObject& syncObject) { LogImplPointer spNewLogger; if (syncObject.getProperty("Logbook_Impl", spNewLogger)) { //there is something to sync for the logbook... if (spNewLogger.GetPointer() != _spLoggerImpl) { _syncedAsDedicated = true; swapImplementations(spNewLogger); } syncObject.getProperty("Logbook_Priority", _currentPriorityLevel); } }; void Logbook:: deSynchronize() { mapLogInfoStaticMacro( << "Attempt to desync logbook."); LogImplPointer spNewImpl = _spLoggerImpl->clone(Logbook::_defaultFilename); //if we reached this point without exception the implementation //with the new file is open and established, thus swap the implmentations, //store the new default file and print the header. swapImplementations(spNewImpl); _syncedAsDedicated = false; }; } // end namespace core } // end namespace map diff --git a/Code/Core/source/mapLogbookImplementation.cpp b/Code/Core/source/mapLogbookImplementation.cpp index 482e081..3794fa5 100644 --- a/Code/Core/source/mapLogbookImplementation.cpp +++ b/Code/Core/source/mapLogbookImplementation.cpp @@ -1,308 +1,307 @@ // ----------------------------------------------------------------------- // 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$ */ #include "mapLogbookImplementation.h" #include "mapExceptionObject.h" -#include "itkFastMutexLock.h" - +#include #include namespace map { namespace core { /*! @class SharedFileStreamBase * @brief Helper class realizing an std stream handled as a object with smart pointer * * Reason: Need for a shared_ptr to handle the same stream across different logbook * implementations. VS2005 has no std::tr1::shared_ptr. Thus uses the itk::SmartPointer * functionality. * @ingroup Logging */ class SharedFileStreamBase : public itk::LightObject { public: using Self = SharedFileStreamBase; using Superclass = itk::LightObject; using Pointer = itk::SmartPointer; using ConstPointer = itk::SmartPointer; itkTypeMacro(SharedFileStreamBase, itk::LightObject); virtual std::ostream& getStream() = 0; virtual const std::ostream& getStream() const = 0; protected: SharedFileStreamBase() = default; ~SharedFileStreamBase() override = default; private: SharedFileStreamBase(const SharedFileStreamBase&) = delete; //purposely not implemented void operator=(const SharedFileStreamBase&) = delete; //purposely not implemented }; /*! @class SharedDefaultLogFileStream * @brief Helper class realizing an dummy stream handled as a object with smart pointer * * Reason: Need for a shared_ptr to handle the same stream across different logbook * implementations. VS2005 has no std::tr1::shared_ptr. Thus uses the itk::SmartPointer * functionality. * @ingroup Logging */ class SharedNULLStream : public SharedFileStreamBase { public: using Self = SharedNULLStream; using Superclass = itk::LightObject; using Pointer = itk::SmartPointer; using ConstPointer = itk::SmartPointer; itkTypeMacro(SharedNULLStream, itk::LightObject); itkNewMacro(Self); std::ostream& getStream() override { return _stream; }; const std::ostream& getStream() const override { return _stream; }; protected: /*! Helper class that allows to generate a dummy os*/ class NullBuffer : public std::streambuf { public: int overflow(int c) override { return c; } }; NullBuffer _buffer; std::ostream _stream; SharedNULLStream() : _stream(&_buffer) { }; ~SharedNULLStream() override = default; private: SharedNULLStream(const SharedNULLStream&) = delete; //purposely not implemented void operator=(const SharedNULLStream&) = delete; //purposely not implemented }; /*! @class SharedDefaultLogFileStream * @brief Helper class realizing an std stream handled as a object with smart pointer * * Reason: Need for a shared_ptr to handle the same stream across different logbook * implementations. VS2005 has no std::tr1::shared_ptr. Thus uses the itk::SmartPointer * functionality. * @ingroup Logging */ class SharedDefaultLogFileStream : public SharedFileStreamBase { public: using Self = SharedDefaultLogFileStream; using Superclass = SharedFileStreamBase; using Pointer = itk::SmartPointer; using ConstPointer = itk::SmartPointer; itkTypeMacro(SharedDefaultLogFileStream, SharedFileStreamBase); itkNewMacro(Self); std::ostream& getStream() override { return _stream; }; const std::ostream& getStream() const override { return _stream; }; std::ofstream& getOFStream() { return _stream; }; const std::ofstream& getOFStream() const { return _stream; }; protected: std::ofstream _stream; SharedDefaultLogFileStream() = default; ~SharedDefaultLogFileStream() override = default; private: SharedDefaultLogFileStream(const SharedDefaultLogFileStream&) = delete; //purposely not implemented void operator=(const SharedDefaultLogFileStream&) = delete; //purposely not implemented }; //************************************************************************************************* //******************** class LogbookImplementation ********************************************** //************************************************************************************************* LogbookImplementation::LoggerType& LogbookImplementation:: getLogger() { return *(_spLogger.GetPointer()); }; void LogbookImplementation:: initializeOutputs(const String& defaultOutputFileName) { if (!defaultOutputFileName.empty()) { SharedDefaultLogFileStream::Pointer spNewStream = SharedDefaultLogFileStream::New(); spNewStream->getOFStream().open(defaultOutputFileName.c_str(), std::ios::out | std::ios::app); if (!(spNewStream->getOFStream().is_open())) { mapLogbookCheckDefaultExceptionMacro(<< "Error: cannot open specified file as default logbook output file. Filename: " << defaultOutputFileName); } _spDefaultStream = spNewStream; _spDefaultOutput->SetStream(_spDefaultStream->getStream()); } else { _spDefaultStream = SharedNULLStream::New(); _spDefaultOutput->SetStream(_spDefaultStream->getStream()); } initializeAdditionalOutputs(); if (_spItkOutputWindow.IsNotNull()) { _spItkOutputWindow->SetLogger(_spLogger); } }; void LogbookImplementation:: addAdditionalLogOutput(OutputType* pOutput) { assert(pOutput); //output may not be null. std::pair result; result = _additionalOutputs.insert(pOutput); if (result.second) { //this output isn't already in the set, //so it was added and shall also be added to the logger. _spLogger->AddLogOutput(pOutput); } }; LogbookImplementation::Pointer LogbookImplementation:: clone() const { Pointer spNewImpl = LogbookImplementation::New(); spNewImpl->_additionalOutputs = this->_additionalOutputs; spNewImpl->_spDefaultStream = this->_spDefaultStream; spNewImpl->_spDefaultOutput->SetStream(spNewImpl->_spDefaultStream->getStream()); spNewImpl->_spItkOutputWindow = this->_spItkOutputWindow; spNewImpl->_currentPriorityLevel = this->_currentPriorityLevel; spNewImpl->initializeAdditionalOutputs(); if (spNewImpl->_spItkOutputWindow.IsNotNull()) { spNewImpl->_spItkOutputWindow->SetLogger(spNewImpl->_spLogger); } return spNewImpl; }; LogbookImplementation::Pointer LogbookImplementation:: clone(const String& newDefaultOutputFileName) const { Pointer spNewImpl = LogbookImplementation::New(); spNewImpl->_additionalOutputs = this->_additionalOutputs; spNewImpl->_spItkOutputWindow = this->_spItkOutputWindow; spNewImpl->_currentPriorityLevel = this->_currentPriorityLevel; spNewImpl->initializeOutputs(newDefaultOutputFileName); return spNewImpl; }; void LogbookImplementation:: initializeAdditionalOutputs() { for (const auto & _additionalOutput : _additionalOutputs) { _spLogger->AddLogOutput(_additionalOutput); } }; LogbookImplementation:: LogbookImplementation() { _spItkOutputWindow = nullptr; _currentPriorityLevel = itk::LoggerBase::INFO; _spLogger = LoggerType::New(); _spDefaultOutput = DefaultOutputType::New(); _spLogger->AddLogOutput(_spDefaultOutput); }; LogbookImplementation:: ~LogbookImplementation() { //ensure that the logger is deleted before the default output (because logger flushes on destruction) //if the logger isn't used by other parts of the program. _spLogger = nullptr; _spDefaultOutput = nullptr; }; } // end namespace core } // end namespace map \ No newline at end of file