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 }