# Generate NRRD header from DICOM header

**URL:** <https://discourse.slicer.org/t/generate-nrrd-header-from-dicom-header/33453>\
**Category:** Support\
**Tags:** dicom\
**Created:** [December 19, 2023, 3:22am UTC](https://discourse.slicer.org/t/generate-nrrd-header-from-dicom-header/33453 "2023-12-19T03:22:02Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lin\_Li](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lin_li/32/67957_2.png) [@Lin\_Li](https://discourse.slicer.org/u/Lin_Li)\
**Post date:** [December 19, 2023, 3:22am UTC](https://discourse.slicer.org/t/generate-nrrd-header-from-dicom-header/33453/1 "2023-12-19T03:22:02Z")

</div>

I already read .npy file from a LPS coordinate system DICOM folder and generate a .npy mask. When I want to generate the .nrrd header from the DICOM header, and I got confused about the results.

For the dicom header, I read:  
(0018, 0050) Slice Thickness DS: ‘1.1000000238419’  
(0028, 0030) Pixel Spacing DS: [0.80357140302658, 0.80357140302658]  
(0020, 0032) Image Position (Patient) DS: [-191.80030483817, -176.12590213898, 86.606538507263]  
(0020, 0037) Image Orientation (Patient) DS: [0.9993283937409, -2.051034E-10, 0.036643709737, 2.049657E-10, 1, 7.5158E-12]

To generate space directions in NRRD, I generate the z space directions by cross product, with the reference of [Slicer Coordinate System](https://slicer.readthedocs.io/en/latest/user_guide/coordinate_systems.html).

origin = dicom\_data.ImagePositionPatient  
x\_spacing, y\_spacing = dicom\_data.PixelSpacing  
z\_spacing = dicom\_data.SliceThickness

direction\_x = np.array(dicom\_data.ImageOrientationPatient[:3])  
direction\_y = np.array(dicom\_data.ImageOrientationPatient[3:])  
direction\_z = np.cross(direction\_x, direction\_y)

space\_direction\_x = direction\_x \* x\_spacing  
space\_direction\_y = direction\_y \* y\_spacing  
space\_direction\_z = direction\_z \* z\_spacing  
space\_directions = np.stack((space\_direction\_x, space\_direction\_y, space\_direction\_z)).tolist()

The generated space\_directions is:  
array([[9.99328394e-01, -2.05103400e-10, 3.66437097e-02],  
[2.04965700e-10, 1.00000000e+00, 7.51580000e-12],  
[-4.03080807e-02, -5.35973205e-17, 1.09926123e+00]])

Looks like the z spacing is positive. But the second slice is DICOM folder has smaller z origin value. Is that possible? Actually I tried to manually draw a segmentation in Slicer and Slicer generate the same NRRD header with same Spacing Directions. And the segmentation I generated can be properly showed in Slicer.

So I’m wondering why the DICOM z spacing (space directions[2][2]) is positive but the second slice origin is smaller than the first slice? And is my code generating NRRD header from LPS DICOM can be applied to all situations? Thanks.
