I am having trouble with dcmread()
on a DICOM file that does exists at given path. I'm not sure what went wrong. Here is my code:
import pydicom
f = "/exact/path/hi.dcm"
fn = get_testdata_file(f)
ds = pydicom.dcmread(fn)
ds.SOPClassUID = ds.MediaStorageSOPClassUID
I am getting below error:
Traceback (most recent call last):
File "addfields.py", line 14, in <module>
ds = pydicom.dcmread(fn)
File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 871, in dcmread
force=force, specific_tags=specific_tags)
File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 668, in read_partial
preamble = read_preamble(fileobj, force)
File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 605, in read_preamble
preamble = fp.read(128)
AttributeError: 'NoneType' object has no attribute 'read'
But I am not sure why, because "hi.dcm" is a file that exists (path is correct) and has metadata inside. I do not know what is preamble and whether it present in the image I am dealing with.
Disclaimer: I am a contributor to pydicom.
The error happens because get_testdata_file
returns None
, which is then used as the filename. The error message itself is a bit misleading - it would probably be better to raise FileNotFound
or ValueError
in this case (Update: it raises TypeError
in current pydicom). What happens instead is that the first thing that is read is the preamble (a marker for DICOM images that consists of 128 zero bytes followed by 'DICM'), and while trying to read this it crashes because of a file pointer which is None
.
Here is the documentation for get_testdata_file
:
Return an absolute path to the first matching dataset with filename name.
First searches the local pydicom data store, then any locally available external sources, and finally the files available in the pydicom/pydicom-data repository.
So this is a convenience function mainly to find pydicom test data files.
If you already have the file path, you can just use it:
import pydicom
fn = "/exact/path/hi.dcm"
ds = pydicom.dcmread(fn)
As for the preamble, if the DICOM file has no preamble (old ACR-NEMA format), you can read such files using the force=True
argument:
ds = pydicom.dcmread(fn, force=True)
Though I would only use this if you really have such files, because it also tries to handle non-DICOM files as DICOM, which may result in some unexpected exceptions. As already mentioned, the error in this case is not related to a missing preamble, but to an incorrect file path.
UPDATE:
Since version 2.1 of pydicom
this behavior has changed. dcmread
will now raise TypeError
with a meaningful message if passed None
.