changeset 556:1028b75ac1ce

merge
author Alain Mazy <am@osimis.io>
date Tue, 27 Jun 2023 16:41:45 +0200
parents 739cad709a8c (current diff) ede184638961 (diff)
children 1cdb14a679f2
files Tests/Tests.py
diffstat 2 files changed, 97 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tests/GuessPixelDataVR.py	Tue Jun 27 16:41:45 2023 +0200
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import pydicom
+
+ROOT = os.path.join(os.path.dirname(__file__), '..', 'Database')
+
+for root, dirs, files in os.walk(ROOT):
+    for f in files:
+        path = os.path.join(root, f)
+        
+        try:
+            ds = pydicom.dcmread(path)
+        except:
+            continue
+
+        ts = ds.file_meta.TransferSyntaxUID
+
+        if not 'PixelData' in ds:
+            print(path, '=> no pixel data')
+            continue
+
+        print(path)
+
+        if ts == '1.2.840.10008.1.2':
+            # Implicit VR Endian
+            # https://dicom.nema.org/medical/dicom/current/output/chtml/part05/chapter_A.html#sect_A.1
+            assert(ds['PixelData'].VR == 'OW')
+            
+        elif ts in [ '1.2.840.10008.1.2.1',
+                     '1.2.840.10008.1.2.2' ]:
+            # Explicit VR Little Endian
+            # https://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_A.2.html
+
+            # DICOM Big Endian Transfer Syntax (Explicit VR) - Retired, but same rule
+            # https://dicom.nema.org/medical/dicom/2016b/output/chtml/part05/sect_A.3.html
+            
+            if f in [ 'PilatesArgenturGEUltrasoundOsiriX.dcm',
+                      'KarstenHilbertRF.dcm',
+                      'Issue143.dcm' ]:
+                continue
+            
+            if ds['BitsAllocated'].value <= 8:
+                assert(ds['PixelData'].VR == 'OB')
+            else:
+                assert(ds['PixelData'].VR == 'OW')
+
+        else:
+            if (('Beaufix/IM-' in path or
+                 'Comunix/Ct/IM-' in path or
+                 'Comunix/Pet/IM-' in path or
+                 'Knee/T1/IM-' in path or
+                 'Knee/T2/IM-' in path) and
+                ts == '1.2.840.10008.1.2.4.91'):
+                # JPEG2k should be "OB", but this is not the case of these modalities
+                continue
+
+            assert(ds['PixelData'].VR == 'OB')
+
--- a/Tests/Tests.py	Tue Jun 27 16:41:28 2023 +0200
+++ b/Tests/Tests.py	Tue Jun 27 16:41:45 2023 +0200
@@ -1171,20 +1171,13 @@
         self.assertEqual(DoGet(_REMOTE, '/series/%s/metadata/RemoteAET' % series), '')  # None, received by REST API
 
         m = DoGet(_REMOTE, '/instances/%s/metadata' % i)
-        if IsOrthancVersionAbove(_REMOTE, 1, 12, 1):
-            self.assertEqual(11, len(m))
-        elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
+        if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertEqual(10, len(m))
         elif IsOrthancVersionAbove(_REMOTE, 1, 9, 1):
             self.assertEqual(9, len(m))
         else:
             self.assertEqual(8, len(m))
 
-        if IsOrthancVersionAbove(_REMOTE, 1, 12, 1):
-            # ./Tests/GetPixelDataVR.py ./Database/Knee/T1/IM-0001-0001.dcm
-            self.assertTrue('PixelDataVR' in m)  # New in Orthanc 1.12.1
-            self.assertEqual('OW', DoGet(_REMOTE, '/instances/%s/metadata/PixelDataVR' % i))
-
         if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertTrue('MainDicomTagsSignature' in m)
 
@@ -1393,20 +1386,13 @@
         self.assertEqual(1, len(i))
         m = DoGet(_REMOTE, '/instances/%s/metadata' % i[0])
 
-        if IsOrthancVersionAbove(_REMOTE, 1, 12, 1):
-            self.assertEqual(11, len(m))
-        elif IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
+        if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertEqual(10, len(m))
         elif IsOrthancVersionAbove(_REMOTE, 1, 9, 1):
             self.assertEqual(9, len(m))
         else:
             self.assertEqual(8, len(m))
 
-        if IsOrthancVersionAbove(_REMOTE, 1, 12, 1):
-            # ./Tests/GetPixelDataVR.py ./Database/ColorTestImageJ.dcm
-            self.assertTrue('PixelDataVR' in m)  # New in Orthanc 1.12.1
-            self.assertEqual('OB', DoGet(_REMOTE, '/instances/%s/metadata/PixelDataVR' % i[0]))
-
         if IsOrthancVersionAbove(_REMOTE, 1, 11, 0):
             self.assertTrue('MainDicomTagsSignature' in m)  # New in Orthanc 1.11.0
 
@@ -9793,3 +9779,38 @@
             self.assertNotEqual(studyLastUpdate1, studyLastUpdate2)
             self.assertNotEqual(patientLastUpdate1, patientLastUpdate2)
 
+    def test_pixel_data_vr(self):
+        def Check(path, hasPixelData, hasMetadata, expectedVR):
+            i = UploadInstance(_REMOTE, path) ['ID']
+            m = DoGet(_REMOTE, '/instances/%s/metadata?expand' % i)
+            if hasMetadata:
+                self.assertTrue('PixelDataVR' in m)
+                self.assertEqual(expectedVR, m['PixelDataVR'])
+            else:
+                self.assertFalse('PixelDataVR' in m)
+
+            if hasPixelData:
+                self.assertTrue('PixelDataOffset' in m)
+                j = DoGet(_REMOTE, '/instances/%s/file?expand' % i, headers = {
+                    'Accept': 'application/dicom+json'
+                    })
+                self.assertEqual(expectedVR, j['7FE00010']['vr'])
+
+        if IsOrthancVersionAbove(_REMOTE, 1, 12, 1):
+            # File without pixel data
+            Check('MarekLatin2.dcm', False, False, None)
+
+            # Those files are badly formatted, and should be 'OB'
+            # according to the DICOM standard => medata is present
+            Check('Issue143.dcm', True, True, 'OW')              # Little Endian Explicit, 8bpp
+            Check('KarstenHilbertRF.dcm', True, True, 'OW')      # Little Endian Explicit, 8bpp
+            Check('PilatesArgenturGEUltrasoundOsiriX.dcm', True, True, 'OW')  # Little Endian Explicit, 8bpp
+
+            # Those files are formatted as expected
+            Check('ColorTestMalaterre.dcm', True, False, 'OW')   # Implicit Little Endian, 8bpp
+            Check('Issue94.dcm', True, False, 'OW')              # Implicit Little Endian, 16bpp
+            Check('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', True, False, 'OB') # Explicit Little Endian, 8bpp
+            Check('Phenix/IM-0001-0001.dcm', True, False, 'OW')  # Explicit Little Endian, 16bpp
+            Check('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', True, False, 'OB') # Explicit Big Endian, 8bpp
+            Check('TransferSyntaxes/1.2.840.10008.1.2.4.50.dcm', True, False, 'OB')  # JPEG
+            Check('Knee/T1/IM-0001-0001.dcm', True, False, 'OB') # JPEG2k