Slicer3:Data Model

From NAMIC Wiki
Revision as of 00:41, 30 December 2006 by Alexy (talk | contribs)
Jump to: navigation, search
Home < Slicer3:Data Model

Slicer3 MRML Overview

Slicer3 MRML Library provides API for managing medical image data types (Volumes, Models, Transforms, Fiducials, Cameras, etc). Each specific data type is represented by a MRML node. MRML Scene is a collection of MRML nodes. MRML scene provides an API that allows adding, deleting, reading/writing, and modifying of MRML nodes.

A Slicer3 data model is implemented independent of the visualization and algorithmic components of the system.

MRML scene provides functionality to serialize and de-serialize the contents in an XML structure. Each MRML node should implement methods for reading and writing its attributes to and from XML files.

For more details on MRML architecture and Undo/Redo design see Architecture Slides.

MRML Nodes

The MRML nodes are designed to store the state of the Slicer application.

There following is a set of core MRLN nodes that store the state of core Slicer modules:

  • vtkMRMLCameraNode
  • vtkMRMLClipModelsNode
  • vtkMRMLSliceCompositeNode
  • vtkMRMLSliceNode
  • vtkMRMLColorNode
  • vtkMRMLTransformNode
  • vtkMRMLLinearTransformNode
  • vtkMRMLTransformableNode
  • vtkMRMLFiducialListNode
  • vtkMRMLModelNode
  • vtkMRMLModelDisplayNode
  • vtkMRMLStorageNode
  • vtkMRMLModelStorageNode
  • vtkMRMLVolumeNode
  • vtkMRMLScalarVolumeNode
  • vtkMRMLVectorVolumeNode
  • vtkMRMLTensorVolumeNode
  • vtkMRMLDiffusionTensorVolumeNode
  • vtkMRMLDiffusionWeightedVolumeNode
  • vtkMRMLVolumeDisplayNode
  • vtkMRMLVectorVolumeDisplayNode
  • vtkMRMLDiffusionTensorVolumeDisplayNode
  • vtkMRMLDiffusionWeightedVolumeDisplayNode
  • vtkMRMLVolumeHeaderlessStorageNode
  • vtkMRMLVolumeArchetypeStorageNode


MRML Nodes are organized into class hierarchies. For example vtkMRMLTransformableNode is the parent class of Volume, Model, Fiducial, and Transformation nodes; vtkVolumeNode is a parent of vtkMRMLScalarVolumeNode and vtkMRMLVectorVolumeNode.


Creating Custom MRML Node Classes

Slicer module developers can create their own custom MRML nodes in order to provide a persistent storage for the module parameters. Additional MRML nodes should be registered with the MRML scene so they can be saved to and read from a mrml scene file.

New MRML node classes should implement the following methods:

  • CreateNodeInstance() – similar to VTK New() method only not static.
  • GetNodeTagName() – return a unique XML tag for this node.
  • ReadXMLAttributes() – reads node attributes from XML file as name-value pairs.
  • WriteXML() – writes node attributes to output stream.
  • Copy() – copies node attributes.

If the node stores references to other nodes (see below) the following additional methods should be implemented:

  • UpdateReferenceID() - updates the stored reference to another node.
  • UpdateScene()- updates other nodes in the scene depending on this node or updates this node if it depends on other nodes when the scene is read in. This method is called automatically by XML parser after all nodes are created.

An example of a custom MRML node implementation, vtkMRMLGradientAnisotropicDiffusionFilterNode calss can be found in the Slicer source repostory, in Modules/GradientAnisotropicDiffusionFilter directory.

In order to create a node and add it to the MRML scene the developers can either:

  • use standard VTK New() method to create a node instance and add it to the scene using vtkMRMLScene::AddNode(vtkMRMLNode *) method, or
  • delegate node creation to the vtkSlicerNodeSelectorWidget that allows users to create a new node from the module’s UI if the NewNodeEnabled flag is set to true.


References to MRML Nodes

Some MRML nodes have references to other nodes. For example vtkMRMLTransformableNode has a references to a Transformation node that represents a specific transformation function between the node space and its parent node space. The Transformation node itself has reference to its parent Transformation node. The references are stored by node ID (a unique node identifier), for example vtkMRMLTransformableNode stores a reference to it’s Transformation node in the “TransformNodeID “ member variable and in the XML file using “transformNodeRef” attribute.

Changes in the MRML nodes that are referenced by other nodes should propagate to these referencing nodes and to the GUI and Logic objects that observe the changes. The VTK’s command-observer mechanism insures the propagation of the modification events from MRML scene and individual nodes. The command-observer mechanism for MRML scene and nodes is implemented using a helper vtkObserverManager class.

Other objects from the Slicer Logic and GUI libraries can observe the MRML nodes as well. The established practice is for a Logic/GUI class to store a registered pointer to a MRML node as well as it’s ID. Any time the class needs to access the MRML node it should check if the referenced node is still in the MRML scene using its ID and if the node is not there it needs to find or create another node, re-register its pointer, and store the new ID.

The following methods and macros should be used for managing references and observers on the MRML nodes in other MRML nodes as well as in the Slicer Logic and GUI classes:

  • vtkSetReferenceStringMacro - should be used to in the MRML node for setting the refrence ID to another node.
  • VtkSetMRMLObjectMacro - registers a MRML node with another vtk object (another MRML node, Logic or GUI).
  • VtkSetAndObserveMRMLObjectMacro - registers a MRML node with another vtk object (another MRML node, Logic or GUI) and adds an observer for vtkCommand::ModifyEvent. The observer will call ProcessMRMLEvents method when node attributes are modified.
  • VtkSetAndObserveMRMLObjectEventsMacro - registers a MRML node with another vtk object (another MRML node, Logic or GUI) and adds an observer for a specified set of events. The observer will call ProcessMRMLEvents method when the events are generated.
  • ProcessMRMLEvents method should be implemented in MRML nodes, Logic, and GUI classes in order to process events from the referenced nodes.
  • UpdateReferenceID method should be implemented on MRML nodes in order to update references to other nodes when the MRML scene changes their ID's.
  • vtkMRMLScene::AddReferencedNodeID should be called in order to register references with the MRML scene when the node reads the reference ID from the XML mrml file.

An example of using this reference/observer mechanism can be found in the implementation of vtkMRMLTransformableNode class.


Undo/Redo Mechanism

Slicer MRML scene provides the Undo/Redo mechanism that is based on saving and restoring the state of MRML nodes. MRML scene can save a current snapshot of all the nodes in the scene into a special Undo stack. The developer controls at which point the snapshot is saved by calling a version of the “SaveStateForUndo” method on the MRML scene. MRML nodes are designed to store the state of the Slicer application and modules with the Logic and GUI classes observing and processing changes in the MRML scene and the individual nodes. When an Undo method is called on the scene, the previous state of the scene and individual MRML nodes is restored which forces the Logic classes to process and the GUI classes to reflect the new state of the MRML scene.

The Undo and Redo stacks store the differences, “deltas” for each MRML node, so that nodes that have not changed from the previous snapshot are stored by a reference (pointer). When an Undo method is called on the scene the current state of Undo stack is copied into Redo stack and then into the current scene.

The Undo and Redo stacks reflect the changes to the attributes of the individual MRML nodes as well as adding and deleting nodes in the scene. For example, if you save the scene current state by calling SaveStateForUndo, then add a new MRML node and then call Undo the resulting scene will not include the node that you just added.

The following methods on the MRML scene are used to create the snashots:

  • vtkMRMLScene::SaveStateForUndo() - saves the state of all nodes in the scene
  • vtkMRMLScene::SetActiveScene(vtkMRMLScene *) - saves the state of the specified node.
  • vtkMRMLScene::SetActiveScene(std::vector<vtkMRMLNode *>) - saves the state of the specified collection of nodes.
  • vtkMRMLScene::SetActiveScene(vtkCollection*) - saves the state of the specified collection of nodes.

The following methods on the MRML scene are used to manage Undo/Redo stacks:

  • vtkMRMLScene::Undo() – restore the previously saved state of the MRML scene.
  • vtkMRMLScene::Redo() – restore the previously undone state of the MREML scene.
  • vtkMRMLScene::SetUndoOff() – ignore following SaveStateForUndo calls (usefull when making multiple changes to the scene/nodes that does not need to be undone).
  • vtkMRMLScene::SetUndoOn() – enable following SaveStateForUndo calls.
  • vtkMRMLScene::ClearUndoStack() – clears the undo history.
  • vtkMRMLScene::ClearRedoStack() – clears the redo history.

Slicer Module developers should call vtkMRMLScne::SaveStateForUndo() method in their modules before changing the state of MRML nodes. This is usually done in the ProcessGUIEvents method that processes events from the user interactions with GUI widgets. Note, that vtkMRMLScne::SaveStateForUndo() method should not be called while processing transient events such as continuos events sent by UI while dragging a slider (for example vtkKWScale::ScaleValueStartChangingEvent).


Other Useful References

MRML API Documentation

The detailed documentaion of MRML API can be found in [| Slicer3 Doxigen pages]

History

See Data Model notes in AHM 2006 Programming week project.

Path-based MRML proposal

Mike's proposal for a path-based MRML3 representation, based on extending the Coordinate Space Manager ideas to the entire MRML3 tree

Slicer Daemon

The goal of the Slicer Daemon project is to allow remote editing of the MRML data model by external programs over a socket.

Slicer 2.6 MRML

Data Represented in MRML in Slicer 2.6

  • Volumes
    • IJK->RAS (VTK->RAS)
    • Scalar Types
    • Multicomponent (RGB, Displacement Vector)
    • Tensor Volumes
    • Label Maps
    • Reference to Lookup Table
  • Models
    • vtkPolyData
      • Named Field Data (scalars, vectors, labels) at points and cells (FreeSurferReaders)
      • Polylines with tensor point data (DTMRI Module)
    • Color, Clipping State, Visibility, Scalar Visibility, LookupTable
  • Transforms
    • Matrix4x4
  • Lookup Tables
    • vtkLookupTable info
  • Fiducials
    • Position, Quaternion
    • Name, Selection State, Type (endoscopic, normal)
    • Glyph Size, Text Size
  • Fiducial Lists
    • Name, Slze, Color, Selection State
  • Colors
    • Name, Label#, Diffuse/Ambient/Specular
  • Model Groups
  • Application State (not to be carried to Slicer3 MRML)
  • Locator (not to be carried to Slicer3 MRML)
  • Module Specific Parameters (not to be carried to Slicer3 MRML)


Operations On MRML Scene

  • Load from File
  • Save to File
  • Traverse Nodes in Tree
  • Insert Node
  • Delete Node
  • Register Tree Observer
  • Update MRML
  • Get Transformations (e.g. IJK to World through transform tree)
  • Data Type Specific Operations
    • Get/Set Node MetaData
    • Get/Set Data (e.g. as vtkImageData)

General References on XML

A wikibook on XML: http://en.wikibooks.org/wiki/XML:_Managing_Data_Exchange

The section on ID/IDREF implementations which are similar to what we use in MRML: http://en.wikibooks.org/wiki/XML:_Managing_Data_Exchange/The_many-to-many_relationship#ID.2FIDREF