00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __freRigidRegistrationControllerBase_txx
00024 #define __freRigidRegistrationControllerBase_txx
00025
00026 #include "freRigidRegistrationControllerBase.h"
00027
00028 #include "freRegistrationProcessEventHandler.h"
00029 #include "freIntensityImageMediaController.h"
00030 #include "freTransformFieldMediaController.h"
00031 #include "freInterpolatorControllerBase.h"
00032 #include "freImageToImageMetricControllerBase.h"
00033 #include "freITKTransformControllerBase.h"
00034 #include "freOptimizerControllerBase.h"
00035 #include "freTransformFunctionMediaController.h"
00036 #include "freTransformFunctionAccessor.h"
00037
00038 namespace FREE
00039 {
00043 template <class ComponentType>
00044 const char* const RigidRegistrationControllerBase<ComponentType> :: cParam_PersistentFinalField = "PersistentFinalField";
00045 template <class ComponentType>
00046 const char* const RigidRegistrationControllerBase<ComponentType> :: cParamDsc_PersistentFinalField = "Indicates if the final field should be stored internally and only will be recomputed if registration is outdated. Keeping the image persistent accelerates the processing, but requires more memory.";
00047
00048 template <class ComponentType>
00049 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaID_finalField = "finalField";
00050 template <class ComponentType>
00051 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaIDDsc_finalField = "Transformation field generated by using the current/final transform of the registration.";
00052 template <class ComponentType>
00053 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaID_fieldReference = "fieldReference";
00054 template <class ComponentType>
00055 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaIDDsc_fieldReference = "Image that is reference for origin, size and spacing of the final field. If not linked the fixed image will be used as reference.";
00056 template <class ComponentType>
00057 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaID_finalTransform = "finalTransform";
00058 template <class ComponentType>
00059 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaIDDsc_finalTransform = "Transformation function of the current/final transform of the registration.";
00060 template <class ComponentType>
00061 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaID_finalInverseTransform = "finalInverseTransform";
00062 template <class ComponentType>
00063 const char* const RigidRegistrationControllerBase<ComponentType> :: MediaIDDsc_finalInverseTransform = "Transformation function of the current/final transform of the registration. This media is only valid if the transform can be inverted";
00064
00065 template <class ComponentType>
00066 typename RigidRegistrationControllerBase<ComponentType>::ComponentPointer
00067 RigidRegistrationControllerBase<ComponentType>::
00068 BuildMainComponent(ComponentSetup* pComponentSetup, SessionComponentCache* pComponentCache) const
00069 {
00070 ComponentPointer mainComponent = Superclass::BuildMainComponent(pComponentSetup,pComponentCache);
00071 DirectSessionComponentAccessor::SetRepositoryElement(SessionComponentRepositoryKeys::Validity("Registration"),ValidityTag::NewNull(),pComponentCache);
00072 return mainComponent;
00073 };
00074
00075 template <class ComponentType>
00076 void
00077 RigidRegistrationControllerBase<ComponentType>::
00078 ActualizeMainComponent(ComponentType* pMainComponent,
00079 SessionComponentCache* pComponentCache,
00080 SessionInfo* pSessionInfo,
00081 const unsigned int& iActLevel) const
00082 {
00083 Superclass::ActualizeMainComponent(pMainComponent,pComponentCache, pSessionInfo, iActLevel);
00084
00085
00086 pMainComponent->SetSessionInfo(pSessionInfo);
00087 pMainComponent->SetComponentCache(pComponentCache);
00088 }
00089
00090 template <class ComponentType>
00091 ValidityTag::Pointer
00092 RigidRegistrationControllerBase<ComponentType>::
00093 GetMediaValidityTagRequirement(const MediaID& mediaID, SessionComponentCache* pComponentCache) const
00094 {
00095 if ((mediaID == MediaID_finalField) || (mediaID == MediaID_finalTransform) || (mediaID == MediaID_finalInverseTransform))
00096 {
00097 ValidityTag::Pointer smpReq = ValidityTag::New(this->GetMediaValidityTag(mediaID,pComponentCache)->GetTimeStamp());
00098
00099
00100 ValidityTag::Pointer smpRegistrationReq = this->GetValidityTagRequirement("Registration",pComponentCache);
00101 if (smpReq->IsOutdated(smpRegistrationReq))
00102 {
00103 smpReq->SetTag(smpRegistrationReq);
00104 }
00105 return smpReq;
00106 }
00107
00108 return Superclass::GetMediaValidityTagRequirement(mediaID, pComponentCache);
00109 }
00110
00111 template <class ComponentType>
00112 ValidityTag::Pointer
00113 RigidRegistrationControllerBase<ComponentType>::
00114 GetValidityTagRequirement(const std::string& id, SessionComponentCache* pComponentCache) const
00115 {
00116 if (id == "Registration")
00117 {
00118 ValidityTag::Pointer smpReq = ValidityTag::New(this->GetValidityTag(id,pComponentCache)->GetTimeStamp());
00119
00120
00121 ComponentMediaLink::Pointer smpLink = pComponentCache->Setup()->MediaLinks().GetElement(Superclass::MediaID_movingImage);
00122 if (smpLink.IsNotNull())
00123 {
00124 ValidityTag::Pointer smpImageReq = SessionAccessor::GetValidityTagRequirement(smpLink->GetSourceIDPath(),pComponentCache);
00125 if (smpReq->IsOutdated(smpImageReq))
00126 {
00127 smpReq->SetTag(smpImageReq);
00128 }
00129 }
00130
00131 smpLink = pComponentCache->Setup()->MediaLinks().GetElement(Superclass::MediaID_fixedImage);
00132 if (smpLink.IsNotNull())
00133 {
00134 ValidityTag::Pointer smpImageReq = SessionAccessor::GetValidityTagRequirement(smpLink->GetSourceIDPath(),pComponentCache);
00135 if (smpReq->IsOutdated(smpImageReq))
00136 {
00137 smpReq->SetTag(smpImageReq);
00138 }
00139 }
00140 return smpReq;
00141 }
00142
00143 return Superclass::GetMediaValidityTagRequirement(id, pComponentCache);
00144 }
00145
00146 template <class ComponentType>
00147 RigidRegistrationControllerBase<ComponentType>::
00148 RigidRegistrationControllerBase()
00149 {
00150
00151 this->UpdateControllerID(ControllerID::OptimizerOwnerControllerBase);
00152 this->UpdateControllerID(ControllerID::RigidRegistrationControllerBase);
00153 this->m_Description = "Realizes a rigid registration.";
00154 };
00155
00156 template <class ComponentType>
00157 void
00158 RigidRegistrationControllerBase<ComponentType>::
00159 GenerateProfile(CtrlProfile::ControllerProfile& profile,
00160 const SessionComponentCache* pComponentCache,
00161 bool bRegardOldSetup) const
00162 {
00163 Superclass::GenerateProfile(profile,pComponentCache,bRegardOldSetup);
00164
00165
00166 profile.Parameters().AddParameter(cParam_PersistentFinalField,Parameter::PVTBool,cParamDsc_PersistentFinalField,1,"true");
00167 profile.Parameters().AddParameter(cParam_MinimizeToOptimize,Parameter::PVTBool,cParamDsc_MinimizeToOptimize,1,"true",1,false,0,DAGet);
00168
00169
00170 profile.SubComponents().AddSubComponent(cComp_MainMetric,1,csUndefinedController,cCompDsc_MainMetric);
00171 profile.SubComponents().AddSubComponent(cComp_MainOptimizer,1,csUndefinedController,cCompDsc_MainOptimizer);
00172 profile.SubComponents().AddSubComponent(cComp_MainTransform,1,csUndefinedController,cCompDsc_MainTransform);
00173 profile.SubComponents().AddSubComponent(cComp_MainInterpolator,1,csUndefinedController,cCompDsc_MainInterpolator);
00174
00175
00176 std::string sImageControllerID = ControllerID::IntensityImage2DMediaController;
00177 std::string sTransformControllerID = ControllerID::TransformField2DMediaController;
00178 if (ComponentType::ImageDimension == 3)
00179 {
00180 sImageControllerID = ControllerID::IntensityImage3DMediaController;
00181 sTransformControllerID = ControllerID::TransformField3DMediaController;
00182 }
00183
00184 profile.MediaMap().AddMedia(Superclass::MediaID_movingImage,sImageControllerID, DASet,ComponentType::ImageDimension);
00185 profile.MediaMap().AddMedia(Superclass::MediaID_fixedImage,sImageControllerID, DASet,ComponentType::ImageDimension);
00186
00187 profile.MediaMap().AddMedia(MediaID_finalField,sTransformControllerID, DAGet,ComponentType::ImageDimension);
00188 profile.MediaMap().AddMedia(MediaID_fieldReference,ControllerID::ImageMediaControllerBase, DASet,ComponentType::ImageDimension,0);
00189
00190 profile.MediaMap().AddMedia(MediaID_finalTransform,ControllerID::TransformFunctionMediaControllerBase, DAGet,ComponentType::ImageDimension);
00191 profile.MediaMap().AddMedia(MediaID_finalInverseTransform,ControllerID::TransformFunctionMediaControllerBase, DAGet,ComponentType::ImageDimension);
00192
00193
00194 CtrlProfile::ProfileOption* pOption;
00195
00196 pOption = profile.Requirements().AddRequirement(cComp_MainInterpolator)->AddProfileOption();
00197 pOption->Inheritance().AddAncestor(ControllerID::InterpolatorControllerBase);
00198 pOption->MediaMap().AddMedia("inputImage",sImageControllerID, DASet, ComponentType::ImageDimension,1,true);
00199 pOption->CheckForInheritance();
00200 pOption->CheckForIO();
00201
00202 pOption = profile.Requirements().AddRequirement(cComp_MainMetric)->AddProfileOption();
00203 pOption->Inheritance().AddAncestor(ControllerID::ImageToImageMetricControllerBase);
00204 pOption->MediaMap().AddMedia(Superclass::MediaID_movingImage,sImageControllerID, DASet, ComponentType::ImageDimension,1,true);
00205 pOption->MediaMap().AddMedia(Superclass::MediaID_fixedImage,sImageControllerID, DASet, ComponentType::ImageDimension,1,true);
00206 pOption->CheckForInheritance();
00207 pOption->CheckForIO();
00208
00209 pOption = profile.Requirements().AddRequirement(cComp_MainOptimizer)->AddProfileOption();
00210 pOption->Inheritance().AddAncestor(ControllerID::OptimizerControllerBase);
00211 pOption->CheckForInheritance();
00212
00213 pOption = profile.Requirements().AddRequirement(cComp_MainTransform)->AddProfileOption();
00214 pOption->Inheritance().AddAncestor(ControllerID::ITKTransformControllerBase);
00215 pOption->MediaMap().AddMedia(Superclass::MediaID_movingImage,ControllerID::MediaControllerBase, DASet, ComponentType::ImageDimension,1,true);
00216 pOption->MediaMap().AddMedia(Superclass::MediaID_fixedImage,ControllerID::MediaControllerBase, DASet, ComponentType::ImageDimension,1,true);
00217 pOption->CheckForInheritance();
00218 pOption->CheckForIO();
00219 };
00220
00221 template <class ComponentType>
00222 typename RigidRegistrationControllerBase<ComponentType>::GenericComponentType*
00223 RigidRegistrationControllerBase<ComponentType>::
00224 GetSubComponentCasted(ComponentType* pMainComponent, const ComponentID& compID,
00225 SessionComponentCache* pMainComponentCache) const
00226 {
00227 if (compID == cComp_MainInterpolator) return pMainComponent->GetInterpolator();
00228 if (compID == cComp_MainMetric) return pMainComponent->GetMetric();
00229 if (compID == cComp_MainOptimizer) return pMainComponent->GetOptimizer();
00230 if (compID == cComp_MainTransform) return pMainComponent->GetTransform();
00231
00232 return Superclass::GetSubComponentCasted(pMainComponent, compID, pMainComponentCache);
00233 };
00234
00235 template <class ComponentType>
00236 void
00237 RigidRegistrationControllerBase<ComponentType>::
00238 SetSubComponentCasted(GenericComponentType* pSubComponent, ComponentType* pMainComponent,
00239 const ComponentID compID, SessionComponentCache* pMainComponentCache) const
00240 {
00241 if (compID == cComp_MainInterpolator) pMainComponent->SetInterpolator(dynamic_cast<typename ComponentType::InterpolatorType*>(pSubComponent));
00242 else if (compID == cComp_MainMetric) pMainComponent->SetMetric(dynamic_cast<typename ComponentType::MetricType*>(pSubComponent));
00243 else if (compID == cComp_MainOptimizer) pMainComponent->SetOptimizer(dynamic_cast<typename ComponentType::OptimizerType*>(pSubComponent));
00244 else if (compID == cComp_MainTransform) pMainComponent->SetTransform(dynamic_cast<typename ComponentType::TransformType*>(pSubComponent));
00245 else Superclass::SetSubComponentCasted(pSubComponent, pMainComponent, compID, pMainComponentCache);
00246 };
00247
00248 template <class ComponentType>
00249 typename RigidRegistrationControllerBase<ComponentType>::GenericMediaPointer
00250 RigidRegistrationControllerBase<ComponentType>::
00251 GetMediaCasted(const MediaID& mediaID,ComponentType* pComponent, SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo) const
00252 {
00253 if ((mediaID == MediaID_finalField) || (mediaID == MediaID_finalTransform) || (mediaID == MediaID_finalInverseTransform))
00254 {
00255 GenericMediaPointer smpMedia;
00256
00257 ValidityTag::Pointer smpRegistrationValidity = this->GetValidityTag("Registration",pComponentCache);
00258 ValidityTag::Pointer smpRegistrationValidityReq = this->GetValidityTagRequirement("Registration",pComponentCache);
00259
00260 if (smpRegistrationValidity->IsOutdated(smpRegistrationValidityReq))
00261 {
00262 this->NotifyProgress(1,"Registration outdated -> actualize",pComponentCache);
00263 SessionBuilder::LinkMediaToComponent(pComponentCache, pSessionInfo);
00264 SessionBuilder::ActualizeComponent(pComponentCache, pSessionInfo);
00265
00266
00267 typedef RegistrationProcessEventHandler<ComponentType> HandlerType;
00268 typename HandlerType::Pointer smpHandler = HandlerType::New();
00269 smpHandler->SetSessionInfo(pSessionInfo);
00270 smpHandler->SetComponentCache(pComponentCache);
00271
00272 DirectSessionComponentAccessor::SetRepositoryElement("EventHandler",smpHandler,pComponentCache);
00273
00274 StatisticEntry* pRegistrationEntry = Superclass::AddStatisticEntry(pComponentCache, pSessionInfo, "Registration", "a rigid registration");
00275
00276 smpHandler->SetRegistrationEntry(pRegistrationEntry);
00277
00278
00279 pComponent->StartRegistration();
00280
00281 if (pRegistrationEntry) pRegistrationEntry->CloseEntry();
00282
00283 this->ResetComponent(pComponentCache, pSessionInfo);
00284
00285 this->ActualizeValidityTag("Registration",pComponentCache);
00286 this->NotifyProgress(1,"Registration updated",pComponentCache);
00287 }
00288
00289 if (mediaID == MediaID_finalField)
00290 {
00291 ValidityTag::Pointer smpVal = this->GetMediaValidityTag(mediaID,pComponentCache);
00292 ValidityTag::Pointer smpValReq = this->GetMediaValidityTagRequirement(mediaID,pComponentCache);
00293
00294 bool bKeep = true;
00295 SessionAccessor::GetParameterValue(pComponentCache,cParam_PersistentFinalField,bKeep);
00296
00297 if (smpVal->IsOutdated(smpValReq) || (!bKeep))
00298 {
00299 this->NotifyProgress(1,"Final field outdated -> actualize",pComponentCache);
00300
00301 StatisticEntry* pRegistrationFieldEntry = Superclass::AddStatisticEntry(pComponentCache, pSessionInfo, "ComputeDeformationField", "Computation of a deformation field");
00302
00303 try
00304 {
00305 ComponentMediaLink::Pointer smpLink = pComponentCache->Setup()->MediaLinks().GetElement(MediaID_fieldReference);
00306 if (smpLink.IsNull())
00307 {
00308 smpMedia = pComponent->GetTransformationField();
00309 }
00310 else
00311 {
00312 GenericMediaPointer smpFieldRef = SessionAccessor::GetMedia(smpLink->GetSourceIDPath(), pSessionInfo);
00313
00314 typedef typename ComponentType::ImageType::Superclass ComponentImageBaseType;
00315 ComponentImageBaseType* pFieldRef = dynamic_cast<ComponentImageBaseType*>(smpFieldRef.GetPointer());
00316 if (!pFieldRef) throwCtrlExceptionMacro("","Error. Link for field reference found, but field seems to have wrong type.");
00317
00318 smpMedia = pComponent->GetTransformationField(pFieldRef->GetOrigin(),pFieldRef->GetLargestPossibleRegion(),pFieldRef->GetSpacing());
00319 }
00320 }
00321 catchAllNPassMacro("Unkown error while computing transormation field.");
00322
00323 if (pRegistrationFieldEntry) pRegistrationFieldEntry->CloseEntry();
00324
00325 if (bKeep) DirectSessionComponentAccessor::SetRepositoryElement(mediaID,smpMedia,pComponentCache);
00326 this->ActualizeMediaValidityTag(mediaID,pComponentCache);
00327 }
00328 else
00329 {
00330 smpMedia = DirectSessionComponentAccessor::GetRepositoryElement(mediaID,pComponentCache);
00331 }
00332 }
00333 else
00334 {
00335 try
00336 {
00337 TransformFunctionAccessor<typename ComponentType::TransformType> transformFunctionAccessor(*pComponentCache,IDPath(cIDPSelf+IDPath(cComp_MainTransform)));
00338
00339 typename ComponentType::TransformParametersType currentParameter = pComponent->GetCurrentTransformParameters();
00340
00341 ComponentMediaLink::Pointer smpLink = pComponentCache->Setup()->MediaLinks().GetElement(MediaID_fieldReference);
00342
00343 if (smpLink.IsNull())
00344 {
00345 if (mediaID == MediaID_finalTransform)
00346 {
00347 smpMedia = transformFunctionAccessor.GetTransformationFunction(currentParameter);
00348 }
00349 else
00350 {
00351 smpMedia = transformFunctionAccessor.GetInverseTransformationFunction(currentParameter);
00352 }
00353 }
00354 else
00355 {
00356 GenericMediaPointer smpFieldRef = SessionAccessor::GetMedia(smpLink->GetSourceIDPath(), pSessionInfo);
00357
00358 typedef typename ComponentType::ImageType::Superclass ComponentImageBaseType;
00359 ComponentImageBaseType* pFieldRef = dynamic_cast<ComponentImageBaseType*>(smpFieldRef.GetPointer());
00360 if (!pFieldRef) throwCtrlExceptionMacro("","Error. Link for field reference found, but field seems to have wrong type.");
00361
00362 if (mediaID == MediaID_finalTransform)
00363 {
00364 smpMedia = transformFunctionAccessor.GetTransformationFunction(currentParameter,pFieldRef->GetOrigin(),pFieldRef->GetLargestPossibleRegion(),pFieldRef->GetSpacing());
00365 }
00366 else
00367 {
00368 smpMedia = transformFunctionAccessor.GetInverseTransformationFunction(currentParameter,pFieldRef->GetOrigin(),pFieldRef->GetLargestPossibleRegion(),pFieldRef->GetSpacing());
00369 }
00370 }
00371 }
00372 catchAllNPassMacro("Unkown error while computing transormation function.");
00373
00374 this->ActualizeMediaValidityTag(mediaID,pComponentCache);
00375 }
00376
00377 return smpMedia;
00378 }
00379
00380 return Superclass::GetMediaCasted(mediaID, pComponent, pComponentCache, pSessionInfo);
00381 };
00382
00383 template <class ComponentType>
00384 void
00385 RigidRegistrationControllerBase<ComponentType>::
00386 ResetSubComponents(SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo) const
00387 {
00388 if (!pComponentCache) throwCtrlExceptionMacro("","Error while resetting sub components; invalid parent component cache (null pointer).");
00389 if (!pSessionInfo) throwCtrlExceptionMacro("","Error while resetting sub components; invalid session info (null pointer).");
00390
00391
00392
00393 try
00394 {
00395 SessionComponentCache* pMetricCache = pComponentCache->SubCaches().GetElement(cComp_MainMetric);
00396 if (pMetricCache->ControllerIsAssigned())
00397 {
00398 pMetricCache->Controller()->ResetComponent(pMetricCache,pSessionInfo);
00399 SetSubComponent(pComponentCache,pMetricCache->Component(),cComp_MainMetric);
00400 }
00401 }
00402 catchAllNPassMacro("Error while resetting metric.");
00403
00404 try
00405 {
00406 SessionComponentCache* pOptCache = pComponentCache->SubCaches().GetElement(cComp_MainOptimizer);
00407 if (pOptCache->ControllerIsAssigned())
00408 {
00409 pOptCache->Controller()->ResetComponent(pOptCache,pSessionInfo);
00410 SetSubComponent(pComponentCache,pOptCache->Component(),cComp_MainOptimizer);
00411 }
00412 }
00413 catchAllNPassMacro("Error while resetting optimizer.");
00414 };
00415
00416 template <class ComponentType>
00417 void
00418 RigidRegistrationControllerBase<ComponentType>::
00419 ResetMainComponent(SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo) const
00420 {
00422 };
00423
00424 template <class ComponentType>
00425 void
00426 RigidRegistrationControllerBase<ComponentType>::
00427 SetMediaCasted(const MediaID& mediaID, GenericMediaType* pMedia, ComponentType* pComponent, SessionComponentCache* pComponentCache,
00428 SessionInfo* pSessionInfo) const
00429 {
00430 if (mediaID == MediaID_fieldReference)
00431 {
00432
00433 }
00434 else Superclass::SetMediaCasted(mediaID, pMedia, pComponent, pComponentCache, pSessionInfo);
00435 };
00436
00437 template <class ComponentType>
00438 Parameter::Pointer
00439 RigidRegistrationControllerBase<ComponentType>::
00440 GetParameter(const SessionComponentCache* pComponentCache,
00441 const std::string& sParameterName) const
00442 {
00443 if (sParameterName == Self::cParam_MinimizeToOptimize)
00444 {
00445 Parameter::Pointer smpParam = Parameter::New(sParameterName);
00446 smpParam->SetParameterValue(this->GetMinimizeToOptimize(pComponentCache));
00447 return smpParam;
00448 }
00449
00450 return Superclass::GetParameter(pComponentCache,sParameterName);
00451 };
00452
00453 template <class ComponentType>
00454 bool
00455 RigidRegistrationControllerBase<ComponentType>::
00456 GetMinimizeToOptimize(const SessionComponentCache* pComponentCache) const
00457 {
00458 if (pComponentCache == 0) throwCtrlExceptionMacro("","Error cannot determine optimization direction, passed pComponentCache is null.");
00459
00460 const SessionComponentCache* pMetricCache = pComponentCache->GetConstCacheByIDPath(IDPath(cComp_MainMetric));
00461 if (pMetricCache == 0) throwCtrlExceptionMacro("","Error cannot determine optimization direction, subcomponent MainMetric does not exist. Ensure proper initialization of the session.");
00462
00463 if (!pMetricCache->ControllerIsAssigned()) throwCtrlExceptionMacro("","Error cannot determine optimization direction, pointer to metric controller is null. Ensure proper initialization of the session.");
00464
00465 Parameter::Pointer smpParam = pMetricCache->Controller()->GetParameter(pMetricCache, cParam_MetricMinimize);
00466
00467 if (smpParam.IsNull()) throwCtrlExceptionMacro("","Error cannot determine optimization direction, subcomponent MainMetric don't know the recommended parameter \"Minimize\". Ensure proper initialization of the session.");
00468
00469 bool bMinimize = true;
00470 smpParam->GetParameterValue(bMinimize);
00471
00472 return bMinimize;
00473 };
00474
00475 }
00476
00477 #endif