Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDataStorage.h
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef MITKDATASTORAGE_H_HEADER_INCLUDED_
18 #define MITKDATASTORAGE_H_HEADER_INCLUDED_
19 
20 #include "itkObject.h"
21 #include "itkSimpleFastMutexLock.h"
22 #include "itkVectorContainer.h"
23 #include "mitkDataNode.h"
24 #include "mitkGeometry3D.h"
25 #include "mitkMessage.h"
26 #include <MitkCoreExports.h>
27 #include <map>
28 
29 namespace mitk
30 {
31  class NodePredicateBase;
32  class DataNode;
33  class BaseRenderer;
34 
35  //##Documentation
36  //## @brief Data management class that handles 'was created by' relations
37  //##
38  //## The DataStorage provides data storage and management functionality.
39  //## It handles a 'was created by' relation by associating each data object with a
40  //## set of source objects, that this object was created from.
41  //## Thus, nodes are stored in a noncyclical directed graph data structure.
42  //## If a new node is added to the DataStorage, AddNodeEvent is emitted.
43  //## If a node is removed, RemoveNodeEvent is emitted.
44  //##
45  //##
46  //## \ingroup DataStorage
47  class MITKCORE_EXPORT DataStorage : public itk::Object
48  {
49  public:
51 
52  //##Documentation
53  //## @brief A Container of objects that is used as a result set of GetSubset() query operations (Set of
54  //SmartPointers
55  // to DataNodes).
56  typedef itk::VectorContainer<unsigned int, mitk::DataNode::Pointer> SetOfObjects;
57 
58  //##Documentation
59  //## @brief Adds a DataNode containing a data object to its internal storage
60  //##
61  //## This Method adds a new data object to the DataStorage. The new object is
62  //## passed in the first parameter. The second parameter is a set
63  //## of source objects, that were used to create this object. The new object will have
64  //## a 'was created from' relation to its source objects.
65  //## the addition of a new object will fire the notification mechanism.
66  //## If the node parameter is NULL or if the DataNode has already been added,
67  //## an exception will be thrown.
68  virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents = nullptr) = 0;
69 
70  //##Documentation
71  //## @brief Convenience method to add a node that has one parent
72  //##
73  void Add(mitk::DataNode *node, mitk::DataNode *parent);
74 
75  //##Documentation
76  //## @brief Removes node from the DataStorage
77  //##
78  virtual void Remove(const mitk::DataNode *node) = 0;
79 
80  //##Documentation
81  //## @brief Checks if a node exists in the DataStorage
82  //##
83  virtual bool Exists(const mitk::DataNode *node) const = 0;
84 
85  //##Documentation
86  //## @brief Removes a set of nodes from the DataStorage
87  //##
88  void Remove(const mitk::DataStorage::SetOfObjects *nodes);
89 
90  //##Documentation
91  //## @brief returns a set of data objects that meet the given condition(s)
92  //##
93  //## GetSubset returns a set of objects with a specific data type that meet the condition(s)
94  //## specified in the condition parameter. Conditions can be
95  //## - data type of the data object
96  //## - is source object of specific object (e.g. all source objects of node x)
97  //## - has property with specific value (e.g. OrganType is Liver)
98  //## - negation of any condition
99  //## - conjunction of a set of conditions
100  //## - disjunction of a set of conditions
101  //## Conditions are implemented as predicates using the Composite Design Pattern
102  //## (see definition of NodePredicateBase for details).
103  //## The method returns a set of SmartPointers to the DataNodes that fulfill the
104  //## conditions. A set of all objects can be retrieved with the GetAll() method;
105  SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const;
106 
107  //##Documentation
108  //## @brief returns a set of source objects for a given node that meet the given condition(s).
109  //##
110  virtual SetOfObjects::ConstPointer GetSources(const mitk::DataNode *node,
111  const NodePredicateBase *condition = nullptr,
112  bool onlyDirectSources = true) const = 0;
113 
114  //##Documentation
115  //## @brief returns a set of derived objects for a given node.
116  //##
117  //## GetDerivations() returns a set of objects that are derived from the DataNode node.
118  //## This means, that node was used to create the returned objects. If the parameter
119  //## onlyDirectDerivations is set to true (default value), only objects that directly have
120  //## node as one of their source objects will be returned. Otherwise, objects that are
121  //## derived from derivations of node are returned too.
122  //## The derived objects can be filtered with a predicate object as described in the GetSubset()
123  //## method by providing a predicate as the condition parameter.
124  virtual SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode *node,
125  const NodePredicateBase *condition = nullptr,
126  bool onlyDirectDerivations = true) const = 0;
127 
128  //##Documentation
129  //## @brief returns a set of all data objects that are stored in the data storage
130  //##
131  virtual SetOfObjects::ConstPointer GetAll() const = 0;
132 
133  //##Documentation
134  //## @brief Convenience method to get the first node that matches the predicate condition
135  //##
136  mitk::DataNode *GetNode(const NodePredicateBase *condition = nullptr) const;
137 
138  //##Documentation
139  //## @brief Convenience method to get the first node with a given name
140  //##
141  mitk::DataNode *GetNamedNode(const char *name) const;
142 
143  //##Documentation
144  //## @brief Convenience method to get the first node with a given name
145  //##
146  mitk::DataNode *GetNamedNode(const std::string name) const { return this->GetNamedNode(name.c_str()); }
147  //##Documentation
148  //## @brief Convenience method to get the first node with a given name that is derived from sourceNode
149  //##
150  mitk::DataNode *GetNamedDerivedNode(const char *name,
151  const mitk::DataNode *sourceNode,
152  bool onlyDirectDerivations = true) const;
153 
154  //##Documentation
155  //## @brief Convenience method to get the first data object of a given data type with a given name
156  //##
157  template <class DataType>
158  DataType *GetNamedObject(const char *name) const
159  {
160  if (name == nullptr)
161  return NULL;
162  mitk::DataNode *n = this->GetNamedNode(name);
163  if (n == nullptr)
164  return NULL;
165  else
166  return dynamic_cast<DataType *>(n->GetData());
167  }
168  //##Documentation
169  //## @brief Convenience method to get the first data object of a given data type with a given name
170  //##
171  template <class DataType>
172  DataType *GetNamedObject(const std::string name) const
173  {
174  return this->GetNamedObject<DataType>(name.c_str());
175  }
176 
177  //##Documentation
178  //## @brief Convenience method to get the first data object of a given data type with a given name that is derived
179  // from a specific node
180  //##
181  template <class DataType>
182  DataType *GetNamedDerivedObject(const char *name,
183  const mitk::DataNode *sourceNode,
184  bool onlyDirectDerivations = true) const
185  {
186  if (name == nullptr)
187  return NULL;
188  mitk::DataNode *n = this->GetNamedDerivedNode(name, sourceNode, onlyDirectDerivations);
189  if (n == nullptr)
190  return NULL;
191  else
192  return dynamic_cast<DataType *>(n->GetData());
193  }
194 
195  //##Documentation
196  //## @brief Returns a list of used grouptags
197  //##
198  const DataNode::GroupTagList GetGroupTags() const;
199 
200  /*ITK Mutex */
201  mutable itk::SimpleFastMutexLock m_MutexOne;
202 
203  /* Public Events */
205  //##Documentation
206  //## @brief AddEvent is emitted whenever a new node has been added to the DataStorage.
207  //##
208  //## Observers should register to this event by calling myDataStorage->AddNodeEvent.AddListener(myObject,
209  // MyObject::MyMethod).
210  //## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
211  //## Observers should unregister by calling myDataStorage->AddNodeEvent.RemoveListener(myObject,
212  //MyObject::MyMethod).
213  //## Note: AddEvents are _not_ emitted if a node is added to DataStorage by adding it to the the underlying
214  //DataTree!
215 
216  // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef
217  // for
218  // a Message1 object which is thread safe
219  DataStorageEvent AddNodeEvent;
220 
221  //##Documentation
222  //## @brief RemoveEvent is emitted directly before a node is removed from the DataStorage.
223  //##
224  //## Observers should register to this event by calling myDataStorage->RemoveNodeEvent.AddListener(myObject,
225  // MyObject::MyMethod).
226  //## After registering, myObject->MyMethod() will be called every time a new node has been added to the DataStorage.
227  //## Observers should unregister by calling myDataStorage->RemoveNodeEvent.RemoveListener(myObject,
228  // MyObject::MyMethod).
229  //## Note: RemoveEvents are also emitted if a node was removed from the DataStorage by deleting it from the
230  //underlying
231  // DataTree
232 
233  // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef
234  // for
235  // a Message1 object which is thread safe
236  DataStorageEvent RemoveNodeEvent;
237 
238  //##Documentation
239  //## @brief ChangedEvent is emitted directly after a node was changed.
240  //##
241  //## Observers should register to this event by calling myDataStorage->ChangedNodeEvent.AddListener(myObject,
242  // MyObject::MyMethod).
243  //## After registering, myObject->MyMethod() will be called every time a new node has been changed.
244  //## Observers should unregister by calling myDataStorage->ChangedNodeEvent.RemoveListener(myObject,
245  // MyObject::MyMethod).
246  //## Internally the DataStorage listens to itk::ModifiedEvents on the nodes and forwards them
247  //## to the listeners of this event.
248 
249  // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef
250  // for
251  // a Message1 object which is thread safe
252  DataStorageEvent ChangedNodeEvent;
253 
254  //##Documentation
255  //## @brief DeleteNodeEvent is emitted directly before a node is deleted.
256  //##
257  //## Observers should register to this event by calling myDataStorage->DeleteNodeEvent.AddListener(myObject,
258  // MyObject::MyMethod).
259  //## After registering, myObject->MyMethod() will be called when a node is deleted.
260  //## Observers should unregister by calling myDataStorage->DeleteNodeEvent.RemoveListener(myObject,
261  // MyObject::MyMethod).
262  //## Internally the DataStorage listens to itk::DeleteEvents on the nodes and forwards them
263  //## to the listeners of this event.
264 
265  // member variable is not needed to be locked in multi threaded scenarios since the DataStorageEvent is a typedef
266  // for
267  // a Message1 object which is thread safe
268  DataStorageEvent DeleteNodeEvent;
269 
270  DataStorageEvent InteractorChangedNodeEvent;
271 
272  //##Documentation
273  //## @brief Compute the axis-parallel bounding geometry of the input objects
274  //##
275  //## Throws std::invalid_argument exception if input is NULL
276  //## @param input set of objects of the DataStorage to be included in the bounding geometry
277  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
278  //## and is set to @a false, the node is ignored for the bounding-box calculation.
279  //## @param renderer see @a boolPropertyKey
280  //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
281  mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D(const SetOfObjects *input,
282  const char *boolPropertyKey = nullptr,
283  const mitk::BaseRenderer *renderer = nullptr,
284  const char *boolPropertyKey2 = nullptr) const;
285 
286  //##Documentation
287  //## @brief Compute the axis-parallel bounding geometry of the data tree
288  //## (bounding box, minimal spacing of the considered nodes, live-span)
289  //##
290  //## it -> an iterator to a data tree structure
291  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
292  //## and is set to @a false, the node is ignored for the bounding-box calculation.
293  //## @param renderer see @a boolPropertyKey
294  //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
295  mitk::TimeGeometry::Pointer ComputeBoundingGeometry3D(const char *boolPropertyKey = nullptr,
296  const mitk::BaseRenderer *renderer = nullptr,
297  const char *boolPropertyKey2 = nullptr) const;
298 
299  //##Documentation
300  //## @brief Compute the axis-parallel bounding geometry of all visible parts of the
301  //## data tree bounding box, minimal spacing of the considered nodes, live-span)
302  //##
303  //## Simply calls ComputeBoundingGeometry3D(it, "visible", renderer, boolPropertyKey).
304  //## it -> an iterator of a data tree structure
305  //## @param renderer the reference to the renderer
306  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
307  //## and is set to @a false, the node is ignored for the bounding-box calculation.
308  mitk::TimeGeometry::Pointer ComputeVisibleBoundingGeometry3D(const mitk::BaseRenderer *renderer = nullptr,
309  const char *boolPropertyKey = nullptr);
310 
311  //##Documentation
312  //## @brief Compute the bounding box of data tree structure
313  //## it -> an iterator to a data tree structure
314  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
315  //## and is set to @a false, the node is ignored for the bounding-box calculation.
316  //## @param renderer see @a boolPropertyKey
317  //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
318  mitk::BoundingBox::Pointer ComputeBoundingBox(const char *boolPropertyKey = nullptr,
319  const mitk::BaseRenderer *renderer = nullptr,
320  const char *boolPropertyKey2 = nullptr);
321 
322  //##Documentation
323  //## \brief Compute the bounding box of all visible parts of the data tree structure, for general
324  //## rendering or renderer specific visibility property checking
325  //##
326  //## Simply calls ComputeBoundingBox(it, "visible", renderer, boolPropertyKey).
327  //## it -> an iterator of a data tree structure
328  //## @param renderer the reference to the renderer
329  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
330  //## and is set to @a false, the node is ignored for the bounding-box calculation.
332  const char *boolPropertyKey = nullptr)
333  {
334  return ComputeBoundingBox("visible", renderer, boolPropertyKey);
335  }
336 
337  //##Documentation
338  //## @brief Compute the time-bounds of the contents of a data tree structure
339  //##
340  //## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
341  //## all data-objects with infinite live-span are ignored.
342  //## it -> an iterator to a data tree structure
343  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
344  //## and is set to @a false, the node is ignored for the time-bounds calculation.
345  //## @param renderer see @a boolPropertyKey
346  //## @param boolPropertyKey2 a second condition that is applied additionally to @a boolPropertyKey
347  mitk::TimeBounds ComputeTimeBounds(const char *boolPropertyKey,
348  const mitk::BaseRenderer *renderer,
349  const char *boolPropertyKey2);
350 
351  //##Documentation
352  //## @brief Compute the time-bounds of all visible parts of the data tree structure, for general
353  //## rendering or renderer specific visibility property checking
354  //##
355  //## The methods returns only [-infinity, +infinity], if all data-objects have an infinite live-span. Otherwise,
356  //## all data-objects with infinite live-span are ignored.
357  //## Simply calls ComputeTimeBounds(it, "visible", renderer, boolPropertyKey).
358  //## @param it an iterator to a data tree structure
359  //## @param boolPropertyKey if a BoolProperty with this boolPropertyKey exists for a node (for @a renderer)
360  //## and is set to @a false, the node is ignored for the time-bounds calculation.
361  //## @param renderer see @a boolPropertyKey
362  mitk::TimeBounds ComputeTimeBounds(const mitk::BaseRenderer *renderer, const char *boolPropertyKey)
363  {
364  return ComputeTimeBounds("visible", renderer, boolPropertyKey);
365  }
366 
367  //##Documentation
368  //## @brief Defines whether or not NodeChangedEvent is invoked .
369  //##
370  //## This method can be used to set m_BlockNodeModifiedEvents.
371  //##
372  //## If this flag is true, NodeChangedEvent is not invoked when a
373  //## DataNode is modified. This might be undesired when setting
374  //## many properties on a datanode and you do not want anyone to
375  //## react.
376  void BlockNodeModifiedEvents(bool block);
377 
378  protected:
379  //##Documentation
380  //## @brief EmitAddNodeEvent emits the AddNodeEvent
381  //##
382  //## This method should be called by subclasses to emit the AddNodeEvent
383  void EmitAddNodeEvent(const mitk::DataNode *node);
384 
385  //##Documentation
386  //## @brief EmitRemoveNodeEvent emits the RemoveNodeEvent
387  //##
388  //## This method should be called by subclasses to emit the RemoveNodeEvent
389  void EmitRemoveNodeEvent(const mitk::DataNode *node);
390 
391  void OnNodeInteractorChanged(itk::Object *caller, const itk::EventObject &event);
392 
393  //##Documentation
394  //## @brief OnNodeModified listens to modified events of DataNodes.
395  //##
396  //## The node is hidden behind the caller parameter, which has to be casted first.
397  //## If the cast succeeds the ChangedNodeEvent is emitted with this node.
398  void OnNodeModifiedOrDeleted(const itk::Object *caller, const itk::EventObject &event);
399 
400  //##Documentation
401  //## @brief Adds a Modified-Listener to the given Node.
402  void AddListeners(const mitk::DataNode *_Node);
403 
404  //##Documentation
405  //## @brief Removes a Modified-Listener from the given Node.
406  void RemoveListeners(const mitk::DataNode *_Node);
407 
408  //##Documentation
409  //## @brief Saves Modified-Observer Tags for each node in order to remove the event listeners again.
410  std::map<const mitk::DataNode *, unsigned long> m_NodeModifiedObserverTags;
411 
412  std::map<const mitk::DataNode *, unsigned long> m_NodeInteractorChangedObserverTags;
413 
414  //##Documentation
415  //## @brief Saves Delete-Observer Tags for each node in order to remove the event listeners again.
416  std::map<const mitk::DataNode *, unsigned long> m_NodeDeleteObserverTags;
417 
418  //##Documentation
419  //## @brief If this class changes nodes itself, set this to TRUE in order
420  //## to suppress NodeChangedEvent to be emitted.
422 
423  //##Documentation
424  //## @brief Standard Constructor for ::New() instantiation
425  DataStorage();
426  //##Documentation
427  //## @brief Standard Destructor
428  virtual ~DataStorage();
429 
430  //##Documentation
431  //## @brief Filters a SetOfObjects by the condition. If no condition is provided, the original set is returned
432  SetOfObjects::ConstPointer FilterSetOfObjects(const SetOfObjects *set, const NodePredicateBase *condition) const;
433 
434  //##Documentation
435  //## @brief Prints the contents of the DataStorage to os. Do not call directly, call ->Print() instead
436  virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override;
437  };
438 } // namespace mitk
439 
440 #endif /* MITKDATASTORAGE_H_HEADER_INCLUDED_ */
mitk::TimeBounds ComputeTimeBounds(const mitk::BaseRenderer *renderer, const char *boolPropertyKey)
Compute the time-bounds of all visible parts of the data tree structure, for general rendering or ren...
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
#define MITKCORE_EXPORT
std::set< std::string > GroupTagList
Definition: mitkDataNode.h:73
itk::VectorContainer< unsigned int, mitk::DataNode::Pointer > SetOfObjects
A Container of objects that is used as a result set of GetSubset() query operations (Set of...
itk::FixedArray< ScalarType, 2 > TimeBounds
Standard typedef for time-bounds.
DataType * GetNamedDerivedObject(const char *name, const mitk::DataNode *sourceNode, bool onlyDirectDerivations=true) const
Convenience method to get the first data object of a given data type with a given name that is derive...
itk::SimpleFastMutexLock m_MutexOne
std::map< const mitk::DataNode *, unsigned long > m_NodeModifiedObserverTags
Saves Modified-Observer Tags for each node in order to remove the event listeners again...
DataType * GetNamedObject(const std::string name) const
Convenience method to get the first data object of a given data type with a given name...
Organizes the rendering process.
DataStorageEvent DeleteNodeEvent
DeleteNodeEvent is emitted directly before a node is deleted.
DataCollection - Class to facilitate loading/accessing structured data.
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
itk::SmartPointer< const Self > ConstPointer
Message1< const mitk::DataNode * > DataStorageEvent
mitk::DataNode * GetNamedNode(const std::string name) const
Convenience method to get the first node with a given name.
DataType * GetNamedObject(const char *name) const
Convenience method to get the first data object of a given data type with a given name...
#define mitkClassMacroItkParent(className, SuperClassName)
Definition: mitkCommon.h:53
std::map< const mitk::DataNode *, unsigned long > m_NodeDeleteObserverTags
Saves Delete-Observer Tags for each node in order to remove the event listeners again.
DataStorageEvent AddNodeEvent
AddEvent is emitted whenever a new node has been added to the DataStorage.
DataStorageEvent RemoveNodeEvent
RemoveEvent is emitted directly before a node is removed from the DataStorage.
std::map< const mitk::DataNode *, unsigned long > m_NodeInteractorChangedObserverTags
DataStorageEvent ChangedNodeEvent
ChangedEvent is emitted directly after a node was changed.
Interface for evaluation conditions used in the DataStorage class GetSubset() method.
bool m_BlockNodeModifiedEvents
If this class changes nodes itself, set this to TRUE in order to suppress NodeChangedEvent to be emit...
DataStorageEvent InteractorChangedNodeEvent
mitk::BoundingBox::Pointer ComputeVisibleBoundingBox(const mitk::BaseRenderer *renderer=nullptr, const char *boolPropertyKey=nullptr)
Compute the bounding box of all visible parts of the data tree structure, for general rendering or re...
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66