|
Tags: 2017 source edit, Replaced |
(28 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| <noinclude>{{documentation/versioncheck}}</noinclude> | | <noinclude>{{documentation/versioncheck}}</noinclude> |
− | = Slicer MRML Overview =
| |
| | | |
− | *MRML Library provides API for managing medical image data types (Volumes, Models, Transforms, Fiducials, Cameras, etc) and their visualization.
| + | {{documentation/banner |
− | *Each data type is represented by a special MRML node.
| + | | text = [https://slicer.readthedocs.io/en/latest/developer_guide/mrml_overview.html This page has been moved to read-the-docs.] |
− | *MRML Scene is a collection of MRML nodes.
| + | | background-color = 8FBC8F }} |
− | *Slicer MRML data model is implemented independent of the visualization and algorithmic components of the system.
| |
− | *Other Slicer components (Logic and GUI) observe changes in MRML scene and individual nodes and process change MRML events.
| |
− | | |
− | For more details on MRML architecture see [http://www.na-mic.org/Wiki/images/e/e3/Slicer_3-alpha-2006-04-03.ppt Architecture Slides].
| |
− | | |
− | = MRML Scene =
| |
− | | |
− | *MRML Scene manages MRML nodes : add, delete, find, find by type, etc.
| |
− | *MRML Scene provides persistence of MRML nodes (reading/writing to/from XML file).
| |
− | *MRML Scene provides Undo/Redo mechanism that restores a previous state of the scene and individual nodes.
| |
− | | |
− | = MRML Nodes =
| |
− |
| |
− | *The MRML nodes are designed to store the state of the Slicer application, both raw data and visualization parameters.
| |
− | | |
− | 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
| |
− | | |
− | <br />
| |
− | *MRML nodes are organized into C++ class hierarchies, all derived from vtkMRMLNode class.
| |
− | *For example vtkMRMLTransformableNode is the parent class of Volume, Model, Fiducial, and Transformation nodes; vtkVolumeNode is a parent of vtkMRMLScalarVolumeNode and vtkMRMLVectorVolumeNode
| |
− | *All MRML nodes have to implement certain standard API: ReadAttributes, WriteAttributes, Copy, etc.
| |
− | {| | |
− | |[[Image: Slicer3_MRML_Node_Hier.jpg|thumb|400px]]
| |
− | |}
| |
− | | |
− | = MRML node attributes =
| |
− | | |
− | MRML nodes can store custom attributes as (attribute name; attribute value) pairs.
| |
− | | |
− | To avoid name clashes custom modules that adds attributes to nodes should prefix the attribute name with the module's name and the '.' character. Example: the DoseVolumeHistogram module can use attribute names such as DoseVolumeHistogram.StructureSetName, DoseVolumeHistogram.Unit, DoseVolumeHistogram.LineStyle.
| |
− | | |
− | = References to MRML Nodes =
| |
− | | |
− | *Some MRML nodes have references to other nodes.
| |
− | *Transformable Node has a reference to a Transformation node. Transformation node has a reference to its parent Transformation node.
| |
− | *References are stored by node ID.
| |
− | *Use vtkSetReferenceStringMacro to set reference ID (it registers reference with the scene).
| |
− | *Access methods should check if the referenced node is still in the MRML scene using its ID.
| |
− | {| | |
− | |[[Image: Slicer3_MRML_Trans_Ref.jpg|thumb|400px]] | |
− | |}
| |
− | | |
− | = MRML Events and Observers =
| |
− | | |
− | *Changes in MRML scene and individual nodes propagate to other observing nodes, GUI and Logic objects via vtk events and command-observer mechanism.
| |
− | *Use vtk AddObserver() and InvokeEvent() methods. vtkSetMacro generates ModifiedEvent.
| |
− | *The command-observer mechanism for MRML is implemented using helper vtkObserverManager, class, MRML Observer macros, and ProcessMRMLEvents method.
| |
− | *Observers should store a registered pointer to a MRML node to prevent callbacks on a deleted object.
| |
− | {|
| |
− | |[[Image: Slicer3_MRML_Observ.jpg|thumb|400px]]
| |
− | |}
| |
− | | |
− | *MRML observer macros are defined in Libs/MRML/vtkMRMLNode.h
| |
− | *vtkSetMRMLObjectMacro - registers MRML node with another vtk object (another MRML node, Logic or GUI). No observers added.
| |
− | *vtkSetAndObserveMRMLObjectMacro - registers MRML node and adds an observer for vtkCommand::ModifyEvent.
| |
− | *vtkSetAndObserveMRMLObjectEventsMacro - registers MRML node and adds an observer for a specified set of events.
| |
− | *SetAndObserveMRMLScene[Events]() method is used in GUI and Logic to observe Modify, NewScene, NodeAdded, etc. events.
| |
− | *ProcessMRMLEvents method should be implemented in MRML nodes, Logic, and GUI classes in order to process events from the observed nodes.
| |
− | | |
− | = Creating Custom MRML Node Classes=
| |
− | | |
− | *Custom MRML nodes provide persistent storage for the module parameters.
| |
− | *Custom MRML nodes should be registered with the MRML scene using RegisterNodeClass() so they can be saved and restored from a scene file.
| |
− | *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 (as in interpolate="1" ).
| |
− | *Copy() – copies node attributes.
| |
− | | |
− | *If the node has references to other nodes 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 in Modules/GradientAnisotropicDiffusionFilter directory.
| |
− | *To add node to the MRML scene:
| |
− | –In the code: use standard vtk New() and add node to the scene using vtkMRMLScene::AddNode(vtkMRMLNode *)
| |
− | –By user request: use vtkSlicerNodeSelectorWidget that creates a new node from the module’s UI.
| |
− | | |
− | = FAQ =
| |
− | == How to add into the scene==
| |
− | * Generic pattern
| |
− | <code>
| |
− | vtkMRML???Node* nodeToAdd = vtkMRML???Node::New();
| |
− | ...
| |
− | mrmlScene->AddNode(nodeToAdd);
| |
− | nodeToAdd->Delete();
| |
− | </code>
| |
− | * Add a polydata to the scene
| |
− | <code>
| |
− | vtkNew<vtkMRMLModelNode> modelNode;
| |
− | modelNode->SetPolyData(polyData);
| |
− | mrmlScene->AddNode(modelNode.GetPointer());
| |
− | </code>
| |
− | * Load a polyData from file
| |
− | <code>
| |
− | vtkSlicerModelsLogic* modelsLogic = ...;
| |
− | //modelsLogic->SetMRMLScene(mrmlScene);
| |
− | modelsLogic->AddModel(polyDataFileName);
| |
− | </code>
| |
− | ==Views==
| |
− | * Change the volumes in the 2D views ([https://github.com/fedorov/ChangeTrackerPy/blob/master/Wizard/Helper.py#L82 source])
| |
− | <code>
| |
− | appLogic = slicer.app.applicationLogic()
| |
− | selectionNode = appLogic.GetSelectionNode()
| |
− | selectionNode.SetReferenceActiveVolumeID(bg)
| |
− | selectionNode.SetReferenceSecondaryVolumeID(fg)
| |
− | appLogic.PropagateVolumeSelection()
| |
− | </code>
| |
− | | |
− | = Undo/Redo Mechanism =
| |
− | | |
− | *Undo/Redo is based on saving and restoring the state of MRML nodes in the Scene.
| |
− | *MRML scene can save snapshot of all nodes into a special Undo and Redo stacks.
| |
− | *The Undo and Redo stacks store copies of nodes that have changed from the previous snapshot. The node that have not changed are stored by a reference (pointer).
| |
− | *When an Undo is called on the scene, the current state of Undo stack is copied into the current scene and also into Redo stack.
| |
− | * All Undoable operations must store their data as MRML nodes
| |
− | | |
− | {|
| |
− | |[[Image: Slicer3_MRML_Undo.jpg|thumb|400px]]
| |
− | |}
| |
− | | |
− | *Developer controls at what point the snapshot is saved by calling SaveStateForUndo method on the MRML scene.
| |
− | –SaveStateForUndo() - saves the state of all nodes in the scene
| |
− | <br />–SetActiveScene(vtkMRMLScene *) - saves the state of the specified node.
| |
− | <br />–SetActiveScene(vtkCollection*) - saves the state of the specified collection of nodes.
| |
− | *SaveStateForUndo() should be called in GUI/Logic classes 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.
| |
− | *SaveStateForUndo() should not be called while processing transient events such as continuous events sent by KW UI while dragging a slider (for example vtkKWScale::ScaleValueStartChangingEvent).
| |
− | | |
− | 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 MRML 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.
| |
− | | |
− | = Other Useful References =
| |
− | | |
− | == MRML API Documentation ==
| |
− | | |
− | The detailed documentation of MRML API can be found in [http://slicer.org/doc/html/classes.html Slicer {{documentation/version}} Doxygen pages]
| |
− | | |
− | == Slice view pipeline ==
| |
− | | |
− | {|
| |
− | |[[Image:SliceView.png|thumb|400px]]
| |
− | |}
| |
− | | |
− | VTK/MRML pipeline for the 2D slice views: [[File:SliceView.pptx]].
| |
− | | |
− | == History ==
| |
− | | |
− | See Data Model notes in [http://wiki.na-mic.org/Wiki/index.php/AHM_2006:ProjectsSlicerDataModel AHM 2006 Programming week project].
| |
− | | |
− | == Path-based MRML proposal ==
| |
− | | |
− | Mike's proposal for a [[Slicer3:MRML3_Path|path-based MRML3 representation]], based on extending the Coordinate Space Manager ideas to the entire MRML3 tree
| |
− | | |
− | == Slicer Daemon == | |
− | | |
− | The goal of the [[Slicer3:Slicer_Daemon|Slicer Daemon]] project is to allow remote editing of the MRML data model by external programs over a socket.
| |
− | | |
− | == EventBroker Discussion ==
| |
− | | |
− | The [[Slicer3:EventBroker|Event Broker]] is a proposal to improve the way events are managed inside slicer.
| |
− | | |
− | = 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)
| |
− | | |
− | <br />
| |
− | | |
− | == 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 ==
| |
− | | |
− | [http://en.wikibooks.org/wiki/XML:_Managing_Data_Exchange A wikibook on XML]
| |
− | | |
− | The [http://en.wikibooks.org/wiki/XML:_Managing_Data_Exchange/The_many-to-many_relationship#ID.2FIDRE section on ID/IDREF implementations], which are similar to what we use in MRML.
| |