Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkStatisticsCalculator.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 // semantic relations UI module
15 
16 // semantic relations module
17 #include <mitkNodePredicates.h>
18 #include <mitkRelationStorage.h>
22 
23 // mitk image statistics module
28 
30  : m_CalculationJob(nullptr)
31  , m_DataStorage(nullptr)
32  , m_MaskVolume(0.0)
33 {
34  m_CalculationJob = new QmitkImageStatisticsCalculationJob();
35 
36  connect(m_CalculationJob, &QmitkImageStatisticsCalculationJob::finished, this,
37  &QmitkStatisticsCalculator::OnStatisticsCalculationEnds, Qt::QueuedConnection);
38 }
39 
41 {
42  if (!m_CalculationJob->isFinished())
43  {
44  m_CalculationJob->terminate();
45  m_CalculationJob->wait();
46  }
47  m_CalculationJob->deleteLater();
48 }
49 
51 {
52  if (m_DataStorage.IsExpired())
53  {
54  return;
55  }
56 
57  auto dataStorage = m_DataStorage.Lock();
58 
59  std::vector<double> lesionVolume;
60  mitk::SemanticTypes::Lesion lesion = lesionData.GetLesion();
61  double volume = 0.0;
62 
64  // sort the vector of control points for the timeline
65  std::sort(controlPoints.begin(), controlPoints.end());
67  for (const auto& informationType : informationTypes)
68  {
69  for (const auto& controlPoint : controlPoints)
70  {
71  mitk::SemanticRelationsDataStorageAccess semanticRelationsDataStorageAccess(dataStorage);
72  mitk::DataNode::Pointer specificImage;
73  mitk::DataNode::Pointer specificSegmentation;
74  try
75  {
76  specificSegmentation = semanticRelationsDataStorageAccess.GetSpecificSegmentation(caseID, controlPoint, informationType, lesion);
77  if (nullptr == specificSegmentation)
78  {
79  volume = 0.0;
80  }
81  else
82  {
83  // get parent node of the specific segmentation node with the node predicate
84  auto parentNodes = dataStorage->GetSources(specificSegmentation, mitk::NodePredicates::GetImagePredicate(), false);
85  for (auto it = parentNodes->Begin(); it != parentNodes->End(); ++it)
86  {
87  specificImage = it->Value();
88  }
89 
90  volume = GetSegmentationMaskVolume(specificImage, specificSegmentation);
91  }
92  }
94  {
95  volume = 0.0;
96  }
97 
98  lesionVolume.push_back(volume);
99  }
100  }
101 
102  lesionData.SetLesionVolume(lesionVolume);
103 }
104 
105 double QmitkStatisticsCalculator::GetSegmentationMaskVolume(mitk::DataNode::Pointer imageNode, mitk::DataNode::Pointer segmentationNode)
106 {
107  m_MaskVolume = 0.0;
108 
109  if (m_DataStorage.IsExpired())
110  {
111  return m_MaskVolume;
112  }
113 
114  auto dataStorage = m_DataStorage.Lock();
115 
116  if (imageNode.IsNull() || segmentationNode.IsNull())
117  {
118  return m_MaskVolume;
119  }
120 
121  m_ImageNode = imageNode;
122  m_SegmentationNode = segmentationNode;
123 
124  auto image = dynamic_cast<mitk::Image*>(m_ImageNode->GetData());
125  auto segmentation = dynamic_cast<mitk::Image*>(m_SegmentationNode->GetData());
126  if (nullptr == image || nullptr == segmentation)
127  {
128  return m_MaskVolume;
129  }
130 
131  // all nodes and images are valid, retrieve statistics
133 
134  bool imageStatisticsOlderThanInputs = false;
135  if (imageStatistics && (imageStatistics->GetMTime() < image->GetMTime() || (imageStatistics->GetMTime() < segmentation->GetMTime())))
136  {
137  imageStatisticsOlderThanInputs = true;
138  }
139  // statistics need to be (re)computed
140  if (!imageStatistics || imageStatisticsOlderThanInputs)
141  {
142  m_CalculationJob->Initialize(image, segmentation, nullptr);
143  try
144  {
145  m_CalculationJob->start();
146  return m_MaskVolume;
147  }
148  catch (const std::exception&)
149  {
150  return m_MaskVolume;
151  }
152  }
153 
154  // use a valid statistics object to get the volume of the image-segmentation pair
156  try
157  {
158  statisticsObject = imageStatistics->GetStatisticsForTimeStep(0);
159  }
160  catch (mitk::Exception&)
161  {
162  return m_MaskVolume;
163  }
164  try
165  {
167  {
168  auto valueVariant = statisticsObject.GetValueNonConverted(mitk::ImageStatisticsConstants::VOLUME());
169  m_MaskVolume = boost::get<double>(valueVariant);
170  }
171  }
172  catch (mitk::Exception&)
173  {
174  return m_MaskVolume;
175  }
176 
177  return m_MaskVolume;
178 }
179 
180 void QmitkStatisticsCalculator::OnStatisticsCalculationEnds()
181 {
182  // taken from 'QmitkImageStatisticsView' (see measurementtoolbox plugin)
183  if (m_DataStorage.IsExpired())
184  {
185  return;
186  }
187 
188  auto dataStorage = m_DataStorage.Lock();
189 
190  if (m_CalculationJob->GetStatisticsUpdateSuccessFlag())
191  {
192  auto statistic = m_CalculationJob->GetStatisticsData();
193  auto image = m_CalculationJob->GetStatisticsImage();
195  auto imageRule = mitk::StatisticsToImageRelationRule::New();
196  imageRule->Connect(statistic, image);
197 
198  if (m_CalculationJob->GetMaskImage())
199  {
200  auto maskRule = mitk::StatisticsToMaskRelationRule::New();
201  mask = m_CalculationJob->GetMaskImage();
202  maskRule->Connect(statistic, mask);
203  }
204 
205  auto imageStatistics = mitk::ImageStatisticsContainerManager::GetImageStatistics(dataStorage, image, mask);
206 
207  // if statistics base data already exist: add to existing node
208  if (nullptr != imageStatistics)
209  {
210  auto allDataNodes = dataStorage->GetAll()->CastToSTLConstContainer();
211  for (auto node : allDataNodes)
212  {
213  auto nodeData = node->GetData();
214  if (nullptr != nodeData && nodeData->GetUID() == imageStatistics->GetUID())
215  {
216  node->SetData(statistic);
217  }
218  }
219  }
220  // statistics base data does not exist: add new node
221  else
222  {
223  auto statisticsNodeName = m_ImageNode->GetName();
224  if (m_SegmentationNode)
225  {
226  statisticsNodeName += "_" + m_SegmentationNode->GetName();
227  }
228  statisticsNodeName += "_statistics";
229  auto statisticsNode = mitk::CreateImageStatisticsNode(statistic, statisticsNodeName);
230  dataStorage->Add(statisticsNode);
231  }
232  }
233 }
itk::SmartPointer< T > Lock() const
void ComputeLesionVolume(mitk::LesionData &lesionData, const mitk::SemanticTypes::CaseID &caseID)
Compute and store lesion volume for all available control points and information types.
DataNode::Pointer GetSpecificSegmentation(const SemanticTypes::CaseID &caseID, const SemanticTypes::ControlPoint &controlPoint, const SemanticTypes::InformationType &informationType, const SemanticTypes::Lesion &lesion) const
Return the single segmentation node that is defined with the given information type, the given control point and is representing the given lesion. The function uses the &#39;GetAllSpecificSegmentations&#39;-function to retrieve the specific segmentations and then checks for the represented lesion.
MITKSEMANTICRELATIONS_EXPORT NodePredicateAnd::Pointer GetImagePredicate()
DataNode::Pointer CreateImageStatisticsNode(ImageStatisticsContainer::Pointer statistic, const std::string &name)
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::InformationTypeVector GetAllInformationTypesOfCase(const SemanticTypes::CaseID &caseID)
SemanticTypes::Lesion GetLesion() const
static mitk::ImageStatisticsContainer::ConstPointer GetImageStatistics(const mitk::DataStorage *dataStorage, const mitk::BaseData *image, const mitk::BaseData *mask=nullptr)
Returns the StatisticContainer for the given image and mask.
mitk::ImageStatisticsContainer * GetStatisticsData() const
std::vector< ControlPoint > ControlPointVector
mitk::DataStorage::Pointer m_DataStorage
An object of this class represents an exception of MITK. Please don&#39;t instantiate exceptions manually...
Definition: mitkException.h:45
bool IsExpired() const noexcept
Image class for storing images.
Definition: mitkImage.h:72
This class holds the data of each lesion in the lesion tree view. The data is the lesion itself with ...
void Initialize(const mitk::Image *image, const mitk::Image *binaryImage, const mitk::PlanarFigure *planarFig)
mitk::Image::Pointer image
void SetLesionVolume(const std::vector< double > &lesionVolume)
The API provides functions to query and manipulate image relations and instances, that are helpful du...
std::vector< InformationType > InformationTypeVector
mitk::Image::Pointer mask
Container class for storing the computed image statistics.
StatisticsVariantType GetValueNonConverted(const std::string &name) const
Returns the requested value.
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPointVector GetAllControlPointsOfCase(const SemanticTypes::CaseID &caseID)