|
Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
|
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
1.7.4