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