00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __freSetupOptimizationMultiThreadMetric_txx
00023 #define __freSetupOptimizationMultiThreadMetric_txx
00024
00025 #include "freSetupOptimizationMultiThreadMetric.h"
00026 #include "itkMultiThreader.h"
00027
00028 namespace FREE
00029 {
00030 template <typename TMonitor, typename TThread>
00031 typename SetupOptimizationMultiThreadMetric<TMonitor, TThread>::DecomposedMeasureType
00032 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00033 ComputeDecomposedValue( const ParametersType & parameters ) const
00034 {
00035 if (this->m_smpAdaptations.IsNull()) throwExceptionMacro("Error. Cannot calculate metric value, adaptiation list is null.");
00036 if (this->m_Transform.IsNull()) throwExceptionMacro("Error. Cannot calculate metric value, no setup transform set.");
00037
00038 if (this->m_Transform->GetNumberOfParameters() != parameters.size()) throwExceptionMacro("Error. Cannot calculate metric value, number of passed parameters is not equal to the parameter size of the transform. Passed parameter count: "<< parameters.size());
00039
00040 this->InitializeValueComputation();
00041
00042 m_Transform->SetParameters(parameters);
00043 Setup::Pointer smpTransformedSetup = m_Transform->GenerateTransformedSetup();
00044
00045 typename MonitorType::Pointer smpMonitor = MonitorType::New();
00046
00047 try
00048 {
00049 smpMonitor->fnOnEvaluationProgress = this->fnOnMonitorEvaluationProgress;
00050 smpMonitor->fnOnEvaluationDone = this->fnOnMonitorEvaluationDone;
00051 smpMonitor->fnOnNextAdaptation = this->fnOnMonitorNextAdaptation;
00052 smpMonitor->fnOnEvaluationFailed = this->fnOnMonitorEvaluationFailed;
00053
00054 smpMonitor->SetGenericSetup(smpTransformedSetup);
00055 smpMonitor->SetAdaptationList(m_smpAdaptations);
00056 smpMonitor->SetMetricStatistic(&(this->GetMetricStatistic()));
00057
00058 this->InitializeMonitor(*(smpMonitor.GetPointer()));
00059 smpMonitor->Initialize();
00060 }
00061 catchAllNPassMacro("Unknown error while initializing the monitor.");
00062
00063 ThreadListType threadList;
00064
00065 itk::MultiThreader::Pointer smpThreader = itk::MultiThreader::New();
00066
00067 long lMaxThreadCount = this->m_NumberOfThreads;
00068 if (lMaxThreadCount<1) lMaxThreadCount = m_smpAdaptations->Size();
00069
00070 smpThreader->SetNumberOfThreads(lMaxThreadCount);
00071
00072 try
00073 {
00074 for (long index = 0; index<lMaxThreadCount; index++)
00075 {
00076
00077 ThreadPointer smpThread = ThreadType::New();
00078 smpThread->SetMonitor(smpMonitor.GetPointer());
00079
00080 this->InitializeThread(*(smpThread.GetPointer()));
00081
00082 threadList.push_back(smpThread);
00083 smpThreader->SetMultipleMethod(index, Self::ThreadExecution, smpThread.GetPointer());
00084 }
00085 }
00086 catchAllNPassMacro("Unknown error while initializing the threads.");
00087
00088 try
00089 {
00090
00091 smpThreader->MultipleMethodExecute();
00092 }
00093 catchAllNPassMacro("Unknown error while executing threads to calculate the metric.");
00094
00095 try
00096 {
00097
00098 return this->ComputeMeasure(*(smpMonitor.GetPointer()));
00099 }
00100 catchAllNPassMacro("Unknown error while computing the measure.");
00101 };
00102
00103 template <typename TMonitor, typename TThread>
00104 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00105 SetupOptimizationMultiThreadMetric()
00106 {
00107 m_NumberOfThreads = 1;
00108
00109 fnOnMonitorEvaluationProgress = ProgressEvent<Self>::New(this,&Self::OnMonitorEvaluationProgress);
00110 fnOnMonitorEvaluationDone = ProgressEvent<Self>::New(this,&Self::OnMonitorEvaluationDone);
00111 fnOnMonitorNextAdaptation = ProgressEvent<Self>::New(this,&Self::OnOnMonitorNextAdaptation);
00112 fnOnMonitorEvaluationFailed = ProgressEvent<Self>::New(this,&Self::OnOnMonitorEvaluationFailed);
00113 };
00114
00115 template <typename TMonitor, typename TThread>
00116 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00117 ~SetupOptimizationMultiThreadMetric()
00118 {
00119 };
00120
00121 template <typename TMonitor, typename TThread>
00122 void
00123 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00124 OnMonitorEvaluationProgress(const long status, const std::string& sComment, void* pSender, long threadID)
00125 {
00126
00127 if (fnOnEvaluationProgress.IsNotNull()) fnOnEvaluationProgress->Execute(status,sComment,(void*)this, threadID);
00128 this->InvokeEvent( EvaluationDoneObserverEvent() );
00129 };
00130
00131 template <typename TMonitor, typename TThread>
00132 void
00133 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00134 OnMonitorEvaluationDone(const long status, const std::string& sComment, void* pSender, long threadID)
00135 {
00136
00137 if (fnOnEvaluationDone.IsNotNull()) fnOnEvaluationDone->Execute(status,sComment,(void*)this, threadID);
00138 this->InvokeEvent( EvaluationDoneObserverEvent() );
00139 };
00140
00141 template <typename TMonitor, typename TThread>
00142 void
00143 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00144 OnOnMonitorNextAdaptation(const long status, const std::string& sComment, void* pSender, long threadID)
00145 {
00146
00147 if (fnOnNextAdaptation.IsNotNull()) fnOnNextAdaptation->Execute(status,sComment,(void*)this, threadID);
00148 this->InvokeEvent( EvaluationDoneObserverEvent() );
00149 };
00150
00151 template <typename TMonitor, typename TThread>
00152 void
00153 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00154 OnOnMonitorEvaluationFailed(const long status, const std::string& sComment, void* pSender, long threadID)
00155 {
00156
00157 if (fnOnEvaluationFailed.IsNotNull()) fnOnEvaluationFailed->Execute(status,sComment,(void*)this, threadID);
00158 this->InvokeEvent( EvaluationDoneObserverEvent() );
00159 };
00160
00161 template <typename TMonitor, typename TThread>
00162 ITK_THREAD_RETURN_TYPE
00163 SetupOptimizationMultiThreadMetric<TMonitor, TThread>::
00164 ThreadExecution( void *arg )
00165 {
00166 ThreadType *pThread;
00167 int threadID;
00168
00169 threadID = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
00170
00171 pThread = (ThreadType *)(((itk::MultiThreader::ThreadInfoStruct *)(arg))->UserData);
00172
00173 if (!pThread) throwStaticExceptionMacro("Error; user data for thread execution is missing");
00174
00175 pThread->SetThreadID(threadID);
00176 pThread->Execute();
00177
00178 return ITK_THREAD_RETURN_VALUE;
00179 };
00180
00181 }
00182
00183 #endif