Documentation/4.6/Developers/Units
For the latest Slicer documentation, visit the read-the-docs. |
Contents
Slicer Units Overview
The Unit module is a loadable module that allows the application to have a notion of unit. A unit is defined by its quantity (cf SI and quantities) and its name.
Intended capabilities
Units are intended to be used to describe the quantity of a given object. Units should help the application to be smarter about how the user can access/view/interact with the data. For example, units help the user by displaying the current unit in spinboxes as a suffix (1.3mm instead of 1.3).
Architecture
Settings
Right now, there are two quantities supported (time and length). For each of these, there is an associated unit node which properties are saved in the settings. These unit nodes are not saved with the scene, they just are settings.
Selection Node
In order to propagate units in the application easily, access methods were added to the selection so it could stores the information regarding the current unit for a given quantity. These methods are based on the reference role of the vtkMRMLNode. The signal vtkMRMLSelectionNode::UnitModifiedEvent was added to the selection node so the application could be updated when a unit is modified/added/removed.
Unit Nodes
vtkMRMLUnitNode are singleton and NOT saved in the scene. They have the following properties:
- Name: The name describes the unit itself. For example, the name of a length unit can be Millimeter, Meter, Centimeter... Setting the node's name also sets the node's singleton tag.
- Quantity: This properties is an attribute so it can be observed by the GUI. It describes what types of unit it is. For example the quantity of second and day is time.
- Precision: Describes the number of digit used after the comma. For example a precision of 2 gives 12.00 and -13.61.
- Prefix/Suffix: Abbreviation/text displayed respectively before and after the unit.
- Minimum Value/Maximum Value: Range of value allowed for the unit. For example, the minimum for the Kelvin value would be 0.
How to access an Unit ?
Units can be accessed through the selection node.
In logic/nodes
For one-time access, it's preferable to do the following:
vtkMRMLSelectionNode* selectionNode = vtkMRMLSelectionNode::SafeDownCast( this->GetMRMLScene()->GetNthNodeByClass(0, "vtkMRMLSelectionNode")); if (selectionNode) { vtkMRMLUnitNode* unitNode = selectionNode->GetUnitNode(quantity); // Note: most often quantity will be a const string like "length" or "time" ... }
If a unit needs to be accessed multiple times (very unlikely), then one can observe the selection nodes vtkMRMLSelectionNode::UnitModifiedEvent.
In the GUI
Three qMRMLWidget have been added (or modified) to integrate unit support:
- qMRMLSpinBox
- qMRMLCoordinateWidget
- qMRMLSliderWidget
- qMRMLRangeWidget
Quantity
These widget derive directly from their CTK counterpart and only add two methods.
- SetMRMLScene() (which is expected for a qMRMLWidget) so they can observe the selection node UnitModifiedEvent
- The "quantity" property. Setting this property (setQuantity()) tells the widget what kind of unit node it should refer to. If a unit node with such quantity is default in the application, the widget will automatically update its minimum value, maximum value, single step, decimals, prefix and suffix according to the unit node.
Customization
In the case where one doesn't want all the parameters of its spinbox controled by the current unit node, one can choose which properties will be updated by setting the unitAwareProperties flag.