cmtkGroupwiseRegistrationFunctionalXformTemplate.cxx

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: 2398 $
00026 //
00027 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 //#define DEBUG_COMM
00034 
00035 #include <Registration/cmtkGroupwiseRegistrationFunctionalXformTemplate.h>
00036 
00037 #include <Base/cmtkMathUtil.h>
00038 #include <IO/cmtkVolumeIO.h>
00039 
00040 #ifdef CMTK_BUILD_MPI
00041 #  include <mpi.h>
00042 #  include <IO/cmtkMPI.h>
00043 #endif
00044 
00045 namespace
00046 cmtk
00047 {
00048 
00051 
00052 template<class TXform>
00053 GroupwiseRegistrationFunctionalXformTemplate<TXform>::GroupwiseRegistrationFunctionalXformTemplate()
00054 {
00055   // allocate storage for four times me parallel tasks than threads in the global thread pool.
00056   this->m_InterpolateTaskInfo.resize( 4 * ThreadPool::GetGlobalThreadPool().GetNumberOfThreads() );
00057 }
00058 
00059 template<class TXform>
00060 void
00061 GroupwiseRegistrationFunctionalXformTemplate<TXform>
00062 ::InterpolateImage
00063 ( const size_t idx, byte* const destination )
00064 { 
00065   for ( size_t task = 0; task < this->m_InterpolateTaskInfo.size(); ++task )
00066     {
00067     this->m_InterpolateTaskInfo[task].thisObject = this;
00068     this->m_InterpolateTaskInfo[task].m_Idx = idx;    
00069     this->m_InterpolateTaskInfo[task].m_Destination = destination;    
00070     }
00071 
00072   ThreadPool& threadPool = ThreadPool::GetGlobalThreadPool();
00073   if ( this->m_ProbabilisticSamples.size() )
00074     threadPool.Run( InterpolateImageProbabilisticThread, this->m_InterpolateTaskInfo );
00075   else
00076     threadPool.Run( InterpolateImageThread, this->m_InterpolateTaskInfo );
00077 
00078   // Sum number of pixels outside FOV from all tasks.
00079   size_t numberOfOutsidePixels = 0;
00080   for ( size_t task = 0; task < this->m_InterpolateTaskInfo.size(); ++task )
00081     {
00082     numberOfOutsidePixels += this->m_InterpolateTaskInfo[task].m_NumberOfOutsidePixels;
00083     }
00084 
00085   // Check whether more than defined proportion threshold was outside
00086   if ( numberOfOutsidePixels > static_cast<size_t>( this->m_MaxRelativeNumberOutsidePixels * this->m_TemplateNumberOfSamples ) )
00087     {
00088     throw typename Self::BadXform();
00089     }
00090 }
00091 
00092 template<class TXform>
00093 void
00094 GroupwiseRegistrationFunctionalXformTemplate<TXform>::InterpolateImageThread
00095 ( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00096 {
00097   InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00098   
00099   const Self* This = threadParameters->thisObject;
00100   const size_t idx = threadParameters->m_Idx;
00101   byte* destination = threadParameters->m_Destination;
00102 
00103   const TXform* xform = This->GetXformByIndex(idx);
00104   const UniformVolume* target = This->m_ImageVector[idx];
00105 
00106   const byte paddingValue = This->m_PaddingValue;
00107   const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00108   threadParameters->m_NumberOfOutsidePixels = 0;
00109 
00110   Vector3D v;
00111   byte value;
00112   const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00113 
00114   const int dimsX = This->m_TemplateGrid->GetDims()[AXIS_X];
00115   const int dimsY = This->m_TemplateGrid->GetDims()[AXIS_Y];
00116   const int dimsZ = This->m_TemplateGrid->GetDims()[AXIS_Z];
00117 
00118   for ( int z = taskIdx; (z < dimsZ); z += taskCnt ) 
00119     {
00120     byte *wptr = destination + z * dimsX * dimsY;
00121     for ( int y = 0; (y < dimsY); ++y )
00122       {
00123       for ( int x = 0; x < dimsX; ++x )
00124         {
00125         This->m_TemplateGrid->GetGridLocation( v, x, y, z );
00126         xform->ApplyInPlace( v );
00127         
00128         if ( target->ProbeData( value, dataPtr, v ) )
00129           {
00130           *wptr = value;
00131           }
00132         else
00133           {
00134           *wptr = backgroundValue;
00135           ++threadParameters->m_NumberOfOutsidePixels;
00136           }
00137         
00138         ++wptr;
00139         }
00140       }
00141     }
00142 }
00143 
00144 template<class TXform>
00145 void
00146 GroupwiseRegistrationFunctionalXformTemplate<TXform>::InterpolateImageProbabilisticThread
00147 ( void *const args, const size_t taskIdx, const size_t taskCnt, const size_t, const size_t )
00148 {
00149   InterpolateImageThreadParameters* threadParameters = static_cast<InterpolateImageThreadParameters*>( args );
00150   
00151   const Self* This = threadParameters->thisObject;
00152   const size_t idx = threadParameters->m_Idx;
00153   byte* destination = threadParameters->m_Destination;
00154   threadParameters->m_NumberOfOutsidePixels = 0;
00155 
00156   const TXform* xform = This->GetXformByIndex(idx);
00157   const UniformVolume* target = This->m_ImageVector[idx];
00158 
00159   const byte paddingValue = This->m_PaddingValue;
00160   const byte backgroundValue = This->m_UserBackgroundFlag ? This->m_PrivateUserBackgroundValue : paddingValue;
00161 
00162   Vector3D v;
00163   byte value;
00164   const byte* dataPtr = static_cast<const byte*>( target->GetData()->GetDataPtr() );
00165 
00166   const size_t startIdx = taskIdx * (This->m_ProbabilisticSamples.size() / taskCnt);
00167   const size_t endIdx = ( taskIdx == taskCnt ) ? This->m_ProbabilisticSamples.size() : (taskIdx+1) * (This->m_ProbabilisticSamples.size() / taskCnt);
00168 
00169   byte *wptr = destination + startIdx;
00170   for ( size_t i = startIdx; i < endIdx; ++i, ++wptr )
00171     {
00172     const size_t offset = This->m_ProbabilisticSamples[i];
00173     This->m_TemplateGrid->GetGridLocation( v, offset );
00174     xform->ApplyInPlace( v );
00175     
00176     if ( target->ProbeData( value, dataPtr, v ) )
00177       {
00178       *wptr = value;
00179       }
00180     else
00181       {
00182       *wptr = backgroundValue;
00183       ++threadParameters->m_NumberOfOutsidePixels;
00184       }
00185     }
00186 }
00187 
00189 
00190 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines