Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
DICOMDiffusionVolumePlugin.py
Go to the documentation of this file.
00001 import os
00002 from __main__ import vtk, qt, ctk, slicer
00003 from DICOMLib import DICOMPlugin
00004 from DICOMLib import DICOMLoadable
00005 
00006 #
00007 # This is the plugin to handle translation of diffusion volumes
00008 # from DICOM files into MRML nodes.  It follows the DICOM module's
00009 # plugin architecture.
00010 #
00011 
00012 class DICOMDiffusionVolumePluginClass(DICOMPlugin):
00013   """ DiffusionVolume specific interpretation code
00014   """
00015 
00016   def __init__(self):
00017     super(DICOMDiffusionVolumePluginClass,self).__init__()
00018     self.loadType = "Diffusion Volume"
00019     # these are the required tags for each vendor
00020     # TODO: it doesn't seem that DicomToNrrd supports
00021     # standard DICOM Diffusion, but when it does we should
00022     # add a set of required tags based on supplement 49
00023     self.diffusionTags = {
00024         'GE' : [
00025             '0043,1039', # B Value of diffusion weighting
00026             '0019,10bb', # X component of gradient direction
00027             '0019,10bc', # Y component of gradient direction
00028             '0019,10bd', # Z component of gradient direction
00029           ],
00030         'Siemens' : [
00031             '0051,100b', # "Mosiac Matrix Size"
00032             '0019,100a', # "Number of Images In Mosaic"
00033             '0019,100c', # "B Value of diffusion weighting"
00034             '0019,100e', # "Diffusion Gradient Direction"
00035             '0019,1027', # "Diffusion Matrix"
00036             '0029,1010', # "Siemens DWI Info"
00037           ],
00038         'Philips' : [
00039             '2001,1003', # "B Value of diffusion weighting"
00040             '2001,1004', # "Diffusion Gradient Direction"
00041             '2005,10b0', # "Diffusion Direction R/L"
00042             '2005,10b1', # "Diffusion Direction A/P"
00043             '2005,10b2', # "Diffusion Direction F/H"
00044           ],
00045         }
00046     # note: the tags here are organized by vendor above, but
00047     # for the tag caching, we create a compatible tags
00048     # array for use by the application
00049     tagIndex = 0
00050     for vendor in self.diffusionTags.keys():
00051       for tag in self.diffusionTags[vendor]:
00052         self.tags[tagIndex] = tag
00053         tagIndex += 1
00054     self.tags['seriesDescription'] = "0008,103e"
00055 
00056   def examine(self,fileLists):
00057     """ Returns a list of DICOMLoadable instances
00058     corresponding to ways of interpreting the
00059     fileLists parameter.
00060     """
00061     loadables = []
00062     for files in fileLists:
00063       loadables += self.examineFiles(files)
00064     return loadables
00065 
00066   def examineFiles(self,files):
00067     """ Returns a list of DICOMLoadable instances
00068     corresponding to ways of interpreting the
00069     files parameter.
00070     Process is to look for 'known' private tags corresponding
00071     to the types of diffusion datasets that the DicomToNrrd utility
00072     should be able to process.  Only need to look at one header
00073     in the series since all should be the same with respect
00074     to this check.
00075 
00076     For testing:
00077     dv = slicer.modules.dicomPlugins['DICOMDiffusionVolumePlugin']()
00078     dv.examine([['/media/extra650/data/DWI-examples/SiemensTrioTimB17-DWI/63000-000025-000001.dcm']])
00079     """
00080 
00081     # get the series description to use as base for volume name
00082     name = slicer.dicomDatabase.fileValue(files[0], self.tags['seriesDescription'])
00083     if name == "":
00084       name = "Unknown"
00085 
00086     validDWI = False
00087     vendorName = ""
00088     for vendor in self.diffusionTags:
00089       matchesVendor = True
00090       for tag in self.diffusionTags[vendor]:
00091         value = slicer.dicomDatabase.fileValue(files[0], tag)
00092         hasTag = value != ""
00093         matchesVendor &= hasTag
00094       if matchesVendor:
00095         validDWI = True
00096         vendorName = vendor
00097 
00098     loadables = []
00099     if validDWI:
00100       # default loadable includes all files for series
00101       loadable = DICOMLib.DICOMLoadable()
00102       loadable.files = files
00103       loadable.name = name + ' - as DWI Volume'
00104       loadable.selected = False
00105       loadable.tooltip = "Appears to be DWI from vendor %s" % vendorName
00106       loadables = [loadable]
00107     return loadables
00108 
00109   def load(self,loadable):
00110     """Load the selection as a diffusion volume
00111     using the dicom to nrrd converter module
00112     """
00113     if not hasattr(slicer.modules, 'dwiconvert'):
00114       print('No diffusion dicom importer module available')
00115       return False
00116     # create an output diffusion node as a target
00117     nodeFactory = slicer.qMRMLNodeFactory()
00118     nodeFactory.setMRMLScene(slicer.mrmlScene)
00119     diffusionNode = nodeFactory.createNode('vtkMRMLDiffusionWeightedVolumeNode')
00120     diffusionNode.SetName(loadable.name)
00121     # set up the parameters
00122     parameters = {}
00123     parameters['inputDicomDirectory'] = os.path.dirname(loadable.files[0])
00124     parameters['outputDirectory'] = slicer.app.temporaryPath
00125     parameters['outputVolume'] = diffusionNode.GetID()
00126     # run the module
00127     dicomDWIConverter = slicer.modules.dwiconvert
00128     cliNode = slicer.cli.run(dicomDWIConverter, None, parameters, wait_for_completion = True)
00129     success = False
00130     if cliNode.GetStatusString() == "Completing" or cliNode.GetStatusString() == "Completed":
00131       if diffusionNode.GetImageData():
00132         success = True
00133     return success
00134 
00135 
00136 #
00137 # DICOMDiffusionVolumePlugin
00138 #
00139 
00140 class DICOMDiffusionVolumePlugin:
00141   """
00142   This class is the 'hook' for slicer to detect and recognize the plugin
00143   as a loadable scripted module
00144   """
00145   def __init__(self, parent):
00146     parent.title = "DICOM Diffusion Volume Plugin"
00147     parent.categories = ["Developer Tools.DICOM Plugins"]
00148     parent.contributors = ["Steve Pieper (Isomics Inc.)"]
00149     parent.helpText = """
00150     Plugin to the DICOM Module to parse and load diffusion volumes
00151     from DICOM files.
00152     No module interface here, only in the DICOM module
00153     """
00154     parent.acknowledgementText = """
00155     This DICOM Plugin was developed by
00156     Steve Pieper, Isomics, Inc.
00157     and was partially funded by NIH grant 3P41RR013218.
00158     """
00159 
00160     # don't show this module - it only appears in the DICOM module
00161     parent.hidden = True
00162 
00163     # Add this extension to the DICOM module's list for discovery when the module
00164     # is created.  Since this module may be discovered before DICOM itself,
00165     # create the list if it doesn't already exist.
00166     try:
00167       slicer.modules.dicomPlugins
00168     except AttributeError:
00169       slicer.modules.dicomPlugins = {}
00170     slicer.modules.dicomPlugins['DICOMDiffusionVolumePlugin'] = DICOMDiffusionVolumePluginClass
00171 
00172 #
00173 # DICOMDiffusionVolumeWidget
00174 #
00175 
00176 class DICOMDiffusionVolumeWidget:
00177   def __init__(self, parent = None):
00178     self.parent = parent
00179 
00180   def setup(self):
00181     # don't display anything for this widget - it will be hidden anyway
00182     pass
00183 
00184   def enter(self):
00185     pass
00186 
00187   def exit(self):
00188     pass
00189 
00190 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines