Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
mitkSemanticRelationsDataStorageAccess.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 
14 
15 // semantic relations module
17 #include "mitkDICOMHelper.h"
18 #include "mitkNodePredicates.h"
19 #include "mitkRelationStorage.h"
22 
23 // c++
24 #include <iterator>
25 #include <algorithm>
26 
28  : m_DataStorage(dataStorage)
29 {
30  // nothing here
31 }
32 
33 /************************************************************************/
34 /* functions to get instances / attributes */
35 /************************************************************************/
36 
38 {
39  if (m_DataStorage.IsExpired())
40  {
41  mitkThrowException(SemanticRelationException) << "Not a valid data storage.";
42  }
43 
45  DataNodeVector allSegmentationsOfCase;
46  // get all segmentation nodes of the current data storage
47  // only those nodes are respected, that are currently held in the data storage
48  DataStorage::SetOfObjects::ConstPointer segmentationNodes = m_DataStorage.Lock()->GetSubset(NodePredicates::GetSegmentationPredicate());
49  for (auto it = segmentationNodes->Begin(); it != segmentationNodes->End(); ++it)
50  {
51  DataNode* segmentationNode = it->Value();
52 
53  SemanticTypes::CaseID currentCaseID;
54  SemanticTypes::ID segmentationID;
55  try
56  {
57  // find the corresponding segmentation node for the given segmentation ID
58  currentCaseID = GetCaseIDFromDataNode(segmentationNode);
59  segmentationID = GetIDFromDataNode(segmentationNode);
60  }
62  {
63  // found a segmentation node that is not stored in the semantic relations
64  // this segmentation node does not have any DICOM information --> exception thrown
65  // continue with the next segmentation to compare IDs
66  continue;
67  }
68 
69  if (caseID == currentCaseID && (std::find(allSegmentationIDsOfCase.begin(), allSegmentationIDsOfCase.end(), segmentationID) != allSegmentationIDsOfCase.end()))
70  {
71  // found current image node in the storage, add it to the return vector
72  allSegmentationsOfCase.push_back(segmentationNode);
73  }
74  }
75 
76  return allSegmentationsOfCase;
77 }
78 
80 {
82  {
83  // lesion exists, retrieve all case segmentations from the storage
84  DataNodeVector allSegmentationsOfLesion = GetAllSegmentationsOfCase(caseID);
85 
86  // filter all segmentations: check for semantic relation with the given lesion using a lambda function
87  auto lambda = [&lesion](DataNode::Pointer segmentation)
88  {
89  try
90  {
92  return lesion.UID != representedLesion.UID;
93  }
94  catch (const SemanticRelationException&)
95  {
96  return true;
97  }
98  };
99  allSegmentationsOfLesion.erase(std::remove_if(allSegmentationsOfLesion.begin(), allSegmentationsOfLesion.end(), lambda), allSegmentationsOfLesion.end());
100 
101  return allSegmentationsOfLesion;
102  }
103  else
104  {
105  mitkThrowException(SemanticRelationException) << "Could not find an existing lesion instance for the given caseID " << caseID << " and lesion " << lesion.UID << ".";
106  }
107 }
108 
110 {
111  if (m_DataStorage.IsExpired())
112  {
113  mitkThrowException(SemanticRelationException) << "Not a valid data storage.";
114  }
115 
117  DataNodeVector allImagesOfCase;
118  // get all image nodes of the current data storage
119  // only those nodes are respected, that are currently held in the data storage
120  DataStorage::SetOfObjects::ConstPointer imageNodes = m_DataStorage.Lock()->GetSubset(NodePredicates::GetImagePredicate());
121  for (auto it = imageNodes->Begin(); it != imageNodes->End(); ++it)
122  {
123  DataNode* imageNode = it->Value();
124 
125  SemanticTypes::CaseID currentCaseID;
126  SemanticTypes::ID imageID;
127  try
128  {
129  // find the corresponding image node for the given segmentation ID
130  currentCaseID = GetCaseIDFromDataNode(imageNode);
131  imageID = GetIDFromDataNode(imageNode);
132  }
134  {
135  // found an image node that is not stored in the semantic relations
136  // this image node does not have any DICOM information --> exception thrown
137  // continue with the next image to compare IDs
138  continue;
139  }
140 
141  if (caseID == currentCaseID && (std::find(allImageIDsOfCase.begin(), allImageIDsOfCase.end(), imageID) != allImageIDsOfCase.end()))
142  {
143  // found current image node in the storage, add it to the return vector
144  allImagesOfCase.push_back(imageNode);
145  }
146  }
147 
148  return allImagesOfCase;
149 }
150 
152 {
153  if (m_DataStorage.IsExpired())
154  {
155  mitkThrowException(SemanticRelationException) << "Not a valid data storage.";
156  }
157 
158  DataNodeVector allImagesOfCase;
159  // get all image nodes of the current data storage
160  // only those nodes are respected, that are currently held in the data storage
161  DataStorage::SetOfObjects::ConstPointer imageNodes = m_DataStorage.Lock()->GetSubset(NodePredicates::GetImagePredicate());
162  for (auto it = imageNodes->Begin(); it != imageNodes->End(); ++it)
163  {
164  DataNode* imageNode = it->Value();
165 
166  SemanticTypes::CaseID currentCaseID;
167  SemanticTypes::ID imageID;
168  try
169  {
170  // find the corresponding image node for the given segmentation ID
171  imageID = GetIDFromDataNode(imageNode);
172  }
174  {
175  // found an image node that is not stored in the semantic relations
176  // this image node does not have any DICOM information --> exception thrown
177  // continue with the next image to compare IDs
178  continue;
179  }
180 
181  if (std::find(imageIDs.begin(), imageIDs.end(), imageID) != imageIDs.end())
182  {
183  // found current image node in the storage, add it to the return vector
184  allImagesOfCase.push_back(imageNode);
185  }
186  }
187 
188  return allImagesOfCase;
189 }
190 
192 {
193  if (m_DataStorage.IsExpired())
194  {
195  mitkThrowException(SemanticRelationException) << "Not a valid data storage.";
196  }
197 
198  DataNodeVector allImagesOfLesion;
199  // 1. get all segmentations that define the lesion
200  // 2. retrieve the parent node (source) of the found segmentation node
201  DataNodeVector allSegmentationsOfLesion = GetAllSegmentationsOfLesion(caseID, lesion);
202  for (const auto& segmentationNode : allSegmentationsOfLesion)
203  {
204  // get parent node of the current segmentation node with the node predicate
205  DataStorage::SetOfObjects::ConstPointer parentNodes = m_DataStorage.Lock()->GetSources(segmentationNode, NodePredicates::GetImagePredicate(), false);
206  for (auto it = parentNodes->Begin(); it != parentNodes->End(); ++it)
207  {
208  DataNode::Pointer dataNode = it->Value();
209  allImagesOfLesion.push_back(it->Value());
210  }
211  }
212 
213  std::sort(allImagesOfLesion.begin(), allImagesOfLesion.end());
214  allImagesOfLesion.erase(std::unique(allImagesOfLesion.begin(), allImagesOfLesion.end()), allImagesOfLesion.end());
215  return allImagesOfLesion;
216 }
217 
219 {
220  if (SemanticRelationsInference::InstanceExists(caseID, controlPoint))
221  {
222  if (SemanticRelationsInference::InstanceExists(caseID, informationType))
223  {
224  // control point exists, information type exists, retrieve all images from the storage
225  DataNodeVector allImagesOfCase = GetAllImagesOfCase(caseID);
226  // filter all images to remove the ones with a different control point and information type using a lambda function
227  auto lambda = [&controlPoint, &informationType](DataNode::Pointer imageNode)
228  {
229  return (informationType != SemanticRelationsInference::GetInformationTypeOfImage(imageNode))
230  || (controlPoint.date != SemanticRelationsInference::GetControlPointOfImage(imageNode).date);
231  };
232 
233  allImagesOfCase.erase(std::remove_if(allImagesOfCase.begin(), allImagesOfCase.end(), lambda), allImagesOfCase.end());
234 
235  return allImagesOfCase;
236  }
237  else
238  {
239  mitkThrowException(SemanticRelationException) << "Could not find an existing information type for the given caseID " << caseID << " and information type " << informationType << ".";
240  }
241  }
242  else
243  {
244  mitkThrowException(SemanticRelationException) << "Could not find an existing control point for the given caseID " << caseID << " and control point " << controlPoint.UID << ".";
245  }
246 }
247 
249 {
250  if (SemanticRelationsInference::InstanceExists(caseID, informationType))
251  {
252  if (SemanticRelationsInference::InstanceExists(caseID, examinationPeriod))
253  {
254  // examination period exists, information type exists, retrieve all imageIDs from the storage
255  auto allImageIDsOfExaminationPeriod = SemanticRelationsInference::GetAllImageIDsOfExaminationPeriod(caseID, examinationPeriod);
256  // filter all images to remove the ones with a different information type using a lambda function
257  auto lambda = [&caseID, &informationType](SemanticTypes::ID imageID)
258  {
259  return (informationType != RelationStorage::GetInformationTypeOfImage(caseID, imageID));
260  };
261 
262  allImageIDsOfExaminationPeriod.erase(std::remove_if(allImageIDsOfExaminationPeriod.begin(), allImageIDsOfExaminationPeriod.end(), lambda), allImageIDsOfExaminationPeriod.end());
263 
264  auto allImagesOfExaminationPeriod = GetAllImagesByID(allImageIDsOfExaminationPeriod);
265  return allImagesOfExaminationPeriod;
266  }
267  else
268  {
269  mitkThrowException(SemanticRelationException) << "Could not find an existing examination period for the given caseID " << caseID << " and examination period " << examinationPeriod.name << ".";
270  }
271  }
272  else
273  {
274  mitkThrowException(SemanticRelationException) << "Could not find an existing information type for the given caseID " << caseID << " and information type " << informationType << ".";
275  }
276 }
277 
279 {
280  if (m_DataStorage.IsExpired())
281  {
282  mitkThrow() << "Not a valid data storage.";
283  }
284 
285  DataNodeVector allSpecificImages;
286  try
287  {
288  allSpecificImages = GetAllSpecificImages(caseID, controlPoint, informationType);
289 
290  }
291  catch (SemanticRelationException& e)
292  {
293  mitkReThrow(e) << "Cannot get the specific segmentation.";
294  }
295 
296  DataNodeVector allSpecificSegmentations;
297  for (const auto& imageNode : allSpecificImages)
298  {
299  DataStorage::SetOfObjects::ConstPointer segmentationNodes = m_DataStorage.Lock()->GetDerivations(imageNode, NodePredicates::GetSegmentationPredicate(), false);
300  for (auto it = segmentationNodes->Begin(); it != segmentationNodes->End(); ++it)
301  {
302  allSpecificSegmentations.push_back(it->Value());
303  }
304  }
305 
306  return allSpecificSegmentations;
307 }
308 
310  const SemanticTypes::InformationType& informationType, const SemanticTypes::Lesion& lesion) const
311 {
312  if (m_DataStorage.IsExpired())
313  {
314  mitkThrow() << "Not a valid data storage.";
315  }
316 
317  DataNodeVector allSpecificSegmentations;
318  try
319  {
320  allSpecificSegmentations = GetAllSpecificSegmentations(caseID, controlPoint, informationType);
321 
322  }
323  catch (SemanticRelationException& e)
324  {
325  mitkReThrow(e) << "Cannot get the specific segmentation.";
326  }
327 
328  for (const auto& segmentationNode : allSpecificSegmentations)
329  {
331  if (representedLesion.UID == lesion.UID)
332  {
333  return segmentationNode;
334  }
335  }
336 
337  return mitk::DataNode::Pointer();
338 }
SemanticTypes::InformationType GetInformationTypeOfImage(const SemanticTypes::CaseID &caseID, const SemanticTypes::ID &imageID)
Data management class that handles &#39;was created by&#39; relations.
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::InformationType GetInformationTypeOfImage(const DataNode *imageNode)
Return the information type of the given image. If the image does not contain any information type...
std::vector< ID > IDVector
DataNodeVector GetAllSegmentationsOfCase(const SemanticTypes::CaseID &caseID) const
Return a vector of all segmentations that are currently available for the given case. The segmentations may be connected / not connected to a lesion of the case. If no segmentations are stored for the current case, an empty vector is returned.
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()
DataNodeVector GetAllImagesOfCase(const SemanticTypes::CaseID &caseID) const
Return a vector of all images that are currently available for the given case.
#define mitkReThrow(mitkexception)
DataNodeVector GetAllSegmentationsOfLesion(const SemanticTypes::CaseID &caseID, const SemanticTypes::Lesion &lesion) const
Return a vector of all segmentations that define the given lesion. These segmentations don&#39;t have to ...
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ControlPoint GetControlPointOfImage(const DataNode *dataNode)
Return the control point of a data node. If the data node is not linked to a control point or the dat...
itk::SmartPointer< Self > Pointer
Definition: mitkDataNode.h:71
MITKSEMANTICRELATIONS_EXPORT NodePredicateAnd::Pointer GetSegmentationPredicate()
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::CaseID GetCaseIDFromDataNode(const mitk::DataNode *dataNode)
mitk::DataStorage::Pointer m_DataStorage
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::IDVector GetAllImageIDsOfExaminationPeriod(const SemanticTypes::CaseID &caseID, const SemanticTypes::ExaminationPeriod &examinationPeriod)
Return a vector of all image IDs that identify images that are related to the given examination perio...
DataNodeVector GetAllImagesByID(const SemanticTypes::IDVector &imageIDs) const
Return a vector of all images that are specified by the given vector of image IDs.
The concept of an examination period. An examination period holds a vector of control point UIDs...
#define mitkThrow()
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::ID GetIDFromDataNode(const mitk::DataNode *dataNode)
DataNodeVector GetAllSpecificSegmentations(const SemanticTypes::CaseID &caseID, const SemanticTypes::ControlPoint &controlPoint, const SemanticTypes::InformationType &informationType) const
Return a vector of all segmentation nodes that are defined with the given control point and the given...
#define mitkThrowException(classname)
std::string InformationType
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::IDVector GetAllSegmentationIDsOfCase(const SemanticTypes::CaseID &caseID)
DataNodeVector GetAllSpecificImages(const SemanticTypes::CaseID &caseID, const SemanticTypes::ControlPoint &controlPoint, const SemanticTypes::InformationType &informationType) const
Return a vector of all image nodes that are defined with the given control point and the given inform...
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::IDVector GetAllImageIDsOfCase(const SemanticTypes::CaseID &caseID)
MITKSEMANTICRELATIONS_EXPORT SemanticTypes::Lesion GetLesionOfSegmentation(const DataNode *segmentationNode)
Return the lesion that is defined by the given segmentation.
DataNodeVector GetAllImagesOfLesion(const SemanticTypes::CaseID &caseID, const SemanticTypes::Lesion &lesion) const
Return a vector of all images that are connected to those segmentations that are linked to the given ...
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
MITKSEMANTICRELATIONS_EXPORT bool InstanceExists(const DataNode *dataNode)
Check if the given data node exists in the relation storage. The function receives the case- and the ...