# Slicer 3D DICOM Import Issues with pydicom DICOM files

**URL:** <https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281>\
**Category:** Development\
**Created:** [September 1, 2020, 4:23pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281 "2020-09-01T16:23:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdp](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@jdp](https://discourse.slicer.org/u/jdp)\
**Post date:** [September 1, 2020, 4:23pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/1 "2020-09-01T16:23:54Z")

</div>

I am trying to develop a DICOM file from scratch (using pydicom) that can be imported into slicer 3D. This DICOM from scratch can be read by other programs with no issue. Although the DICOM I can generate has a Patient Name, Patient ID, etc. - slicer doesn’t show in the DICOM database.

To further highlight the issue, in the pydicom code (below) I have “ds” as the dicom data that I’m trying to create and “ds\_in” as the read in data of the original dicom. If I set ds=ds\_in (committed out currently in code below) and make modifications then the pydicom can be read by slicer (not too surprising). Furthermore, if I delete all unwanted dicom tags (so just the specific dicoms I’m manually writing from ds\_in to ds in the code current are present), the dicom file still has no issue as long as I set ds=ds\_in after “file\_meta = FileMetaDataset()”. It is the minute that I comment out ds=ds\_in but try to pass in the ds\_in tags directly to the ds tags on a tag by tag bases then that file does not work. In other words, if I manually try to force each and every ds\_in file meta dataset from the ds\_in to the ds variable, I have an issue.

It seems the “file\_meta = FileMetaDataset()” is key here in which manually rewriting it, i.e., setting the ds\_in tags to the ds file\_meta tag group, is not the same as copying the file meta dataset from the original dicom? I am also making sure I’m being consistent with my image datatype - you can see I set my modified image to a uint16 at the end.

Are there any suggestions or example codes to write a basic dicom from scratch with pydicom that is Slicer 3D compatible?

```python
import pydicom
from pydicom.dataset import FileDataset, FileMetaDataset

ds_in = pydicom.dcmread(ReadPath1)

#
file_meta = FileMetaDataset()
file_meta.FileMetaInformationGroupLength = ds_in.file_meta.FileMetaInformationGroupLength
file_meta.FileMetaInformationVersion = ds_in.file_meta.FileMetaInformationVersion #b'\x01\x00'
file_meta.MediaStorageSOPClassUID = ds_in.file_meta.MediaStorageSOPClassUID
file_meta.MediaStorageSOPInstanceUID = ds_in.file_meta.MediaStorageSOPInstanceUID
file_meta.TransferSyntaxUID = ds_in.file_meta.TransferSyntaxUID
file_meta.ImplementationClassUID = ds_in.file_meta.ImplementationClassUID #pydicom.uid.UID(pydicom.uid.PYDICOM_IMPLEMENTATION_UID) #ds_in.file_meta.ImplementationClassUID
file_meta.ImplementationVersionName = ds_in.file_meta.ImplementationVersionName #pydicom.uid.UID(pydicom.uid.PYDICOM_IMPLEMENTATION_UID).name

FileName_TMP = tempfile.NamedTemporaryFile(suffix='.dcm').name
ds = FileDataset(FileName_TMP, {}, file_meta=file_meta, preamble=b"\0" * 128)

# # Works if I set ds to equal ds_in
# ds_in.remove_private_tags()
# ds = ds_in

ds.StudyInstanceUID = ds_in.StudyInstanceUID
ds.SeriesInstanceUID = ds_in.SeriesInstanceUID
ds.SamplesPerPixel = ds_in.SamplesPerPixel
ds.PhotometricInterpretation = ds_in.PhotometricInterpretation
ds.BitsStored = ds_in.BitsStored
ds.BitsAllocated = ds_in.BitsAllocated
ds.HighBit = ds_in.HighBit
ds.PixelRepresentation = ds_in.PixelRepresentation
ds.Rows = ds_in.Rows
ds.Columns = ds_in.Columns
ds.PixelSpacing = ds_in.PixelSpacing
ds.InstanceNumber = ds_in.InstanceNumber
ds.SliceThickness = 2
ds.SpacingBetweenSlices = 15

# Modify image
A = ds_in.pixel_array
from scipy import ndimage
Aavg = ndimage.gaussian_filter(A, 5)
Aedge = ndimage.filters.laplace(A)
A = Aavg + Aedge
A[A > 1000] = 0
A = numpy.uint16(A)

ds.PixelData = A.tobytes()
ds.Modality = ds_in.Modality
ds.ImagePositionPatient = ds_in.ImagePositionPatient
ds.ImageOrientationPatient = ds_in.ImageOrientationPatient

ds.InstanceCreatorUID = ds_in.InstanceCreatorUID
ds.SpecificCharacterSet = ds_in.SpecificCharacterSet
ds.ContentDate = ds_in.ContentDate
ds.ContentTime = ds_in.ContentTime
ds.PatientName = ds_in.PatientName
ds.PatientID = ds_in.PatientID

pydicom.dataset.validate_file_meta(ds.file_meta, enforce_standard=True)

ds.save_as(WritePath + '/' + WriteFile + '.dcm')

```

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [September 1, 2020, 4:54pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/2 "2020-09-01T16:54:34Z")

</div>

Did you look in the slicer error log? I’d expect some diagnostic output.

---

<div class="post-metadata">

**Author:** ![jdp](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@jdp](https://discourse.slicer.org/u/jdp)\
**Post date:** [September 1, 2020, 5:00pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/3 "2020-09-01T17:00:32Z")

</div>

The first error that pops up is listed as critical and states:

W: DcmItem: Non-standard VR ’ ’ (0a\00) encountered while parsing element (0008,0005), assuming 2 byte length field

W: DcmItem: Non-standard VR ‘IR’ (49\52) encountered while parsing element (5349,5f4f), assuming 4 byte length field

E: DcmElement: Unknown Tag & Data (5349,5f4f) larger (536624) than remaining bytes in file

What is interesting is the element (0008,0005) shows as a VR of CS and a Size of 10 when I open it up with another viewer.

---

<div class="post-metadata">

**Author:** ![jdp](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@jdp](https://discourse.slicer.org/u/jdp)\
**Post date:** [September 1, 2020, 8:28pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/4 "2020-09-01T20:28:35Z")

</div>

I did get an error (attached it above - not sure if I applied directly to you). However, I am now really stripping down the code (see below) and I’ve gotten the following read error. Any suggestions to get this to work as normal dicom viewers can read and display the image with no issue? Note the image is a randomized intensity image. The error is:

Traceback (most recent call last):  
File “C:\Users\jdp\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-20\lib\Slicer-4.11\qt-scripted-modules\DICOMLib\DICOMBrowser.py”, line 212, in timerCallback  
self.promptForExtensions()  
File “C:\Users\jdp\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-20\lib\Slicer-4.11\qt-scripted-modules\DICOMLib\DICOMBrowser.py”, line 217, in promptForExtensions  
extensionsToOffer = self.checkForExtensions()  
File “C:\Users\jdp\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-20\lib\Slicer-4.11\qt-scripted-modules\DICOMLib\DICOMBrowser.py”, line 280, in checkForExtensions  
instance0 = slicer.dicomDatabase.filesForSeries(series)[0]  
IndexError: tuple index out of range

the stripped down code (using pydicom) is:

file\_meta = FileMetaDataset()  
file\_meta.FileMetaInformationGroupLength = int(192)  
file\_meta.MediaStorageSOPClassUID = pydicom.uid.generate\_uid()  
file\_meta.MediaStorageSOPInstanceUID = pydicom.uid.generate\_uid()  
file\_meta.TransferSyntaxUID = str(‘1.2.840.10008.1.2’) #ds\_in.file\_meta.TransferSyntaxUID

FileName\_TMP = tempfile.NamedTemporaryFile(suffix=’.dcm’).name  
ds = FileDataset(FileName\_TMP, {}, file\_meta=file\_meta, preamble=b"\0" \* 128)

ds.StudyInstanceUID = pydicom.uid.generate\_uid()  
ds.SeriesInstanceUID = pydicom.uid.generate\_uid()  
ds.SamplesPerPixel = int(1)  
ds.PhotometricInterpretation = str(‘MONOCHROME2’)  
ds.BitsStored = int(16)  
ds.BitsAllocated = int(16)  
ds.HighBit = int(15)  
ds.PixelRepresentation = int(0)  
ds.Rows = int(512)  
ds.Columns = int(512)  
ds.PixelSpacing = [float(.5), float(.5)]  
ds.InstanceNumber = int(1)  
ds.SliceThickness = int(4)  
ds.SpacingBetweenSlices = int(5)

# Modify image

A = numpy.uint((numpy.power(2, 16)-1) \* numpy.random.rand(512, 512))

ds.PixelData = A.tobytes()  
ds.Modality = str(‘MR’)  
ds.ImagePositionPatient = [float(.5), float(.5), float(.5)]  
ds.ImageOrientationPatient = [float(0), float(0), float(1), float(0), float(0), float(-1)]

ds.InstanceCreatorUID = pydicom.uid.generate\_uid()  
ds.PatientName = str(‘Cheese’)  
ds.PatientID = str(‘12345667’)

pydicom.dataset.validate\_file\_meta(ds.file\_meta, enforce\_standard=True)  
ds.save\_as(WritePath + ‘/’ + WriteFile + ‘.dcm’)

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [September 1, 2020, 9:01pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/5 "2020-09-01T21:01:00Z")

</div>

> [@jdp](#):
>
> W: DcmItem: Non-standard VR ’ ’ (0a\00) encountered while parsing element (0008,0005), assuming 2 byte length field
> 
> W: DcmItem: Non-standard VR ‘IR’ (49\52) encountered while parsing element (5349,5f4f), assuming 4 byte length field
> 
> E: DcmElement: Unknown Tag & Data (5349,5f4f) larger (536624) than remaining bytes in file

I would say these together are problematic. I’d guess one of the assumptions has led to the wrong bytes being decoded as if they were group,element tags and length entries.

One option would be to get the [dciodvfy](http://dclunie.com/dicom3tools/dciodvfy.html) tool and see what it reports.

---

<div class="post-metadata">

**Author:** ![jdp](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@jdp](https://discourse.slicer.org/u/jdp)\
**Post date:** [September 1, 2020, 10:38pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/7 "2020-09-01T22:38:48Z")

</div>

I ran the tool you suggested for the stripped down pydicom DICOM and it says:

jdp$ ./dcentvfy NewDICOM.dcm  
Warning - Unrecognized SOP Class - - so cannot determine information entity of attributes within file \<NewDICOM.dcm\>

It seems because pydicom made this, the SOP isn’t recognized by the tool you suggested I use. I did have a slight error in the stripped down code with:  
file\_meta.MediaStorageSOPClassUID = pydicom.uid.generate\_uid()  
should have been:  
file\_meta.MediaStorageSOPClassUID = str(‘1.2.840.10008.5.1.4.1.1.7’)

- but the error is happening after the correction (and the same issue is happening in slicer). Any other suggestions here as I’m at a loss at this point?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [September 2, 2020, 1:31pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/8 "2020-09-02T13:31:54Z")

</div>

> [@jdp](#):
>
> file\_meta.MediaStorageSOPClassUID = pydicom.uid.generate\_uid()

This is probably the issue - SOPClassUIDs are a set of pre-defined constants that are part of the dicom standard but here you are assigning a random number so Slicer doesn’t know what to do with it. Since you set the modality to MR you should use the MRImage.

If you are still having trouble you can try dcmdump from dcmtk and compare the values it shows to what you expect to see based on your pydicom code.

---

<div class="post-metadata">

**Author:** ![jdp](https://avatars.discourse-cdn.com/v4/letter/j/c6cbf5/32.png) [@jdp](https://discourse.slicer.org/u/jdp)\
**Post date:** [September 2, 2020, 5:18pm UTC](https://discourse.slicer.org/t/slicer-3d-dicom-import-issues-with-pydicom-dicom-files/13281/9 "2020-09-02T17:18:17Z")

</div>

Your suggestion of using dcmdump was exactly what I needed to find my issue. I started making my pydicom code worse as I was trying to find the original issue. The SOP error you highlighted was a side error I put in as I was debugging by accident. I’ve now isolated my underlining issue and understand you need to embed the SOP and transfer syntax in both the meta and the general data sections of the pydicom write dicom code (furthermore the transfer syntax can be different between the meta and the general data). I apricate your patience and guidance, Steve.
