From 01c5f96008715e7400b57d9188cc7d1fe5a8f76f Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Thu, 13 Dec 2018 03:34:43 -0500
Subject: [PATCH 1/6] ENH: Skip "delayDisplay" dialog popup for short delay
This commit skips dialog popup when interval for slicer.util.delayDisplay
is less than 400ms.
For such short interval, it is not relevant to show the dialog.
---
Base/Python/slicer/util.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Base/Python/slicer/util.py b/Base/Python/slicer/util.py
index ff5a35412..cb9d2d1ed 100644
--- a/Base/Python/slicer/util.py
+++ b/Base/Python/slicer/util.py
@@ -1030,6 +1030,9 @@ def delayDisplay(message,autoCloseMsec=1000):
import qt, slicer
import logging
logging.info(message)
+ if autoCloseMsec < 400:
+ slicer.app.processEvents()
+ return
messagePopup = qt.QDialog()
layout = qt.QVBoxLayout()
messagePopup.setLayout(layout)
--
GitLab
From d647f59c457a88a2c2ce727f57a2aec44dbcbb1f Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Thu, 13 Dec 2018 03:34:57 -0500
Subject: [PATCH 2/6] ENH: Speedup AtlasTest removing hard-coded message delays
---
Applications/SlicerApp/Testing/Python/AtlasTests.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Applications/SlicerApp/Testing/Python/AtlasTests.py b/Applications/SlicerApp/Testing/Python/AtlasTests.py
index 75e6226c9..eaf9d28af 100644
--- a/Applications/SlicerApp/Testing/Python/AtlasTests.py
+++ b/Applications/SlicerApp/Testing/Python/AtlasTests.py
@@ -229,15 +229,15 @@ class AtlasTestsTest(ScriptedLoadableModuleTest):
hierarchyOriginalExpanded = mh.GetExpanded()
# collapse and change the colour on the hierarchy to full red
mh.SetExpanded(0)
- self.delayDisplay("Model hierarchy " + mh.GetName() + ": expanded = false",msec=10)
+ self.delayDisplay("Model hierarchy " + mh.GetName() + ": expanded = false")
mhd.SetColor(1,0,0)
- self.delayDisplay("Model hierarchy " + mh.GetName() + ": color = red",msec=10)
+ self.delayDisplay("Model hierarchy " + mh.GetName() + ": color = red")
# set the collapsed visibility to 0
mhd.SetVisibility(0)
- self.delayDisplay("Model hierarchy " + mh.GetName() + ": visibility = off",msec=10)
+ self.delayDisplay("Model hierarchy " + mh.GetName() + ": visibility = off")
# expand, should see all models in correct colour
mh.SetExpanded(1)
- self.delayDisplay("Model hierarchy " + mh.GetName() + ": expanded = true",msec=10)
+ self.delayDisplay("Model hierarchy " + mh.GetName() + ": expanded = true")
# reset the hierarchy
mhd.SetVisibility(hierarchyOriginalVisibility)
mhd.SetColor(hierarchyOriginalColour)
@@ -251,7 +251,7 @@ class AtlasTestsTest(ScriptedLoadableModuleTest):
numSceneViews = slicer.mrmlScene.GetNumberOfNodesByClass("vtkMRMLSceneViewNode")
for s in range(numSceneViews):
sv = slicer.mrmlScene.GetNthNodeByClass(s, "vtkMRMLSceneViewNode")
- self.delayDisplay("Restoring scene " + sv.GetName() + " (" + str(s+1) + "/" + str(numSceneViews) + ")",msec=500)
+ self.delayDisplay("Restoring scene " + sv.GetName() + " (" + str(s+1) + "/" + str(numSceneViews) + ")")
sv.RestoreScene()
self.delayDisplay('Test passed!')
--
GitLab
From 6c270d376a8ef4830f2739d2bb3c29a1c5a26905 Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Fri, 14 Dec 2018 13:57:55 -0500
Subject: [PATCH 3/6] ENH: Improve SampleData API to support scene loading and
zip file download
Improve docstrings
Adds "downloadFromSources" function
Improve "downloadFromSource" to support 'ZipFile' and 'SceneFile' file types.
---
Modules/Scripted/SampleData/SampleData.py | 101 ++++++++++++++++++----
1 file changed, 86 insertions(+), 15 deletions(-)
diff --git a/Modules/Scripted/SampleData/SampleData.py b/Modules/Scripted/SampleData/SampleData.py
index 76d46b6c0..d28869f13 100644
--- a/Modules/Scripted/SampleData/SampleData.py
+++ b/Modules/Scripted/SampleData/SampleData.py
@@ -68,9 +68,9 @@ use it for commercial purposes.
# SampleDataSource
#
class SampleDataSource:
- """Can be a passed a simple strings
- or lists as used in the logic below.
- e.g.
+ """Describe a set of sample data associated with one or multiple URIs and filenames.
+
+ Example::
import SampleData
dataSource = SampleData.SampleDataSource(
@@ -78,16 +78,27 @@ class SampleDataSource:
fileNames='fixed.nrrd',
uris='http://slicer.kitware.com/midas3/download/item/157188/small-mr-eye-fixed.nrrd')
loadedNode = SampleData.SampleDataLogic().downloadFromSource(dataSource)[0]
-
"""
def __init__(self, sampleName=None, uris=None, fileNames=None, nodeNames=None,
customDownloader=None, thumbnailFileName=None,
loadFileType='VolumeFile', loadFileProperties={}):
-
+ """
+ :param sampleName: Displayed name of data set in SampleData module GUI.
+ :param thumbnailFileName: Displayed thumbnail of data set in SampleData module GUI,
+ :param uris: Download URL(s).
+ :param fileNames: File name(s) that will be loaded.
+ :param nodeNames: Node name(s) in the scene.
+ :param customDownloader: Custom function for downloading.
+ :param loadFileType: file format name(s) ('VolumeFile' by default).
+ :param loadFileProperties: custom properties passed to the IO plugin.
+ """
self.sampleName = sampleName
- if (isinstance(uris, list) or isinstance(uris, tuple)) and isinstance(loadFileType, basestring):
- loadFileType = [loadFileType] * len(uris)
+ if (isinstance(uris, list) or isinstance(uris, tuple)):
+ if isinstance(loadFileType, basestring):
+ loadFileType = [loadFileType] * len(uris)
+ if nodeNames is None:
+ nodeNames = [os.path.splitext(fileName) for fileName in fileNames]
elif isinstance(uris, basestring):
uris = [uris,]
fileNames = [fileNames,]
@@ -238,9 +249,9 @@ class SampleDataLogic:
:param thumbnailFileName: Displayed thumbnail of data set in SampleData module GUI,
:param uris: Download URL(s).
:param fileNames: File name(s) that will be loaded.
- :param nodeNames: Node name in the scene.
+ :param nodeNames: Node name(s) in the scene.
:param customDownloader: Custom function for downloading.
- :param loadFileType: file format name ('VolumeFile' by default).
+ :param loadFileType: file format name(s) ('VolumeFile' by default).
:param loadFileProperties: custom properties passed to the IO plugin.
"""
@@ -309,6 +320,7 @@ class SampleDataLogic:
slicer.modules.sampleDataSources[self.builtInCategoryName].append(SampleDataSource(*sourceArgument))
def registerDevelopmentSampleDataSources(self):
+ """Fills in the sample data sources displayed only if developer mode is enabled."""
iconPath = os.path.join(os.path.dirname(__file__).replace('\\','/'), 'Resources','Icons')
self.registerCustomSampleDataSource(
category=self.developmentCategoryName, sampleName='TinyPatient',
@@ -337,23 +349,72 @@ class SampleDataLogic:
filePaths.append(self.downloadFileIntoCache(uri, fileName))
return filePaths
+ def downloadFromSources(self,sources,attemptCount=0):
+ """Given one or multiple instances of SampleDataSource, downloads the associated data and
+ load them into Slicer if it applies."""
+ return [self.downloadFromSource(source, attemptCount=attemptCount) for source in sources]
+
def downloadFromSource(self,source,attemptCount=0):
- """Given an instance of SampleDataSource, downloads the data
- if needed and loads the results in slicer"""
+ """Given an instance of SampleDataSource, downloads the associated data and
+ load them into Slicer if it applies.
+
+ The function always returns a list.
+
+ Based on the file type associated with the source, different values may
+ be returned.
+
+ - for ``SceneFile``, returns path of downloaded file
+ - for ``VolumeFile`` or any other type supported by Slicer, returns associated node
+ - for ``ZipFile``, returns directory of extracted archive
+ """
nodes = []
+
for uri,fileName,nodeName,loadFileType in zip(source.uris,source.fileNames,source.nodeNames,source.loadFileType):
+
+ current_source = SampleDataSource(uris=uri, fileNames=fileName, nodeNames=nodeName, loadFileType=loadFileType, loadFileProperties=source.loadFileProperties)
filePath = self.downloadFileIntoCache(uri, fileName)
- if nodeName:
+
+ if loadFileType == 'ZipFile':
+ outputDir = slicer.mrmlScene.GetCacheManager().GetRemoteCacheDirectory() + "/" + os.path.splitext(os.path.basename(filePath))[0]
+ qt.QDir().mkpath(outputDir)
+ success = slicer.util.extractArchive(filePath, outputDir)
+ if not success and attemptCount < 5:
+ attemptCount += 1
+ self.logMessage('Load failed! Trying to download again (%d of 5 attempts)...' % (attemptCount), logging.ERROR)
+ file = qt.QFile(filePath)
+ if not file.remove():
+ self.logMessage('Load failed! Unable to delete and try again loading %s!' % filePath, logging.ERROR)
+ nodes.append(None)
+ break
+ outputDir = self.downloadFromSource(current_source,attemptCount)[0]
+ nodes.append(outputDir)
+
+ elif loadFileType == 'SceneFile':
+ success = self.loadScene(filePath, source.loadFileProperties)
+ if not success and attemptCount < 5:
+ attemptCount += 1
+ self.logMessage('Load failed! Trying to download again (%d of 5 attempts)...' % (attemptCount), logging.ERROR)
+ file = qt.QFile(filePath)
+ if not file.remove():
+ self.logMessage('Load failed! Unable to delete and try again loading %s!' % filePath, logging.ERROR)
+ nodes.append(None)
+ break
+ filePath = self.downloadFromSource(current_source,attemptCount)[0]
+ nodes.append(filePath)
+
+ elif nodeName:
loadedNode = self.loadNode(filePath, nodeName, loadFileType, source.loadFileProperties)
if loadedNode is None and attemptCount < 5:
attemptCount += 1
- self.logMessage('Load failed! Trying to download again...', logging.ERROR)
+ self.logMessage('Load failed! Trying to download again (%d of 5 attempts)...' % (attemptCount), logging.ERROR)
file = qt.QFile(filePath)
if not file.remove():
self.logMessage('Load failed! Unable to delete and try again loading %s!' % filePath, logging.ERROR)
- return None
- return self.downloadFromSource(source,attemptCount)
+ loadedNode.append(None)
+ break
+ loadedNode = self.downloadFromSource(current_source,attemptCount)[0]
nodes.append(loadedNode)
+
return nodes
def sourceForSampleName(self,sampleName):
@@ -450,6 +511,16 @@ class SampleDataLogic:
self.logMessage('File already exists in cache - reusing it.')
return filePath
+ def loadScene(self, uri, fileProperties = {}):
+ self.logMessage('Requesting load %s...' % uri)
+ fileProperties['fileName'] = uri
+ success = slicer.app.coreIOManager().loadNodes('SceneFile', fileProperties)
+ if not success:
+ self.logMessage('\tLoad failed!', logging.ERROR)
+ return False
+ self.logMessage('Load finished')
+ return True
+
def loadNode(self, uri, name, fileType = 'VolumeFile', fileProperties = {}):
self.logMessage('Requesting load %s from %s...' % (name, uri))
--
GitLab
From 817e62f3e653661dec4a1f91f7bdc2d1e3eada1d Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Fri, 14 Dec 2018 13:58:36 -0500
Subject: [PATCH 4/6] STYLE: Update self-test to use SampleData downloadFromURL
API
---
.../SlicerApp/Testing/Python/AtlasTests.py | 37 +++----
.../SlicerApp/Testing/Python/DICOMReaders.py | 49 ++++-----
.../SlicerApp/Testing/Python/JRC2013Vis.py | 92 ++++------------
.../Testing/Python/RSNA2012ProstateDemo.py | 35 +-----
.../Testing/Python/RSNAQuantTutorial.py | 42 ++------
.../Testing/Python/RSNAVisTutorial.py | 74 ++++---------
.../Testing/Python/SliceLinkLogic.py | 17 +--
.../SlicerApp/Testing/Python/Slicer4Minute.py | 17 +--
.../SlicerRestoreSceneViewCrashIssue3445.py | 23 +---
.../Testing/Python/slicerCloseCrashBug2590.py | 18 +---
.../ScriptedLoadableModuleTemplate.py | 17 +--
.../Python/SegmentationsModuleTest1.py | 24 +----
Modules/Scripted/DataProbe/DataProbe.py | 17 +--
Modules/Scripted/SampleData/SampleData.py | 101 +++++++++++++++---
.../Scripted/SurfaceToolbox/SurfaceToolbox.py | 19 +---
.../Templates/Modules/Scripted/TemplateKey.py | 17 +--
16 files changed, 208 insertions(+), 391 deletions(-)
diff --git a/Applications/SlicerApp/Testing/Python/AtlasTests.py b/Applications/SlicerApp/Testing/Python/AtlasTests.py
index eaf9d28af..8e5fcc0f5 100644
--- a/Applications/SlicerApp/Testing/Python/AtlasTests.py
+++ b/Applications/SlicerApp/Testing/Python/AtlasTests.py
@@ -150,30 +150,33 @@ class AtlasTestsTest(ScriptedLoadableModuleTest):
def test_AbdominalAtlasTest(self):
self.delayDisplay('Running Abdominal Atlas Test')
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8301', 'Abdominal_Atlas_2012.mrb', slicer.util.loadScene),
- )
+ downloads = {
+ 'fileNames': 'Abdominal_Atlas_2012.mrb',
+ 'uris': 'http://slicer.kitware.com/midas3/download?items=8301'
+ }
self.perform_AtlasTest(downloads,'I')
def test_BrainAtlasTest(self):
self.delayDisplay('Running Brain Atlas Test')
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=10937', 'BrainAtlas2012.mrb', slicer.util.loadScene),
- )
+ downloads = {
+ 'fileNames': 'BrainAtlas2012.mrb',
+ 'uris': 'http://slicer.kitware.com/midas3/download?items=10937'
+ }
self.perform_AtlasTest(downloads,'A1_grayT1')
def test_KneeAtlasTest(self):
self.delayDisplay('Running Knee Atlas Test')
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=9912', 'KneeAtlas2012.mrb', slicer.util.loadScene),
- )
+ downloads = {
+ 'fileNames': 'KneeAtlas2012.mrb',
+ 'uris': 'http://slicer.kitware.com/midas3/download?items=9912'
+ }
self.perform_AtlasTest(downloads,'I')
- def perform_AtlasTest(self, downloads,testVolumePattern):
+ def perform_AtlasTest(self, downloads, testVolumePattern):
""" Perform the actual atlas test.
This includes: download and load the given data, touch all
model hierarchies, and restore all scene views.
- downloads : list of lists of: url, file save name, load callable
+ downloads : dictionnary of URIs and fileNames
testVolumePattern : volume name/id that is tested for valid load
"""
@@ -181,16 +184,8 @@ class AtlasTestsTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(**downloads)
self.delayDisplay('Finished with download and loading\n')
volumeNode = slicer.util.getNode(pattern=testVolumePattern)
diff --git a/Applications/SlicerApp/Testing/Python/DICOMReaders.py b/Applications/SlicerApp/Testing/Python/DICOMReaders.py
index b906f9077..a49ffa32a 100644
--- a/Applications/SlicerApp/Testing/Python/DICOMReaders.py
+++ b/Applications/SlicerApp/Testing/Python/DICOMReaders.py
@@ -2,7 +2,6 @@ import logging
import numpy
import os
import unittest
-import urllib
import vtk, qt, ctk, slicer
from slicer.ScriptedLoadableModule import *
from DICOMLib import DICOMUtils
@@ -66,24 +65,24 @@ class DICOMReadersTest(ScriptedLoadableModuleTest):
import os, json
self.delayDisplay("Starting the DICOM test")
- referenceData = json.JSONDecoder().decode('''[
- { "url": "http://slicer.kitware.com/midas3/download/item/292839/Mouse-MR-example-where-GDCM_fails.zip",
+ referenceData = [
+ { "url": "http://slicer.kitware.com/midas3/download?items=292839",
"fileName": "Mouse-MR-example-where-GDCM_fails.zip",
"name": "Mouse-MR-example-where-GDCM_fails",
"seriesUID": "1.3.6.1.4.1.9590.100.1.2.366426457713813178933224342280246227461",
"expectedFailures": ["GDCM", "Archetype"],
- "voxelValueQuantity": "(110852, DCM, \\"MR signal intensity\\")",
- "voxelValueUnits": "(1, UCUM, \\"no units\\")"
+ "voxelValueQuantity": "(110852, DCM, \"MR signal intensity\")",
+ "voxelValueUnits": "(1, UCUM, \"no units\")"
},
- { "url": "http://slicer.kitware.com/midas3/download/item/294857/deidentifiedMRHead-dcm-one-series.zip",
+ { "url": "http://slicer.kitware.com/midas3/download?items=294857",
"fileName": "deidentifiedMRHead-dcm-one-series.zip",
"name": "deidentifiedMRHead-dcm-one-series",
"seriesUID": "1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.270.0",
"expectedFailures": [],
- "voxelValueQuantity": "(110852, DCM, \\"MR signal intensity\\")",
- "voxelValueUnits": "(1, UCUM, \\"no units\\")"
+ "voxelValueQuantity": "(110852, DCM, \"MR signal intensity\")",
+ "voxelValueUnits": "(1, UCUM, \"no units\")"
}
- ]''')
+ ]
# another dataset that could be added in the future - currently fails for all readers
# due to invalid format - see https://issues.slicer.org/view.php?id=3569
@@ -101,16 +100,10 @@ class DICOMReadersTest(ScriptedLoadableModuleTest):
self.delayDisplay("Downloading")
for dataset in referenceData:
try:
- filePath = slicer.app.temporaryPath + '/' + dataset['fileName']
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- self.delayDisplay('Requesting download %s from %s...\n' % (dataset['fileName'], dataset['url']))
- urllib.urlretrieve(dataset['url'], filePath)
- self.delayDisplay('Finished with download\n')
-
- self.delayDisplay("Unzipping")
- dicomFilesDirectory = slicer.app.temporaryPath + dataset['name']
- qt.QDir().mkpath(dicomFilesDirectory)
- slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)
+ import SampleData
+ dicomFilesDirectory = SampleData.downloadFromURL(
+ fileNames=dataset['fileName'], uris=dataset['url'])[0]
+ self.delayDisplay('Finished with download')
#
# insert the data into th database
@@ -211,9 +204,12 @@ reloadScriptedModule('DICOMReaders'); import DICOMReaders; tester = DICOMReaders
import os, json
self.delayDisplay("Starting the DICOM test")
- datasetURL = "http://slicer.kitware.com/midas3/download/item/294857/deidentifiedMRHead-dcm-one-series.zip"
- fileName = "deidentifiedMRHead-dcm-one-series.zip"
- filePath = os.path.join(slicer.app.temporaryPath,fileName)
+ import SampleData
+ dicomFilesDirectory = SampleData.downloadFromURL(
+ fileNames='deidentifiedMRHead-dcm-one-series.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=294857')[0]
+ self.delayDisplay('Finished with download\n')
+
seriesUID = "1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.270.0"
seriesRASBounds = [-87.29489517211913, 81.70450973510744,
-121.57139587402344, 134.42860412597656,
@@ -241,15 +237,6 @@ reloadScriptedModule('DICOMReaders'); import DICOMReaders; tester = DICOMReaders
]
try:
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- self.delayDisplay('Requesting download %s from %s...\n' % (fileName, datasetURL))
- urllib.urlretrieve(datasetURL, filePath)
- self.delayDisplay('Finished with download\n')
-
- self.delayDisplay("Unzipping")
- dicomFilesDirectory = slicer.app.temporaryPath + 'MRhead'
- qt.QDir().mkpath(dicomFilesDirectory)
- slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)
print('Removing %d files from the middle of the series' % len(filesToRemove))
for file in filesToRemove:
diff --git a/Applications/SlicerApp/Testing/Python/JRC2013Vis.py b/Applications/SlicerApp/Testing/Python/JRC2013Vis.py
index b2231eb8c..09ac46aa0 100644
--- a/Applications/SlicerApp/Testing/Python/JRC2013Vis.py
+++ b/Applications/SlicerApp/Testing/Python/JRC2013Vis.py
@@ -91,22 +91,10 @@ class JRC2013VisWidget(ScriptedLoadableModuleWidget):
configFilePath = dicomFilesDirectory + '/dcmqrscp.cfg'
processCurrentPath = dicomFilesDirectory
else:
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=18822', 'Dcmtk-db.zip'),
- )
- print 'Downloading'
-
- import urllib
- for url,name in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print 'Requesting download %s from %s...\n' % (name, url)
- urllib.urlretrieve(url, filePath)
- print 'Finished with download'
-
- print 'Unzipping'
- qt.QDir().mkpath(dicomFilesDirectory)
- slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='Dcmtk-db.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=18822')[0]
import subprocess
dcmqrscpExeOptions = (
@@ -184,23 +172,10 @@ class JRC2013VisTestTest(ScriptedLoadableModuleTest):
#
# first, get the data - a zip file of dicom data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=18822', 'Dcmtk-db.zip'),
- )
-
- self.delayDisplay("Downloading")
- for url,name in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- self.delayDisplay('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- self.delayDisplay('Finished with download\n')
-
- self.delayDisplay("Unzipping")
- dicomFilesDirectory = slicer.app.temporaryPath + '/dicomFiles'
- qt.QDir().mkpath(dicomFilesDirectory)
- slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='Dcmtk-db.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=18822')[0]
try:
self.delayDisplay("Switching to temp database directory")
@@ -319,19 +294,10 @@ class JRC2013VisTestTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8609', '3DHeadData.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='3DHeadData.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=8609')
self.delayDisplay('Finished with download and loading\n')
try:
@@ -400,19 +366,10 @@ class JRC2013VisTestTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8611', 'LiverData.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='LiverData.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=8611')
self.delayDisplay('Finished with download and loading\n')
try:
@@ -476,19 +433,10 @@ class JRC2013VisTestTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8612', 'LungData.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='LungData.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=8612')
self.delayDisplay('Finished with download and loading\n')
try:
diff --git a/Applications/SlicerApp/Testing/Python/RSNA2012ProstateDemo.py b/Applications/SlicerApp/Testing/Python/RSNA2012ProstateDemo.py
index b6219731a..d0528bab0 100644
--- a/Applications/SlicerApp/Testing/Python/RSNA2012ProstateDemo.py
+++ b/Applications/SlicerApp/Testing/Python/RSNA2012ProstateDemo.py
@@ -64,22 +64,10 @@ class RSNA2012ProstateDemoTest(ScriptedLoadableModuleTest):
print("Running RSNA2012ProstateDemo Test case:")
- import urllib
-
- # perform the downloads if needed, then load
- filePath = slicer.app.temporaryPath + '/RSNA2012ProstateDemo.mrb'
- urlPath = 'http://slicer.kitware.com/midas3/download?items=10697'
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- self.delayDisplay('Downloading MRB from %s to %s...\n' % (urlPath, filePath))
- urllib.urlretrieve(urlPath, filePath)
- else:
- self.delayDisplay('Using existing %s...\n' % filePath)
- slicer.mrmlScene.Clear(0)
- appLogic = slicer.app.applicationLogic()
- self.delayDisplay('Done loading data! Will now open the bundle')
- mrbExtractPath = self.tempDirectory('__prostate_mrb_extract__')
- mrbLoaded = appLogic.OpenSlicerDataBundle(filePath, mrbExtractPath)
- slicer.app.processEvents()
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='RSNA2012ProstateDemo.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=10697')
# get all scene view nodes and test switching
svns = slicer.util.getNodes('vtkMRMLSceneViewNode*')
@@ -93,18 +81,3 @@ class RSNA2012ProstateDemoTest(ScriptedLoadableModuleTest):
self.delayDisplay('Done testing scene views, will clear the scene')
slicer.mrmlScene.Clear(0)
self.delayDisplay('Test passed')
-
- def tempDirectory(self,key='__SlicerTestTemp__',tempDir=None,includeDateTime=False):
- """Come up with a unique directory name in the temp dir and make it and return it
- # TODO: switch to QTemporaryDir in Qt5.
- Note: this directory is not automatically cleaned up
- """
- if not tempDir:
- tempDir = qt.QDir(slicer.app.temporaryPath)
- tempDirName = key
- if includeDateTime:
- key += qt.QDateTime().currentDateTime().toString("yyyy-MM-dd_hh+mm+ss.zzz")
- fileInfo = qt.QFileInfo(qt.QDir(tempDir), tempDirName)
- dirPath = fileInfo.absoluteFilePath()
- qt.QDir().mkpath(dirPath)
- return dirPath
diff --git a/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py b/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
index ee90c5334..6d9e9f925 100644
--- a/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
+++ b/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
@@ -217,27 +217,10 @@ class RSNAQuantTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124185', 'dataset3_PETCT.zip'),
- )
-
- self.delayDisplay("Downloading")
-
- for url,name in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- self.delayDisplay('Finished with download\n')
-
- self.delayDisplay("Unzipping to %s" % (slicer.app.temporaryPath))
- zipFilePath = slicer.app.temporaryPath + '/' + 'dataset3_PETCT.zip'
- extractPath = slicer.app.temporaryPath + '/' + 'dataset3_PETCT'
- qt.QDir().mkpath(extractPath)
- self.delayDisplay("Using extract path %s" % (extractPath))
- applicationLogic = slicer.app.applicationLogic()
- applicationLogic.Unzip(zipFilePath, extractPath)
+ import SampleData
+ extractPath = SampleData.downloadFromURL(
+ fileNames='dataset3_PETCT.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=124185')[0]
self.delayDisplay("Loading PET_CT_pre-treatment.mrb")
preTreatmentPath = extractPath + '/PET_CT_pre-treatment.mrb'
@@ -340,19 +323,10 @@ class RSNAQuantTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124184', 'ChangeTrackerScene.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='ChangeTrackerScene.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=124184')
logic.takeScreenshot('ChangeTracker-Loaded','Finished with download and loading',-1)
try:
diff --git a/Applications/SlicerApp/Testing/Python/RSNAVisTutorial.py b/Applications/SlicerApp/Testing/Python/RSNAVisTutorial.py
index 0af91fe3b..490534fc7 100644
--- a/Applications/SlicerApp/Testing/Python/RSNAVisTutorial.py
+++ b/Applications/SlicerApp/Testing/Python/RSNAVisTutorial.py
@@ -183,23 +183,10 @@ class RSNAVisTutorialTest(ScriptedLoadableModuleTest):
#
# first, get the data - a zip file of dicom data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124183', 'dataset1_Thorax_Abdomen.zip'),
- )
-
- self.delayDisplay("Downloading")
- for url,name in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- self.delayDisplay('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- self.delayDisplay('Finished with download\n')
-
- self.delayDisplay("Unzipping")
- dicomFilesDirectory = slicer.app.temporaryPath + '/dicomFiles'
- qt.QDir().mkpath(dicomFilesDirectory)
- slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)
+ import SampleData
+ dicomFilesDirectory = SampleData.downloadFromURL(
+ fileNames='dataset1_Thorax_Abdomen.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=124183')[0]
try:
self.delayDisplay("Switching to temp database directory")
@@ -319,19 +306,11 @@ class RSNAVisTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124180', 'Head_Scene.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='Head_Scene.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=124180')
+
logic.takeScreenshot('Head-Downloaded','Finished with download and loading',-1)
try:
@@ -426,19 +405,10 @@ class RSNAVisTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124181', 'LiverSegments_Scene.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='LiverSegments_Scene.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=124181')
logic.takeScreenshot('Liver-Loaded','Loaded Liver scene',-1)
@@ -507,19 +477,11 @@ class RSNAVisTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=124182', 'LungSegments_Scene.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='LungSegments_Scene.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=124182')
+
logic.takeScreenshot('Lung-Loaded','Finished with download and loading',-1)
try:
diff --git a/Applications/SlicerApp/Testing/Python/SliceLinkLogic.py b/Applications/SlicerApp/Testing/Python/SliceLinkLogic.py
index ced46ad04..35f9258af 100644
--- a/Applications/SlicerApp/Testing/Python/SliceLinkLogic.py
+++ b/Applications/SlicerApp/Testing/Python/SliceLinkLogic.py
@@ -122,19 +122,10 @@ class SliceLinkLogicTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='FA.nrrd',
+ uris='http://slicer.kitware.com/midas3/download?items=5767')
self.delayDisplay('Finished with download and loading')
print('')
diff --git a/Applications/SlicerApp/Testing/Python/Slicer4Minute.py b/Applications/SlicerApp/Testing/Python/Slicer4Minute.py
index ea78943ec..0a8edce88 100644
--- a/Applications/SlicerApp/Testing/Python/Slicer4Minute.py
+++ b/Applications/SlicerApp/Testing/Python/Slicer4Minute.py
@@ -119,19 +119,10 @@ class Slicer4MinuteTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8466', 'slicer4minute.mrb', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='slicer4minute.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=8466')
self.delayDisplay('Finished with download and loading')
# Testing "Part 2" of Tutorial
diff --git a/Applications/SlicerApp/Testing/Python/SlicerRestoreSceneViewCrashIssue3445.py b/Applications/SlicerApp/Testing/Python/SlicerRestoreSceneViewCrashIssue3445.py
index 6f7b5dd72..bc591025c 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerRestoreSceneViewCrashIssue3445.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerRestoreSceneViewCrashIssue3445.py
@@ -93,28 +93,15 @@ class SlicerRestoreSceneViewCrashIssue3445Test(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=10937', 'BrainAtlas2012.mrb', None),
- )
-
- filePaths = []
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- logging.info('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- filePaths.append(filePath)
- if loader:
- logging.info('Loading %s...' % (name,))
- loader(filePath)
- self.delayDisplay('Finished with download')
+ import SampleData
+ filePath = SampleData.downloadFromURL(
+ fileNames='BrainAtlas2012.mrb',
+ uris='http://slicer.kitware.com/midas3/download?items=10937')[0]
- filePath = filePaths[0]
+ self.delayDisplay('Finished with download')
ioManager = slicer.app.ioManager()
- ioManager.loadFile(filePath)
ioManager.loadFile(filePath)
slicer.mrmlScene.Clear(0)
diff --git a/Applications/SlicerApp/Testing/Python/slicerCloseCrashBug2590.py b/Applications/SlicerApp/Testing/Python/slicerCloseCrashBug2590.py
index 6b547787e..87715a28c 100644
--- a/Applications/SlicerApp/Testing/Python/slicerCloseCrashBug2590.py
+++ b/Applications/SlicerApp/Testing/Python/slicerCloseCrashBug2590.py
@@ -88,20 +88,10 @@ class slicerCloseCrashBug2590Test(ScriptedLoadableModuleTest):
#
self.delayDisplay("Starting the test")
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=8986', 'RSNA2011_ChangeTracker_data.zip', slicer.util.loadScene),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
- self.delayDisplay('Finished with download and loading\n')
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='RSNA2011_ChangeTracker_data.zip',
+ uris='http://slicer.kitware.com/midas3/download?items=8986')
try:
mainWindow = slicer.util.mainWindow()
diff --git a/Extensions/Testing/ScriptedLoadableExtensionTemplate/ScriptedLoadableModuleTemplate/ScriptedLoadableModuleTemplate.py b/Extensions/Testing/ScriptedLoadableExtensionTemplate/ScriptedLoadableModuleTemplate/ScriptedLoadableModuleTemplate.py
index 74edebb5b..6126e91c4 100644
--- a/Extensions/Testing/ScriptedLoadableExtensionTemplate/ScriptedLoadableModuleTemplate/ScriptedLoadableModuleTemplate.py
+++ b/Extensions/Testing/ScriptedLoadableExtensionTemplate/ScriptedLoadableModuleTemplate/ScriptedLoadableModuleTemplate.py
@@ -232,19 +232,10 @@ class ScriptedLoadableModuleTemplateTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- logging.info('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- logging.info('Loading %s...' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='FA.nrrd',
+ uris='http://slicer.kitware.com/midas3/download?items=5767')
self.delayDisplay('Finished with download and loading')
volumeNode = slicer.util.getNode(pattern="FA")
diff --git a/Modules/Loadable/Segmentations/Testing/Python/SegmentationsModuleTest1.py b/Modules/Loadable/Segmentations/Testing/Python/SegmentationsModuleTest1.py
index 3d6557a30..f87d38e6a 100644
--- a/Modules/Loadable/Segmentations/Testing/Python/SegmentationsModuleTest1.py
+++ b/Modules/Loadable/Segmentations/Testing/Python/SegmentationsModuleTest1.py
@@ -64,28 +64,8 @@ class SegmentationsModuleTest1(unittest.TestCase):
#------------------------------------------------------------------------------
def TestSection_RetrieveInputData(self):
try:
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download/folder/3763/TinyPatient_Seg.zip', self.dataZipFilePath),
- )
-
- downloaded = 0
- for url,filePath in downloads:
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- if downloaded == 0:
- logging.info('Downloading input data to folder\n' + self.dataZipFilePath)
- logging.info('Requesting download from %s...' % (url))
- urllib.urlretrieve(url, filePath)
- downloaded += 1
- else:
- logging.info('Input data has been found in folder ' + self.dataZipFilePath)
- if downloaded > 0:
- logging.info('Downloading input data finished')
-
- numOfFilesInDataDir = len([name for name in os.listdir(self.dataDir) if os.path.isfile(self.dataDir + '/' + name)])
- if (numOfFilesInDataDir != self.expectedNumOfFilesInDataDir):
- slicer.app.applicationLogic().Unzip(self.dataZipFilePath, self.segmentationsModuleTestDir)
- logging.info("Unzipping done")
+ slicer.util.downloadAndExtractArchive(
+ 'http://slicer.kitware.com/midas3/download/folder/3763/TinyPatient_Seg.zip', self.dataZipFilePath, self.segmentationsModuleTestDir)
numOfFilesInDataDirTest = len([name for name in os.listdir(self.dataDir) if os.path.isfile(self.dataDir + '/' + name)])
self.assertEqual( numOfFilesInDataDirTest, self.expectedNumOfFilesInDataDir )
diff --git a/Modules/Scripted/DataProbe/DataProbe.py b/Modules/Scripted/DataProbe/DataProbe.py
index db3d68f07..9bc2b4d0f 100644
--- a/Modules/Scripted/DataProbe/DataProbe.py
+++ b/Modules/Scripted/DataProbe/DataProbe.py
@@ -583,19 +583,10 @@ class DataProbeTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- logging.info('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- logging.info('Loading %s...' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='FA.nrrd',
+ uris='http://slicer.kitware.com/midas3/download?items=5767')
self.delayDisplay('Finished with download and loading')
self.widget = DataProbeInfoWidget()
diff --git a/Modules/Scripted/SampleData/SampleData.py b/Modules/Scripted/SampleData/SampleData.py
index d28869f13..239226b1e 100644
--- a/Modules/Scripted/SampleData/SampleData.py
+++ b/Modules/Scripted/SampleData/SampleData.py
@@ -4,6 +4,39 @@ import vtk, qt, ctk, slicer
from slicer.ScriptedLoadableModule import *
import logging
+#
+# SampleData methods
+#
+
+def downloadFromURL(uris, fileNames, nodeNames=None,
+ customDownloader=None, loadFileTypes=None, loadFileProperties={}):
+ """Download and optionally load data into the application.
+
+ :param uris: Download URL(s).
+ :param fileNames: File name(s) that will be loaded.
+ :param nodeNames: Node name(s) in the scene.
+ :param customDownloader: Custom function for downloading.
+ :param loadFileTypes: file format name(s) ('VolumeFile' by default).
+ :param loadFileProperties: custom properties passed to the IO plugin.
+
+ If the given ``fileNames`` are not found in the application cache directory, they
+ are downloaded using the associated URIs.
+ See ``slicer.mrmlScene.GetCacheManager().GetRemoteCacheDirectory()``
+
+ If not explicitly provided or if set to ``None``, the ``loadFileTypes`` are
+ guessed based on the corresponding filename extensions.
+
+ If not explicitly provided or if set to ``None``, the ``nodeNames`` are
+ set based on the corresponding filename basename.
+
+ The ``loadFileProperties`` are common for all files. If different properties
+ need to be associated with files of different types, downloadFromURL must
+ be called for each.
+ """
+ return SampleDataLogic().downloadFromURL(
+ uris, fileNames, nodeNames, customDownloader, loadFileTypes, loadFileProperties)
+
+
#
# SampleData
#
@@ -74,7 +107,6 @@ class SampleDataSource:
import SampleData
dataSource = SampleData.SampleDataSource(
- nodeNames='fixed',
fileNames='fixed.nrrd',
uris='http://slicer.kitware.com/midas3/download/item/157188/small-mr-eye-fixed.nrrd')
loadedNode = SampleData.SampleDataLogic().downloadFromSource(dataSource)[0]
@@ -82,7 +114,7 @@ class SampleDataSource:
def __init__(self, sampleName=None, uris=None, fileNames=None, nodeNames=None,
customDownloader=None, thumbnailFileName=None,
- loadFileType='VolumeFile', loadFileProperties={}):
+ loadFileType=None, loadFileProperties={}):
"""
:param sampleName: Displayed name of data set in SampleData module GUI.
:param thumbnailFileName: Displayed thumbnail of data set in SampleData module GUI,
@@ -95,23 +127,41 @@ class SampleDataSource:
"""
self.sampleName = sampleName
if (isinstance(uris, list) or isinstance(uris, tuple)):
- if isinstance(loadFileType, basestring):
+ if isinstance(loadFileType, basestring) or loadFileType is None:
loadFileType = [loadFileType] * len(uris)
- if nodeNames is None:
- nodeNames = [os.path.splitext(fileName) for fileName in fileNames]
elif isinstance(uris, basestring):
uris = [uris,]
fileNames = [fileNames,]
nodeNames = [nodeNames,]
loadFileType = [loadFileType,]
+
+ updatedFileType = []
+ updatedNodeNames = []
+ for fileName, nodeName, fileType in zip(fileNames, nodeNames, loadFileType):
+ # If not explicitly specified, attempt to guess fileType
+ if fileType is None:
+ # TODO: Use method from Slicer IO logic ?
+ ext = os.path.splitext(fileName.lower())[1]
+ if ext in [".mrml", ".mrb"]:
+ fileType = "SceneFile"
+ elif ext in [".zip"]:
+ fileType = "ZipFile"
+ else:
+ fileType = "VolumeFile"
+ updatedFileType.append(fileType)
+ # If not explicitly specified, attempt to guess nodeName
+ if nodeName is None and fileType not in ["SceneFile", "ZipFile"]:
+ nodeName = fileName.split(".")[0]
+ updatedNodeNames.append(nodeName)
+
self.uris = uris
self.fileNames = fileNames
- self.nodeNames = nodeNames
+ self.nodeNames = updatedNodeNames
self.customDownloader = customDownloader
self.thumbnailFileName = thumbnailFileName
- self.loadFileType = loadFileType
+ self.loadFileType = updatedFileType
self.loadFileProperties = loadFileProperties
- if len(uris) != len(fileNames) or len(uris) != len(nodeNames) or len(uris) != len(loadFileType):
+ if len(uris) != len(fileNames) or len(uris) != len(updatedNodeNames) or len(uris) != len(updatedFileType):
raise Exception("All fields of sample data source must have the same length")
@@ -349,11 +399,6 @@ class SampleDataLogic:
filePaths.append(self.downloadFileIntoCache(uri, fileName))
return filePaths
- def downloadFromSources(self,sources,attemptCount=0):
- """Given one or multiple instances of SampleDataSource, downloads the associated data and
- load them into Slicer if it applies."""
- return [self.downloadFromSource(source, attemptCount=attemptCount) for source in sources]
-
def downloadFromSource(self,source,attemptCount=0):
"""Given an instance of SampleDataSource, downloads the associated data and
load them into Slicer if it applies.
@@ -426,6 +471,36 @@ class SampleDataLogic:
return source
return None
+ def downloadFromURL(self, uris, fileNames, nodeNames=None,
+ customDownloader=None, loadFileTypes=None, loadFileProperties={}):
+ """Download and optionally load data into the application.
+
+ :param uris: Download URL(s).
+ :param fileNames: File name(s) that will be loaded.
+ :param nodeNames: Node name(s) in the scene.
+ :param customDownloader: Custom function for downloading.
+ :param loadFileTypes: file format name(s) ('VolumeFile' by default).
+ :param loadFileProperties: custom properties passed to the IO plugin.
+
+ If the given ``fileNames`` are not found in the application cache directory, they
+ are downloaded using the associated URIs.
+ See ``slicer.mrmlScene.GetCacheManager().GetRemoteCacheDirectory()``
+
+ If not explicitly provided or if set to ``None``, the ``loadFileTypes`` are
+ guessed based on the corresponding filename extensions.
+
+ If not explicitly provided or if set to ``None``, the ``nodeNames`` are
+ set based on the corresponding filename basename.
+
+ The ``loadFileProperties`` are common for all files. If different properties
+ need to be associated with files of different types, downloadFromURL must
+ be called for each.
+ """
+ return self.downloadFromSource(SampleDataSource(
+ uris=uris, fileNames=fileNames, nodeNames=nodeNames,
+ loadFileType=loadFileTypes, loadFileProperties=loadFileProperties
+ ))
+
def downloadSample(self,sampleName):
"""For a given sample name this will search the available sources
and load it if it is available. Returns the loaded nodes."""
diff --git a/Modules/Scripted/SurfaceToolbox/SurfaceToolbox.py b/Modules/Scripted/SurfaceToolbox/SurfaceToolbox.py
index 542646cc5..b34b015d4 100644
--- a/Modules/Scripted/SurfaceToolbox/SurfaceToolbox.py
+++ b/Modules/Scripted/SurfaceToolbox/SurfaceToolbox.py
@@ -542,20 +542,11 @@ class SurfaceToolboxTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- print('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- print('Loading %s...\n' % (name,))
- loader(filePath)
- self.delayDisplay('Finished with download and loading\n')
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='FA.nrrd',
+ uris='http://slicer.kitware.com/midas3/download?items=5767')
+ self.delayDisplay('Finished with download and loading')
volumeNode = slicer.util.getNode(pattern="FA")
logic = SurfaceToolboxLogic()
diff --git a/Utilities/Templates/Modules/Scripted/TemplateKey.py b/Utilities/Templates/Modules/Scripted/TemplateKey.py
index f486a1973..ef3c26d6d 100644
--- a/Utilities/Templates/Modules/Scripted/TemplateKey.py
+++ b/Utilities/Templates/Modules/Scripted/TemplateKey.py
@@ -232,19 +232,10 @@ class TemplateKeyTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- import urllib
- downloads = (
- ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
- )
-
- for url,name,loader in downloads:
- filePath = slicer.app.temporaryPath + '/' + name
- if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
- logging.info('Requesting download %s from %s...\n' % (name, url))
- urllib.urlretrieve(url, filePath)
- if loader:
- logging.info('Loading %s...' % (name,))
- loader(filePath)
+ import SampleData
+ SampleData.downloadFromURL(
+ fileNames='FA.nrrd',
+ uris='http://slicer.kitware.com/midas3/download?items=5767')
self.delayDisplay('Finished with download and loading')
volumeNode = slicer.util.getNode(pattern="FA")
--
GitLab
From fdaf282eae4bde3726f442fcf745cdd3021b564e Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Fri, 14 Dec 2018 20:19:05 -0500
Subject: [PATCH 5/6] STYLE: Update CompareVolumes,LandmarkRegistration to use
ScriptedLoadableModule base classes
List of CompareVolumes changes:
$ git shortlog 9a41493..b2a9a0d --no-merges
Jean-Christophe Fillion-Robin (2):
STYLE: Remove import specific to futurize
STYLE: Re-factor scripted module to use ScriptedLoadableModule base classes
ihnorton (1):
Python 3 compatibility via futurize
List of LandmarkRegistration changes:
$ git shortlog beb4e47..837e5ed --no-merges
Jean-Christophe Fillion-Robin (1):
STYLE: Re-factor scripted module to use ScriptedLoadableModule base classes
---
SuperBuild.cmake | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/SuperBuild.cmake b/SuperBuild.cmake
index 5d01d2baa..2ea0be0cd 100644
--- a/SuperBuild.cmake
+++ b/SuperBuild.cmake
@@ -309,7 +309,7 @@ list_conditional_append(Slicer_BUILD_DataStore Slicer_REMOTE_DEPENDENCIES DataSt
Slicer_Remote_Add(CompareVolumes
GIT_REPOSITORY "${EP_GIT_PROTOCOL}://github.com/pieper/CompareVolumes"
- GIT_TAG "9a41493ed810a85b97245604af4138c5f45ff52f"
+ GIT_TAG "b2a9a0d9045f3bc819504ad25a20409047e61694"
OPTION_NAME Slicer_BUILD_CompareVolumes
OPTION_DEPENDS "Slicer_USE_PYTHONQT"
LABELS REMOTE_MODULE
@@ -318,7 +318,7 @@ list_conditional_append(Slicer_BUILD_CompareVolumes Slicer_REMOTE_DEPENDENCIES C
Slicer_Remote_Add(LandmarkRegistration
GIT_REPOSITORY "${EP_GIT_PROTOCOL}://github.com/pieper/LandmarkRegistration"
- GIT_TAG "beb4e47a5455bf2bfa8cde8aee6b03c76844c4c2"
+ GIT_TAG "837e5edfb3b69844f2f06bf152a6edc6e7af1e8d"
OPTION_NAME Slicer_BUILD_LandmarkRegistration
OPTION_DEPENDS "Slicer_BUILD_CompareVolumes;Slicer_USE_PYTHONQT"
LABELS REMOTE_MODULE
--
GitLab
From 2adbdae1ec94ef4eeded05adaaf32c26829f23f9 Mon Sep 17 00:00:00 2001
From: Jean-Christophe Fillion-Robin
Date: Fri, 14 Dec 2018 19:00:43 -0500
Subject: [PATCH 6/6] STYLE: Add SampleData.downloadSample
---
...RAINSFitRigidRegistrationCrashIssue4139.py | 6 +-
.../SlicerApp/Testing/Python/CLIEventTest.py | 4 +-
.../Python/FiducialLayoutSwitchBug1914.py | 4 +-
.../Testing/Python/RSNAQuantTutorial.py | 4 +-
.../Testing/Python/SlicerBoundsTest.py | 4 +-
.../SlicerMRBMultipleSaveRestoreLoopTest.py | 4 +-
.../SlicerMRBMultipleSaveRestoreTest.py | 4 +-
.../SlicerMRBSaveRestoreCheckPathsTest.py | 4 +-
.../Python/SlicerOrientationSelectorTest.py | 4 +-
.../Python/SlicerTransformInteractionTest1.py | 4 +-
.../SlicerApp/Testing/Python/UtilTest.py | 28 +-
...iewControllersSliceInterpolationBug1926.py | 6 +-
.../Testing/Python/sceneImport2428.py | 4 +-
Base/Python/slicer/util.py | 4 +-
Base/Python/tests/test_sitkUtils.py | 8 +-
CMake/DeployQt5.cmake | 353 ++++++++++++++++++
...riptedSegmentEditorEffectModuleTemplate.py | 4 +-
.../Testing/Python/CropVolumeSelfTest.py | 6 +-
.../Python/MarkupsInCompareViewersSelfTest.py | 4 +-
.../Testing/Python/MarkupsInViewsSelfTest.py | 4 +-
...surgicalPlanningTutorialMarkupsSelfTest.py | 4 +-
.../AddStorableDataAfterSceneViewTest.py | 6 +-
.../Python/SegmentationWidgetsTest1.py | 4 +-
.../Python/VolumeRenderingSceneClose.py | 4 +-
.../Python/VolumeRenderingThreeDOnlyLayout.py | 4 +-
.../LoadVolumeDisplaybleSceneModelClose.py | 4 +-
.../VolumesLogicCompareVolumeGeometry.py | 4 +-
.../Testing/StandaloneEditorWidgetTest.py | 4 +-
.../Testing/ThresholdThreadingTest.py | 4 +-
.../LabelStatistics/LabelStatistics.py | 6 +-
.../PerformanceTests/PerformanceTests.py | 4 +-
Modules/Scripted/SampleData/SampleData.py | 5 +
.../Scripted/ScreenCapture/ScreenCapture.py | 6 +-
.../SegmentStatistics/SegmentStatistics.py | 8 +-
.../SegmentEditorTemplateKey.py | 4 +-
35 files changed, 446 insertions(+), 88 deletions(-)
create mode 100644 CMake/DeployQt5.cmake
diff --git a/Applications/SlicerApp/Testing/Python/BRAINSFitRigidRegistrationCrashIssue4139.py b/Applications/SlicerApp/Testing/Python/BRAINSFitRigidRegistrationCrashIssue4139.py
index a477a9524..ef92aae57 100644
--- a/Applications/SlicerApp/Testing/Python/BRAINSFitRigidRegistrationCrashIssue4139.py
+++ b/Applications/SlicerApp/Testing/Python/BRAINSFitRigidRegistrationCrashIssue4139.py
@@ -103,12 +103,12 @@ class BRAINSFitRigidRegistrationCrashIssue4139Test(ScriptedLoadableModuleTest):
logic = BRAINSFitRigidRegistrationCrashIssue4139Logic()
- from SampleData import SampleDataLogic
+ import SampleData
- fixed = SampleDataLogic().downloadMRBrainTumor1()
+ fixed = SampleData.downloadSample('MRBrainTumor1')[0]
self.assertIsNotNone(logic.hasImageData(fixed))
- moving = SampleDataLogic().downloadMRBrainTumor2()
+ moving = SampleData.downloadSample('MRBrainTumor2')[0]
self.assertIsNotNone(logic.hasImageData(moving))
self.delayDisplay('Finished with download and loading')
diff --git a/Applications/SlicerApp/Testing/Python/CLIEventTest.py b/Applications/SlicerApp/Testing/Python/CLIEventTest.py
index a7de28161..1027ee207 100644
--- a/Applications/SlicerApp/Testing/Python/CLIEventTest.py
+++ b/Applications/SlicerApp/Testing/Python/CLIEventTest.py
@@ -219,8 +219,8 @@ class CLIEventTestTest(ScriptedLoadableModuleTest):
self.delayDisplay('Test that output node moved to referenced node location in subject hierarchy')
self.delayDisplay('Load input volume')
- from SampleData import SampleDataLogic
- inputVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ inputVolume = SampleData.downloadSample("MRHead")[0]
self.delayDisplay('Create subject hierarchy of input volume')
shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)
diff --git a/Applications/SlicerApp/Testing/Python/FiducialLayoutSwitchBug1914.py b/Applications/SlicerApp/Testing/Python/FiducialLayoutSwitchBug1914.py
index 5e8cddb0a..9f5735550 100644
--- a/Applications/SlicerApp/Testing/Python/FiducialLayoutSwitchBug1914.py
+++ b/Applications/SlicerApp/Testing/Python/FiducialLayoutSwitchBug1914.py
@@ -135,8 +135,8 @@ class FiducialLayoutSwitchBug1914Logic(ScriptedLoadableModuleLogic):
self.delayDisplay("Conventional view")
# Download MRHead from sample data
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
# Place a fiducial on the red slice
markupsLogic = slicer.modules.markups.logic()
diff --git a/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py b/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
index 6d9e9f925..c09997bee 100644
--- a/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
+++ b/Applications/SlicerApp/Testing/Python/RSNAQuantTutorial.py
@@ -158,8 +158,8 @@ class RSNAQuantTutorialTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- from SampleData import SampleDataLogic
- tumor = SampleDataLogic().downloadMRBrainTumor1()
+ import SampleData
+ tumor = SampleData.downloadSample('MRBrainTumor1')[0]
try:
# four up view
diff --git a/Applications/SlicerApp/Testing/Python/SlicerBoundsTest.py b/Applications/SlicerApp/Testing/Python/SlicerBoundsTest.py
index 4a5a1f260..463b8b1e9 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerBoundsTest.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerBoundsTest.py
@@ -71,8 +71,8 @@ class SlicerBoundsTestTest(ScriptedLoadableModuleTest):
""" Test the GetRASBounds & GetBounds method on a volume.
"""
#self.delayDisplay("Starting test_Volume")
- from SampleData import SampleDataLogic
- volumeNode = SampleDataLogic().downloadAbdominalCTVolume()
+ import SampleData
+ volumeNode = SampleData.downloadSample('CTA abdomen\n(Panoramix)')[0]
bounds = range(6)
volumeNode.GetRASBounds(bounds)
diff --git a/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreLoopTest.py b/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreLoopTest.py
index 5ca879b99..31d6afa28 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreLoopTest.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreLoopTest.py
@@ -89,8 +89,8 @@ class SlicerMRBMultipleSaveRestoreLoop(ScriptedLoadableModuleTest):
# first, get the data
#
print("Getting MR Head Volume")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
# Place a fiducial
markupsLogic = slicer.modules.markups.logic()
diff --git a/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreTest.py b/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreTest.py
index 7cdb31827..47e3c6a6e 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreTest.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerMRBMultipleSaveRestoreTest.py
@@ -86,8 +86,8 @@ class SlicerMRBMultipleSaveRestore(ScriptedLoadableModuleTest):
# first, get the data
#
print("Getting MR Head Volume")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
# Place a fiducial
markupsLogic = slicer.modules.markups.logic()
diff --git a/Applications/SlicerApp/Testing/Python/SlicerMRBSaveRestoreCheckPathsTest.py b/Applications/SlicerApp/Testing/Python/SlicerMRBSaveRestoreCheckPathsTest.py
index 8eae0afb9..fe3027688 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerMRBSaveRestoreCheckPathsTest.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerMRBSaveRestoreCheckPathsTest.py
@@ -154,8 +154,8 @@ class SlicerMRBSaveRestoreCheckPaths(ScriptedLoadableModuleTest):
# first, get the volume data
#
print("Getting MR Head Volume")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
slicer.util.delayDisplay('Finished with download of volume')
diff --git a/Applications/SlicerApp/Testing/Python/SlicerOrientationSelectorTest.py b/Applications/SlicerApp/Testing/Python/SlicerOrientationSelectorTest.py
index bde741952..c28ef5f8f 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerOrientationSelectorTest.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerOrientationSelectorTest.py
@@ -100,8 +100,8 @@ class SlicerOrientationSelectorTestTest(ScriptedLoadableModuleTest):
logic = SlicerOrientationSelectorTestLogic()
self.delayDisplay("Starting the test")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
slicer.util.selectModule('Reformat')
diff --git a/Applications/SlicerApp/Testing/Python/SlicerTransformInteractionTest1.py b/Applications/SlicerApp/Testing/Python/SlicerTransformInteractionTest1.py
index c68cae575..af6642469 100644
--- a/Applications/SlicerApp/Testing/Python/SlicerTransformInteractionTest1.py
+++ b/Applications/SlicerApp/Testing/Python/SlicerTransformInteractionTest1.py
@@ -135,8 +135,8 @@ class SlicerTransformInteractionTest1Test(ScriptedLoadableModuleTest):
"""
logic = SlicerTransformInteractionTest1Logic()
- from SampleData import SampleDataLogic
- volume = SampleDataLogic().downloadAbdominalCTVolume()
+ import SampleData
+ volume = SampleData.downloadSample('CTA abdomen\n(Panoramix)')[0]
#self.delayDisplay("Starting test_3D_interactionVolume")
logic = SlicerTransformInteractionTest1Logic()
diff --git a/Applications/SlicerApp/Testing/Python/UtilTest.py b/Applications/SlicerApp/Testing/Python/UtilTest.py
index 1987501b6..7735829a6 100644
--- a/Applications/SlicerApp/Testing/Python/UtilTest.py
+++ b/Applications/SlicerApp/Testing/Python/UtilTest.py
@@ -96,11 +96,11 @@ class UtilTestTest(ScriptedLoadableModuleTest):
self.assertIsNone(redSliceCompositeNode.GetForegroundVolumeID())
self.assertIsNone(redSliceCompositeNode.GetLabelVolumeID())
- from SampleData import SampleDataLogic
+ import SampleData
- backgroundNode = SampleDataLogic().downloadMRHead()
+ backgroundNode = SampleData.downloadSample("MRHead")[0]
backgroundNode.SetName('Background')
- foregroundNode = SampleDataLogic().downloadMRHead()
+ foregroundNode = SampleData.downloadSample("MRHead")[0]
foregroundNode.SetName('Foreground')
volumesLogic = slicer.modules.volumes.logic()
@@ -133,9 +133,9 @@ class UtilTestTest(ScriptedLoadableModuleTest):
self.assertEqual(redSliceCompositeNode.GetLabelOpacity(), 0.1)
# Try to reset
- otherBackgroundNode = SampleDataLogic().downloadMRHead()
+ otherBackgroundNode = SampleData.downloadSample("MRHead")[0]
otherBackgroundNode.SetName('OtherBackground')
- otherForegroundNode = SampleDataLogic().downloadMRHead()
+ otherForegroundNode = SampleData.downloadSample("MRHead")[0]
otherForegroundNode.SetName('OtherForeground')
otherLabelmapNode = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, backgroundNode, 'OtherLabelmap' )
@@ -199,8 +199,8 @@ class UtilTestTest(ScriptedLoadableModuleTest):
# Test if retrieving voxels as a numpy array works
self.delayDisplay('Download sample data')
- from SampleData import SampleDataLogic
- volumeNode = SampleDataLogic().downloadMRHead()
+ import SampleData
+ volumeNode = SampleData.downloadSample("MRHead")[0]
self.delayDisplay('Test voxel value read')
voxelPos = [120,135,89]
@@ -221,8 +221,8 @@ class UtilTestTest(ScriptedLoadableModuleTest):
# Test if updating voxels from a numpy array works
self.delayDisplay('Download sample data')
- from SampleData import SampleDataLogic
- volumeNode = SampleDataLogic().downloadMRHead()
+ import SampleData
+ volumeNode = SampleData.downloadSample("MRHead")[0]
import numpy as np
import math
@@ -254,8 +254,8 @@ class UtilTestTest(ScriptedLoadableModuleTest):
self.assertEqual(tableNode1.GetNumberOfRows(), 3)
self.delayDisplay('Download sample data')
- from SampleData import SampleDataLogic
- volumeNode = SampleDataLogic().downloadMRHead()
+ import SampleData
+ volumeNode = SampleData.downloadSample("MRHead")[0]
self.delayDisplay('Compute histogram')
histogram = np.histogram(slicer.util.arrayFromVolume(volumeNode))
@@ -290,8 +290,8 @@ class UtilTestTest(ScriptedLoadableModuleTest):
# Test if convenience function of getting numpy array from various nodes works
self.delayDisplay('Test array with scalar image')
- from SampleData import SampleDataLogic
- volumeNode = SampleDataLogic().downloadMRHead()
+ import SampleData
+ volumeNode = SampleData.downloadSample("MRHead")[0]
voxelPos = [120,135,89]
voxelValueVtk = volumeNode.GetImageData().GetScalarComponentAsDouble(voxelPos[0], voxelPos[1], voxelPos[2], 0)
narray = slicer.util.arrayFromVolume(volumeNode)
@@ -299,7 +299,7 @@ class UtilTestTest(ScriptedLoadableModuleTest):
self.assertEqual(voxelValueVtk, voxelValueNumpy)
self.delayDisplay('Test array with tensor image')
- tensorVolumeNode = SampleDataLogic().downloadDTIBrain()
+ tensorVolumeNode = SampleData.downloadSample('DTIBrain')[0]
narray = slicer.util.array(tensorVolumeNode.GetName())
self.assertEqual(narray.shape, (85, 144, 144, 3, 3))
diff --git a/Applications/SlicerApp/Testing/Python/ViewControllersSliceInterpolationBug1926.py b/Applications/SlicerApp/Testing/Python/ViewControllersSliceInterpolationBug1926.py
index 52aa77fdf..e0a63a968 100644
--- a/Applications/SlicerApp/Testing/Python/ViewControllersSliceInterpolationBug1926.py
+++ b/Applications/SlicerApp/Testing/Python/ViewControllersSliceInterpolationBug1926.py
@@ -96,9 +96,9 @@ class ViewControllersSliceInterpolationBug1926Test(ScriptedLoadableModuleTest):
# first, get some data
#
self.delayDisplay("Getting Data")
- from SampleData import SampleDataLogic
- head = SampleDataLogic().downloadMRHead()
- tumor = SampleDataLogic().downloadMRBrainTumor1()
+ import SampleData
+ head = SampleData.downloadSample("MRHead")[0]
+ tumor = SampleData.downloadSample('MRBrainTumor1')[0]
# Change to a CompareView
ln = slicer.util.getNode(pattern='vtkMRMLLayoutNode*')
diff --git a/Applications/SlicerApp/Testing/Python/sceneImport2428.py b/Applications/SlicerApp/Testing/Python/sceneImport2428.py
index aca2f1d25..c7c5ba940 100644
--- a/Applications/SlicerApp/Testing/Python/sceneImport2428.py
+++ b/Applications/SlicerApp/Testing/Python/sceneImport2428.py
@@ -97,8 +97,8 @@ class sceneImport2428Test(ScriptedLoadableModuleTest):
# first, get some data
#
self.delayDisplay("Getting Data")
- from SampleData import SampleDataLogic
- head = SampleDataLogic().downloadMRHead()
+ import SampleData
+ head = SampleData.downloadSample("MRHead")[0]
#
# create a label map and set it for editing
diff --git a/Base/Python/slicer/util.py b/Base/Python/slicer/util.py
index cb9d2d1ed..83db6917c 100644
--- a/Base/Python/slicer/util.py
+++ b/Base/Python/slicer/util.py
@@ -1366,7 +1366,7 @@ def plot(narray, xColumnIndex = -1, columnNames = None, title = None, show = Tru
# Get sample data
import numpy as np
import SampleData
- volumeNode = SampleData.SampleDataLogic().downloadMRHead()
+ volumeNode = SampleData.downloadSample("MRHead")[0]
# Create new plot
histogram = np.histogram(arrayFromVolume(volumeNode), bins=50)
@@ -1383,7 +1383,7 @@ def plot(narray, xColumnIndex = -1, columnNames = None, title = None, show = Tru
# Get sample data
import numpy as np
import SampleData
- volumeNode = SampleData.SampleDataLogic().downloadMRHead()
+ volumeNode = SampleData.downloadSample("MRHead")[0]
# Create variable that will store plot nodes (chart, table, series)
plotNodes = {}
diff --git a/Base/Python/tests/test_sitkUtils.py b/Base/Python/tests/test_sitkUtils.py
index c6ebe1ef2..cef301e3b 100644
--- a/Base/Python/tests/test_sitkUtils.py
+++ b/Base/Python/tests/test_sitkUtils.py
@@ -13,8 +13,8 @@ class SitkUtilsTests(unittest.TestCase):
""" Download the MRHead node
"""
- from SampleData import SampleDataLogic
- SampleDataLogic().downloadMRHead()
+ import SampleData
+ SampleData.downloadSample("MRHead")[0]
volumeNode1 = slicer.util.getNode('MRHead')
self.assertEqual(volumeNode1.GetName(), "MRHead")
@@ -86,8 +86,8 @@ class SitkUtilsTests(unittest.TestCase):
""" Download the MRHead node
"""
- from SampleData import SampleDataLogic
- SampleDataLogic().downloadMRHead()
+ import SampleData
+ SampleData.downloadSample("MRHead")[0]
volumeNode1 = slicer.util.getNode('MRHead')
self.assertEqual(volumeNode1.GetName(), "MRHead")
diff --git a/CMake/DeployQt5.cmake b/CMake/DeployQt5.cmake
new file mode 100644
index 000000000..d92109e8a
--- /dev/null
+++ b/CMake/DeployQt5.cmake
@@ -0,0 +1,353 @@
+#.rst:
+# DeployQt5
+# ---------
+#
+# Functions to help assemble a standalone Qt5 executable.
+#
+# A collection of CMake utility functions useful for deploying Qt5
+# executables.
+#
+# The following functions are provided by this module:
+#
+# ::
+#
+# write_qt5_conf
+# resolve_qt5_paths
+# fixup_qt5_executable
+# install_qt5_plugin_path
+# install_qt5_plugin
+# install_qt5_executable
+#
+# Requires CMake 2.8.9 or greater because Qt 5 does.
+# Also depends on BundleUtilities.cmake.
+#
+# ::
+#
+# WRITE_QT5_CONF( )
+#
+# Writes a qt.conf file with the into .
+#
+# ::
+#
+# RESOLVE_QT5_PATHS( [])
+#
+# Loop through list and if any don't exist resolve them
+# relative to the (if supplied) or the
+# CMAKE_INSTALL_PREFIX.
+#
+# ::
+#
+# FIXUP_QT5_EXECUTABLE( [ ])
+#
+# Copies Qt plugins, writes a Qt configuration file (if needed) and
+# fixes up a Qt5 executable using BundleUtilities so it is standalone
+# and can be drag-and-drop copied to another machine as long as all of
+# the system libraries are compatible.
+#
+# should point to the executable to be fixed-up.
+#
+# should contain a list of the names or paths of any Qt
+# plugins to be installed.
+#
+# will be passed to BundleUtilities and should be a list of any
+# already installed plugins, libraries or executables to also be
+# fixed-up.
+#
+# will be passed to BundleUtilities and should contain and
+# directories to be searched to find library dependencies.
+#
+# allows an custom plugins directory to be used.
+#
+# will force a qt.conf file to be written even if not
+# needed.
+#
+# ::
+#
+# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var )
+#
+# Install (or copy) a resolved to the default plugins directory
+# (or ) relative to and store the result in
+# .
+#
+# If is set to TRUE then the plugins will be copied rather than
+# installed. This is to allow this module to be used at CMake time
+# rather than install time.
+#
+# If is set then anything installed will use this COMPONENT.
+#
+# ::
+#
+# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var )
+#
+# Install (or copy) an unresolved to the default plugins
+# directory (or ) relative to and store the
+# result in . See documentation of
+# INSTALL_QT5_PLUGIN_PATH.
+#
+# ::
+#
+# INSTALL_QT5_EXECUTABLE( [ ])
+#
+# Installs Qt plugins, writes a Qt configuration file (if needed) and
+# fixes up a Qt5 executable using BundleUtilities so it is standalone
+# and can be drag-and-drop copied to another machine as long as all of
+# the system libraries are compatible. The executable will be fixed-up
+# at install time. is the COMPONENT used for bundle fixup
+# and plugin installation. See documentation of FIXUP_QT5_BUNDLE.
+
+#=============================================================================
+# Copyright 2011 Mike McQuaid
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# The functions defined in this file depend on the fixup_bundle function
+# (and others) found in BundleUtilities.cmake
+
+include(BundleUtilities)
+set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
+set(DeployQt5_apple_plugins_dir "PlugIns")
+
+function(write_qt5_conf qt_conf_dir qt_conf_contents)
+ set(qt_conf_path "${qt_conf_dir}/qt.conf")
+ message(STATUS "Writing ${qt_conf_path}")
+ file(WRITE "${qt_conf_path}" "${qt_conf_contents}")
+endfunction()
+
+function(resolve_qt5_paths paths_var)
+ set(executable_path ${ARGV1})
+
+ set(paths_resolved)
+ foreach(path ${${paths_var}})
+ if(EXISTS "${path}")
+ list(APPEND paths_resolved "${path}")
+ else()
+ if(${executable_path})
+ list(APPEND paths_resolved "${executable_path}/${path}")
+ else()
+ list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}")
+ endif()
+ endif()
+ endforeach()
+ set(${paths_var} ${paths_resolved} PARENT_SCOPE)
+endfunction()
+
+function(fixup_qt5_executable executable)
+ set(qtplugins ${ARGV1})
+ set(libs ${ARGV2})
+ set(dirs ${ARGV3})
+ set(plugins_dir ${ARGV4})
+ set(request_qt_conf ${ARGV5})
+
+ message(STATUS "fixup_qt5_executable")
+ message(STATUS " executable='${executable}'")
+ message(STATUS " qtplugins='${qtplugins}'")
+ message(STATUS " libs='${libs}'")
+ message(STATUS " dirs='${dirs}'")
+ message(STATUS " plugins_dir='${plugins_dir}'")
+ message(STATUS " request_qt_conf='${request_qt_conf}'")
+
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+
+ if(APPLE)
+ set(qt_conf_dir "${executable}/Contents/Resources")
+ set(executable_path "${executable}")
+ set(write_qt_conf TRUE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt5_apple_plugins_dir}")
+ endif()
+ else()
+ get_filename_component(executable_path "${executable}" PATH)
+ if(NOT executable_path)
+ set(executable_path ".")
+ endif()
+ set(qt_conf_dir "${executable_path}")
+ set(write_qt_conf ${request_qt_conf})
+ endif()
+
+ foreach(plugin ${qtplugins})
+ set(installed_plugin_path "")
+ install_qt5_plugin("${plugin}" "${executable}" 1 installed_plugin_path)
+ list(APPEND libs ${installed_plugin_path})
+ endforeach()
+
+ foreach(lib ${libs})
+ if(NOT EXISTS "${lib}")
+ message(FATAL_ERROR "Library does not exist: ${lib}")
+ endif()
+ endforeach()
+
+ resolve_qt5_paths(libs "${executable_path}")
+
+ if(write_qt_conf)
+ set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}")
+ write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}")
+ endif()
+
+ fixup_bundle("${executable}" "${libs}" "${dirs}")
+endfunction()
+
+function(install_qt5_plugin_path plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ set(configurations ${ARGV6})
+ if(EXISTS "${plugin}")
+ if(APPLE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt5_apple_plugins_dir}")
+ endif()
+ set(plugins_path "${executable}/Contents/${plugins_dir}")
+ else()
+ get_filename_component(plugins_path "${executable}" PATH)
+ if(NOT plugins_path)
+ set(plugins_path ".")
+ endif()
+ if(plugins_dir)
+ set(plugins_path "${plugins_path}/${plugins_dir}")
+ endif()
+ endif()
+
+ set(plugin_group "")
+
+ get_filename_component(plugin_path "${plugin}" PATH)
+ get_filename_component(plugin_parent_path "${plugin_path}" PATH)
+ get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME)
+ get_filename_component(plugin_name "${plugin}" NAME)
+ string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name)
+
+ if("${plugin_parent_dir_name}" STREQUAL "plugins")
+ get_filename_component(plugin_group "${plugin_path}" NAME)
+ set(${plugin_group_var} "${plugin_group}")
+ endif()
+ set(plugins_path "${plugins_path}/${plugin_group}")
+
+ if(${copy})
+ file(MAKE_DIRECTORY "${plugins_path}")
+ file(COPY "${plugin}" DESTINATION "${plugins_path}")
+ else()
+ if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE))
+ set(configurations CONFIGURATIONS ${configurations})
+ else()
+ unset(configurations)
+ endif()
+ install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component})
+ endif()
+ set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(install_qt5_plugin plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ if(EXISTS "${plugin}")
+ install_qt5_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ else()
+ string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var)
+ set(plugin_release_var "${plugin_var}_RELEASE")
+ set(plugin_debug_var "${plugin_var}_DEBUG")
+ set(plugin_release "${${plugin_release_var}}")
+ set(plugin_debug "${${plugin_debug_var}}")
+ if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}")
+ message(WARNING "Qt plugin \"${plugin}\" not recognized or found.")
+ endif()
+ if(NOT EXISTS "${${plugin_debug_var}}")
+ set(plugin_debug "${plugin_release}")
+ endif()
+
+ if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel")
+ install_qt5_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug")
+
+ if(CMAKE_BUILD_TYPE MATCHES "^Debug$")
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug})
+ else()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release})
+ endif()
+ else()
+ install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ endif()
+ endif()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE)
+endfunction()
+
+function(install_qt5_executable executable)
+ set(qtplugins ${ARGV1})
+ set(libs ${ARGV2})
+ set(dirs ${ARGV3})
+ set(plugins_dir ${ARGV4})
+ set(request_qt_conf ${ARGV5})
+ set(component ${ARGV6})
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+ if(TARGET Qt5::Core)
+ get_property(_locCore TARGET Qt5::Core PROPERTY LOCATION_RELEASE)
+ get_filename_component(_loc ${_locCore} DIRECTORY)
+ message(STATUS "Adding Qt 5 directory: ${_loc}")
+ list(APPEND dirs "${_loc}")
+ else()
+ message(FATAL_ERROR "No Qt5::Core target found, ensure it is available")
+ endif()
+ if(component)
+ set(component COMPONENT ${component})
+ else()
+ unset(component)
+ endif()
+
+ get_filename_component(executable_absolute "${executable}" ABSOLUTE)
+ if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type)
+ elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type)
+ endif()
+ if(qtcore_type STREQUAL "system")
+ set(qt_plugins_dir "")
+ endif()
+
+ if(QT_IS_STATIC)
+ message(WARNING "Qt built statically: not installing plugins.")
+ else()
+ if(APPLE)
+ get_property(loc TARGET Qt5::QCocoaIntegrationPlugin
+ PROPERTY LOCATION_RELEASE)
+ install_qt5_plugin("${loc}" "${executable}" 0 installed_plugin_paths
+ "PlugIns" "${component}")
+ list(APPEND libs ${installed_plugin_paths})
+ elseif(WIN32)
+ get_property(loc TARGET Qt5::QWindowsIntegrationPlugin
+ PROPERTY LOCATION_RELEASE)
+ install_qt5_plugin("${loc}" "${executable}" 0 installed_plugin_paths
+ "" "${component}")
+ list(APPEND libs ${installed_plugin_paths})
+ endif()
+ foreach(plugin ${qtplugins})
+ set(installed_plugin_paths "")
+ install_qt5_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}")
+ list(APPEND libs ${installed_plugin_paths})
+ endforeach()
+ endif()
+
+ resolve_qt5_paths(libs "")
+
+ install(CODE
+ "include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\")
+ set(BU_CHMOD_BUNDLE_ITEMS TRUE)
+ fixup_qt5_executable(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
+ ${component}
+ )
+endfunction()
diff --git a/Extensions/Testing/ScriptedSegmentEditorEffectExtensionTemplate/ScriptedSegmentEditorEffectModuleTemplate/SegmentEditorScriptedSegmentEditorEffectModuleTemplate.py b/Extensions/Testing/ScriptedSegmentEditorEffectExtensionTemplate/ScriptedSegmentEditorEffectModuleTemplate/SegmentEditorScriptedSegmentEditorEffectModuleTemplate.py
index ce0c39c82..3cc8dc65f 100644
--- a/Extensions/Testing/ScriptedSegmentEditorEffectExtensionTemplate/ScriptedSegmentEditorEffectModuleTemplate/SegmentEditorScriptedSegmentEditorEffectModuleTemplate.py
+++ b/Extensions/Testing/ScriptedSegmentEditorEffectExtensionTemplate/ScriptedSegmentEditorEffectModuleTemplate/SegmentEditorScriptedSegmentEditorEffectModuleTemplate.py
@@ -66,8 +66,8 @@ class SegmentEditorScriptedSegmentEditorEffectModuleTemplateTest(ScriptedLoadabl
##################################
self.delayDisplay("Load master volume")
- from SampleData import SampleDataLogic
- masterVolumeNode = SampleDataLogic().downloadMRBrainTumor1()
+ import SampleData
+ masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')[0]
##################################
self.delayDisplay("Create segmentation containing a few spheres")
diff --git a/Modules/Loadable/CropVolume/Testing/Python/CropVolumeSelfTest.py b/Modules/Loadable/CropVolume/Testing/Python/CropVolumeSelfTest.py
index fb978a976..6d724b95b 100644
--- a/Modules/Loadable/CropVolume/Testing/Python/CropVolumeSelfTest.py
+++ b/Modules/Loadable/CropVolume/Testing/Python/CropVolumeSelfTest.py
@@ -58,9 +58,9 @@ class CropVolumeSelfTestTest(ScriptedLoadableModuleTest):
print("Running CropVolumeSelfTest Test case:")
- from SampleData import SampleDataLogic
+ import SampleData
- vol = SampleDataLogic().downloadMRHead()
+ vol = SampleData.downloadSample("MRHead")[0]
roi = slicer.vtkMRMLAnnotationROINode()
roi.Initialize(slicer.mrmlScene)
@@ -87,7 +87,7 @@ class CropVolumeSelfTestTest(ScriptedLoadableModuleTest):
mainWindow.moduleSelector().selectModule('Transforms')
mainWindow.moduleSelector().selectModule('CropVolume')
cropVolumeNode = slicer.mrmlScene.GetNodeByID('vtkMRMLCropVolumeParametersNode1')
- vol = SampleDataLogic().downloadMRHead()
+ vol = SampleData.downloadSample("MRHead")[0]
roi = slicer.vtkMRMLAnnotationROINode()
roi.Initialize(slicer.mrmlScene)
cropVolumeNode.SetInputVolumeNodeID(vol.GetID())
diff --git a/Modules/Loadable/Markups/Testing/Python/MarkupsInCompareViewersSelfTest.py b/Modules/Loadable/Markups/Testing/Python/MarkupsInCompareViewersSelfTest.py
index 5c70de08e..3ac5ef23f 100644
--- a/Modules/Loadable/Markups/Testing/Python/MarkupsInCompareViewersSelfTest.py
+++ b/Modules/Loadable/Markups/Testing/Python/MarkupsInCompareViewersSelfTest.py
@@ -80,8 +80,8 @@ class MarkupsInCompareViewersSelfTestLogic(ScriptedLoadableModuleLogic):
# first load the data
#
print("Getting MR Head Volume")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
#
# link the viewers
diff --git a/Modules/Loadable/Markups/Testing/Python/MarkupsInViewsSelfTest.py b/Modules/Loadable/Markups/Testing/Python/MarkupsInViewsSelfTest.py
index 7d83be338..620208d83 100644
--- a/Modules/Loadable/Markups/Testing/Python/MarkupsInViewsSelfTest.py
+++ b/Modules/Loadable/Markups/Testing/Python/MarkupsInViewsSelfTest.py
@@ -135,8 +135,8 @@ class MarkupsInViewsSelfTestLogic(ScriptedLoadableModuleLogic):
# first load the data
#
print("Getting MR Head Volume")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
#
# link the viewers
diff --git a/Modules/Loadable/Markups/Testing/Python/NeurosurgicalPlanningTutorialMarkupsSelfTest.py b/Modules/Loadable/Markups/Testing/Python/NeurosurgicalPlanningTutorialMarkupsSelfTest.py
index 91b477ded..2799b5a31 100644
--- a/Modules/Loadable/Markups/Testing/Python/NeurosurgicalPlanningTutorialMarkupsSelfTest.py
+++ b/Modules/Loadable/Markups/Testing/Python/NeurosurgicalPlanningTutorialMarkupsSelfTest.py
@@ -143,8 +143,8 @@ class NeurosurgicalPlanningTutorialMarkupsSelfTestLogic(ScriptedLoadableModuleLo
# use the sample data module logic to load data for the self test
self.delayDisplay("Getting Baseline volume")
- from SampleData import SampleDataLogic
- baselineVolume = SampleDataLogic().downloadWhiteMatterExplorationBaselineVolume()
+ import SampleData
+ baselineVolume = SampleData.downloadSample('BaselineVolume')[0]
self.takeScreenshot('NeurosurgicalPlanning-Loaded','Data loaded')
diff --git a/Modules/Loadable/SceneViews/Testing/Python/AddStorableDataAfterSceneViewTest.py b/Modules/Loadable/SceneViews/Testing/Python/AddStorableDataAfterSceneViewTest.py
index 8f1e1194a..99245fc21 100644
--- a/Modules/Loadable/SceneViews/Testing/Python/AddStorableDataAfterSceneViewTest.py
+++ b/Modules/Loadable/SceneViews/Testing/Python/AddStorableDataAfterSceneViewTest.py
@@ -156,8 +156,8 @@ class AddStorableDataAfterSceneViewTestTest(ScriptedLoadableModuleTest):
# add another storable node, a volume
#
slicer.util.delayDisplay("Adding a new storable node, after creating a scene view")
- from SampleData import SampleDataLogic
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
mrHeadID = mrHeadVolume.GetID()
#
@@ -178,7 +178,7 @@ class AddStorableDataAfterSceneViewTestTest(ScriptedLoadableModuleTest):
#
# add new storable again
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
mrHeadID = mrHeadVolume.GetID()
#
diff --git a/Modules/Loadable/Segmentations/Testing/Python/SegmentationWidgetsTest1.py b/Modules/Loadable/Segmentations/Testing/Python/SegmentationWidgetsTest1.py
index 4044aaa8f..f13151249 100644
--- a/Modules/Loadable/Segmentations/Testing/Python/SegmentationWidgetsTest1.py
+++ b/Modules/Loadable/Segmentations/Testing/Python/SegmentationWidgetsTest1.py
@@ -132,8 +132,8 @@ class SegmentationWidgetsTest1(ScriptedLoadableModuleTest):
closedSurfaceReprName = vtkSegmentationCore.vtkSegmentationConverter.GetClosedSurfaceRepresentationName()
# Use MRHead and Tinypatient for testing
- from SampleData import SampleDataLogic
- mrVolumeNode = SampleDataLogic().downloadMRHead()
+ import SampleData
+ mrVolumeNode = SampleData.downloadSample("MRHead")[0]
[tinyVolumeNode, tinySegmentationNode] = SampleDataLogic().downloadSample('TinyPatient')
# Convert MRHead to oriented image data
diff --git a/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingSceneClose.py b/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingSceneClose.py
index 1bb05274a..c75a9c253 100644
--- a/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingSceneClose.py
+++ b/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingSceneClose.py
@@ -97,8 +97,8 @@ class VolumeRenderingSceneCloseLogic(ScriptedLoadableModuleLogic):
self.delayDisplay('Running the aglorithm')
- from SampleData import SampleDataLogic
- ctVolume = SampleDataLogic().downloadCTChest()
+ import SampleData
+ ctVolume = SampleData.downloadSample('CTChest')[0]
self.delayDisplay('Downloaded CT sample data')
# go to the volume rendering module
diff --git a/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingThreeDOnlyLayout.py b/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingThreeDOnlyLayout.py
index a08071fb0..148f09396 100644
--- a/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingThreeDOnlyLayout.py
+++ b/Modules/Loadable/VolumeRendering/Testing/Python/VolumeRenderingThreeDOnlyLayout.py
@@ -34,8 +34,8 @@ class VolumeRenderingThreeDOnlyLayout(ScriptedLoadableModuleTest):
layoutManager.setMRMLScene(mrmlScene)
# Load MRHead volume
- from SampleData import SampleDataLogic
- SampleDataLogic().downloadMRHead()
+ import SampleData
+ SampleData.downloadSample("MRHead")[0]
# Enter the volume rendering module
slicer.util.mainWindow().moduleSelector().selectModule('VolumeRendering')
diff --git a/Modules/Loadable/Volumes/Testing/Python/LoadVolumeDisplaybleSceneModelClose.py b/Modules/Loadable/Volumes/Testing/Python/LoadVolumeDisplaybleSceneModelClose.py
index 720dcf4ed..82892899e 100644
--- a/Modules/Loadable/Volumes/Testing/Python/LoadVolumeDisplaybleSceneModelClose.py
+++ b/Modules/Loadable/Volumes/Testing/Python/LoadVolumeDisplaybleSceneModelClose.py
@@ -17,8 +17,8 @@ class VolumesLoadSceneCloseTesting(ScriptedLoadableModuleTest):
#
# first, get some sample data
#
- from SampleData import SampleDataLogic
- SampleDataLogic().downloadMRHead()
+ import SampleData
+ SampleData.downloadSample("MRHead")[0]
#
# enter the models module
diff --git a/Modules/Loadable/Volumes/Testing/Python/VolumesLogicCompareVolumeGeometry.py b/Modules/Loadable/Volumes/Testing/Python/VolumesLogicCompareVolumeGeometry.py
index 7548784a9..9d342022e 100644
--- a/Modules/Loadable/Volumes/Testing/Python/VolumesLogicCompareVolumeGeometry.py
+++ b/Modules/Loadable/Volumes/Testing/Python/VolumesLogicCompareVolumeGeometry.py
@@ -18,8 +18,8 @@ class VolumesLogicCompareVolumeGeometryTesting(ScriptedLoadableModuleTest):
#
# first, get some sample data
#
- from SampleData import SampleDataLogic
- head = SampleDataLogic().downloadMRHead()
+ import SampleData
+ head = SampleData.downloadSample("MRHead")[0]
#
# get the volumes logic and print out default epsilon and precision
diff --git a/Modules/Scripted/EditorLib/Testing/StandaloneEditorWidgetTest.py b/Modules/Scripted/EditorLib/Testing/StandaloneEditorWidgetTest.py
index 49ce46d79..ec012b996 100644
--- a/Modules/Scripted/EditorLib/Testing/StandaloneEditorWidgetTest.py
+++ b/Modules/Scripted/EditorLib/Testing/StandaloneEditorWidgetTest.py
@@ -30,8 +30,8 @@ class EditorLibTesting(ScriptedLoadableModuleTest):
#
# first, get some sample data
#
- from SampleData import SampleDataLogic
- head = SampleDataLogic().downloadMRHead()
+ import SampleData
+ head = SampleData.downloadSample("MRHead")[0]
#
# create a label map and set it for editing
diff --git a/Modules/Scripted/EditorLib/Testing/ThresholdThreadingTest.py b/Modules/Scripted/EditorLib/Testing/ThresholdThreadingTest.py
index e56bff398..eeaf15a40 100644
--- a/Modules/Scripted/EditorLib/Testing/ThresholdThreadingTest.py
+++ b/Modules/Scripted/EditorLib/Testing/ThresholdThreadingTest.py
@@ -58,8 +58,8 @@ class ThresholdThreadingTestTest(ScriptedLoadableModuleTest):
# first, get some sample data
#
self.delayDisplay("Get some data")
- from SampleData import SampleDataLogic
- head = SampleDataLogic().downloadMRHead()
+ import SampleData
+ head = SampleData.downloadSample("MRHead")[0]
#
# now, define an ROI in it
diff --git a/Modules/Scripted/LabelStatistics/LabelStatistics.py b/Modules/Scripted/LabelStatistics/LabelStatistics.py
index 7c18d5015..6f521fe51 100644
--- a/Modules/Scripted/LabelStatistics/LabelStatistics.py
+++ b/Modules/Scripted/LabelStatistics/LabelStatistics.py
@@ -517,9 +517,9 @@ class LabelStatisticsTest(ScriptedLoadableModuleTest):
#
# first, get some data
#
- from SampleData import SampleDataLogic
- mrHead = SampleDataLogic().downloadMRHead()
- ctChest = SampleDataLogic().downloadCTChest()
+ import SampleData
+ mrHead = SampleData.downloadSample("MRHead")[0]
+ ctChest = SampleData.downloadSample('CTChest')[0]
self.delayDisplay('Two data sets loaded')
volumesLogic = slicer.modules.volumes.logic()
diff --git a/Modules/Scripted/PerformanceTests/PerformanceTests.py b/Modules/Scripted/PerformanceTests/PerformanceTests.py
index 9cfa63c38..3b6c8fc2a 100644
--- a/Modules/Scripted/PerformanceTests/PerformanceTests.py
+++ b/Modules/Scripted/PerformanceTests/PerformanceTests.py
@@ -54,10 +54,10 @@ class PerformanceTestsWidget(ScriptedLoadableModuleWidget):
self.layout.addStretch(1)
def downloadMRHead(self):
- from SampleData import SampleDataLogic
+ import SampleData
self.log.insertHtml('Requesting downloading MRHead')
self.log.repaint()
- mrHeadVolume = SampleDataLogic().downloadMRHead()
+ mrHeadVolume = SampleData.downloadSample("MRHead")[0]
if mrHeadVolume:
self.log.insertHtml('finished.\n')
self.log.insertPlainText('\n')
diff --git a/Modules/Scripted/SampleData/SampleData.py b/Modules/Scripted/SampleData/SampleData.py
index 239226b1e..cc24d1617 100644
--- a/Modules/Scripted/SampleData/SampleData.py
+++ b/Modules/Scripted/SampleData/SampleData.py
@@ -37,6 +37,11 @@ def downloadFromURL(uris, fileNames, nodeNames=None,
uris, fileNames, nodeNames, customDownloader, loadFileTypes, loadFileProperties)
+def downloadSample(sampleName):
+ """For a given sample name this will search the available sources
+ and load it if it is available. Returns the loaded nodes."""
+ return SampleDataLogic().downloadSample(sampleName)
+
#
# SampleData
#
diff --git a/Modules/Scripted/ScreenCapture/ScreenCapture.py b/Modules/Scripted/ScreenCapture/ScreenCapture.py
index f6e22054c..e8f83c13d 100644
--- a/Modules/Scripted/ScreenCapture/ScreenCapture.py
+++ b/Modules/Scripted/ScreenCapture/ScreenCapture.py
@@ -1130,9 +1130,9 @@ class ScreenCaptureTest(ScriptedLoadableModuleTest):
""" Do whatever is needed to reset the state - typically a scene clear will be enough.
"""
slicer.mrmlScene.Clear(0)
- from SampleData import SampleDataLogic
- self.image1 = SampleDataLogic().downloadMRBrainTumor1()
- self.image2 = SampleDataLogic().downloadMRBrainTumor2()
+ import SampleData
+ self.image1 = SampleData.downloadSample('MRBrainTumor1')[0]
+ self.image2 = SampleData.downloadSample('MRBrainTumor2')[0]
# make the output volume appear in all the slice views
selectionNode = slicer.app.applicationLogic().GetSelectionNode()
diff --git a/Modules/Scripted/SegmentStatistics/SegmentStatistics.py b/Modules/Scripted/SegmentStatistics/SegmentStatistics.py
index 1aaca31c5..c1e3bcf83 100644
--- a/Modules/Scripted/SegmentStatistics/SegmentStatistics.py
+++ b/Modules/Scripted/SegmentStatistics/SegmentStatistics.py
@@ -645,12 +645,12 @@ class SegmentStatisticsTest(ScriptedLoadableModuleTest):
self.delayDisplay("Starting test_SegmentStatisticsBasic")
import vtkSegmentationCorePython as vtkSegmentationCore
- from SampleData import SampleDataLogic
+ import SampleData
from SegmentStatistics import SegmentStatisticsLogic
self.delayDisplay("Load master volume")
- masterVolumeNode = SampleDataLogic().downloadMRBrainTumor1()
+ masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')[0]
self.delayDisplay("Create segmentation containing a few spheres")
@@ -703,12 +703,12 @@ class SegmentStatisticsTest(ScriptedLoadableModuleTest):
self.delayDisplay("Starting test_SegmentStatisticsPlugins")
import vtkSegmentationCorePython as vtkSegmentationCore
- from SampleData import SampleDataLogic
+ import SampleData
from SegmentStatistics import SegmentStatisticsLogic
self.delayDisplay("Load master volume")
- masterVolumeNode = SampleDataLogic().downloadMRBrainTumor1()
+ masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')[0]
self.delayDisplay("Create segmentation containing a few spheres")
diff --git a/Utilities/Templates/Modules/ScriptedSegmentEditorEffect/SegmentEditorTemplateKey.py b/Utilities/Templates/Modules/ScriptedSegmentEditorEffect/SegmentEditorTemplateKey.py
index de4a6f7fc..02f2ada77 100644
--- a/Utilities/Templates/Modules/ScriptedSegmentEditorEffect/SegmentEditorTemplateKey.py
+++ b/Utilities/Templates/Modules/ScriptedSegmentEditorEffect/SegmentEditorTemplateKey.py
@@ -60,13 +60,13 @@ class SegmentEditorTemplateKeyTest(ScriptedLoadableModuleTest):
import vtkSegmentationCorePython as vtkSegmentationCore
import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
- from SampleData import SampleDataLogic
+ import SampleData
from SegmentStatistics import SegmentStatisticsLogic
##################################
self.delayDisplay("Load master volume")
- masterVolumeNode = SampleDataLogic().downloadMRBrainTumor1()
+ masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')[0]
##################################
self.delayDisplay("Create segmentation containing a few spheres")
--
GitLab