/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkLevelSetEquationTermContainer_hxx #define itkLevelSetEquationTermContainer_hxx #include "itkMath.h" #include "itkLevelSetEquationTermContainer.h" #include "itkObject.h" namespace itk { // ---------------------------------------------------------------------------- template LevelSetEquationTermContainer::LevelSetEquationTermContainer() { this->m_CurrentLevelSetId = LevelSetIdentifierType(); } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::Iterator LevelSetEquationTermContainer::Begin() { return Iterator(this->m_Container.begin()); } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::Iterator LevelSetEquationTermContainer::End() { return Iterator(this->m_Container.end()); } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::ConstIterator LevelSetEquationTermContainer::Begin() const { return ConstIterator(this->m_Container.begin()); } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::ConstIterator LevelSetEquationTermContainer::End() const { return ConstIterator(this->m_Container.end()); } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::AddTerm(const TermIdType & iId, TermType * iTerm) { if (iTerm) { if (!iTerm->GetInput()) { if (m_Input.IsNotNull()) { iTerm->SetInput(m_Input); } else { itkGenericExceptionMacro(<< "m_Input and iTerm->GetInput are nullptr"); } } iTerm->SetCurrentLevelSetId(this->m_CurrentLevelSetId); if (this->m_LevelSetContainer.IsNotNull()) { iTerm->SetLevelSetContainer(this->m_LevelSetContainer); } else { if (!iTerm->GetLevelSetContainer()) { itkGenericExceptionMacro(<< "m_LevelSetContainer and iTerm->GetLevelSetContainer() are nullptr"); } } m_Container[iId] = iTerm; m_TermContribution[iId] = NumericTraits::ZeroValue(); m_NameContainer[iTerm->GetTermName()] = iTerm; RequiredDataType termRequiredData = iTerm->GetRequiredData(); typename RequiredDataType::const_iterator dIt = termRequiredData.begin(); typename RequiredDataType::const_iterator dEnd = termRequiredData.end(); while (dIt != dEnd) { m_RequiredData.insert(*dIt); ++dIt; } this->Modified(); } else { itkGenericExceptionMacro(<< "Term supplied is null"); } } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::PushTerm(TermType * iTerm) { if (iTerm) { if (!iTerm->GetInput()) { if (m_Input.IsNotNull()) { iTerm->SetInput(m_Input); } else { itkGenericExceptionMacro(<< "m_Input and iTerm->GetInput are nullptr"); } } iTerm->SetCurrentLevelSetId(this->m_CurrentLevelSetId); if (this->m_LevelSetContainer.isNotNull()) { iTerm->SetLevelSetContainer(this->m_LevelSetContainer); } else { if (!iTerm->GetLevelSetContainer()) { itkGenericExceptionMacro(<< "m_LevelSetContainer and iTerm->GetLevelSetContainer() are nullptr"); } } TermIdType id = (m_Container.rbegin())->first; ++id; m_Container[id] = iTerm; m_TermContribution[id] = NumericTraits::ZeroValue(); m_NameContainer[iTerm->GetTermName()] = iTerm; RequiredDataType termRequiredData = iTerm->GetRequiredData(); typename RequiredDataType::const_iterator dIt = termRequiredData.begin(); typename RequiredDataType::const_iterator dEnd = termRequiredData.end(); while (dIt != dEnd) { m_RequiredData.insert(*dIt); ++dIt; } this->Modified(); } else { itkGenericExceptionMacro(<< "Term supplied is null"); } } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::TermType * LevelSetEquationTermContainer::GetTerm(const std::string & iName) { MapTermContainerIteratorType it = m_Container.find(iName); if (it == m_Container.end()) { itkGenericExceptionMacro(<< "the term " << iName.c_str() << " is not present in the container"); } return it->second; } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::TermType * LevelSetEquationTermContainer::GetTerm(const TermIdType & iId) { auto it = m_Container.find(iId); if (it == m_Container.end()) { itkGenericExceptionMacro(<< "the term " << iId << " is not present in the container"); } return it->second; } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::Initialize(const LevelSetInputIndexType & iP) { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); while (term_it != term_end) { (term_it->second)->Initialize(iP); ++term_it; } } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::UpdatePixel(const LevelSetInputIndexType & iP, const LevelSetOutputRealType & oldValue, const LevelSetOutputRealType & newValue) { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); while (term_it != term_end) { (term_it->second)->UpdatePixel(iP, oldValue, newValue); ++term_it; } } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::InitializeParameters() { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); while (term_it != term_end) { (term_it->second)->InitializeParameters(); ++term_it; } } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::LevelSetOutputRealType LevelSetEquationTermContainer::Evaluate(const LevelSetInputIndexType & iP) { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); auto cfl_it = m_TermContribution.begin(); LevelSetOutputRealType oValue = NumericTraits::ZeroValue(); while (term_it != term_end) { LevelSetOutputRealType temp_val = (term_it->second)->Evaluate(iP); cfl_it->second = std::max(itk::Math::abs(temp_val), cfl_it->second); oValue += temp_val; ++term_it; ++cfl_it; } return oValue; } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::LevelSetOutputRealType LevelSetEquationTermContainer::Evaluate(const LevelSetInputIndexType & iP, const LevelSetDataType & iData) { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); auto cfl_it = m_TermContribution.begin(); LevelSetOutputRealType oValue = NumericTraits::ZeroValue(); while (term_it != term_end) { LevelSetOutputRealType temp_val = (term_it->second)->Evaluate(iP, iData); cfl_it->second = std::max(itk::Math::abs(temp_val), cfl_it->second); oValue += temp_val; ++term_it; ++cfl_it; } return oValue; } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::Update() { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); auto cfl_it = m_TermContribution.begin(); while (term_it != term_end) { (term_it->second)->Update(); (cfl_it->second) = NumericTraits::ZeroValue(); ++term_it; ++cfl_it; } } // ---------------------------------------------------------------------------- template typename LevelSetEquationTermContainer::LevelSetOutputRealType LevelSetEquationTermContainer::ComputeCFLContribution() const { auto term_it = m_Container.begin(); auto term_end = m_Container.end(); auto cfl_it = m_TermContribution.begin(); LevelSetOutputRealType oValue = NumericTraits::ZeroValue(); while (term_it != term_end) { LevelSetOutputRealType cfl = (term_it->second)->GetCFLContribution(); if (Math::AlmostEquals(cfl, NumericTraits::ZeroValue())) { cfl = (cfl_it->second); } oValue += cfl; ++term_it; ++cfl_it; } return oValue; } // ---------------------------------------------------------------------------- template void LevelSetEquationTermContainer::ComputeRequiredData(const LevelSetInputIndexType & iP, LevelSetDataType & ioData) { typename RequiredDataType::const_iterator dIt = m_RequiredData.begin(); typename RequiredDataType::const_iterator dEnd = m_RequiredData.end(); auto tIt = m_Container.begin(); LevelSetPointer levelset = (tIt->second)->GetModifiableCurrentLevelSetPointer(); while (dIt != dEnd) { if (*dIt == "Value") { levelset->Evaluate(iP, ioData); } if (*dIt == "Gradient") { levelset->EvaluateGradient(iP, ioData); } if (*dIt == "Hessian") { levelset->EvaluateHessian(iP, ioData); } if (*dIt == "Laplacian") { levelset->EvaluateLaplacian(iP, ioData); } if (*dIt == "GradientNorm") { levelset->EvaluateGradientNorm(iP, ioData); } if (*dIt == "MeanCurvature") { levelset->EvaluateMeanCurvature(iP, ioData); } if (*dIt == "ForwardGradient") { levelset->EvaluateForwardGradient(iP, ioData); } if (*dIt == "BackwardGradient") { levelset->EvaluateBackwardGradient(iP, ioData); } // here add new characteristics ++dIt; } } } // namespace itk #endif // itkLevelSetEquationTermContainer_hxx