Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <Base/cmtkTransformedVolumeAxes.h>
00034
00035 namespace
00036 cmtk
00037 {
00038
00039 template<class VM>
00040 typename ImagePairAffineRegistrationFunctionalTemplate<VM>::ReturnType
00041 ImagePairAffineRegistrationFunctionalTemplate<VM>
00042 ::Evaluate()
00043 {
00044 const TransformedVolumeAxes axesHash( *this->m_ReferenceGrid, this->m_AffineXform, this->m_FloatingGrid->Deltas().begin(), this->m_FloatingGrid->m_Offset.begin() );
00045 const Vector3D *axesHashX = axesHash[0], *axesHashY = axesHash[1], *axesHashZ = axesHash[2];
00046
00047 this->m_Metric->Reset();
00048
00049 const DataGrid::IndexType& Dims = this->m_ReferenceGrid->GetDims();
00050 const int DimsX = Dims[0], DimsY = Dims[1], DimsZ = Dims[2];
00051
00052 this->Clipper.SetDeltaX( axesHashX[DimsX-1] - axesHashX[0] );
00053 this->Clipper.SetDeltaY( axesHashY[DimsY-1] - axesHashY[0] );
00054 this->Clipper.SetDeltaZ( axesHashZ[DimsZ-1] - axesHashZ[0] );
00055 this->Clipper.SetClippingBoundaries( this->m_FloatingCropRegionFractIndex );
00056
00057 DataGrid::IndexType::ValueType startZ, endZ;
00058 if ( this->ClipZ( this->Clipper, axesHashZ[0], startZ, endZ ) )
00059 {
00060 startZ = std::max<DataGrid::IndexType::ValueType>( startZ, this->m_ReferenceCropRegion.From()[2] );
00061 endZ = std::min<DataGrid::IndexType::ValueType>( endZ, this->m_ReferenceCropRegion.To()[2] + 1 );
00062
00063 const int numberOfTasks = std::min<size_t>( 4 * this->m_NumberOfThreads - 3, endZ - startZ + 1 );
00064 this->m_EvaluateTaskInfo.resize( numberOfTasks );
00065
00066 for ( int taskIdx = 0; taskIdx < numberOfTasks; ++taskIdx )
00067 {
00068 this->m_EvaluateTaskInfo[taskIdx].thisObject = this;
00069 this->m_EvaluateTaskInfo[taskIdx].AxesHash = &axesHash;
00070 this->m_EvaluateTaskInfo[taskIdx].StartZ = startZ;
00071 this->m_EvaluateTaskInfo[taskIdx].EndZ = endZ;
00072 }
00073
00074 ThreadPool::GetGlobalThreadPool().Run( EvaluateThread, this->m_EvaluateTaskInfo );
00075 }
00076 return this->m_Metric->Get();
00077 }
00078
00079 template<class VM>
00080 void
00081 ImagePairAffineRegistrationFunctionalTemplate<VM>
00082 ::EvaluateThread( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t threadIdx, const size_t )
00083 {
00084 typename Self::EvaluateTaskInfo *info = static_cast<typename Self::EvaluateTaskInfo*>( args );
00085
00086 Self *me = info->thisObject;
00087 VM& metric = dynamic_cast<VM&>( *(me->m_Metric) );
00088
00089 VM& threadMetric = me->m_ThreadMetric[threadIdx];
00090 threadMetric.Reset();
00091
00092 const Vector3D *hashX = (*info->AxesHash)[0], *hashY = (*info->AxesHash)[1], *hashZ = (*info->AxesHash)[2];
00093 Vector3D pFloating;
00094
00095 const DataGrid::IndexType& Dims = me->m_ReferenceGrid->GetDims();
00096 const int DimsX = Dims[0], DimsY = Dims[1];
00097
00098 int fltIdx[3];
00099 Types::Coordinate fltFrac[3];
00100
00101 Vector3D rowStart;
00102 Vector3D planeStart;
00103
00104 DataGrid::IndexType::ValueType pX, pY, pZ;
00105
00106 for ( pZ = info->StartZ + taskIdx; pZ < info->EndZ; pZ += taskCnt )
00107 {
00108
00109 int r = pZ * DimsX * DimsY;
00110
00111 planeStart = hashZ[pZ];
00112
00113 DataGrid::IndexType::ValueType startY, endY;
00114 if ( me->ClipY( me->Clipper, planeStart, startY, endY ) )
00115 {
00116 startY = std::max<DataGrid::IndexType::ValueType>( startY, me->m_ReferenceCropRegion.From()[1] );
00117 endY = std::min<DataGrid::IndexType::ValueType>( endY, me->m_ReferenceCropRegion.To()[1] + 1 );
00118 r += startY * DimsX;
00119
00120
00121 for ( pY = startY; pY<endY; ++pY )
00122 {
00123 (rowStart = planeStart) += hashY[pY];
00124
00125 DataGrid::IndexType::ValueType startX, endX;
00126 if ( me->ClipX( me->Clipper, rowStart, startX, endX ) )
00127 {
00128 startX = std::max<DataGrid::IndexType::ValueType>( startX, me->m_ReferenceCropRegion.From()[0] );
00129 endX = std::min<DataGrid::IndexType::ValueType>( endX, me->m_ReferenceCropRegion.To()[0] + 1 );
00130
00131 r += startX;
00132
00133 for ( pX = startX; pX<endX; ++pX, ++r )
00134 {
00135
00136 Types::DataItem sampleX;
00137 if ( metric.GetSampleX( sampleX, r ) )
00138 {
00139 (pFloating = rowStart) += hashX[pX];
00140
00141
00142 if ( me->m_FloatingGrid->FindVoxelByIndex( pFloating, fltIdx, fltFrac ) )
00143 {
00144 threadMetric.Increment( sampleX, metric.GetSampleY( fltIdx, fltFrac ) );
00145 }
00146 else
00147 {
00148 if ( me->m_ForceOutsideFlag )
00149 {
00150 threadMetric.Increment( sampleX, me->m_ForceOutsideValueRescaled );
00151 }
00152 }
00153 }
00154 }
00155 r += (DimsX-endX);
00156 }
00157 else
00158 {
00159 r += DimsX;
00160 }
00161 }
00162
00163 r += (DimsY-endY) * DimsX;
00164 }
00165 else
00166 {
00167 r += DimsY * DimsX;
00168 }
00169 }
00170
00171 me->m_MetricMutex.Lock();
00172 metric.Add( threadMetric );
00173 me->m_MetricMutex.Unlock();
00174 }
00175
00176 }