cmtkSplineWarpMultiChannelRegistrationFunctionalThreadFunctions.txx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2453 $
00026 //
00027 //  $LastChangedDate: 2010-10-18 10:33:06 -0700 (Mon, 18 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 namespace
00034 cmtk
00035 {
00036 
00039 
00040 template<class TMetricFunctional>
00041 void
00042 SplineWarpMultiChannelRegistrationFunctional<TMetricFunctional>
00043 ::EvaluateThreadFunction( void* args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00044 {
00045   ThreadParameters<Self>* params = static_cast<ThreadParameters<Self>*>( args );
00046 
00047   Self* This = params->thisObject;
00048   const Self* constThis = This;
00049 
00050   typename Self::MetricData metricData;
00051   metricData.Init( This );
00052 
00053   const DataGrid::IndexType& dims = constThis->m_ReferenceDims;
00054   const int dimsX = dims[0], dimsY = dims[1], dimsZ = dims[2];
00055   std::vector<Vector3D> pFloating( dimsX );
00056 
00057   for ( int pZ = taskIdx; pZ < dimsZ; pZ += taskCnt ) 
00058     {
00059     for ( int pY = 0; pY < dimsY; ++pY ) 
00060       {
00061       constThis->m_Transformation.GetTransformedGridRow( dimsX, &pFloating[0], 0, pY, pZ );
00062       
00063       size_t r = dimsX * (pY + dimsY * pZ );
00064       for ( int pX = 0; pX < dimsX; ++pX, ++r ) 
00065         {
00066         // Continue metric computation.
00067         This->ContinueMetricStoreReformatted( metricData, r, pFloating[pX] );
00068         }
00069       }
00070     }
00071 
00072   This->m_MetricDataMutex.Lock();
00073   This->m_MetricData += metricData;
00074   This->m_MetricDataMutex.Unlock();
00075 }
00076 
00077 template<class TMetricFunctional>
00078 void
00079 SplineWarpMultiChannelRegistrationFunctional<TMetricFunctional>
00080 ::EvaluateWithGradientThreadFunction( void* args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00081 {
00082   EvaluateGradientThreadParameters* params = static_cast<EvaluateGradientThreadParameters*>( args );
00083 
00084   Self* This = params->thisObject;
00085   const Self* constThis = This;
00086 
00087   const size_t numberOfParameters = This->VariableParamVectorDim();
00088   const size_t numberOfControlPoints = numberOfParameters / 3;
00089 
00090   SplineWarpXform::SmartPtr transformation = constThis->m_ThreadTransformations[threadIdx];
00091   transformation->SetParamVector( *(params->m_ParameterVector) );
00092 
00093   for ( size_t cp = taskIdx; cp < numberOfControlPoints; cp += taskCnt ) 
00094     {
00095     typename Superclass::MetricData localMetricDataCP = constThis->m_MetricData;
00096     This->BacktraceMetric( localMetricDataCP, constThis->m_VolumeOfInfluenceVector[cp] );
00097 
00098     size_t idx = 3 * cp;
00099     for ( int dim = 0; dim < 3; ++dim, ++idx )
00100       {
00101       if ( constThis->m_StepScaleVector[idx] <= 0 ) 
00102         {
00103         params->m_Gradient[idx] = 0;
00104         } 
00105       else
00106         {
00107         const Types::Coordinate vOld = transformation->GetParameter( idx );
00108         
00109         Types::Coordinate thisStep = params->m_Step * constThis->m_StepScaleVector[idx];
00110         
00111         typename Superclass::MetricData localMetricData = localMetricDataCP;
00112         transformation->SetParameter( idx, vOld + thisStep );
00113         double upper = This->EvaluateIncremental( transformation, localMetricData, constThis->m_VolumeOfInfluenceVector[cp] );
00114         
00115         localMetricData = localMetricDataCP;
00116         transformation->SetParameter( idx, vOld - thisStep );
00117         double lower = This->EvaluateIncremental( transformation, localMetricData, constThis->m_VolumeOfInfluenceVector[cp] );
00118         
00119         transformation->SetParameter( idx, vOld );
00120         
00121         if ( constThis->m_JacobianConstraintWeight > 0 )
00122           {
00123           double lowerConstraint = 0, upperConstraint = 0;
00124           transformation->GetJacobianConstraintDerivative( lowerConstraint, upperConstraint, idx, constThis->m_VolumeOfInfluenceVector[cp], thisStep );
00125           lower -= constThis->m_JacobianConstraintWeight * lowerConstraint;
00126           upper -= constThis->m_JacobianConstraintWeight * upperConstraint;
00127           }
00128         
00129         if ( finite( upper ) && finite(lower) && ((upper > params->m_MetricBaseValue ) || (lower > params->m_MetricBaseValue)) )
00130           {
00131           params->m_Gradient[idx] = upper-lower;
00132           } 
00133         else 
00134           {
00135           params->m_Gradient[idx] = 0;
00136           }
00137         }
00138       }
00139     }
00140 }
00141 
00142 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines