comparison Tests/Tests.py @ 21:2a29bcff60a7

tests of image decoding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Jun 2015 14:14:37 +0200
parents 16c37933384d
children 8f4b70c89467
comparison
equal deleted inserted replaced
20:f3d08a75a636 21:2a29bcff60a7
57 57
58 def UninstallLuaCallbacks(): 58 def UninstallLuaCallbacks():
59 DoPost(_REMOTE, '/tools/execute-script', 'function OnStoredInstance() end', 'application/lua') 59 DoPost(_REMOTE, '/tools/execute-script', 'function OnStoredInstance() end', 'application/lua')
60 60
61 61
62 def CompareLists(a, b):
63 if len(a) != len(b):
64 return False
65
66 for i in range(len(a)):
67 d = a[i] - b[i]
68 if abs(d) >= 0.51: # Add some tolerance for rounding errors
69 return False
70
71 return True
72
73
74
75
62 76
63 class Orthanc(unittest.TestCase): 77 class Orthanc(unittest.TestCase):
64 def setUp(self): 78 def setUp(self):
65 DropOrthanc(_LOCAL) 79 DropOrthanc(_LOCAL)
66 DropOrthanc(_REMOTE) 80 DropOrthanc(_REMOTE)
81 #print "In test", self._testMethodName
82
83 def AssertSameImages(self, truth, url):
84 im = GetImage(_REMOTE, url)
85 self.assertTrue(CompareLists(truth, im.getdata()))
86
67 87
68 def test_system(self): 88 def test_system(self):
69 self.assertTrue('Version' in DoGet(_REMOTE, '/system')) 89 self.assertTrue('Version' in DoGet(_REMOTE, '/system'))
70 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalDiskSize']) 90 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalDiskSize'])
71 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalUncompressedSize']) 91 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalUncompressedSize'])
241 DropOrthanc(_REMOTE) 261 DropOrthanc(_REMOTE)
242 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalDiskSize']) 262 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalDiskSize'])
243 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalUncompressedSize']) 263 self.assertEqual('0', DoGet(_REMOTE, '/statistics')['TotalUncompressedSize'])
244 264
245 265
246 def test_multi_frame(self): 266 def test_multiframe(self):
247 i = UploadInstance(_REMOTE, 'Multiframe.dcm')['ID'] 267 i = UploadInstance(_REMOTE, 'Multiframe.dcm')['ID']
248 self.assertEqual(76, len(DoGet(_REMOTE, '/instances/%s/frames' % i))) 268 self.assertEqual(76, len(DoGet(_REMOTE, '/instances/%s/frames' % i)))
249 269
250 im = GetImage(_REMOTE, '/instances/%s/frames/0/preview' % i) 270 im = GetImage(_REMOTE, '/instances/%s/frames/0/preview' % i)
251 self.assertEqual("L", im.mode) 271 self.assertEqual("L", im.mode)
1320 for i in range(len(a)): 1340 for i in range(len(a)):
1321 self.assertEqual(a[i], ComputeMD5(DoGet(_REMOTE, '/instances/%s/frames/%d/preview' % (s, i)))) 1341 self.assertEqual(a[i], ComputeMD5(DoGet(_REMOTE, '/instances/%s/frames/%d/preview' % (s, i))))
1322 1342
1323 1343
1324 def test_issue_19(self): 1344 def test_issue_19(self):
1325 # This is an image with "YBR_FULL" photometric interpretation 1345 # This is an image with "YBR_FULL" photometric interpretation, it is not supported by Orthanc
1326 # gdcmconv -i /home/jodogne/DICOM/GdcmDatabase/US_DataSet/HDI5000_US/3EAF5E01 -w -o Issue19.dcm 1346 # gdcmconv -i /home/jodogne/DICOM/GdcmDatabase/US_DataSet/HDI5000_US/3EAF5E01 -w -o Issue19.dcm
1327 1347
1328 a = UploadInstance(_REMOTE, 'Issue19.dcm')['ID'] 1348 a = UploadInstance(_REMOTE, 'Issue19.dcm')['ID']
1329 i = DoGet(_REMOTE, '/instances/941ad3c8-05d05b88-560459f9-0eae0e20-6cddd533/preview') 1349 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/941ad3c8-05d05b88-560459f9-0eae0e20-6cddd533/preview'))
1330
1331 # eb5d156c3594497f589158a6c6f3ca51 <=> Unsupported.png
1332 self.assertEqual('eb5d156c3594497f589158a6c6f3ca51', ComputeMD5(i))
1333 1350
1334 1351
1335 def test_issue_37(self): 1352 def test_issue_37(self):
1336 # Same test for issues 35 and 37. Fixed in Orthanc 0.9.1 1353 # Same test for issues 35 and 37. Fixed in Orthanc 0.9.1
1337 u = UploadInstance(_REMOTE, 'Beaufix/IM-0001-0001.dcm')['ID'] 1354 u = UploadInstance(_REMOTE, 'Beaufix/IM-0001-0001.dcm')['ID']
1798 b = ModifyAndUpload(i, '{"Replace":{"StudyDescription":"hello","Modality":"world"}}') 1815 b = ModifyAndUpload(i, '{"Replace":{"StudyDescription":"hello","Modality":"world"}}')
1799 self.assertEqual('Jodogne', DoGet(_REMOTE, '/instances/%s/content/PatientName' % b).strip()) 1816 self.assertEqual('Jodogne', DoGet(_REMOTE, '/instances/%s/content/PatientName' % b).strip())
1800 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/content/StudyDescription' % b).strip()) 1817 self.assertEqual('hello', DoGet(_REMOTE, '/instances/%s/content/StudyDescription' % b).strip())
1801 self.assertEqual('world', DoGet(_REMOTE, '/instances/%s/content/Modality' % b).strip()) 1818 self.assertEqual('world', DoGet(_REMOTE, '/instances/%s/content/Modality' % b).strip())
1802 1819
1820
1821 def test_incoming_jpeg(self):
1822 def storescu():
1823 with open(os.devnull, 'w') as FNULL:
1824 subprocess.check_call([ 'storescu', '-xs',
1825 _REMOTE['Server'], str(_REMOTE['DicomPort']),
1826 GetDatabasePath('Knix/Loc/IM-0001-0001.dcm') ],
1827 stderr = FNULL)
1828
1829 self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
1830 InstallLuaScript('Lua/TransferSyntaxDisable.lua')
1831 self.assertRaises(Exception, storescu)
1832 self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
1833 InstallLuaScript('Lua/TransferSyntaxEnable.lua')
1834 storescu()
1835 self.assertEqual(1, len(DoGet(_REMOTE, '/patients')))
1836
1837
1838 def test_storescu_jpeg(self):
1839 self.assertEqual(0, len(DoGet(_REMOTE, '/exports')['Exports']))
1840
1841 knixStudy = 'b9c08539-26f93bde-c81ab0d7-bffaf2cb-a4d0bdd0'
1842 UploadInstance(_REMOTE, 'Knix/Loc/IM-0001-0001.dcm')
1843 UploadInstance(_REMOTE, 'Knix/Loc/IM-0001-0002.dcm')
1844 UploadInstance(_REMOTE, 'Knix/Loc/IM-0001-0003.dcm')
1845
1846 a = UploadInstance(_REMOTE, 'Brainix/Flair/IM-0001-0001.dcm')['ID']
1847 b = UploadInstance(_REMOTE, 'ColorTestImageJ.dcm')['ID']
1848 self.assertEqual(0, len(DoGet(_LOCAL, '/instances')))
1849 DoPost(_REMOTE, '/modalities/orthanctest/store', [ knixStudy, a, b ])
1850 self.assertEqual(5, len(DoGet(_LOCAL, '/instances')))
1851
1852 self.assertEqual(3, len(DoGet(_REMOTE, '/exports')['Exports']))
1853
1854 DropOrthanc(_REMOTE)
1855 self.assertEqual(0, len(DoGet(_REMOTE, '/exports')['Exports']))
1856
1857
1858 def test_pixel_data(self):
1859 jpeg = UploadInstance(_REMOTE, 'Knix/Loc/IM-0001-0001.dcm')['ID']
1860 color = UploadInstance(_REMOTE, 'ColorTestImageJ.dcm')['ID']
1861 phenix = UploadInstance(_REMOTE, 'Phenix/IM-0001-0001.dcm')['ID']
1862
1863 phenixSize = 358 * 512 * 2
1864 colorSize = 1000 * 1000 * 3
1865 jpegSize = 51918
1866
1867 self.assertEqual(1, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010' % phenix)))
1868 self.assertEqual(1, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010' % color)))
1869 self.assertEqual(2, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010' % jpeg)))
1870
1871 self.assertEqual(0, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010/0' % jpeg)))
1872 self.assertEqual(jpegSize, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010/1' % jpeg)))
1873
1874 self.assertEqual(phenixSize, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010/0' % phenix)))
1875 self.assertEqual(colorSize, len(DoGet(_REMOTE, '/instances/%s/content/7fe0-0010/0' % color)))
1876
1877
1878 def test_decode_brainix(self):
1879 brainix = [
1880 UploadInstance(_REMOTE, 'Brainix/Epi/IM-0001-0001.dcm')['ID'], # (*)
1881 UploadInstance(_REMOTE, 'Formats/JpegLossless.dcm')['ID'], # JPEG-LS, same as (*) (since Orthanc 0.7.6)
1882 UploadInstance(_REMOTE, 'Formats/Jpeg.dcm')['ID'], # JPEG, same as (*) (since Orthanc 0.7.6)
1883 ]
1884 h = '6fb11b932d535c2be04beabd99793ff8'
1885 maxValue = 426.0
1886
1887 truth = Image.open(GetDatabasePath('Formats/Brainix.png'))
1888 for i in brainix:
1889 self.AssertSameImages(truth.getdata(), '/instances/%s/image-int16' % i)
1890 self.AssertSameImages(truth.getdata(), '/instances/%s/image-uint16' % i)
1891
1892 truth2 = map(lambda x: min(255, x), truth.getdata())
1893 for i in brainix:
1894 self.AssertSameImages(truth2, '/instances/%s/image-uint8' % i)
1895
1896 truth2 = map(lambda x: x * 255.0 / maxValue, truth.getdata())
1897 for i in brainix:
1898 self.AssertSameImages(truth2, '/instances/%s/preview' % i)
1899
1900 for i in brainix:
1901 self.assertEqual(h, ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % i)))
1902
1903
1904 def test_decode_color(self):
1905 imagej = UploadInstance(_REMOTE, 'ColorTestImageJ.dcm')['ID']
1906 color = UploadInstance(_REMOTE, 'ColorTestMalaterre.dcm')['ID']
1907
1908 for i in [ imagej, color ]:
1909 for j in [ 'image-uint8', 'image-uint16', 'image-int16' ]:
1910 self.assertRaises(Exception, lambda: DoGet(_REMOTE, '/instances/%s/%s' % (i, j)))
1911
1912 self.assertEqual('c14c687f7a1ea9fe022479fc87c67274', ComputeMD5(DoGet(_REMOTE, '/instances/%s/preview' % imagej)))
1913 self.assertEqual('a87d122918a56f803bcfe9d2586b9125', ComputeMD5(DoGet(_REMOTE, '/instances/%s/preview' % color)))
1914
1915 self.assertEqual('30cc46bfa7aba77a40e4178f6184c25a', ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % imagej)))
1916 self.assertEqual('ff195005cef06b59666fd220a9b4cd9a', ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % color)))
1917
1918
1919 def test_decode_rf(self):
1920 rf = UploadInstance(_REMOTE, 'KarstenHilbertRF.dcm')['ID']
1921 truth = Image.open(GetDatabasePath('Formats/KarstenHilbertRF.png'))
1922
1923 self.AssertSameImages(truth.getdata(), '/instances/%s/image-uint8' % rf)
1924 self.AssertSameImages(truth.getdata(), '/instances/%s/image-uint16' % rf)
1925 self.AssertSameImages(truth.getdata(), '/instances/%s/image-int16' % rf)
1926 self.AssertSameImages(truth.getdata(), '/instances/%s/preview' % rf)
1927
1928 self.assertEqual('42254d70efd2f4a1b8f3455909689f0e', ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % rf)))
1929
1930
1931 def test_decode_multiframe(self):
1932 mf = UploadInstance(_REMOTE, 'Multiframe.dcm')['ID']
1933
1934 # Test the first frame
1935 truth = Image.open(GetDatabasePath('Formats/Multiframe0.png'))
1936 self.AssertSameImages(truth.getdata(), '/instances/%s/image-uint8' % mf)
1937 self.AssertSameImages(truth.getdata(), '/instances/%s/image-uint16' % mf)
1938 self.AssertSameImages(truth.getdata(), '/instances/%s/image-int16' % mf)
1939 self.AssertSameImages(truth.getdata(), '/instances/%s/preview' % mf)
1940 self.assertEqual('9812b99d93bbcd4e7684ded089b5dfb3', ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % mf)))
1941
1942 self.AssertSameImages(truth.getdata(), '/instances/%s/frames/0/image-uint16' % mf)
1943
1944 # Test the last frame
1945 truth = Image.open(GetDatabasePath('Formats/Multiframe75.png'))
1946 self.AssertSameImages(truth.getdata(), '/instances/%s/frames/75/image-uint16' % mf)
1947
1948
1949 def test_decode_signed(self):
1950 signed = UploadInstance(_REMOTE, 'SignedCT.dcm')['ID']
1951 minValue = -2000
1952 maxValue = 4042
1953
1954 truth = Image.open(GetDatabasePath('Formats/SignedCT.png'))
1955 self.AssertSameImages(truth.getdata(), '/instances/%s/image-int16' % signed)
1956
1957 truth2 = map(lambda x: 0 if x >= 32768 else x, truth.getdata())
1958 self.AssertSameImages(truth2, '/instances/%s/image-uint16' % signed)
1959
1960 truth3 = map(lambda x: 255 if x >= 256 else x, truth2)
1961 self.AssertSameImages(truth3, '/instances/%s/image-uint8' % signed)
1962
1963 tmp = map(lambda x: x - 65536 if x >= 32768 else x, truth.getdata())
1964 tmp = map(lambda x: (255.0 * (x - minValue)) / (maxValue - minValue), tmp)
1965 self.AssertSameImages(tmp, '/instances/%s/preview' % signed)
1966
1967 self.assertEqual('b57e6c872a3da50877c7da689b03a444', ComputeMD5(DoGet(_REMOTE, '/instances/%s/matlab' % signed)))