Get filename of loaded volume

Operating system: MS windows 10 64bit
Slicer version: 4.9.0
Expected behavior: not report error of NoneType
Actual behavior: failed at NoneType error

Hi developers,

I just found this error in Slicer 4.9.0, not sure this one is bug in fnmatch.translate, could you help to confirm?

    BNode = slicer.util.getNode(BId)
  File "C:\Program Files\Slicer 4.9.0-2017-10-23\bin\Python\slicer\util.py", line 622, in getNode
    nodes = getNodes(pattern, scene)
  File "C:\Program Files\Slicer 4.9.0-2017-10-23\bin\Python\slicer\util.py", line 609, in getNodes
    if (fnmatch.fnmatchcase(name, pattern) or
  File "C:\Program Files\Slicer 4.9.0-2017-10-23\lib\Python\Lib\fnmatch.py", line 78, in fnmatchcase
    res = translate(pat)
  File "C:\Program Files\Slicer 4.9.0-2017-10-23\lib\Python\Lib\fnmatch.py", line 89, in translate
    i, n = 0, len(pat)
TypeError: object of type 'NoneType' has no len()

Thanks,
Chunbo

To specify a string, you need to put it between quotation marks:

BNode = slicer.util.getNode("BId")

Thanks for your quick replies,Lassoan.
I tried the line with quotation marks (str(BID)), but reported following error:

Traceback (most recent call last):
  File "widgetMammogram.py", line 162, in onSideSelect
    filename1 = self.getFileNameByTag('View1')
  File "widgetMammogram.py", line 173, in getFileNameByTag
    StorageNode = BNode.GetStorageNode()
AttributeError: 'NoneType' object has no attribute 'GetStorageNode'

I attached my codes now:

    def getFileNameByTag(self, tag):
        widget = slicer.app.layoutManager().sliceWidget(tag)
        CNode = widget.sliceLogic().GetSliceCompositeNode()
        BId = CNode.GetBackgroundVolumeID()
        BNode = slicer.util.getNode(str(BId))
        StorageNode = BNode.GetStorageNode()
        filename=StorageNode.GetFileName()
        print('filename = {}'.format(filename))
        return filename

btw, it can print the filename correctly after outputing above error message. Here, I have convert the args(BID) as String, not sure BNode is None?

Thanks,
Chunbo

This works for me:

def getFileNameByTag(tag):
  sliceWidget = slicer.app.layoutManager().sliceWidget(tag)
  sliceCompositeNode = sliceWidget.sliceLogic().GetSliceCompositeNode()
  backgroundVolumeID = sliceCompositeNode.GetBackgroundVolumeID()
  backgroundVolume = slicer.mrmlScene.GetNodeByID(backgroundVolumeID)
  storageNode = backgroundVolume.GetStorageNode()
  if not storageNode:
    return None
  filename = backgroundVolume.GetStorageNode().GetFileName()
  return filename

print getFileNameByTag("Red")

However, filename may not be always available and it should not be necessary to access it anyway. What would you like to achieve? Pass the image to an external software? Or get additional metadata from the image?

Hi Lassoan,

“What would you like to achieve? Pass the image to an external software? Or get additional metadata from the image?”

The background is: I setted Slicer’s layout as two scenes (widgets), each scene will display one dcm file, the user will add some polydata in the scenes and we will save the position of these polydata into a json file for each dcm file (the path is same of each dcm file), so we have to know the source path of each node (dcm).

Any good ideas ?

Thanks,
Chunbo

This should do what you need:
https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How_to_get_path_and_filename_of_a_loaded_DICOM_volume.3F

Thanks,Lassoan.

Yes,these lines work well(to get dcm file’s path from it’s name). If we want to get the file’s path from sliceWidgets,is there anyother good methods?

Thanks,
Chunbo

It is a trivial combination of the two examples above.

1 Like