Source code for slicer.util

from __future__ import print_function

#
# General
#

EXIT_SUCCESS = 0
EXIT_FAILURE = 1

def quit():
[docs] exit(EXIT_SUCCESS) def exit(status=EXIT_SUCCESS):
[docs] from slicer import app app.exit(status) def restart():
[docs] from slicer import app app.restart() # # Custom Import # def importVTKClassesFromDirectory(directory, dest_module_name, filematch = '*'):
[docs] importClassesFromDirectory(directory, dest_module_name, 'vtkclass', filematch) def importQtClassesFromDirectory(directory, dest_module_name, filematch = '*'):
[docs] importClassesFromDirectory(directory, dest_module_name, 'PythonQtClassWrapper', filematch) def importClassesFromDirectory(directory, dest_module_name, type_name, filematch = '*'):
[docs] import glob, os, re, fnmatch for fname in glob.glob(os.path.join(directory, filematch)): if not re.compile(fnmatch.translate(filematch)).match(os.path.basename(fname)): continue try: from_module_name = os.path.splitext(os.path.basename(fname))[0] importModuleObjects(from_module_name, dest_module_name, type_name) except ImportError as detail: import sys print(detail, file=sys.stderr) def importModuleObjects(from_module_name, dest_module_name, type_name):
[docs] """Import object of type 'type_name' from module identified by 'from_module_name' into the module identified by 'dest_module_name'.""" # Obtain a reference to the module identifed by 'dest_module_name' import sys dest_module = sys.modules[dest_module_name] exec "import %s" % (from_module_name) # Obtain a reference to the associated VTK module module = eval(from_module_name) # Loop over content of the python module associated with the given VTK python library for item_name in dir(module): # Obtain a reference associated with the current object item = eval("%s.%s" % (from_module_name, item_name)) # Add the object to dest_module_globals_dict if any if type(item).__name__ == type_name: exec("from %s import %s" % (from_module_name, item_name)) exec("dest_module.%s = %s"%(item_name, item_name)) # # UI # def lookupTopLevelWidget(objectName, verbose = True):
[docs] """Loop over all top level widget associated with 'slicer.app' and return the one matching 'objectName'""" from slicer import app for w in app.topLevelWidgets(): if hasattr(w,'objectName'): if w.objectName == objectName: return w if verbose: import sys print("Failed to obtain reference to '%s'" % objectName, file=sys.stderr) return None def mainWindow(verbose = True):
[docs] return lookupTopLevelWidget('qSlicerAppMainWindow', verbose) def pythonShell(verbose = True):
[docs] return lookupTopLevelWidget('pythonConsole', verbose) def showStatusMessage(message, duration = 0):
[docs] mw = mainWindow(verbose=False) if mw: mw.statusBar().showMessage(message, duration) def findChildren(widget=None,name="",text="",title="",className=""):
[docs] """ return a list of child widgets that match the passed name """ # TODO: figure out why the native QWidget.findChildren method # does not seem to work from PythonQt import slicer, fnmatch if not widget: widget = mainWindow() if not widget: return [] children = [] parents = [widget] while parents != []: p = parents.pop() # sometimes, p is null, f.e. when using --python-script or --python-code if not p: break if not hasattr(p,'children'): continue parents += p.children() if name and fnmatch.fnmatch(p.name, name): children.append(p) elif text: try: p.text if fnmatch.fnmatch(p.text, text): children.append(p) except (AttributeError, TypeError): pass elif title: try: p.title if fnmatch.fnmatch(p.title, title): children.append(p) except AttributeError: pass elif className: try: p.className() if fnmatch.fnmatch(p.className(), className): children.append(p) except AttributeError: pass return children # # IO # def loadNodeFromFile(filename, filetype, properties={}, returnNode=False):
[docs] from slicer import app from vtk import vtkCollection properties['fileName'] = filename if returnNode: loadedNodes = vtkCollection() success = app.coreIOManager().loadNodes(filetype, properties, loadedNodes) return success, loadedNodes.GetItemAsObject(0) else: success = app.coreIOManager().loadNodes(filetype, properties) return success def loadColorTable(filename, returnNode=False):
[docs] filetype = 'ColorTableFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadFiberBundle(filename, returnNode=False):
[docs] filetype = 'FiberBundleFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadFiducialList(filename, returnNode=False):
[docs] filetype = 'FiducialListFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadAnnotationFiducial(filename, returnNode=False):
[docs] filetype = 'AnnotationFile' properties = {} properties['fiducial'] = 1 return loadNodeFromFile(filename, filetype, properties, returnNode) def loadMarkupsFiducialList(filename, returnNode=False):
[docs] filetype = 'MarkupsFiducials' properties = {} return loadNodeFromFile(filename, filetype, properties, returnNode) def loadModel(filename, returnNode=False):
[docs] filetype = 'ModelFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadScalarOverlay(filename, returnNode=False):
[docs] filetype = 'ScalarOverlayFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadTransform(filename, returnNode=False):
[docs] filetype = 'TransformFile' return loadNodeFromFile(filename, filetype, {}, returnNode) def loadLabelVolume(filename, properties, returnNode=False):
[docs] filetype = 'VolumeFile' properties['labelmap'] = True return loadNodeFromFile(filename, filetype, properties, returnNode) def loadVolume(filename, properties={}, returnNode=False):
[docs] filetype = 'VolumeFile' return loadNodeFromFile(filename, filetype, properties, returnNode) def loadScene(filename, properties={}):
[docs] filetype = 'SceneFile' return loadNodeFromFile(filename, filetype, properties, returnNode=False) def openAddDataDialog():
[docs] from slicer import app return app.coreIOManager().openAddDataDialog() def openAddVolumeDialog():
[docs] from slicer import app return app.coreIOManager().openAddVolumeDialog() def openAddModelDialog():
[docs] from slicer import app return app.coreIOManager().openAddModelDialog() def openAddScalarOverlayDialog():
[docs] from slicer import app return app.coreIOManager().openAddScalarOverlayDialog() def openAddTransformDialog():
[docs] from slicer import app return app.coreIOManager().openAddTransformDialog() def openAddColorTableDialog():
[docs] from slicer import app return app.coreIOManager().openAddColorTableDialog() def openAddFiducialDialog():
[docs] from slicer import app return app.coreIOManager().openAddFiducialDialog() def openAddFiberBundleDialog():
[docs] from slicer import app return app.coreIOManager().openAddFiberBundleDialog() def openSaveDataDialog():
[docs] from slicer import app return app.coreIOManager().openSaveDataDialog() def saveNode(node, filename, properties={}):
[docs] """Save 'node' data into 'filename'. It is the user responsability to provide the appropriate file extension. User has also the possibility to overwrite the fileType internally retrieved using method 'qSlicerCoreIOManager::fileWriterFileType(vtkObject*)'. This can be done by specifiying a 'fileType'attribute to the optional 'properties' dictionary. """ from slicer import app properties["nodeID"] = node.GetID(); properties["fileName"] = filename if hasattr(properties, "fileType"): filetype = properties["fileType"] else: filetype = app.coreIOManager().fileWriterFileType(node) return app.coreIOManager().saveNodes(filetype, properties) def saveScene(filename, properties={}):
[docs] """Save the current scene. Based on the value of 'filename', the current scene is saved either as a MRML file, MRB file or directory. If filename ends with '.mrml', the scene is saved as a single file without associated data. If filename ends with '.mrb', the scene is saved as a MRML bundle (Zip archive with scene and data files). In every other case, the scene is saved in the directory specified by 'filename'. Both MRML scene file and data will be written to disk. If needed, directories and sub-directories will be created. """ from slicer import app filetype = 'SceneFile' properties['fileName'] = filename return app.coreIOManager().saveNodes(filetype, properties) # # Module # def selectModule(module):
[docs] moduleName = module if not isinstance(module, basestring): moduleName = module.name w = mainWindow() if not w: return w.moduleSelector().selectModule(moduleName) def moduleNames():
[docs] from slicer import app return app.moduleManager().factoryManager().loadedModuleNames() def getModule(moduleName):
[docs] from slicer import app module = app.moduleManager().module(moduleName); if not module: import sys print("Could not find module with name '%s" % moduleName, file=sys.stderr) return None return module def getModuleGui(module):
[docs] if isinstance(module, basestring): module = getModule(module) widgetRepr = module.widgetRepresentation() if not widgetRepr: import sys print("Could not find module widget representation with name '%s" % module.name, file=sys.stderr) return widgetRepr def getNewModuleGui(module):
[docs] if isinstance(module, basestring): module = getModule(module) widgetRepr = module.createNewWidgetRepresentation() if not widgetRepr: import sys print("Could not find module widget representation with name '%s" % module.name, file=sys.stderr) return widgetRepr def reloadScriptedModule(moduleName):
[docs] """Generic reload method for any scripted module. """ import imp, sys, os import slicer widgetName = moduleName + "Widget" # reload the source code # - set source file path # - load the module to the global space filePath = eval('slicer.modules.%s.path' % moduleName.lower()) p = os.path.dirname(filePath) if not sys.path.__contains__(p): sys.path.insert(0,p) with open(filePath, "r") as fp: globals()[moduleName] = imp.load_module( moduleName, fp, filePath, ('.py', 'r', imp.PY_SOURCE)) # rebuild the widget # - find and hide the existing widget # - create a new widget in the existing parent parent = eval('slicer.modules.%s.widgetRepresentation()' % moduleName.lower()) for child in parent.children(): try: child.hide() except AttributeError: pass # Remove spacer items item = parent.layout().itemAt(0) while item: parent.layout().removeItem(item) item = parent.layout().itemAt(0) # delete the old widget instance if hasattr(slicer.modules, widgetName): w = getattr(slicer.modules, widgetName) if hasattr(slicer.modules, 'cleanup'): w.cleanup() # create new widget inside existing parent globals()[widgetName.lower()] = eval( 'globals()["%s"].%s(parent)' % (moduleName, widgetName)) globals()[widgetName.lower()].setup() setattr(slicer.modules, widgetName, globals()[widgetName.lower()]) # # MRML # def getNodes(pattern = ""):
[docs] """Return a dictionary of nodes where the name or id matches the 'pattern'. Providing an empty 'pattern' string will return all nodes. """ import slicer, fnmatch nodes = {} scene = slicer.mrmlScene count = scene.GetNumberOfNodes() for idx in range(count): node = scene.GetNthNode(idx) name = node.GetName() id = node.GetID() if fnmatch.fnmatch(name, pattern) or fnmatch.fnmatch(id, pattern): nodes[node.GetName()] = node return nodes def getNode(pattern = "", index = 0):
[docs] """Return the indexth node where name or id matches 'pattern'. Providing an empty 'pattern' string will return all nodes. """ nodes = getNodes(pattern) try: if nodes.keys(): return nodes.values()[index] except IndexError: return None # # MRML-numpy # def array(pattern = "", index = 0):
[docs] """Return the array you are "most likely to want" from the indexth MRML node that matches the pattern. Meant to be used in the python console for quick debugging/testing. More specific API should be used in scripts to be sure you get exactly what you want. """ vectorTypes = ('vtkMRMLVectorVolumeNode', 'vtkMRMLMultiVolumeNode') tensorTypes = ('vtkMRMLDiffusionTensorVolumeNode',) import vtk.util.numpy_support n = getNode(pattern=pattern, index=index) if n.GetClassName() == 'vtkMRMLScalarVolumeNode': i = n.GetImageData() shape = list(n.GetImageData().GetDimensions()) shape.reverse() a = vtk.util.numpy_support.vtk_to_numpy(i.GetPointData().GetScalars()).reshape(shape) return a elif n.GetClassName() in vectorTypes: i = n.GetImageData() shape = list(n.GetImageData().GetDimensions()) shape.reverse() components = i.GetNumberOfScalarComponents() if components > 1: shape.append(components) a = vtk.util.numpy_support.vtk_to_numpy(i.GetPointData().GetScalars()).reshape(shape) return a elif n.GetClassName() in tensorTypes: i = n.GetImageData() shape = list(n.GetImageData().GetDimensions()) shape.reverse() a = vtk.util.numpy_support.vtk_to_numpy(i.GetPointData().GetTensors()).reshape(shape+[3,3]) return a # TODO: accessors for other node types: polydata (verts, polys...), colors