Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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