1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkImageToImageMetricv4GetValueAndDerivativeThreaderBase_h 19 #define itkImageToImageMetricv4GetValueAndDerivativeThreaderBase_h 20 21 #include "itkDomainThreader.h" 22 #include "itkCompensatedSummation.h" 23 24 namespace itk 25 { 26 27 /** \class ImageToImageMetricv4GetValueAndDerivativeThreaderBase 28 * \brief Provides threading for ImageToImageMetricv4::GetValueAndDerivative. 29 * 30 * \tparam TDomainPartitioner type of the Domain, 31 * ThreadedImageRegionPartitioner or ThreadedIndexedContainerPartitioner 32 * \tparam TImageToImageMetricv4 type of the ImageToImageMetricv4 33 * 34 * This class provides a \c BeforeThreadedExecution, and \c 35 * AfterThreadedExecution. 36 * 37 * The \c ThreadedExecution in 38 * ImageToImageMetricv4GetValueAndDerivativeThreader calls \c 39 * ProcessVirtualPoint on every point in the virtual image domain. \c 40 * ProcessVirtualPoint calls \c ProcessPoint on each point. 41 * 42 * \ingroup ITKMetricsv4 */ 43 template < typename TDomainPartitioner, typename TImageToImageMetricv4 > 44 class ITK_TEMPLATE_EXPORT ImageToImageMetricv4GetValueAndDerivativeThreaderBase 45 : public DomainThreader< TDomainPartitioner, TImageToImageMetricv4 > 46 { 47 public: 48 ITK_DISALLOW_COPY_AND_ASSIGN(ImageToImageMetricv4GetValueAndDerivativeThreaderBase); 49 50 /** Standard class type aliases. */ 51 using Self = ImageToImageMetricv4GetValueAndDerivativeThreaderBase; 52 using Superclass = DomainThreader< TDomainPartitioner, TImageToImageMetricv4 >; 53 using Pointer = SmartPointer< Self >; 54 using ConstPointer = SmartPointer< const Self >; 55 56 itkTypeMacro( ImageToImageMetricv4GetValueAndDerivativeThreaderBase, DomainThreader ); 57 58 /** Superclass types. */ 59 using DomainType = typename Superclass::DomainType; 60 using AssociateType = typename Superclass::AssociateType; 61 62 /** Types of the target class. */ 63 using ImageToImageMetricv4Type = TImageToImageMetricv4; 64 using VirtualImageType = typename ImageToImageMetricv4Type::VirtualImageType; 65 using VirtualIndexType = typename ImageToImageMetricv4Type::VirtualIndexType; 66 using VirtualPointType = typename ImageToImageMetricv4Type::VirtualPointType; 67 using FixedImagePointType = typename ImageToImageMetricv4Type::FixedImagePointType; 68 using FixedImagePixelType = typename ImageToImageMetricv4Type::FixedImagePixelType; 69 using FixedImageIndexType = typename ImageToImageMetricv4Type::FixedImageIndexType; 70 using FixedImageGradientType = typename ImageToImageMetricv4Type::FixedImageGradientType; 71 using MovingImagePointType = typename ImageToImageMetricv4Type::MovingImagePointType; 72 using MovingImagePixelType = typename ImageToImageMetricv4Type::MovingImagePixelType; 73 using MovingImageGradientType = typename ImageToImageMetricv4Type::MovingImageGradientType; 74 75 using FixedTransformType = typename ImageToImageMetricv4Type::FixedTransformType; 76 using FixedOutputPointType = typename FixedTransformType::OutputPointType; 77 using MovingTransformType = typename ImageToImageMetricv4Type::MovingTransformType; 78 using MovingOutputPointType = typename MovingTransformType::OutputPointType; 79 80 using MeasureType = typename ImageToImageMetricv4Type::MeasureType; 81 using DerivativeType = typename ImageToImageMetricv4Type::DerivativeType; 82 using DerivativeValueType = typename ImageToImageMetricv4Type::DerivativeValueType; 83 using JacobianType = typename ImageToImageMetricv4Type::JacobianType; 84 using ImageDimensionType = typename ImageToImageMetricv4Type::ImageDimensionType; 85 86 using InternalComputationValueType = typename ImageToImageMetricv4Type::InternalComputationValueType; 87 using NumberOfParametersType = typename ImageToImageMetricv4Type::NumberOfParametersType; 88 89 using CompensatedDerivativeValueType = CompensatedSummation<DerivativeValueType>; 90 using CompensatedDerivativeType = std::vector<CompensatedDerivativeValueType>; 91 92 /** Access the GetValueAndDerivative() accesor in image metric base. */ 93 virtual bool GetComputeDerivative() const; 94 95 protected: 96 ImageToImageMetricv4GetValueAndDerivativeThreaderBase(); 97 ~ImageToImageMetricv4GetValueAndDerivativeThreaderBase() override; 98 99 /** Resize and initialize per thread objects. */ 100 void BeforeThreadedExecution() override; 101 102 /** Collects the results from each thread and sums them. Results are stored 103 * in the enclosing class \c m_Value and \c m_DerivativeResult. Behavior 104 * depends on m_AverageValueAndDerivativeByNumberOfValuePoints, 105 * m_NumberOfValidPoints, to average the value sum, and to average 106 * derivative sums for global transforms only (i.e. transforms without local 107 * support). */ 108 void AfterThreadedExecution() override; 109 110 /** Method called by the threaders to process the given virtual point. This 111 * in turn calls \c TransformAndEvaluateFixedPoint, \c 112 * TransformAndEvaluateMovingPoint, and \c ProcessPoint. 113 * And adds entries to m_MeasurePerThread and m_LocalDerivativesPerThread, 114 * m_NumberOfValidPointsPerThread. */ 115 virtual bool ProcessVirtualPoint( const VirtualIndexType & virtualIndex, 116 const VirtualPointType & virtualPoint, 117 const ThreadIdType threadId ); 118 119 /** Method to calculate the metric value and derivative 120 * given a point, value and image derivative for both fixed and moving 121 * spaces. The provided values have been calculated from \c virtualPoint, 122 * which is provided in case it's needed. 123 * \param virtualIndex 124 * \param virtualPoint is the point within the virtual domain from which 125 * the passed parameters have been calculated. 126 * \param mappedFixedPoint is a valid point within the moving image space 127 * that has passed bounds checking, and lies within any mask that may 128 * be assigned. 129 * \param mappedFixedPixelValue holds the pixel value at the mapped fixed 130 * point. 131 * \param mappedFixedImageGradient holds the image gradient at the fixed point, 132 * but only when \c m_GradientSource is set to calculate fixed image gradients 133 * (either when it's set to calculate only fixed gradients, or both fixed and 134 * moving). Otherwise, the value is meaningless and should be ignored. 135 * \param mappedMovingPoint 136 * \param mappedMovingPixelValue 137 * \param mappedMovingImageGradient 138 * These three parameters hold the point, pixel value and image gradient for 139 * the moving image space, as described above for the fixed image space. 140 * Results must be returned by derived classes in: 141 * \param metricValueReturn 142 * \param localDerivativeReturn 143 * \param threadId may be used as needed, for example to access any per-thread 144 * data cached during pre-processing by the derived class. 145 * \warning This is called from the threader, and thus must be thread-safe. 146 */ 147 virtual bool ProcessPoint( 148 const VirtualIndexType & virtualIndex, 149 const VirtualPointType & virtualPoint, 150 const FixedImagePointType & mappedFixedPoint, 151 const FixedImagePixelType & mappedFixedPixelValue, 152 const FixedImageGradientType & mappedFixedImageGradient, 153 const MovingImagePointType & mappedMovingPoint, 154 const MovingImagePixelType & mappedMovingPixelValue, 155 const MovingImageGradientType & mappedMovingImageGradient, 156 MeasureType & metricValueReturn, 157 DerivativeType & localDerivativeReturn, 158 const ThreadIdType threadId ) const = 0; 159 160 161 /** Store derivative result from a single point calculation. 162 * \warning If this method is overridden or otherwise not used 163 * in a derived class, be sure to *accumulate* results. */ 164 virtual void StorePointDerivativeResult( const VirtualIndexType & virtualIndex, 165 const ThreadIdType threadId ); 166 167 struct GetValueAndDerivativePerThreadStruct 168 { 169 /** Intermediary threaded metric value storage. */ 170 InternalComputationValueType Measure; 171 /** Intermediary threaded metric value storage. */ 172 DerivativeType Derivatives; 173 /** Intermediary threaded metric value storage. This is used only with global transforms. */ 174 CompensatedDerivativeType CompensatedDerivatives; 175 /** Intermediary threaded metric value storage. */ 176 DerivativeType LocalDerivatives; 177 /** Intermediary threaded metric value storage. */ 178 SizeValueType NumberOfValidPoints; 179 /** Pre-allocated transform jacobian objects, for use as needed by dervied 180 * classes for efficiency. */ 181 JacobianType MovingTransformJacobian; 182 JacobianType MovingTransformJacobianPositional; 183 }; 184 itkPadStruct( ITK_CACHE_LINE_ALIGNMENT, GetValueAndDerivativePerThreadStruct, 185 PaddedGetValueAndDerivativePerThreadStruct); 186 itkAlignedTypedef( ITK_CACHE_LINE_ALIGNMENT, PaddedGetValueAndDerivativePerThreadStruct, 187 AlignedGetValueAndDerivativePerThreadStruct ); 188 mutable AlignedGetValueAndDerivativePerThreadStruct * m_GetValueAndDerivativePerThreadVariables; 189 190 /** Cached values to avoid call overhead. 191 * These will only be set once threading has been started. */ 192 mutable NumberOfParametersType m_CachedNumberOfParameters; 193 mutable NumberOfParametersType m_CachedNumberOfLocalParameters; 194 }; 195 196 } // end namespace itk 197 198 #ifndef ITK_MANUAL_INSTANTIATION 199 #include "itkImageToImageMetricv4GetValueAndDerivativeThreaderBase.hxx" 200 #endif 201 202 #endif 203