diff --git a/Modules/ImageStatistics/mitkImageStatisticsContainerManager.cpp b/Modules/ImageStatistics/mitkImageStatisticsContainerManager.cpp index 087b38fd99..30aafaa124 100644 --- a/Modules/ImageStatistics/mitkImageStatisticsContainerManager.cpp +++ b/Modules/ImageStatistics/mitkImageStatisticsContainerManager.cpp @@ -1,166 +1,160 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkImageStatisticsContainerManager.h" #include "mitkNodePredicateAnd.h" #include "mitkNodePredicateOr.h" -#include "mitkNodePredicateNot.h" #include "mitkNodePredicateDataType.h" mitk::ImageStatisticsContainerManager::ImageStatisticsContainerManager() { } void mitk::ImageStatisticsContainerManager::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { if (!dataStorage) { mitkThrow() << "dataStorage is nullptr"; } m_DataStorage = dataStorage; } void mitk::ImageStatisticsContainerManager::SetRules(const std::vector& rules) { m_ImageStatisticRules = rules; } mitk::StatisticsContainer::ConstPointer mitk::ImageStatisticsContainerManager::GetImageStatistics(mitk::BaseData::ConstPointer image, mitk::BaseData::ConstPointer mask) const { if (m_ImageStatisticRules.empty()) { return nullptr; } if (!m_DataStorage) { mitkThrow() << "data storage is nullptr!"; } mitk::NodePredicateBase::ConstPointer allPredicates = nullptr; for (const auto& imageStatisticOneRule : m_ImageStatisticRules) { auto currentPredicate = GetPredicateForSources(imageStatisticOneRule, image, mask); if (currentPredicate) { if (!allPredicates) { allPredicates = currentPredicate; } else { allPredicates = mitk::NodePredicateOr::New(allPredicates, currentPredicate); } } } if (allPredicates) { auto nodePredicateImageStatisticsContainer = mitk::NodePredicateDataType::New("StatisticsContainer"); allPredicates = mitk::NodePredicateAnd::New(allPredicates, nodePredicateImageStatisticsContainer); - auto nodes = m_DataStorage->GetSubset(allPredicates); - - if (!mask) { - auto filteredNodes = mitk::DataStorage::SetOfObjects::New(); - for (const auto& node : *nodes) { + auto statisticContainerCandidateNodes = m_DataStorage->GetSubset(allPredicates); + mitk::DataStorage::SetOfObjects::Pointer statisticContainerCandidateNodesFiltered; + + statisticContainerCandidateNodesFiltered = mitk::DataStorage::SetOfObjects::New(); + for (const auto& node : *statisticContainerCandidateNodes) { auto nodeData = node->GetData(); bool ok = true; - if (nodeData) { - for (const auto& imageStatisticOneRule : m_ImageStatisticRules) { - for (const auto& aRule : imageStatisticOneRule) { - if (aRule->GetRuleID() == "IDRelation_statisticsToMask") { - auto isSource = aRule->IsSource(nodeData); - if (isSource) { - ok = false; + //special case: we are looking for statistics --> image but might have statistics --> image AND statistics --> mask rule + if (!mask) { + if (nodeData) { + for (const auto& imageStatisticOneRule : m_ImageStatisticRules) { + for (const auto& aRule : imageStatisticOneRule) { + if (aRule->GetRuleID() == "IDRelation_statisticsToMask") { + auto isSource = aRule->IsSource(nodeData); + if (isSource) { + ok = false; + } } } } } } + if (ok) { - filteredNodes->push_back(node); + statisticContainerCandidateNodesFiltered->push_back(node); } } - if (filteredNodes->empty()) { - return nullptr; - } - if (filteredNodes->size() > 1) { - MITK_WARN << "multiple statistics (" << filteredNodes->size() << ") for image/mask found. Returning only first one."; - } - return dynamic_cast(filteredNodes->front()->GetData()); - } - else { - if (nodes->empty()) { + if (statisticContainerCandidateNodesFiltered->empty()) { return nullptr; } - if (nodes->size() > 1) { - MITK_WARN << "multiple statistics (" << nodes->size() << ") for image/mask found. Returning only first one."; - for (const auto& node : *nodes) { - MITK_WARN << node->GetName(); - } + if (statisticContainerCandidateNodesFiltered->size() > 1) { + //in case of multiple found statistics, return only newest one + std::sort(statisticContainerCandidateNodesFiltered->begin(), statisticContainerCandidateNodesFiltered->end(), [](mitk::DataNode::Pointer a, mitk::DataNode::Pointer b) { + return a->GetMTime() > b->GetMTime(); + }); + MITK_WARN << "multiple statistics (" << statisticContainerCandidateNodesFiltered->size() << ") for image/mask found. Returning only newest one."; } - return dynamic_cast(nodes->front()->GetData()); - } + return dynamic_cast(statisticContainerCandidateNodesFiltered->front()->GetData()); } else { return nullptr; } } mitk::NodePredicateBase::ConstPointer mitk::ImageStatisticsContainerManager::GetPredicateForSources(const mitk::PropertyRelations::RuleResultVectorType& rules, mitk::BaseData::ConstPointer image, mitk::BaseData::ConstPointer mask) const { if (image.IsNull()) { mitkThrow() << "Image is nullptr"; } if (rules.empty()) { return nullptr; } //only image as input, but !=1 rules: can't find any imageStatistic object if (!mask && rules.size() != 1) { return nullptr; } //image+(mask || planarFigure) as input, but !=2 rules: can't find any imageStatistic object if ((mask) && rules.size() != 2) { return nullptr; } mitk::NodePredicateBase::ConstPointer statisticsFromImageAndMaskAndPlanarFigure = nullptr; for (const auto& rule : rules) { //choose correct rule for image, mask or planarFigure if (rule->GetRuleID() == "IDRelation_statisticsToImage") { auto statisticsFromImagePredicate = rule->GetSourcesDetector(image); if (!statisticsFromImageAndMaskAndPlanarFigure) { statisticsFromImageAndMaskAndPlanarFigure = statisticsFromImagePredicate; } else { statisticsFromImageAndMaskAndPlanarFigure = mitk::NodePredicateAnd::New(statisticsFromImagePredicate, statisticsFromImageAndMaskAndPlanarFigure); } } else if (mask && rule->GetRuleID() == "IDRelation_statisticsToMask") { auto statisticsFromMaskPredicate = rule->GetSourcesDetector(mask); if (!statisticsFromImageAndMaskAndPlanarFigure) { statisticsFromImageAndMaskAndPlanarFigure = statisticsFromMaskPredicate; } else { statisticsFromImageAndMaskAndPlanarFigure = mitk::NodePredicateAnd::New(statisticsFromMaskPredicate, statisticsFromImageAndMaskAndPlanarFigure); } } else { return nullptr; } } return statisticsFromImageAndMaskAndPlanarFigure; }