https://www.slicer.org/w/api.php?action=feedcontributions&user=Sunderlandkyl&feedformat=atomSlicer Wiki - User contributions [en]2024-03-28T20:28:38ZUser contributionsMediaWiki 1.33.0https://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/Tutorials/MigrationGuide/Slicer&diff=63312Documentation/Nightly/Developers/Tutorials/MigrationGuide/Slicer2020-06-25T17:46:56Z<p>Sunderlandkyl: Add FreeSurfer migration info</p>
<hr />
<div><noinclude>__TOC__</noinclude><br />
==Slicer backward incompatible changes==<br />
<br />
===Slicer 5.0: API changes since 4.10===<br />
<br />
*Removed protected method <tt>vtkMRMLModelDisplayableManager::FindPickedDisplayNodeFromMesh</tt><br />
<br />
====Python 2 to Python 3====<br />
<br />
Slicer core has been updated to only support Python 3.<br />
<br />
C++ classes and python scripts have been updated to use idioms and constructs only available in Python 3.<br />
<br />
Update to python scripts have been done leveraging the CLI provided by https://python-future.org by (1) iteratively applying each one of the associates "fixes", (2) reviewing associated changes and (3) updating as needed.<br />
<br />
Updates specific to extensions are discussed in [[Documentation/Nightly/Developers/Tutorials/MigrationGuide#Slicer_5.0:_Python2_to_Python3]]<br />
<br />
====Interactor styles====<br />
<br />
Limitations of VTK widgets (editable points, lines, curves, etc.) prevented Slicer from having sophisticated user interaction in slice and 3D views. In Slicer5, we replaced VTK widgets with MRML widgets. These widgets are still VTK-based and somewhat similar to VTK widgets, but they operate directly on MRML nodes, they use direct method calls between widgets and their representation, and they use a more efficient and flexible event processing. Instead of hardcoding how viewers behave in response to interaction (mouse move, button click, keyboard, ...) events in an interactor style, all these events are translated to actions and performed in a MRML widget. Most modules are not expected to observe interactor events or styles directly, but if they did, then they may need to be updated accordingly.<br />
<br />
*vtkSliceViewInteractorStyle renamed to vtkMRMLSliceDViewInteractorStyle to reflect that it uses MRML classes directly.<br />
*vtkThreeDViewInteractorStyle renamed to vtkMRMLThreeDViewInteractorStyle to reflect that it uses MRML classes directly.<br />
<br />
====slicer.util functions====<br />
<br />
*slicer.util.loadVolume (and other node load functions) now return the loaded node instead of a True/False flag. In case of an error, a RuntimeError exception is thrown.<br />
**Old way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd', returnNode=True)[1]</code><br />
**New way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd')</code><br />
<br />
====Markups====<br />
<br />
*<tt>vtkCommand::Modified</tt> events are no longer invoked when control points are added/removed/modified to improve performance. Modules that need to know If a point position is modified need to add observers to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt> events. See example in [[Documentation/Nightly/ScriptRepository#Get_a_notification_if_a_markup_point_position_is_modified|script repository]].<br />
*<tt>vtkMRMLMarkupsNode::MarkupAddedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>. This is called even when preview point is created. Use <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> to get notification only when position of a point becomes defined (and not during preview).<br />
*<tt>vtkMRMLMarkupsNode::MarkupRemovedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>. This is called even when preview point is removed. Use <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> to get notification only when position of a point becomes undefined (and not during preview).<br />
*<tt>vtkMRMLMarkupsNode::NthMarkupModifiedEvent</tt> is replaced by <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt><br />
*During placement of markups, a preview markup point is created. If number of already placed markup points needs to be determined then <code>GetNumberOfDefinedControlPoints()</code> method can be used.<br />
*<tt>GetDefaultMarkups...()</tt> and <tt>SetDefaultMarkups...()</tt> methods are removed. Instead default display node can be accessed by <tt>GetDefaultMarkupsDisplayNode()</tt> method and default values can be get/set in that class.<br />
*<tt>vtkMRMLMarkupsNode::GetNthMarkupSelected()</tt> is replaced by <tt>GetNthControlPointSelected()</tt><br />
*<tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> event is added. This event is invoked whenever position is defined for a new point.<br />
*<tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> event is added. This event is invoked whenever point with defined position is removed (point is deleted or its position gets undefined).<br />
*For more details, see [{{doxygen-class-url|vtkMRMLMarkupsNode}} vtkMRMLMarkupsNode]<br />
<br />
====Segmentations====<br />
<br />
Binary labelmap segmentations can now be represented as shared labelmaps.<br />
The previous implementation of binary labelmaps was performance intensive as each labelmap was represented using a separate vtkDataObject.<br />
Visualizing and editing segmentations that contained a large number of segments could cause performance issues, due to the large number of vtkActors required, as well as calculating masks and overwriting other segments when editing.<br />
<br />
By default, newly created segments will now be contained on the same layer.<br />
Segments will only be separated into multiple layers if the user creates an overlapping segment when editing.<br />
<br />
Segments are now saved as a 4D volume with shared 3D layers.<br />
For a segmentation that only uses one layer, the resulting image is a 3D volume.<br />
Before saving, the labelmaps will be collapsed into as few layers as possible.<br />
<br />
*seg.nrrd files now contain two additional attributes for each segment: SegmentX_LabelValue and SegmentX_Layer<br />
*The label value of a segment can be found using vtkSegment::GetLabelValue()<br />
*Whether or not a segment is shared can be found using vtkSegmentation::IsSharedBinaryLabelmap()<br />
*The other segments sharing the same labelmap can be found using vtkSegmentation::GetSegmentIDsSharingBinaryLabelmapRepresentation()<br />
*Segment editor effects should generally use modifySelectedSegmentByLabelmap rather than SetBinaryLabelmapToSegment to manage layer separation<br />
*Conversion rules now call PreConvert() and PostConvert() before and after conversion to perform pre and post processing steps on the segmentation as a whole<br />
*The function signature for vtkSegmentationConverterRule::Convert now accepts a vtkSegment rather than two vtkDataObjects<br />
*slicer.util.arrayFromSegment has been deprecated. slicer.util.arrayFromSegmentBinaryLabelmap and slicer.util.arrayFromSegmentInternalBinaryLabelmap can be used instead<br />
<br />
=====Erase the contents of a single segment=====<br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.ClearSegment(segmentId)<br />
</pre><br />
<br />
=====Set labelmap in a segment=====<br />
<br />
Directly, bypassing masking settings:<br />
<br />
<pre><br />
slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(orientedImageDataToSet, segmentationNode, segmentId)<br />
</pre><br />
<br />
=====Move a segment from a shared labelmap to a separate layer=====<br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.SeparateSegmentLabelmap(segmentId)<br />
</pre><br />
<br />
=====Combine all binary labelmaps to as few layers as possible=====<br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.CollapseBinaryLabelmaps(forceToSingleLayer=false)<br />
</pre><br />
<br />
<b>Get a read-only labelmap for a single segment:</b><br />
<br />
<pre><br />
labelmap = slicer.vtkOrientedImageData()<br />
segmentationNode.GetBinaryLabelmapRepresentation(segmentId, labelmap)<br />
</pre><br />
<br />
(similarly, use GetClosedSurfaceRepresentation with an additional vtk.vtkPolyData parameter to get a read-only surface mesh)<br />
<br />
or<br />
<br />
<pre><br />
labelmapNumpyArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId)<br />
</pre><br />
<br />
=====Get a modifiable shared labelmap=====<br />
<br />
<pre><br />
labelmap = slicer.vtkOrientedImageData()<br />
segmentationNode.GetBinaryLabelmapInternalRepresentation(segmentId, labelmap)<br />
</pre><br />
<br />
(similarly, use GetClosedSurfaceInternalRepresentation to get a modifiable surface mesh)<br />
<br />
or<br />
<br />
<pre><br />
labelmapNumpyArray = slicer.util.arrayFromSegmentInternalBinaryLabelmap(segmentationNode, segmentId)<br />
</pre><br />
<br />
=====Export segments to models=====<br />
<br />
Model hierarchies no longer exist in Slicer5, but instead various kinds of hierarchies are now replaced by "subject hierarchy", which can accommodate any node types in a single hierarchy. Accordingly, `ExportSegmentsToModelHierarchy`, `ExportAllSegmentsToModelHierarchy`, etc. are replaced by `ExportSegmentsToModels`, `ExportAllSegmentsToModels`, which take a subject hierarchy folder item ID as input.<br />
Documentation/Nightly<br />
See code example in [[Documentation/{{documentation/version}}/ScriptRepository#Export_model_nodes_from_segmentation_node|script repository]].<br />
<br />
====Volume rendering====<br />
<br />
vtkMRMLVolumeRenderingDisplayNode::SetAndObserveVolumeNodeID method was removed, as display node base class already maintains a pointer to the displayed (volume) node. To associate a volume display node with a volume node, call <pre>volumeNode->AddAndObserveDisplayNodeID(volumeRenderingDisplayNode->GetID());</pre> after both nodes are added to the scene.<br />
<br />
===Slicer 5.0: SlicerPython was removed. Use PythonSlicer instead===<br />
<br />
<b>Error message:</b><br />
<br />
<pre><br />
SlicerPython executable is obsolete and will be removed. Use PythonSlicer executable instead.<br />
For more details, see https://github.com/Slicer/Slicer/issues/4843<br />
</pre><br />
<br />
<b>Solution:</b><br />
<br />
Use <tt>PythonSlicer</tt> instead of <tt>SlicerPython</tt><br />
<br />
<b>Background:</b><br />
<br />
Python IDEs (specifically PyCharm, but potentially others) only recognize <tt>Python*.exe</tt> files as Python interpreters.<br />
<br />
To allow using Slicer's Python interpreter in these IDEs, we had to add <tt>PythonSlicer</tt>, but kept <tt>SlicerPython</tt> around for not immediately breaking things.<br />
<br />
This redundancy is confusing for users that we could resolve by simply removing SlicerPython for Slicer5.<br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/issues/4843<br />
<br />
===Slicer 5.0: Models are saved in LPS coordinate system by default===<br />
<br />
While Slicer uses RAS coordinate system internally, images, transforms, and markups files are stored in LPS coordinate system, because DICOM and all medical image computing software (maybe except a few very old ones) uses LPS coordinate system in files.<br />
<br />
However, Slicer has been still using its internal RAS coordinate system in mesh files (STL, VTK, VTP, OBJ, PLY), which caused issues when interfacing with third-party software.<br />
<br />
From Slicer-4.11.0-2020-02-26 (revision 28794) models are saved in LPS coordinate system, and mesh files assumed to be in LPS coordinate system by default (if no other coordinate system specified in the file).<br />
<br />
Slicer started embedding coordinate system name in mesh files a few years ago (see <code>SPACE=RAS</code> in the file header), so all the files that Slicer saved in recent years will load correctly and any scene files created with any version of Slicer will also load the models with correct orientation, too.<br />
<br />
Manual setting of coordinate system (in Add data dialog / Options column) is only needed when loading a mesh file without a scene that were created by Slicer-4.6 (2017-09-27) and earlier; and obj files created by Slicer-4.6 and Slicer-4.8 (between 2016-10-11 and 2018-03-26), or files are created by third-party software in RAS coordinate system.<br />
<br />
If you encounter orientation issues when loading a model file, you have the following options:<br />
<br />
*Option A: Specify the coordinate system when you open the model file. In “Add data” dialog, click “Show Options” and then choose “RAS” as coordinate system.<br />
*Option B: Update the third-party software that generate the mesh to save coordinates in LPS coordinate system instead of RAS coordinate system. Conversion is simple inverting the sign of the first two coordinates.<br />
*Option C: Write <code>SPACE=RAS</code> in the comment/description field in the mesh file (for STL, OBJ, PLY, VTK file; for VTP files, add in the first value of a vtkStringArray field array named <code>SPACE</code>) to indicate that the values are stored in RAS coordinate system. This option is useful if coordinates have to be stored in RAS coordinate system (for example, for compatibility with other software). See implementation example [https://github.com/Slicer/SlicerGitSVNArchive/blob/c0829f596f0ea661e0c5484056bd1374a3d22958/Libs/MRML/Core/vtkMRMLModelStorageNode.cxx#L421-L647 here].<br />
<br />
See more information, discussion of this topic on the [https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446 Slicer forum].<br />
<br />
===Slicer 5.0: Sequences extension has been merged into Slicer core===<br />
<br />
Sequences extension has been merged into Slicer core, therefore extensions do not need to depend on Sequences extension anymore.<br />
<br />
SequenceBrowser module has been merged into Sequences module, therefore previous code that used SequenceBrowser module now should use Sequences module instead.<br />
<br />
=== Slicer 5.0: FreeSurfer support has been removed from Slicer core ===<br />
The loading of FreeSurfer models and scalar overlays, as well as the FreeSurfer-specific color nodes, have been moved to the new [https://github.com/PerkLab/SlicerFreeSurfer SlicerFreeSurfer] extension. Tutorials on how to use the FreeSurfer Importer module to load multiple files at once can be found on the [https://github.com/PerkLab/SlicerFreeSurfer/wiki/Tutorials SlicerFreeSurfer tutorial page].<br />
<br />
===Slicer 5.0 : Avoid typedef of anonymous structure===<br />
<br />
Due to a recent (but retroactive) C++ rule change, only sufficiently C-compatible classes are permitted to be given a typedef name for linkage purposes. Add an <tt>enabled-by-default</tt> warning for these cases, and rephrase our existing error for the case where we encounter the <tt>typedef</tt> name for linkage after we've already computed and used a wrong linkage in terms of the new rule.<br />
<br />
<b>To fix warning message similar to:</b><br />
<br />
<pre><br />
Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:95:17:<br />
warning: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Wnon-c-typedef-for-linkage]<br />
typedef struct<br />
^<br />
ColumnInfo<br />
Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:99:5:<br />
note: type is not C-compatible due to this default member initializer<br />
int ScalarType = VTK_STRING;<br />
^~~~~~~~~~~~~~<br />
Slicer/Libs/MRML/Core/vtkMRMLTableStorageNode.h:102:5:<br />
note: type is given name 'ColumnInfo' for linkage purposes by this typedef declaration<br />
} ColumnInfo;<br />
^<br />
For consistency, Use 'using' to a named structure definintion for all <br />
structures.<br />
</pre><br />
<br />
<b>Replace code like this:</b><br />
<br />
<pre><br />
typedef struct<br />
{<br />
std::string ColumnName;<br />
std::vector<vtkAbstractArray*> RawComponentArrays;<br />
int ScalarType = VTK_STRING;<br />
std::vector<std::string> ComponentNames;<br />
std::string NullValueString;<br />
} ColumnInfo;<br />
</pre><br />
<br />
<b>By this:</b><br />
<br />
<pre><br />
struct StructColumnInfo<br />
{<br />
std::string ColumnName;<br />
std::vector<vtkAbstractArray*> RawComponentArrays;<br />
int ScalarType = VTK_STRING;<br />
std::vector<std::string> ComponentNames;<br />
std::string NullValueString;<br />
};<br />
using ColumnInfo = struct StructColumnInfo;<br />
</pre><br />
<br />
<br />
<b>References:</b><br />
<br />
https://reviews.llvm.org/D74103<br />
<br />
===Slicer 4.11: Variable CMAKE_DEFAULT_BUILD_TYPE renamed to Slicer_DEFAULT_BUILD_TYPE===<br />
<br />
Setting the default build type for single config generator may be done setting <tt>Slicer_DEFAULT_BUILD_TYPE</tt> instead of <tt>CMAKE_DEFAULT_BUILD_TYPE</tt>.<br />
<br />
<b>Error message similar to:</b><br />
<br />
<pre><br />
CMake Error:<br />
Generator<br />
<br />
Visual Studio 15 2017<br />
<br />
does not support variable<br />
<br />
CMAKE_DEFAULT_BUILD_TYPE<br />
<br />
but it has been specified.<br />
</pre><br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/pull/4799<br />
<br />
===Slicer 4.11: teem python module renamed to vtkTeem, explicit import required===<br />
<br />
*Since the module provides VTK classes interfacing with "teem", the name is now representative of the class it contains.<br />
*<tt>vtkTeem</tt> classes are expected to be used by explicitly importing the module.<br />
<br />
<b>Replace code like this:</b><br />
<br />
<pre><br />
import teem<br />
<br />
class CalculateTensorScalars(object):<br />
def __init__(self):<br />
self.dti_math = teem.vtkDiffusionTensorMathematics()<br />
</pre><br />
<br />
<b>By this:</b><br />
<br />
<pre><br />
import vtkTeem<br />
<br />
class CalculateTensorScalars(object):<br />
def __init__(self):<br />
self.dti_math = vtkTeem.vtkDiffusionTensorMathematics()<br />
</pre><br />
<br />
===Slicer 4.11: Display window/level (brightness/contrast) adjustment===<br />
<br />
*A new "Window/level" mouse interaction mode was introduced. Volume display window/level can only be changed if this mode is activated by clicking the corresponding button in the toolbar. The new mouse mode prevents accidental modification of volume window/level (when for example the user accidentally clicked too far from a markup) and it also allows more sophisticated window/level adjustments.<br />
*New region-based auto window/level feature added: activate "Window/level" mouse mode and use Ctrl + left-click-and-drag to highlight a region and optimize window/level for that (pressing Escape or right-click cancels the operation).<br />
*Auto window/level reset: activate "Window/level" mouse mode and double-click the left mouse button.<br />
*Improved auto window/level algorithm to prevent too bright display of images. Window/level is set to display values between 0.1th and 99.9th percentile of gray levels. See details here: https://discourse.slicer.org/t/feedback-requested-how-to-improve-mouse-interaction-in-views/6420.<br />
*Removed class <tt>vtkImageBimodalAnalysis</tt><br />
<br />
===Slicer 4.10: Registration of runTest function done in ScriptedLoadableModule base class===<br />
<br />
Following [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27617 r27617]:<br />
<br />
*the <code>ScriptedLoadableModule</code> class takes care of registering the <code>runTest</code> function.<br />
*the <code>runTest</code> function expects <code>msec</code> keyword argument.<br />
<br />
<b>Error message similar to:</b><br />
<br />
<pre><br />
Traceback (most recent call last):<br />
File "/path/to/Slicer-SuperBuild/Slicer-build/bin/Python/slicer/ScriptedLoadableModule.py", line 205, in onReloadAndTest<br />
test(msec=int(slicer.app.userSettings().value("Developer/SelfTestDisplayMessageDelay")), **kwargs)<br />
TypeError: runTest() got an unexpected keyword argument 'msec'<br />
Reload and Test: Exception!<br />
<br />
runTest() got an unexpected keyword argument 'msec'<br />
</pre><br />
<br />
<b>Replace code like this:</b><br />
<br />
<pre><br />
class sceneImport2428(ScriptedLoadableModule):<br />
[...]<br />
def __init__(self, parent):<br />
ScriptedLoadableModule.__init__(self, parent)<br />
parent.title = "..."<br />
[...]<br />
parent.acknowledgementText = "..."<br />
self.parent = parent <br />
<br />
# Add this test to the SelfTest module's list for discovery when the module <br />
# is created. Since this module may be discovered before SelfTests itself, <br />
# create the list if it doesn't already exist. <br />
try: <br />
slicer.selfTests <br />
except AttributeError: <br />
slicer.selfTests = {} <br />
slicer.selfTests['sceneImport2428'] = self.runTest <br />
<br />
def runTest(self): <br />
tester = sceneImport2428Test() <br />
tester.runTest()<br />
<br />
[...]<br />
</pre><br />
<br />
<b>By this:</b><br />
<br />
<pre><br />
class sceneImport2428(ScriptedLoadableModule):<br />
[...]<br />
def __init__(self, parent):<br />
ScriptedLoadableModule.__init__(self, parent)<br />
parent.title = "..."<br />
[...]<br />
parent.acknowledgementText = "..."<br />
<br />
[...]<br />
</pre><br />
<br />
===Slicer 4.9: Update of VTK version from 9.0 to 8.2===<br />
<br />
Following [https://github.com/Kitware/VTK/commit/b703d78be3ffd8ae69c319afa0230097ff270f26 kitware/VTK@b703d78be], VTK has updated to use version number 8.2 instead of 9.0. This was discussed in on the VTK mailing list in http://vtk.1045678.n5.nabble.com/Discussion-OK-to-change-VTK-s-version-number-from-9-0-to-8-2-tt5748702.html<br />
<br />
At first, this VTK commit and its companion [https://github.com/Kitware/VTK/commit/8a00b357e84eec695bda049216f30f2b76d80855 kitware/VTK@8a00b357e] were both reverted from the [https://github.com/Slicer/VTK/ Slicer/VTK] fork. Then, since having the corresponding changes reverted in VTK was not possible, it was decided to also update Slicer. This was done in the following commits:<br />
<br />
*[http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27472 r27472]: COMP: Update c++ classes to support building against VTK >= 9 and VTK >= 8.2<br />
*[http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27473 r27473]: COMP: Update VTK to include version change from 9.0 to 8.2. Fixes #4623<br />
<br />
This means that code depending on VTK must also be updated to include similar fixes.<br />
<br />
'''Replace this:'''<br />
#if VTK_MAJOR_VERSION >= 9<br />
<br />
'''By this:'''<br />
#if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 2)<br />
<br />
and<br />
<br />
'''Replace this:'''<br />
#if VTK_MAJOR_VERSION < 9<br />
<br />
'''By this:'''<br />
#if VTK_MAJOR_VERSION <= 7 || (VTK_MAJOR_VERSION <= 8 && VTK_MINOR_VERSION <= 1)<br />
<br />
<br />
===Slicer 4.9: ITK_LEGACY_REMOVE is now OFF===<br />
In preparation to switch to ITK 5.0, we disable legacy functionality in ITK. This might affect some modules which rely on ITK. Take a look at [https://itk.org/migrationv4 ITK 4 migration guide] before [https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md ITK 5 migration guide].<br />
<br />
===Slicer 4.9: vtkMRMLPlotDataNode renamed to vtkMRMLPlotSeriesNode===<br />
Plotting was improved in [https://github.com/Slicer/Slicer/commit/082edc40c this commit]<br />
<br />
'''Replace this:'''<br />
<br />
vtkMRMLPlotDataNode<br />
<br />
'''By this:'''<br />
vtkMRMLPlotSeriesNode<br />
<br />
===Slicer 4.9: CMake: Module MIDAS not available===<br />
<br />
The test infrastructure of your project should be updated to use [https://cmake.org/cmake/help/latest/module/ExternalData.html ExternalData] built-in CMake module<br />
instead of the specific <tt>MIDAS</tt> module.<br />
<br />
See EMSegment commit [http://viewvc.slicer.org/viewvc.cgi/Slicer3?view=revision&revision=17150 r17150] for an example of transition.<br />
<br />
This means that instead of using <tt>midas_add_test</tt> with the <tt>MIDAS{path/to/file.ext.md5}</tt><br />
syntax for addressing the test data, the function [https://cmake.org/cmake/help/latest/module/ExternalData.html#command:externaldata_add_test ExternalData_add_target] is used by<br />
specifying both <tt>DATA{path/to/file.ext}</tt> and a download target name.<br />
<br />
'''Replace this:'''<br />
<br />
midas_add_test(NAME test1 COMMAND ...)<br />
midas_add_test(NAME test2 COMMAND ...)<br />
<br />
'''By this:'''<br />
<br />
ExternalData_add_test(EMSegmentData NAME test1 COMMAND ...)<br />
ExternalData_add_test(EMSegmentData NAME test2 COMMAND ...)<br />
<br />
[...]<br />
<br />
ExternalData_add_target(EMSegmentData)<br />
<br />
<br />
A key difference with the former approaches is that instead of adding two tests (one named<br />
<tt><testName>_fetchData</tt> to downoad the data and one running the test command), only one<br />
test is added but a common download target is added at the end using [https://cmake.org/cmake/help/latest/module/ExternalData.html#command:externaldata_add_target ExternalData_add_target]<br />
function.<br />
<br />
This means that test data can now be downloaded in parallel (and cached) at build time instead<br />
of testing time.<br />
<br />
===Slicer 4.9: CMake: Module SlicerMacroCheckExternalProjectDependency not available===<br />
<br />
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26992 r26992], consider updating<br />
your build system to use CMake module <code>ExternalProjectDependency</code><br />
<br />
===Slicer 4.9: CMake: Module SlicerMacroEmptyExternalProject not available===<br />
<br />
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26991 r26991]<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
include(SlicerMacroEmptyExternalProject)<br />
<br />
[...]<br />
<br />
SlicerMacroEmptyExternalProject("${proj}" "${${proj}_DEPENDENCIES}")<br />
</pre><br />
<br />
'''By this:'''<br />
<br />
<pre><br />
include(ExternalProjectDependency)<br />
<br />
[...]<br />
<br />
ExternalProject_Add_Empty(${proj} DEPENDS ${${proj}_DEPENDENCIES})<br />
</pre><br />
<br />
===Slicer 4.9: CMake: Module SlicerBlockSetCMakeOSXVariables not available===<br />
<br />
Since it was renamed to <tt>SlicerInitializeOSXVariables</tt> in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26982 r26982]<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
include(SlicerBlockSetCMakeOSXVariables)<br />
</pre><br />
<br />
'''By this:'''<br />
<br />
<pre><br />
include(SlicerInitializeOSXVariables)<br />
</pre><br />
<br />
===Slicer 4.9: Application: isRelease() function not available===<br />
<br />
See [[#Slicer_4.8:_Application:_isRelease.28.29_function_not_available_or_deprecated]]<br />
<br />
===Slicer 4.9: slicer.util.getNode() raises exception if node not found===<br />
<br />
If slicer.util.getNode() is called and the node is not found then instead of just returning None (Slicer 4.8 behavior), the method now raises a MRMLNodeNotFoundException. This makes code debugging easier (the error is reported when it happens), and in general more consistent with Python conventions.<br />
<br />
How to update existing code:<br />
<br />
It is advisable to only use slicer.util.getNode in tests, or interactively in the Python console, as its behavior is somewhat unpredictable (it may either found a node by name or ID, and result of wildcard search is even less deterministic). In general, it is recommended to use the MRML scene's GetFirstNodeByName and GetNodeByID methods instead.<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
n = slicer.util.getNode(nodeNameOrID)<br />
</pre><br />
<br />
'''By one of these:'''<br />
<br />
If node is to be found by name:<br />
<pre><br />
n = slicer.mrmlScene.GetFirstNodeByName(nodeName)<br />
</pre><br />
<br />
If node is to be found by ID:<br />
<pre><br />
n = slicer.mrmlScene.GetNodeByID(nodeID)<br />
</pre><br />
<br />
If node is to be found by name or ID (slower, less predictable, recommended for testing only):<br />
<br />
<pre><br />
try:<br />
n = slicer.util.getNode(nodeNameOrID)<br />
except slicer.util.MRMLNodeNotFoundException:<br />
n = None<br />
</pre><br />
<br />
More information: https://github.com/Slicer/Slicer/commit/b63484af1b1b413f35396f8f7efb73e870448bd4<br />
<br />
===Slicer 4.8: Application: isRelease() function not available or deprecated===<br />
<br />
<b>Error message similar to:</b><br />
<br />
Missing/deprecated qSlicerCoreApplication::isRelease()<br />
<br />
or<br />
<br />
Missing/deprecated slicer.app.isRelease()<br />
<br />
<br />
<b>Solution:</b><br />
<br />
Use <tt>qSlicerCoreApplication::releaseType() == "Stable"</tt><br />
<br />
<b>Summary:</b><br />
<br />
Prior to r26420, the variable <tt>Slicer_VERSION_TWEAK</tt> was used to check if a "stable release" was built. The variable value<br />
was set by updating the sources and defining the variable to an integer greater or equal to 0. In other word, if the variable<br />
evaluated to an empty string, a nighty or experimental build was being done, if it evaluated to an integer, a stable release build<br />
was being done.<br />
<br />
The approach had few issues:<br />
<br />
*the name of the variable was confusing<br />
*identifying a "stable release" only from a source tree revision was not enough. Indeed the environment defining a "release" is the one found on the build machines used to generate the installer.<br />
*nightly build are also considered as release<br />
<br />
To address this, the CMake variable <tt>Slicer_RELEASE_TYPE</tt> was introduced. As of 2017-10-04, it can be set to <tt>Experimental</tt>, <tt>Nightly</tt><br />
or <tt>Stable</tt> with <tt>Experimental</tt> being the value hard-coded in the source.<br />
<br />
Identifying a build as "stable" is now explicitly done by setting <tt>Slicer_RELEASE_TYPE</tt> to <tt>Stable</tt> at configure time.<br />
<br />
Also, since the concept of release types was introduced, the function <tt>isRelease()</tt> has been removed in favor of <tt>releaseType()</tt>.<br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/pull/354<br />
<br />
===Slicer Python Module: modulewidget and others removed.===<br />
<br />
<b> Summary</b><br />
Python classes formerly in "slicer.moduledm", "slicer.modulelogic", "slicer.modulemrml"<br />
and "slicer.modulewidget" are now directly available in the slicer module.<br />
<br />
See example of change [https://github.com/QIICR/LongitudinalPETCT/pull/11 here].<br />
<br />
<b>Rational:</b><br />
<br />
See comments in commit messages referenced blow.<br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/commit/628f83fe7a6f4e0710e306bcaf7c04b9e3e5e6bd<br />
<br />
https://github.com/Slicer/Slicer/commit/9cb5668fde1abc8f0430a91ca37fc29277ceeb4e<br />
<br />
===MRML: Slicer 4.6: Moved up vtkMRMLStorableNode in the MRML node hierarchy.===<br />
<br />
<b>Rational:</b><br />
<br />
vtkMRMLStorableNode is not a children of vtkMRMLTransformable node anymore,<br />
but directly a children of vtkMRMLNode.<br />
<br />
This allows making a node storable without requiring it to be also<br />
transformable. It is important for several node types (color maps, tables,<br />
etc), which require separate storage node but are not transformable.<br />
<br />
<b>References:</b><br />
<br />
*Changed introduced in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24891 r24891]<br />
<br />
<b>Error message similar to:</b><br />
<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx: In member function ‘void vtkMRMLLongitudinalPETCTStudyNode::ObserveRegistrationTransform(bool)’:<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:478:28: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘GetParentTransformNode’<br />
&& propNode->GetParentTransformNode()<br />
^<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:480:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’<br />
propNode->SetAndObserveTransformNodeID(<br />
^<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:503:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’<br />
propNode->SetAndObserveTransformNodeID(NULL);<br />
^<br />
<br />
<b>Solution:</b><br />
<br />
Removes lines and/or refactor code<br />
<br />
<br />
===MRML: Slicer 4.5: Introduction of vtkMRMLLabelMapVolumeNode===<br />
<br />
<b>Rational:</b><br />
<br />
Before <tt>vtkMRMLScalarVolumeNode</tt> was used for both scalar and label map<br />
volumes and the LabelMap custom MRML node attribute was used for<br />
distinguishing between them (0=scalar; 1=label map volume).<br />
<br />
This made conversion between labelmap/scalar volumes very easy but made<br />
it difficult to customize behavior, display, processing of segmentation<br />
information.<br />
<br />
Now a new <tt>vtkMRMLLabelMapVolumeNode</tt> class is used for storing segmentation<br />
information (still using <tt>vtkMRMLScalarVolume</tt> used as base class for backward<br />
compatibility; but in the future the base class may be changed to reflect<br />
that segmentation can be represented in various ways, not just as volumes).<br />
<br />
<b>Error message similar to:</b><br />
<br />
error: ‘class vtkMRMLScalarVolumeNode’ has no member named ‘SetLabelMap’<br />
outputVolumeNode->SetLabelMap(1);<br />
^<br />
<br />
<b>Solution (part1: down cast to <tt>vtkMRMLLabelMapVolumeNode</tt>, remove call to <tt>SetLabelMap</tt>)</b><br />
<br />
Replace lines like:<br />
<br />
vtkMRMLNode* outputNode = d->OutputLabelVolumeMRMLNodeComboBox->currentNode();<br />
vtkMRMLScalarVolumeNode* outputVolumeNode = vtkMRMLScalarVolumeNode::SafeDownCast(outputNode);<br />
[...]<br />
outputVolumeNode->SetLabelMap(1);<br />
<br />
<br />
with:<br />
<br />
vtkMRMLLabelMapVolumeNode* outputVolumeNode =<br />
vtkMRMLLabelMapVolumeNode::SafeDownCast(d->OutputLabelVolumeMRMLNodeComboBox->currentNode());<br />
[...]<br />
<br />
<br />
<b>Solution (part2: Update UI file):</b><br />
<br />
Replace lines like:<br />
<br />
<widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox"><br />
<property name="nodeTypes"><br />
<stringlist><br />
<string>vtkMRMLScalarVolumeNode</string><br />
</stringlist><br />
</property><br />
[...]<br />
</widget><br />
<br />
with:<br />
<br />
<widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox"><br />
<property name="nodeTypes"><br />
<stringlist><br />
<string>vtkMRMLLabelMapVolumeNode</string> <------------- Update Here<br />
</stringlist><br />
</property><br />
[...]<br />
</widget><br />
<br />
<br />
<b>Solution (part3: Update node selector configuration):</b><br />
<br />
Replace lines like:<br />
<br />
nodeSelector.setNodeTypes(QStringList("vtkMRMLScalarVolumeNode"));<br />
nodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "1");<br />
<br />
with:<br />
<br />
nodeSelector.setNodeTypes(QStringList("vtkMRMLLabelMapVolumeNode"));<br />
<br />
<br />
<b>References:</b><br />
<br />
*https://www.slicer.org/wiki/Documentation/Labs/Segmentations#vtkMRMLLabelMapVolumeNode_integration* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24291<br />
<br />
<br />
===CLI: Slicer 4.3: Add ITKFactoryRegistration library centralizing ITK IO factory registration===<br />
<br />
<b>Rational:</b><br />
<br />
Linking against <tt>ITKFactoryRegistration</tt> ensures that ITK IO factory are properly registered on all supported platforms.<br />
<br />
<b>Error message similar to:</b><br />
<br />
Undefined symbols for architecture x86_64:<br />
"itk::itkFactoryRegistration()", referenced from:<br />
_main in ImageMakerTest.cxx.o<br />
ld: symbol(s) not found for architecture x86_64<br />
<br />
<b>Solution:</b><br />
<br />
Replace lines like:<br />
<br />
target_link_libraries(${CLP}Test ${CLP}Lib)<br />
<br />
with:<br />
<br />
target_link_libraries(${CLP}Test ${CLP}Lib ${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES})<br />
<br />
<b>References:</b><br />
<br />
*http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=21592<br />
*https://issues.slicer.org/view.php?id=2813</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Modules/VolumeResliceDriver&diff=61559Documentation/Nightly/Modules/VolumeResliceDriver2019-11-14T20:44:14Z<p>Sunderlandkyl: Update link</p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-header}}<br />
<!-- ---------------------------- --><br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Introduction and Acknowledgements}}<br />
{{documentation/{{documentation/version}}/module-introduction-start|{{documentation/modulename}}}}<br />
{{documentation/{{documentation/version}}/module-introduction-row}}<br />
This work is supported by NA-MIC, NCIGT, and the Slicer Community. This work is partially supported by NIH 1R01CA111288-01A1 "Enabling Technologies for MRI-Guided Prostate Interventions" (PI: Clare Tempany), P01-CA67165 "Image Guided Therapy" (PI: Ferenc Joelsz) and AIST Intelligent Surgical Instrument Project (PI: Makoto Hashizume, Site-PI: Nobuhiko Hata).<br><br />
Author: Junichi Tokuda, Laurent Chauvin, Tamas Ungi, Nobuhiko Hata<br><br />
Contact: Junichi Tokuda <email> tokuda@bwh.harvard.edu</email> <br><br />
{{documentation/{{documentation/version}}/module-introduction-row}}<br />
{{documentation/{{documentation/version}}/module-introduction-logo-gallery<br />
|{{collaborator|logo|namic}}|NA-MIC<br />
|{{collaborator|logo|ncigt}}|NCIGT<br />
|{{collaborator|logo|spl}}|SPL<br />
}}<br />
{{documentation/{{documentation/version}}/module-introduction-end}}<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Module Description}}<br />
{|<br />
|<br />
{{documentation/modulename}} module allows updating a reslicing plane by a linear transform node. It is particularly useful for stereotactic surgical navigation, where position and orientation of surgical tools are being detected by 3D position sensor and imported to 3D Slicer; the module can reslice a volumetric image of the patient with a plane along the surgical tool and visualize the sectional image on 2D and 3D viewer on the 3D Slicer window. The module was originally developed part of 3D Slicer OpenIGTLink IF in version 3.x, and became an independent extension since version 4.x. <br />
|}<br />
<br />
{|<br />
|[[Image:Slicer4-VolumeResliceDriver-GUI.png|thumb|400px|VolumeResliceDriver GUI ]]<br />
|}<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Use Cases}}<br />
*Surgical navigation system with optical or EM tracking system<br />
*Tracked catheter navigation<br />
*Ultrasound-guided percunaneous procedure<br />
** See https://github.com/SlicerIGT/SlicerIGT/wiki<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|TUtorial}}<br />
Please follow the [[Media:OpenIGTLinkTutorial_Slicer4.1.0_JunichiTokuda_Oct2012.pdf|OpenIGTLink IF Tutorial presentation file]].<br />
<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Panels and their use}}<br />
<!--<br />
<br />
{|<br />
|[[Image:Slicer4-OpenIGTLinkIF-GUI.png|thumb|200px|OpenIGTLinkIF ]]<br />
|}<br />
{|style="width: 100%"<br />
|<br />
* Connectors panel: The list of connectors and their properties.<br />
**Add ("+") / Remove ("-") buttons: Add / remove connector nodes.<br />
**Properties<br />
***Name: The name of the connector node selected in the list.<br />
***Type: The type of connector node. If "Server" is specified, the connector waits for a connection from OpenIGTLink client.<br />
***Status: Checkbox to turn on/off the server.<br />
***Hostname: The TCP/IP host name of the remote OpenIGTLink server (only available if the connector is client)<br />
***Port: The TCP/IP port number of the remote OpenIGTLink (if the connector is configured as a client) or the port number of this OpenIGTLink connector (if the connector is configured as a server).<br />
| align="right"|<br />
[[Image:Slicer4-OpenIGTLinkIF-Connectors.png|thumb|200px|Connector Properties]]<br />
|-<br />
|<br />
* I/O Configuration panel: The list of nodes that are used to receive/send data through OpenIGTLink connectors.<br />
**IN: The list of incoming data (node names) received through the connector node.<br />
**OUT: The list of outgoing data (node names) sent through the connector node.<br />
| align="right"|<br />
[[Image:Slicer4-OpenIGTLinkIF-IOConfiguration.png|thumb|200px|I/O Configuration Tree interface]]<br />
|}<br />
--><br />
<br />
<br />
<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Similar Modules}}<br />
N/A<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|References}}<br />
#Tokuda J, Fischer GS, Papademetris X, Yaniv Z, Ibanez L, Cheng P, Liu H, Blevins J, Arata J, Golby A, Kapur T, Pieper S, Burdette EC, Fichtinger G, Tempany CM, Hata N, OpenIGTLink: An Open Network Protocol for Image-Guided Therapy Environment, Int J Med Robot 2009; 5(4):423-34.<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Information for Developers}}<br />
{{documentation/{{documentation/version}}/module-developerinfo}}<br />
<br />
{{documentation/{{documentation/version}}/module-subsection|Logo}}<br />
[[Image:VolumeResliceDriverIcon.png]]<br />
<br />
The {{documentation/modulename}} logo is designed by Tamas Ungi (Queen's University).<br />
<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-footer}}<br />
<!-- ---------------------------- --></div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Modules/OpenIGTLinkRemote&diff=61558Documentation/Nightly/Modules/OpenIGTLinkRemote2019-11-14T20:42:03Z<p>Sunderlandkyl: Update links</p>
<hr />
<div><noinclude>{{documentation/versioncheck}}<br />
</noinclude><br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-header}}<br />
<!-- ---------------------------- --><br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Introduction and Acknowledgements}}<br />
Author: Tamas Ungi, Isaiah Norton, Junichi Tokuda<br><br />
Contact: Tamas Unig<email> Tamas Ungi <ungi@cs.queensu.ca> </email> <br><br />
Website: https://github.com/SlicerIGT/VolumeResliceDriver<br><br />
License: [http://www.slicer.org/pages/LicenseText Slicer license]<br />
{{documentation/{{documentation/version}}/module-introduction-row}}<br />
{{documentation/{{documentation/version}}/module-introduction-logo-gallery<br />
|{{collaborator|logo|namic}}|NA-MIC<br />
|{{collaborator|logo|ncigt}}|NCIGT<br />
|{{collaborator|logo|spl}}|SPL<br />
}}<br />
<br />
This work is supported by NA-MIC, NCIGT, and the Slicer Community. This work is partially supported by NIH 1R01CA111288-01A1 "Enabling Technologies for MRI-Guided Prostate Interventions" (PI: Clare Tempany).<br><br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|Extension Description}}<br />
{{documentation/modulename}} <br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|Use Cases}}<br />
<br />
*Transrectal ultrasound (TRUS)-guided prostate interventions<br />
*Neurosurgical navigation<br />
*Navigation for RF/cryo ablation of abdominal organ.<br />
*Ultrasound-guided percunaneous procedure<br />
**See https://github.com/SlicerIGT/SlicerIGT/wiki<br />
<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|Tutorials}}<br />
[[Documentation/Nightly/Modules/OpenIGTLinkRemote/BrainlabTutorial]]<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|Similar Extensions}}<br />
<br />
*[[Documentation/{{documentation/version}}/Modules/OpenIGTLinkIF|OpenIGTLinkIF]]: OpenIGTlinkRemote is designed to be used with OpenIGTLinkIF, which allows importing real-time tool tracking data from external tracking devices e.g. optical tracking system, EM tracking system or real-time image stream from external imaging scanners over the network.<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|References}}<br />
<br />
#[http://wiki.na-mic.org/Wiki/index.php/2012_Summer_Project_Week:OpenIGTLinkIF NA-MIC Summer Project Week 2012 page]<br />
#Tokuda J, Fischer GS, Papademetris X, Yaniv Z, Ibanez L, Cheng P, Liu H, Blevins J, Arata J, Golby A, Kapur T, Pieper S, Burdette EC, Fichtinger G, Tempany CM, Hata N, OpenIGTLink: An Open Network Protocol for Image-Guided Therapy Environment, Int J Med Robot 2009; 5(4):423-34.<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-section|Information for Developers}}<br />
{{documentation/{{documentation/version}}/module-subsection|Logo}}<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/extension-footer}}<br />
<!-- ---------------------------- --></div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61557Documentation/Nightly/Developers/CompressedVideo2019-11-14T20:11:02Z<p>Sunderlandkyl: Add streaming section</p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer compressed video overview and acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame dimensions, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
= Streaming =<br />
Compressed video frames can be streamed from external applications using the SlicerOpenIGTLink extension.<br />
The [https://plustoolkit.github.io/ PLUS Server] application can stream compressed video to Slicer from hardware devices such as webcam and ultrasound.<br />
<br />
=Available codecs and video containers=<br />
The following codecs and video container formats are available in Slicer:<br />
<br /><br />
<br />
<br /><br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<b>Video containers</b><br />
<br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Modules/PlusRemote&diff=61556Documentation/Nightly/Modules/PlusRemote2019-11-14T20:06:01Z<p>Sunderlandkyl: Update link to PLUS user documentation</p>
<hr />
<div><noinclude>{{documentation/versioncheck}}<br />
</noinclude><br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-header}}<br />
<!-- ---------------------------- --><br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Introduction and Acknowledgements}}<br />
{{documentation/{{documentation/version}}/module-introduction-start|{{documentation/modulename}}}}<br />
{{documentation/{{documentation/version}}/module-introduction-row}}<br />
<br><br />
Author: Franklin King (PerkLab, Queen's University)<br><br />
Contributors: Tamas Ungi (PerkLab, Queen's University), Andras Lasso (PerkLab, Queen's University), Amélie Meyer (Télécom Physique Strasbourg, Université de Strasbourg)<br><br />
Contact: Tamas Ungi, <email>ungi@cs.queensu.ca</email><br><br />
{{documentation/{{documentation/version}}/module-introduction-row}}<br />
{{documentation/{{documentation/version}}/module-introduction-logo-gallery<br />
|{{collaborator|logo|cco}}|{{collaborator|longname|cco}}<br />
}}<br />
{{documentation/{{documentation/version}}/module-introduction-end}}<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Module Description}}<br />
Convenience module for sending commands through OpenIGTLink Remote to PLUS. Requires OpenIGTLink Remote module available in the SlicerIGT extension. See PLUS [https://plustoolkit.github.io/usersguide user guide] and [http://perk-software.cs.queensu.ca/plus/doc/nightly/user/PlusServerCommands.html manual] for more information about PLUS server commands.<br />
<br />
'''Demo video:''' https://youtu.be/lfZeXabDjMg<br />
<br />
The module provides the following features:<br />
<br />
*Recording of 2D tracked ultrasound frames<br />
*Volume reconstruction of recorded frames<br />
*Live ultrasound volume reconstruction using scout scanning<br />
*Sending Transform Update command to PLUS server<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Use Cases}}<br />
Some ultrasound-guided interventions require a general view of an entire area followed by more detailed images of a specific region. One example is spinal injection procedures. The problem is that, for elderly patients, the epidural area is not directly visible in ultrasound images because the intervertebral space is often compressed or deformed. In this case, physicians use four vertebrae landmarks to estimate the position of the target. Visualization can be improved using reconstructed 3D ultrasound volumes, but often there is not enough time for high resolution reconstruction of a large area during interventions.<br />
<br />
The live ultrasound volume reconstruction workflow using scout scanning is then adapted for these procedures. The two-step method allows user to perform quick low resolution scout scan followed by high resolution volume reconstruction of a selected region of interest, in real-time. Low resolution scout scanning offers visualization of the global area and selection of the region of interest, and then high resolution reconstruction provides a good image quality of the targeted region. <br />
<br />
<gallery widths="250px" heights="200px" perrow="3"><br />
Image:VolRec_Workflow.jpg|Workflow for live ultrasound volume reconstruction using scout scanning<br><br />
Image:PlusRemote_phantom_scan.jpg|Completed scout scan (left-side image), live update of reconstruction (middle) and final live reconstructed volume (right) of a spine phantom<br><br />
Image:PlusRemote_volunteer_scan.jpg|Scout scan (left) and live reconstruction (right) of an adult spine<br><br />
</gallery><br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Tutorials}}<br />
The SlicerIGT [http://www.slicerigt.org/wp/user-tutorial/ website] provides a [https://onedrive.live.com/view.aspx?cid=7230D4DEC6058018&resid=7230D4DEC6058018%213992&app=PowerPoint&authkey=%21AGQkSCZOwjVYXw8 tutorial] for ultrasound volume reconstruction in Slicer using Plus Remote (U35).<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Panels and their use}}<br />
[[File:PlusRemote_panel.png|500px|thumb|right|Plus Remote panel]] <br />
[[File:PlusRemote_AdvancedOptions.png|500px|thumb|right|Plus Remote panel with advanced parameters]] <br />
<br />
*'''Parameters sets:''' saving of all parameters<br />
**Create a new parameter set to save your parameters<br />
**Select previously saved ones<br />
**Default parameter set is selected when entering the module<br />
<br />
This is useful when user knows optimal parameters for a specific procedure. The parameters set is saved when saving the scene and is reloaded when opening a saved scene.<br />
<br />
<br />
*'''Parameters:''' parameters for communication with PLUS server, recording and reconstruction<br />
**OpenIGTLinkConnector<br />
**Capture Device ID<br />
**Volume Reconstructor ID<br />
<br />
These parameters are essential. Therefore all commands are disabled when these parameters are not set. List of available OpenIGTLinkConnector is available once you created connections in [https://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Modules/OpenIGTLinkIF OpenIGTLinkIF] module. When a connector is selected, capture device ID and volume reconstruction ID lists are automatically filled. <br />
<br />
<br />
*'''Recording:''' <br />
**Start and stop recording<br />
**Advanced parameters:<br />
***Modify default output filename "Recording.mha"<br />
***Add timestamp (YYYYMMDD_HHMMSS) to filename<br />
<br />
<br />
*'''Offline reconstruction of recorded volume:''' <br />
**Offline reconstruction<br />
**Advanced parameters:<br />
***Spacing (default value is 3mm)<br />
***Output volume device name<br />
***Volume to reconstruct filename (automatically filled when user record a file, but user can also edit this line and reconstruct previously saved files)<br />
***Show results on completion (display reconstructed volume in the green, yellow and 3D views)<br />
<br />
<br />
*'''Scout scan and live reconstruction:''' <br />
**Start and stop scout scan<br />
**Advanced parameters:<br />
***Spacing (default value is 3mm as we expect a low resolution scout scan)<br />
***Modify default output filename "ScoutScanRecording.mha"<br />
***Add timestamp (YYYYMMDD_HHMMSS) to filename<br />
***Show results on completion (display reconstructed volume in the green, yellow and 3D views)<br />
<br />
Scout scan button record a file and automatically performs the volume reconstruction once the recording is over. The result of scout scan volume reconstruction is saved in "scoutFile.mha"<br />
<br />
**Start and stop live volume reconstruction:<br />
**Display and modify ROI using eye icon (initialized to fit scout scan volume)<br />
**Spacing (default value is 1mm for high resolution reconstruction)<br />
**Advanced parameters:<br />
***Output volume device name (read only)<br />
***Modify default output filename "LiveReconstructedVolume.mha"<br />
***Add timestamp (YYYYMMDD_HHMMSS) to filename<br />
***Display volume extent values (updated when clicking on scout scan or live reconstruction command buttons)<br />
***Display snapshots during live volume reconstruction (if 0, no snapshots)<br />
***Show results on completion (display reconstructed volume in the green, yellow and 3D views)<br />
<br />
<br />
*Transform Update: Update transform from what is set in the PLUS config file; Requires name of transform node to match an existing transform in the PLUS config file<br />
*Reply: Feedback message from PLUS server (also visible when moving the mouse on blue information icons)<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Similar Modules}}<br />
N/A<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|References}}<br />
<br />
*[http://perk-software.cs.queensu.ca/plus/doc/nightly/user/PlusServerCommands.html PlusServer commands]<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-section|Information for Developers}}<br />
<br />
<br />
<!-- ---------------------------- --><br />
{{documentation/{{documentation/version}}/module-footer}}<br />
<!-- ---------------------------- --></div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61555Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:56:10Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer compressed video overview and acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame dimensions, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
=Available codecs and video containers=<br />
The following codecs and video container formats are available in Slicer:<br />
<br /><br />
<br />
<br /><br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<b>Video containers</b><br />
<br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61554Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:55:09Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer compressed video overview and acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame dimensions, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
=Available codecs and video containers=<br />
The following codecs and video container formats are available in Slicer.<br />
<br /><br />
<br />
<br /><br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<b>Video containers</b><br />
<br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61553Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:53:21Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer compressed video overview and acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame size, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
=Available codecs and video containers=<br />
The following codecs and video container formats are available in Slicer.<br />
<br /><br />
<br />
<br /><br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<b>Video containers</b><br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers&diff=61552Documentation/Nightly/Developers2019-11-14T19:52:01Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
__NOTOC__<br />
{| border="0" align="center" width="98%" cellspacing="7" cellpadding="2" valign="top"<br />
|-<br />
|<span style="color: #555555; font-size: 18px; font-weight: bold;">New Developers</span>:&nbsp;&nbsp;&nbsp;&nbsp;<big><big>Welcome ! Check these '''[[{{FULLPAGENAME}}/StartHere|instructions]]''' !</big></big><br />
|}<br />
<br />
{| border="0" align="center" width="98%" cellspacing="7" cellpadding="2" valign="top"<br />
|-<br />
! width="33%" |<br />
! |<br />
! width="33%" |<br />
! |<br />
! width="33%" |<br />
|- <br />
| valign="top" |<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">Getting involved</span><br />
----<br />
<br />
[[Documentation/{{documentation/version}}/Developers/StartHere|Start here]]<br />
<br />
:New community member checklist<br />
<br />
[[{{FULLPAGENAME}}/Meetings|Developer meetings]]<br />
<br />
:It is open to everyone, feel free to join.<br />
<br />
[https://discourse.slicer.org Discussion Forum]<br />
<br />
:The most effective way to get help from the community<br />
<!--<br />
[http://slicer-devel.65872.n3.nabble.com/ Search developers mailing list] / [http://massmail.spl.harvard.edu/mailman/listinfo/slicer-devel Sign-up]<br />
: Intended for discussion of programming related questions<br />
--><br />
<br />
[[Documentation/{{documentation/version}}/Developers/FAQ|FAQ]]<br />
<br />
:Set of common development questions/answers<br />
<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">Resources</span><br />
----<br />
[[Roadmap|Roadmap]]{{updated}}<br />
<br />
:What's next ? What's the plan ?<br />
<br />
[[Documentation/Labs|Labs]] {{new}}<br />
<br />
:Keep track of on-going experiments.<br />
<br />
[http://apidocs.slicer.org/master/annotated.html Doxygen]<br />
<br />
:Source code API documentation.<br />
<br />
Source code repository<br />
<br />
:[https://github.com/Slicer/Slicer Github] or [http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk SVN]<br />
<br />
CDash Quality Dashboard: [http://slicer.cdash.org/index.php?project=Slicer4 SlicerStable], [http://slicer.cdash.org/index.php?project=SlicerPreview SlicerPreview]<br />
<br />
:Nightly, continuous and experimental dashboards. - <small>[[{{FULLPAGENAME}}/Tutorials/DashboardSetup|Setup a dashboard]]</small><br />
<br />
[https://issues.slicer.org Bug tracker] / [https://issues.slicer.org/signup_page.php Register] / [[Documentation/{{documentation/version}}/Report_a_problem|Report a problem]] / [[Documentation/{{documentation/version}}/Developers/Tutorials/ContributePatch|Contribute a patch]]<br />
<br />
:Web-based bug tracking system - <small>[[Documentation/{{documentation/version}}/Developers/BugTrackerConfiguration|Configuration]]</small><br />
<br />
[[{{FULLPAGENAME}}/Style Guide|Slicer Style Guidelines]]<br />
<br />
:Consistency and Readability for a manageable code base<br />
<br />
[[Documentation/{{documentation/version}}/ScriptRepository|Script repository]]<br />
<br />
:Collection of python scripts manipulating various Slicer components.<br />
<br />
[[Release Details|Change logs and release details]]<br />
<br />
:Informations about Slicer releases<br />
<br />
[[Resources]]<br />
<br />
:List Slicer resources and who to contact in case of problem.<br />
<br />
| bgcolor="#CCCCCC" |<br />
| valign="top" |<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">Build instructions</span><br />
----<br />
<br />
[[Documentation/{{documentation/version}}/Developers/Tutorials/BuildTestPackageDistributeExtensions|Create Slicer extensions]] {{updated}}<br />
<br />
:Build, test, package and distribute extensions<br />
<br />
[[Documentation/{{documentation/version}}/Developers/Build Instructions|Build Slicer application]]<br />
<br />
:Compiling and installing Slicer from source.<br />
<br />
[[Documentation/{{documentation/version}}/Developers/Build Module|Build Module]]<br />
<br />
:Compiling slicer modules outside of the slicer source tree.<br />
<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">How-tos</span>&nbsp;&nbsp;<br />
----<br />
{{:{{FULLPAGENAME}}/Tutorials}}<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">Quick links</span>&nbsp;&nbsp;<br />
----<br />
{{:{{FULLPAGENAME}}/Quicklinks}}<br />
<br />
| bgcolor="#CCCCCC" |<br />
| valign="top" |<br />
----<br />
<span style="color: #555555; font-size: 18px; font-weight: bold;">Design & Implementation</span><br />
----<br />
<br />
[[{{FULLPAGENAME}}/Modules | Modules]]<br />
<br />
:Comparison between the different supported module types<br />
<br />
[[{{FULLPAGENAME}}/MRML | Data Model / MRML]]<br />
<br />
:Objects and their organization. MRML Library provides API for managing medical image data type<br />
<br />
[[{{FULLPAGENAME}}/Logics | Logics]]<br />
<br />
:Details the role of MRML/Slicer/Application/Modules logics and Displayable managers<br />
<br />
[[{{FULLPAGENAME}}/Layouts | Layouts]] {{updated}}<br />
<br />
:How to control the layout of the views<br />
<br />
[[{{FULLPAGENAME}}/Slice Orientation Presets | Slice Orientation Presets]] {{new}}<br />
<br />
:How to manage slice orientation presets<br />
<br />
[[{{FULLPAGENAME}}/Slicelets | Slicelets]]<br />
<br />
:Create simple standalone applications (slicelets)<br />
<br />
[[{{FULLPAGENAME}}/IO | IO Mechanism]]<br />
<br />
:How to read or write nodes from file<br />
<br />
[[{{FULLPAGENAME}}/Python scripting | Python scripting]]<br />
<br />
:Presents the underlying infrastructure.<br />
<br />
[[{{FULLPAGENAME}}/Charts | Charts]]<br />
<br />
:Description of the Charting (jqPlot) architecture.<br />
<br />
[[{{FULLPAGENAME}}/Plots | Plots]] {{new}}<br />
<br />
:Description of the Plotting (VTK) architecture.<br />
<br />
[[{{FULLPAGENAME}}/CompressedVideo | Compressed Video]] {{new}}<br />
<br />
:Description of the compressed video architecture.<br />
<br />
[[{{FULLPAGENAME}}/DirectoryStructure | Directory Structure]]<br />
<br />
:Files location in the build and install tree.<br />
<br />
[[{{FULLPAGENAME}}/QtPlugins|Qt Plugins]]<br />
<br />
:How to build and load Qt plugins.<br />
<br />
[[{{FULLPAGENAME}}/Build system | Build system / Release process / Factory description]]<br />
<br />
:Details how Slicer is built and packaged.<br />
<br />
[[{{FULLPAGENAME}}/QtTesting | QtTesting]]<br />
<br />
:Testing framework to test Slicer application. It complements unit tests.<br />
<br />
|}<br />
<br />
<hr /><br />
<br />
<br />
[[{{collaborator|logo|slicer4}}|x300px|center]]</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61551Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:50:31Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer compressed video overview and acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame size, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
=Available codecs and video containers=<br />
The following codecs and video container formats are available in Slicer.<br />
<br /><br />
<br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<br />
<b>Video containers</b><br />
<br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61550Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:48:39Z<p>Sunderlandkyl: </p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
=Slicer Compressed Video Overview and Acknowledgements= <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors: <br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br><br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
=Architecture=<br />
==Frame Management== <br />
<br />
;[{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
:Contains the frame data and metadata information.<br />
:Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame size, and a vtkUnsignedCharArray representing the encoded frame data.<br />
:The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
:Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
:When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
;[{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
:Factory for registering availiable codecs.<br />
:Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
==MRML Nodes==<br />
<br />
;[{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
:Represents a volume created from a compressed video frame.<br />
:Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
=Available Codecs and Video Containers Formats=<br />
The following codecs and video container formats are available in Slicer.<br />
<br /><br />
<br />
<b>Codecs</b><br />
<br />
*Uncompressed RGB: Included in Slicer<br />
*VP9: Included in the SlicerIGSIO extension<br />
<br />
<br /><br />
<br />
<b>Video containers</b><br />
<br />
*MKV: Included in the SlicerIGSIO extension<br />
<br />
=Future Work= <br />
<br />
*Add support for additional codecs<br />
*Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/CompressedVideo&diff=61549Documentation/Nightly/Developers/CompressedVideo2019-11-14T19:47:50Z<p>Sunderlandkyl: Add compressed video page</p>
<hr />
<div><noinclude>{{documentation/versioncheck}}</noinclude><br />
{{Clear}}{{TOC right}}<br />
<br />
= Slicer Compressed Video Overview and Acknowledgements = <br />
Slicer provides infrastructure for visualizing, and managing compressed video frames.<br />
Compressed video data is stored in a volume node that performs automatic encoding and decoding as needed.<br />
In conjunction with the Sequences and SlicerIGSIO modules, it is also possible to playback and record video sequences in a compressed format.<br />
These compressed video sequences can be read and written to a video container format that can be played back in any supporting media player.<br />
<br />
Authors:<br><br />
<b>Kyle Sunderland</b> (PerkLab, Queen's University) <br> <br />
<b>Andras Lasso</b> (PerkLab, Queen's University) <br> <br />
<br />
Acknowledgements: <br />
Development was funded in part by CANARIE’s Research Software Program.<br />
<br />
= Architecture =<br />
== Frame Management == <br />
<br />
; [{{doxygen-class-url|vtkStreamingVolumeFrame}} vtkStreamingVolumeFrame]<br />
: Contains the frame data and metadata information.<br />
: Represents the [https://en.wikipedia.org/wiki/Video_compression_picture_types frame type], codec, decoded frame size, and a vtkUnsignedCharArray representing the encoded frame data.<br />
: The frame also contains a pointer to the previous frame that must be decoded before the current frame can be decoded.<br />
; [{{doxygen-class-url|vtkStreamingVolumeCodec}} vtkStreamingVolumeCodec]<br />
: Decodes/Encodes the vtkStreamingVolumeFrame to convert the contents to/from vtkImageData.<br />
: When decoding a frame, it will compare against the last decoded frame and decode as many previous frames as necessary for the current frame.<br />
; [{{doxygen-class-url|vtkStreamingVolumeCodecFactory}} vtkStreamingVolumeCodecFactory]<br />
: Factory for registering availiable codecs.<br />
: Can create a new codec given a [http://www.fourcc.org/ FOURCC].<br />
<br />
== MRML Nodes ==<br />
; [{{doxygen-class-url|vtkMRMLStreamingVolumeNode}} vtkMRMLStreamingVolumeNode]<br />
: Represents a volume created from a compressed video frame.<br />
: Automatically decodes the frame when it is set and GetImageData() is called, or if there are observers on the vtkImageData.<br />
<br />
= Available Codecs and Video Containers Formats =<br />
The following codecs and video container formats are available in Slicer.<br />
<br/><br />
<br />
<b>Codecs</b><br />
* Uncompressed RGB: Included in Slicer<br />
* VP9: Included in the SlicerIGSIO extension<br />
<br/><br />
<br />
<b>Video containers</b><br />
* MKV: Included in the SlicerIGSIO extension<br />
<br />
= Future Work = <br />
* Add support for additional codecs<br />
* Add support for additional video container formats</div>Sunderlandkylhttps://www.slicer.org/w/index.php?title=Documentation/Nightly/Developers/Tutorials/MigrationGuide/Slicer&diff=61493Documentation/Nightly/Developers/Tutorials/MigrationGuide/Slicer2019-10-16T16:16:29Z<p>Sunderlandkyl: Added migration information for Segmentations</p>
<hr />
<div><noinclude>__TOC__</noinclude><br />
==Slicer backward incompatible changes==<br />
<br />
=== Slicer 5.0: API changes since 4.10 ===<br />
<br />
* Removed protected method <tt>vtkMRMLModelDisplayableManager::FindPickedDisplayNodeFromMesh</tt><br />
<br />
==== Python 2 to Python 3 ====<br />
<br />
Slicer core has been updated to only support Python 3.<br />
<br />
C++ classes and python scripts have been updated to use idioms and constructs only available in Python 3.<br />
<br />
Update to python scripts have been done leveraging the CLI provided by https://python-future.org by (1) iteratively applying each one of the associates "fixes", (2) reviewing associated changes and (3) updating as needed.<br />
<br />
Updates specific to extensions are discussed in [[Documentation/Nightly/Developers/Tutorials/MigrationGuide#Slicer_5.0:_Python2_to_Python3]]<br />
<br />
==== Interactor styles ====<br />
<br />
Limitations of VTK widgets (editable points, lines, curves, etc.) prevented Slicer from having sophisticated user interaction in slice and 3D views. In Slicer5, we replaced VTK widgets with MRML widgets. These widgets are still VTK-based and somewhat similar to VTK widgets, but they operate directly on MRML nodes, they use direct method calls between widgets and their representation, and they use a more efficient and flexible event processing. Instead of hardcoding how viewers behave in response to interaction (mouse move, button click, keyboard, ...) events in an interactor style, all these events are translated to actions and performed in a MRML widget. Most modules are not expected to observe interactor events or styles directly, but if they did, then they may need to be updated accordingly.<br />
<br />
* vtkSliceViewInteractorStyle renamed to vtkMRMLSliceDViewInteractorStyle to reflect that it uses MRML classes directly.<br />
* vtkThreeDViewInteractorStyle renamed to vtkMRMLThreeDViewInteractorStyle to reflect that it uses MRML classes directly.<br />
<br />
==== slicer.util functions ====<br />
<br />
* slicer.util.loadVolume (and other node load functions) now return the loaded node instead of a True/False flag. In case of an error, a RuntimeError exception is thrown.<br />
** Old way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd', returnNode=True)[1]</code><br />
** New way of loading a node and get it in a variable: <code>volumeNode = slicer.util.loadVolume('path/to/volume.nrrd')</code><br />
<br />
==== Markups ====<br />
<br />
* <tt>vtkCommand::Modified</tt> events are no longer invoked when control points are added/removed/modified to improve performance. Modules that need to know If a point position is modified need to add observers to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>, <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt> events. See example in [[Documentation/Nightly/ScriptRepository#Get_a_notification_if_a_markup_point_position_is_modified|script repository]].<br />
* <tt>vtkMRMLMarkupsNode::MarkupAddedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointAddedEvent</tt>. This is called even when preview point is created. Use <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> to get notification only when position of a point becomes defined (and not during preview).<br />
* <tt>vtkMRMLMarkupsNode::MarkupRemovedEvent</tt> is renamed to <tt>vtkMRMLMarkupsNode::PointRemovedEvent</tt>. This is called even when preview point is removed. Use <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> to get notification only when position of a point becomes undefined (and not during preview).<br />
* <tt>vtkMRMLMarkupsNode::NthMarkupModifiedEvent</tt> is replaced by <tt>vtkMRMLMarkupsNode::PointModifiedEvent</tt><br />
* During placement of markups, a preview markup point is created. If number of already placed markup points needs to be determined then <code>GetNumberOfDefinedControlPoints()</code> method can be used.<br />
* <tt>GetDefaultMarkups...()</tt> and <tt>SetDefaultMarkups...()</tt> methods are removed. Instead default display node can be accessed by <tt>GetDefaultMarkupsDisplayNode()</tt> method and default values can be get/set in that class.<br />
* <tt>vtkMRMLMarkupsNode::GetNthMarkupSelected()</tt> is replaced by <tt>GetNthControlPointSelected()</tt><br />
* <tt>vtkMRMLMarkupsNode::PointPositionDefinedEvent</tt> event is added. This event is invoked whenever position is defined for a new point.<br />
* <tt>vtkMRMLMarkupsNode::PointPositionUndefinedEvent</tt> event is added. This event is invoked whenever point with defined position is removed (point is deleted or its position gets undefined).<br />
* For more details, see [{{doxygen-class-url|vtkMRMLMarkupsNode}} vtkMRMLMarkupsNode]<br />
<br />
==== Segmentations ====<br />
<br />
Binary labelmap segmentations can now be represented as shared labelmaps.<br />
The previous implementation of binary labelmaps was performance intensive as each labelmap was represented using a separate vtkDataObject.<br />
Visualizing and editing segmentations that contained a large number of segments could cause performance issues, due to the large number of vtkActors required, as well as calculating masks and overwriting other segments when editing.<br />
<br />
By default, newly created segments will now be contained on the same layer.<br />
Segments will only be separated into multiple layers if the user creates an overlapping segment when editing.<br />
<br />
Segments are now saved as a 4D volume with shared 3D layers.<br />
For a segmentation that only uses one layer, the resulting image is a 3D volume.<br />
Before saving, the labelmaps will be collapsed into as few layers as possible.<br />
<br />
* seg.nrrd files now contain two additional attributes for each segment: SegmentX_LabelValue and SegmentX_Layer<br />
* The label value of a segment can be found using vtkSegment::GetLabelValue()<br />
* Whether or not a segment is shared can be found using vtkSegmentation::IsSharedBinaryLabelmap()<br />
* The other segments sharing the same labelmap can be found using vtkSegmentation::GetSegmentIDsSharingBinaryLabelmapRepresentation()<br />
* Segment editor effects should generally use modifySelectedSegmentByLabelmap rather than SetBinaryLabelmapToSegment to manage layer separation<br />
* Conversion rules now call PreConvert() and PostConvert() before and after conversion to perform pre and post processing steps on the segmentation as a whole<br />
* The function signature for vtkSegmentationConverterRule::Convert now accepts a vtkSegment rather than two vtkDataObjects<br />
* slicer.util.arrayFromSegment has been deprecated. slicer.util.arrayFromSegmentBinaryLabelmap and slicer.util.arrayFromSegmentInternalBinaryLabelmap can be used instead<br />
<br />
<b>Erase the contents of a single segment:</b><br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.ClearSegment(segmentId)<br />
</pre><br />
<br />
<br />
<b>Move a segment from a shared labelmap to a separate layer:</b><br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.SeparateSegmentLabelmap(segmentId)<br />
</pre><br />
<br />
<b>Combine all binary labelmaps to as few layers as possible:</b><br />
<br />
<pre><br />
segmentation = segmentationNode.GetSegmentation()<br />
segmentation.CollapseBinaryLabelmaps(forceToSingleLayer=false)<br />
</pre><br />
<br />
<b>Get a read-only labelmap for a single segment:</b><br />
<br />
<pre><br />
labelmap = slicer.vtkOrientedImageData()<br />
segmentationNode.GetBinaryLabelmapRepresentation(segmentId, labelmap)<br />
</pre><br />
<br />
or<br />
<br />
<pre><br />
labelmapNumpyArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId)<br />
</pre><br />
<br />
<br />
<b>Get a modifiable shared labelmap:</b><br />
<br />
<pre><br />
labelmap = slicer.vtkOrientedImageData()<br />
segmentationNode.GetBinaryLabelmapInternalRepresentation(segmentId, labelmap)<br />
</pre><br />
<br />
or<br />
<br />
<pre><br />
labelmapNumpyArray = slicer.util.arrayFromSegmentInternalBinaryLabelmap(segmentationNode, segmentId)<br />
</pre><br />
<br />
<br />
=== Slicer 4.11: teem python module renamed to vtkTeem, explicit import required ===<br />
<br />
* Since the module provides VTK classes interfacing with "teem", the name is now representative of the class it contains.<br />
* <tt>vtkTeem</tt> classes are expected to be used by explicitly importing the module.<br />
<br />
<b>Replace code like this:</b><br />
<br />
<pre><br />
import teem<br />
<br />
class CalculateTensorScalars(object):<br />
def __init__(self):<br />
self.dti_math = teem.vtkDiffusionTensorMathematics()<br />
</pre><br />
<br />
<b>By this:</b><br />
<br />
<pre><br />
import vtkTeem<br />
<br />
class CalculateTensorScalars(object):<br />
def __init__(self):<br />
self.dti_math = vtkTeem.vtkDiffusionTensorMathematics()<br />
</pre><br />
<br />
=== Slicer 4.11: Display window/level (brightness/contrast) adjustment ===<br />
* A new "Window/level" mouse interaction mode was introduced. Volume display window/level can only be changed if this mode is activated by clicking the corresponding button in the toolbar. The new mouse mode prevents accidental modification of volume window/level (when for example the user accidentally clicked too far from a markup) and it also allows more sophisticated window/level adjustments.<br />
* New region-based auto window/level feature added: activate "Window/level" mouse mode and use Ctrl + left-click-and-drag to highlight a region and optimize window/level for that (pressing Escape or right-click cancels the operation).<br />
* Auto window/level reset: activate "Window/level" mouse mode and double-click the left mouse button.<br />
* Improved auto window/level algorithm to prevent too bright display of images. Window/level is set to display values between 0.1th and 99.9th percentile of gray levels. See details here: https://discourse.slicer.org/t/feedback-requested-how-to-improve-mouse-interaction-in-views/6420.<br />
* Removed class <tt>vtkImageBimodalAnalysis</tt><br />
<br />
=== Slicer 4.10: Registration of runTest function done in ScriptedLoadableModule base class===<br />
<br />
Following [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27617 r27617]:<br />
* the <code>ScriptedLoadableModule</code> class takes care of registering the <code>runTest</code> function.<br />
* the <code>runTest</code> function expects <code>msec</code> keyword argument.<br />
<br />
<b>Error message similar to:</b><br />
<br />
<pre><br />
Traceback (most recent call last):<br />
File "/path/to/Slicer-SuperBuild/Slicer-build/bin/Python/slicer/ScriptedLoadableModule.py", line 205, in onReloadAndTest<br />
test(msec=int(slicer.app.userSettings().value("Developer/SelfTestDisplayMessageDelay")), **kwargs)<br />
TypeError: runTest() got an unexpected keyword argument 'msec'<br />
Reload and Test: Exception!<br />
<br />
runTest() got an unexpected keyword argument 'msec'<br />
</pre><br />
<br />
<b>Replace code like this:</b><br />
<br />
<pre><br />
class sceneImport2428(ScriptedLoadableModule):<br />
[...]<br />
def __init__(self, parent):<br />
ScriptedLoadableModule.__init__(self, parent)<br />
parent.title = "..."<br />
[...]<br />
parent.acknowledgementText = "..."<br />
self.parent = parent <br />
<br />
# Add this test to the SelfTest module's list for discovery when the module <br />
# is created. Since this module may be discovered before SelfTests itself, <br />
# create the list if it doesn't already exist. <br />
try: <br />
slicer.selfTests <br />
except AttributeError: <br />
slicer.selfTests = {} <br />
slicer.selfTests['sceneImport2428'] = self.runTest <br />
<br />
def runTest(self): <br />
tester = sceneImport2428Test() <br />
tester.runTest()<br />
<br />
[...]<br />
</pre><br />
<br />
<b>By this:</b><br />
<br />
<pre><br />
class sceneImport2428(ScriptedLoadableModule):<br />
[...]<br />
def __init__(self, parent):<br />
ScriptedLoadableModule.__init__(self, parent)<br />
parent.title = "..."<br />
[...]<br />
parent.acknowledgementText = "..."<br />
<br />
[...]<br />
</pre><br />
<br />
=== Slicer 4.9: Update of VTK version from 9.0 to 8.2 ===<br />
<br />
Following [https://github.com/Kitware/VTK/commit/b703d78be3ffd8ae69c319afa0230097ff270f26 kitware/VTK@b703d78be], VTK has updated to use version number 8.2 instead of 9.0. This was discussed in on the VTK mailing list in http://vtk.1045678.n5.nabble.com/Discussion-OK-to-change-VTK-s-version-number-from-9-0-to-8-2-tt5748702.html<br />
<br />
At first, this VTK commit and its companion [https://github.com/Kitware/VTK/commit/8a00b357e84eec695bda049216f30f2b76d80855 kitware/VTK@8a00b357e] were both reverted from the [https://github.com/Slicer/VTK/ Slicer/VTK] fork. Then, since having the corresponding changes reverted in VTK was not possible, it was decided to also update Slicer. This was done in the following commits:<br />
* [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27472 r27472]: COMP: Update c++ classes to support building against VTK >= 9 and VTK >= 8.2<br />
* [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=27473 r27473]: COMP: Update VTK to include version change from 9.0 to 8.2. Fixes #4623<br />
<br />
This means that code depending on VTK must also be updated to include similar fixes.<br />
<br />
'''Replace this:'''<br />
#if VTK_MAJOR_VERSION >= 9<br />
<br />
'''By this:'''<br />
#if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 2)<br />
<br />
and<br />
<br />
'''Replace this:'''<br />
#if VTK_MAJOR_VERSION < 9<br />
<br />
'''By this:'''<br />
#if VTK_MAJOR_VERSION <= 7 || (VTK_MAJOR_VERSION <= 8 && VTK_MINOR_VERSION <= 1)<br />
<br />
<br />
<br />
=== Slicer 4.9: ITK_LEGACY_REMOVE is now OFF ===<br />
In preparation to switch to ITK 5.0, we disable legacy functionality in ITK. This might affect some modules which rely on ITK. Take a look at [https://itk.org/migrationv4 ITK 4 migration guide] before [https://github.com/InsightSoftwareConsortium/ITK/blob/master/Documentation/ITK5MigrationGuide.md ITK 5 migration guide].<br />
<br />
=== Slicer 4.9: vtkMRMLPlotDataNode renamed to vtkMRMLPlotSeriesNode ===<br />
Plotting was improved in [https://github.com/Slicer/Slicer/commit/082edc40c this commit]<br />
<br />
'''Replace this:'''<br />
<br />
vtkMRMLPlotDataNode<br />
<br />
'''By this:'''<br />
vtkMRMLPlotSeriesNode<br />
<br />
=== Slicer 4.9: CMake: Module MIDAS not available ===<br />
<br />
The test infrastructure of your project should be updated to use [https://cmake.org/cmake/help/latest/module/ExternalData.html ExternalData] built-in CMake module<br />
instead of the specific <tt>MIDAS</tt> module.<br />
<br />
See EMSegment commit [http://viewvc.slicer.org/viewvc.cgi/Slicer3?view=revision&revision=17150 r17150] for an example of transition.<br />
<br />
This means that instead of using <tt>midas_add_test</tt> with the <tt>MIDAS{path/to/file.ext.md5}</tt><br />
syntax for addressing the test data, the function [https://cmake.org/cmake/help/latest/module/ExternalData.html#command:externaldata_add_test ExternalData_add_target] is used by<br />
specifying both <tt>DATA{path/to/file.ext}</tt> and a download target name.<br />
<br />
'''Replace this:'''<br />
<br />
midas_add_test(NAME test1 COMMAND ...)<br />
midas_add_test(NAME test2 COMMAND ...)<br />
<br />
'''By this:'''<br />
<br />
ExternalData_add_test(EMSegmentData NAME test1 COMMAND ...)<br />
ExternalData_add_test(EMSegmentData NAME test2 COMMAND ...)<br />
<br />
[...]<br />
<br />
ExternalData_add_target(EMSegmentData)<br />
<br />
<br />
A key difference with the former approaches is that instead of adding two tests (one named<br />
<tt><testName>_fetchData</tt> to downoad the data and one running the test command), only one<br />
test is added but a common download target is added at the end using [https://cmake.org/cmake/help/latest/module/ExternalData.html#command:externaldata_add_target ExternalData_add_target]<br />
function.<br />
<br />
This means that test data can now be downloaded in parallel (and cached) at build time instead<br />
of testing time.<br />
<br />
=== Slicer 4.9: CMake: Module SlicerMacroCheckExternalProjectDependency not available ===<br />
<br />
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26992 r26992], consider updating<br />
your build system to use CMake module <code>ExternalProjectDependency</code><br />
<br />
=== Slicer 4.9: CMake: Module SlicerMacroEmptyExternalProject not available ===<br />
<br />
Since the module was removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26991 r26991]<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
include(SlicerMacroEmptyExternalProject)<br />
<br />
[...]<br />
<br />
SlicerMacroEmptyExternalProject("${proj}" "${${proj}_DEPENDENCIES}")<br />
</pre><br />
<br />
'''By this:'''<br />
<br />
<pre><br />
include(ExternalProjectDependency)<br />
<br />
[...]<br />
<br />
ExternalProject_Add_Empty(${proj} DEPENDS ${${proj}_DEPENDENCIES})<br />
</pre><br />
<br />
=== Slicer 4.9: CMake: Module SlicerBlockSetCMakeOSXVariables not available ===<br />
<br />
Since it was renamed to <tt>SlicerInitializeOSXVariables</tt> in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26982 r26982]<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
include(SlicerBlockSetCMakeOSXVariables)<br />
</pre><br />
<br />
'''By this:'''<br />
<br />
<pre><br />
include(SlicerInitializeOSXVariables)<br />
</pre><br />
<br />
=== Slicer 4.9: Application: isRelease() function not available ===<br />
<br />
See [[#Slicer_4.8:_Application:_isRelease.28.29_function_not_available_or_deprecated]]<br />
<br />
=== Slicer 4.9: slicer.util.getNode() raises exception if node not found ===<br />
<br />
If slicer.util.getNode() is called and the node is not found then instead of just returning None (Slicer 4.8 behavior), the method now raises a MRMLNodeNotFoundException. This makes code debugging easier (the error is reported when it happens), and in general more consistent with Python conventions.<br />
<br />
How to update existing code:<br />
<br />
It is advisable to only use slicer.util.getNode in tests, or interactively in the Python console, as its behavior is somewhat unpredictable (it may either found a node by name or ID, and result of wildcard search is even less deterministic). In general, it is recommended to use the MRML scene's GetFirstNodeByName and GetNodeByID methods instead.<br />
<br />
'''Replace this:'''<br />
<br />
<pre><br />
n = slicer.util.getNode(nodeNameOrID)<br />
</pre><br />
<br />
'''By one of these:'''<br />
<br />
If node is to be found by name:<br />
<pre><br />
n = slicer.mrmlScene.GetFirstNodeByName(nodeName)<br />
</pre><br />
<br />
If node is to be found by ID:<br />
<pre><br />
n = slicer.mrmlScene.GetNodeByID(nodeID)<br />
</pre><br />
<br />
If node is to be found by name or ID (slower, less predictable, recommended for testing only):<br />
<br />
<pre><br />
try:<br />
n = slicer.util.getNode(nodeNameOrID)<br />
except slicer.util.MRMLNodeNotFoundException:<br />
n = None<br />
</pre><br />
<br />
More information: https://github.com/Slicer/Slicer/commit/b63484af1b1b413f35396f8f7efb73e870448bd4<br />
<br />
===Slicer 4.8: Application: isRelease() function not available or deprecated===<br />
<br />
<b>Error message similar to:</b><br />
<br />
Missing/deprecated qSlicerCoreApplication::isRelease()<br />
<br />
or<br />
<br />
Missing/deprecated slicer.app.isRelease()<br />
<br />
<br />
<b>Solution:</b><br />
<br />
Use <tt>qSlicerCoreApplication::releaseType() == "Stable"</tt><br />
<br />
<b>Summary:</b><br />
<br />
Prior to r26420, the variable <tt>Slicer_VERSION_TWEAK</tt> was used to check if a "stable release" was built. The variable value<br />
was set by updating the sources and defining the variable to an integer greater or equal to 0. In other word, if the variable<br />
evaluated to an empty string, a nighty or experimental build was being done, if it evaluated to an integer, a stable release build<br />
was being done.<br />
<br />
The approach had few issues:<br />
* the name of the variable was confusing<br />
* identifying a "stable release" only from a source tree revision was not enough. Indeed the environment defining a "release" is the one found on the build machines used to generate the installer.<br />
* nightly build are also considered as release<br />
<br />
To address this, the CMake variable <tt>Slicer_RELEASE_TYPE</tt> was introduced. As of 2017-10-04, it can be set to <tt>Experimental</tt>, <tt>Nightly</tt><br />
or <tt>Stable</tt> with <tt>Experimental</tt> being the value hard-coded in the source.<br />
<br />
Identifying a build as "stable" is now explicitly done by setting <tt>Slicer_RELEASE_TYPE</tt> to <tt>Stable</tt> at configure time.<br />
<br />
Also, since the concept of release types was introduced, the function <tt>isRelease()</tt> has been removed in favor of <tt>releaseType()</tt>.<br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/pull/354<br />
<br />
===Slicer Python Module: modulewidget and others removed.===<br />
<br />
<b> Summary</b><br />
Python classes formerly in "slicer.moduledm", "slicer.modulelogic", "slicer.modulemrml"<br />
and "slicer.modulewidget" are now directly available in the slicer module.<br />
<br />
See example of change [https://github.com/QIICR/LongitudinalPETCT/pull/11 here].<br />
<br />
<b>Rational:</b><br />
<br />
See comments in commit messages referenced blow.<br />
<br />
<b>References:</b><br />
<br />
https://github.com/Slicer/Slicer/commit/628f83fe7a6f4e0710e306bcaf7c04b9e3e5e6bd<br />
<br />
https://github.com/Slicer/Slicer/commit/9cb5668fde1abc8f0430a91ca37fc29277ceeb4e<br />
<br />
===MRML: Slicer 4.6: Moved up vtkMRMLStorableNode in the MRML node hierarchy.===<br />
<br />
<b>Rational:</b><br />
<br />
vtkMRMLStorableNode is not a children of vtkMRMLTransformable node anymore,<br />
but directly a children of vtkMRMLNode.<br />
<br />
This allows making a node storable without requiring it to be also<br />
transformable. It is important for several node types (color maps, tables,<br />
etc), which require separate storage node but are not transformable.<br />
<br />
<b>References:</b><br />
* Changed introduced in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24891 r24891]<br />
<br />
<b>Error message similar to:</b><br />
<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx: In member function ‘void vtkMRMLLongitudinalPETCTStudyNode::ObserveRegistrationTransform(bool)’:<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:478:28: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘GetParentTransformNode’<br />
&& propNode->GetParentTransformNode()<br />
^<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:480:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’<br />
propNode->SetAndObserveTransformNodeID(<br />
^<br />
/tmp/LongitudinalPETCT/MRML/vtkMRMLLongitudinalPETCTStudyNode.cxx:503:23: error: ‘class vtkMRMLVolumePropertyNode’ has no member named ‘SetAndObserveTransformNodeID’<br />
propNode->SetAndObserveTransformNodeID(NULL);<br />
^<br />
<br />
<b>Solution:</b><br />
<br />
Removes lines and/or refactor code<br />
<br />
<br />
<br />
===MRML: Slicer 4.5: Introduction of vtkMRMLLabelMapVolumeNode===<br />
<br />
<b>Rational:</b><br />
<br />
Before <tt>vtkMRMLScalarVolumeNode</tt> was used for both scalar and label map<br />
volumes and the LabelMap custom MRML node attribute was used for<br />
distinguishing between them (0=scalar; 1=label map volume).<br />
<br />
This made conversion between labelmap/scalar volumes very easy but made<br />
it difficult to customize behavior, display, processing of segmentation<br />
information.<br />
<br />
Now a new <tt>vtkMRMLLabelMapVolumeNode</tt> class is used for storing segmentation<br />
information (still using <tt>vtkMRMLScalarVolume</tt> used as base class for backward<br />
compatibility; but in the future the base class may be changed to reflect<br />
that segmentation can be represented in various ways, not just as volumes).<br />
<br />
<b>Error message similar to:</b><br />
<br />
error: ‘class vtkMRMLScalarVolumeNode’ has no member named ‘SetLabelMap’<br />
outputVolumeNode->SetLabelMap(1);<br />
^<br />
<br />
<b>Solution (part1: down cast to <tt>vtkMRMLLabelMapVolumeNode</tt>, remove call to <tt>SetLabelMap</tt>)</b><br />
<br />
Replace lines like:<br />
<br />
vtkMRMLNode* outputNode = d->OutputLabelVolumeMRMLNodeComboBox->currentNode();<br />
vtkMRMLScalarVolumeNode* outputVolumeNode = vtkMRMLScalarVolumeNode::SafeDownCast(outputNode);<br />
[...]<br />
outputVolumeNode->SetLabelMap(1);<br />
<br />
<br />
with:<br />
<br />
vtkMRMLLabelMapVolumeNode* outputVolumeNode =<br />
vtkMRMLLabelMapVolumeNode::SafeDownCast(d->OutputLabelVolumeMRMLNodeComboBox->currentNode());<br />
[...]<br />
<br />
<br />
<b>Solution (part2: Update UI file):</b><br />
<br />
Replace lines like:<br />
<br />
<widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox"><br />
<property name="nodeTypes"><br />
<stringlist><br />
<string>vtkMRMLScalarVolumeNode</string><br />
</stringlist><br />
</property><br />
[...]<br />
</widget><br />
<br />
with:<br />
<br />
<widget class="qMRMLNodeComboBox" name="InputLabelVolumeMRMLNodeComboBox"><br />
<property name="nodeTypes"><br />
<stringlist><br />
<string>vtkMRMLLabelMapVolumeNode</string> <------------- Update Here<br />
</stringlist><br />
</property><br />
[...]<br />
</widget><br />
<br />
<br />
<b>Solution (part3: Update node selector configuration):</b><br />
<br />
Replace lines like:<br />
<br />
nodeSelector.setNodeTypes(QStringList("vtkMRMLScalarVolumeNode"));<br />
nodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "1");<br />
<br />
with:<br />
<br />
nodeSelector.setNodeTypes(QStringList("vtkMRMLLabelMapVolumeNode"));<br />
<br />
<br />
<b>References:</b><br />
* http://www.slicer.org/slicerWiki/index.php/Documentation/Labs/Segmentations#vtkMRMLLabelMapVolumeNode_integration<br />
* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=24291<br />
<br />
<br />
===CLI: Slicer 4.3: Add ITKFactoryRegistration library centralizing ITK IO factory registration===<br />
<br />
<b>Rational:</b><br />
<br />
Linking against <tt>ITKFactoryRegistration</tt> ensures that ITK IO factory are properly registered on all supported platforms.<br />
<br />
<b>Error message similar to:</b><br />
<br />
Undefined symbols for architecture x86_64:<br />
"itk::itkFactoryRegistration()", referenced from:<br />
_main in ImageMakerTest.cxx.o<br />
ld: symbol(s) not found for architecture x86_64<br />
<br />
<b>Solution:</b><br />
<br />
Replace lines like:<br />
<br />
target_link_libraries(${CLP}Test ${CLP}Lib)<br />
<br />
with:<br />
<br />
target_link_libraries(${CLP}Test ${CLP}Lib ${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES})<br />
<br />
<b>References:</b><br />
<br />
* http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=21592<br />
* https://issues.slicer.org/view.php?id=2813</div>Sunderlandkyl