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