3 from gdcmPython import *
5 from libvtkgdcmPython import *
7 from vtkgdcmPython import *
9 class gdcmTestCase(unittest.TestCase):
10 # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm)
11 # come from Sebastien Barre's Dicom2 highly recommendable site
12 # http://www.barre.nom.fr/medical/samples/index.html
14 ####################################
15 # CT modality examples:
16 ####################################
17 ["CT-MONO2-16-ort.dcm",
18 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
22 ["Bits Stored", "16"],
23 ["Bits Allocated", "16"],
25 ["Pixel Representation", "1"],
26 ["Manufacturer", "GE MEDICAL SYSTEMS"],
27 ["Manufacturer's Model Name", "HiSpeed CT/i"],
28 ["Pixel Data", "gdcm::NotLoaded. Address:1674 Length:524288 x(80000)"]
30 ["CT-MONO2-16-ankle.dcm",
31 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little
35 ["Bits Stored", "16"],
36 ["Bits Allocated", "16"],
38 ["Pixel Representation", "1"],
39 ["Manufacturer", "GE MEDICAL SYSTEMS"],
40 ["Manufacturer's Model Name", "GENESIS_ZEUS"],
41 ["Pixel Data", "gdcm::NotLoaded. Address:1148 Length:524288 x(80000)"]
43 ["CT-MONO2-8-abdo.dcm",
44 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little
49 ["Bits Allocated", "8"],
51 ["Pixel Representation", "0"],
52 ["Manufacturer", "FUJI"],
53 ["Pixel Data", "gdcm::NotLoaded. Address:796 Length:262144 x(40000)"]
55 ["CT-MONO2-12-lomb-an2.acr",
57 #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
60 ["Bits Stored", "12"],
61 ["Bits Allocated", "16"],
63 ["Pixel Representation", "0"],
64 ["Manufacturer", "SIEMENS"],
65 ["Pixel Data", "gdcm::NotLoaded. Address:1230 Length:524288 x(80000)"]
67 ["CT-MONO2-16-chest.dcm",
68 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg...
70 ["Photometric Interpretation", "MONOCHROME2"],
73 ["Bits Stored", "16"],
74 ["Bits Allocated", "16"],
76 ["Pixel Representation", "1"],
77 ["Manufacturer", "GE MEDICAL SYSTEMS"],
78 ["Pixel Data", "gdcm::NotLoaded. Address:1638 Length:143498 x(2308a)"]
80 ####################################
81 ### MR modality examples:
82 ####################################
83 ["MR-MONO2-12-angio-an1.acr",
84 [ ["Recognition Code (RET)", "ACR-NEMA 1.0"],
86 #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
89 ["Bits Stored", "12"],
90 ["Bits Allocated", "12"],
92 ["Pixel Representation", "0"],
93 ["Manufacturer", "Philips"],
94 # Note: 256*256*12/8 = 98304
95 ["Pixel Data", "gdcm::NotLoaded. Address:650 Length:98304 x(18000)"]
97 ["MR-MONO2-12-an2.acr",
99 ["Photometric Interpretation", "MONOCHROME2"],
102 ["Bits Stored", "12"],
103 ["Bits Allocated", "16"],
105 ["Pixel Representation", "0"],
106 ["Manufacturer", "SIEMENS"],
107 ["Manufacturer's Model Name", "MAGNETOM VISION"],
108 ["Pixel Data", "gdcm::NotLoaded. Address:1866 Length:131072 x(20000)"]
110 ["MR-MONO2-16-head.dcm",
111 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Imp VR, LE
113 ["Photometric Interpretation", "MONOCHROME2"],
116 ["Bits Stored", "16"],
117 ["Bits Allocated", "16"],
119 ["Pixel Representation", "1"],
120 ["Manufacturer", "GE MEDICAL SYSTEMS"],
121 ["Manufacturer's Model Name", "GENESIS_SIGNA"],
122 ["Pixel Data", "gdcm::NotLoaded. Address:1804 Length:131072 x(20000)"]
124 # MR-MONO2-12-shoulder example is present in the Jpeg section.
125 # MR-MONO2-16-knee is not present in the test suite since it is too
126 # closely related to MR-MONO2-16-head.dcm to be of interest.
127 ####################################
128 # OT modality examples:
129 ####################################
130 # OT-MONO2-8-hip is not present in the test suite since it is too
131 # closely related to OT-MONO2-8-a7 to be of interest.
132 ["OT-PAL-8-face.dcm",
133 # Interest: has a color palette
134 [#"Transfer Syntax UID", and "Manufacturer" are absent.
136 ["Photometric Interpretation", "PALETTE COLOR"],
139 ["Bits Stored", "8"],
140 ["Bits Allocated", "8"],
142 ["Pixel Representation", "0"],
143 ["Pixel Data", "gdcm::NotLoaded. Address:1654 Length:307200 x(4b000)"]
145 # OT-MONO2-8-colon is not present in the test suite since it is too
146 # closely related to OT-MONO2-8-a7 to be of interest.
147 ["OT-MONO2-8-a7.dcm",
148 [#"Transfer Syntax UID" is absent.
150 ["Photometric Interpretation", "MONOCHROME2"],
153 ["Bits Stored", "8"],
154 ["Bits Allocated", "8"],
156 ["Pixel Representation", "0"],
157 ["Manufacturer", "Philips Medical Systems"],
158 ["Pixel Data", "gdcm::NotLoaded. Address:438 Length:262144 x(40000)"]
160 ####################################
161 # US (Ultra Sound) modality examples:
162 ####################################
163 ["US-RGB-8-esopecho.dcm",
164 # Interest: RGB image
165 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Exp VR, LE
167 ["Photometric Interpretation", "RGB"],
170 ["Bits Stored", "8"],
171 ["Bits Allocated", "8"],
173 ["Pixel Representation", "0"],
174 ["Manufacturer", "Acme Products"],
175 # FIXME: 92160 / (120*256) = 3 bytes per pixel NOT 1. Maybe
176 # it has something to do with [Samples Per Pixel] = [3] ???
177 # You said it, puffy (tu l'as dit, bouffi, in french language)
178 # RGB is 3 bytes per pixel
179 # + Planar configuration (0028,0006) = 0 --> Pixels RGB
180 ["Pixel Data", "gdcm::NotLoaded. Address:904 Length:92160 x(16800)"]
182 ["US-RGB-8-epicard.dcm",
183 # Interest: Big endian transfert syntax
184 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.2"], # Big endian
185 # But ... group 0000 is LE .
187 ["Photometric Interpretation", "RGB"],
190 ["Bits Stored", "8"],
191 ["Bits Allocated", "8"],
193 ["Pixel Representation", "0"],
194 ["Manufacturer", "G.E. Medical Systems"],
195 ["Manufacturer's Model Name", "LOGIQ 700"],
196 # + Planar configuration (0028,0006) = 1 --> Plane R, Plane G, Plane B
197 ["Implementation Version Name", "OFFIS-DCMTK-311"],
198 ["Pixel Data", "gdcm::NotLoaded. Address:1012 Length:921600 x(e1000)"]
203 # The number of images is contained in the "Number of Frames" element
204 ["MR-MONO2-8-16x-heart.dcm",
205 # Interest: multi-frame
206 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
207 ["Number of Frames", "16"],
209 ["Photometric Interpretation", "MONOCHROME2"],
212 ["Bits Stored", "8"],
213 ["Bits Allocated", "8"],
215 ["Pixel Representation", "0"],
216 ["Manufacturer", "Philips"],
217 # Note: 256*256*16=1048576 (16 is the number of Frames)
218 ["Pixel Data", "gdcm::NotLoaded. Address:920 Length:1048576 x(100000)"]
220 ["NM-MONO2-16-13x-heart.dcm",
221 # Interest: NM modality, multi-frame
222 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
223 ["Number of Frames", "13"],
225 ["Photometric Interpretation", "MONOCHROME2"],
228 ["Bits Stored", "16"],
229 ["Bits Allocated", "16"],
231 ["Pixel Representation", "0"],
232 ["Manufacturer", "ACME Products"],
233 # Note: 64*64*13*2=106496
234 ["Pixel Data", "gdcm::NotLoaded. Address:1234 Length:106496 x(1a000)"]
236 ["US-MONO2-8-8x-execho.dcm",
237 # Interest: multi-frame
238 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
239 ["Number of Frames", "8"],
241 ["Photometric Interpretation", "MONOCHROME2"],
244 ["Bits Stored", "8"],
245 ["Bits Allocated", "8"],
247 ["Pixel Representation", "0"],
248 ["Manufacturer", "Acme Products"],
249 ["Pixel Data", "gdcm::NotLoaded. Address:976 Length:122880 x(1e000)"]
251 ["US-PAL-8-10x-echo.dcm",
252 # Interest: RLE (Run Length Encoded) compression, multiframe
253 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.5"], # RLE
254 ["Number of Frames", "10"],
256 ["Photometric Interpretation", "PALETTE COLOR"],
259 ["Bits Stored", "8"],
260 ["Bits Allocated", "8"],
262 ["Pixel Representation", "0"],
263 ["Manufacturer", "ACME Products"],
264 ["Pixel Data", "gdcm::NotLoaded. Address:2428 Length:481182 x(7579e)"]
266 ["XA-MONO2-8-12x-catheter.dcm",
267 # Interest: XA modality, multi-frame
268 [ #["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg
269 ["Number of Frames", "12"], # 12 images
271 ["Photometric Interpretation", "MONOCHROME2"],
274 ["Bits Stored", "8"],
275 ["Bits Allocated", "8"],
277 ["Pixel Representation", "0"],
278 ["Manufacturer", "Acme Products"],
279 ["Pixel Data", "gdcm::NotLoaded. Address:1006 Length:920072 x(e0a08)"]
284 ["gdcm-MR-SIEMENS-16-1.acr",
285 # Interest: good old Acr-Nema Version 1, see also Oddities below
286 [ ["Recognition Code (RET)", "ACR-NEMA 1.0"],
290 ["Bits Stored", "12"],
291 ["Bits Allocated", "16"],
293 ["Pixel Representation", "0"],
294 ["Manufacturer", "SIEMENS"],
295 ["Manufacturer's Model Name", "GBS III"],
296 # FIXME: this image looks padded at the end. The length of the file
297 # is 140288. Notice that, 256*256*2 + 1024 = 131072 + 1024 = 132096
298 ["Pixel Data", "gdcm::NotLoaded. Address:8192 Length:132096 x(20400)"],
299 # Oddities: "Study ID" and "Series Number" are empty
301 ["Series Number", ""] ] ],
302 # Oddities: "Study" and "Serie Instance UID" are not present
303 ["gdcm-MR-SIEMENS-16-2.acr",
304 # Interest: Acr-Nema Version 2
305 [ ["Recognition Code (RET)", "ACR-NEMA 2.0"],
309 ["Bits Stored", "12"],
310 ["Bits Allocated", "16"],
312 ["Pixel Representation", "0"],
313 ["Manufacturer", "SIEMENS"],
314 ["Manufacturer's Model Name", "MAGNETOM VISION"],
315 ["Study Instance UID",
316 "1.3.12.2.1107.5.2.4.7630.20000918174641000"],
318 ["Series Instance UID",
319 "1.3.12.2.1107.5.2.4.7630.20000918175714000007"],
320 ["Series Number", "7"],
321 ["Pixel Data", "gdcm::NotLoaded. Address:6052 Length:524288 x(80000)"]
323 ["gdcm-US-ALOKA-16.dcm",
324 # Interest: - possesses 3 LUTS: a Green (checked), a Red and BLue.
325 # - announced as implicit VR, but really explicit VR.
326 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
328 ["Photometric Interpretation", "PALETTE COLOR"],
329 ["Segmented Green Palette Color Lookup Table Data",
330 "gdcm::NotLoaded. Address:89576 Length:113784 x(1bc78)"],
333 ["Bits Stored", "16"],
334 ["Bits Allocated", "16"],
336 ["Pixel Representation", "0"],
337 ["Manufacturer", "ALOKA CO., LTD."],
338 ["Manufacturer's Model Name", "SSD-4000"],
339 ["Pixel Data", "gdcm::NotLoaded. Address:258740 Length:614400 x(96000)"]
341 ["gdcm-MR-PHILIPS-16.dcm",
342 # Interest: - possesses a sequence
343 # - dicom file, with a recognition code of ACR-NEMA1
344 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
345 ["Recognition Code (RET)", "ACR-NEMA 1.0"],
347 ["Photometric Interpretation", "MONOCHROME2"],
350 ["Bits Stored", "8"],
351 ["Bits Allocated", "16"],
353 ["Pixel Representation", "0"],
354 ["Manufacturer", "Philips Medical Systems"],
355 ["Manufacturer's Model Name", "Gyroscan Intera"],
356 ["Sequence Variant", "OTHER"],
357 ["Pixel Data", "gdcm::NotLoaded. Address:6584 Length:131072 x(20000)"]
359 ["gdcm-MR-PHILIPS-16-Multi-Seq.dcm",
360 # Interest: - possesses many sequences in group 0x0029
361 # - Big sequence 28808 bytes at (0x0029, 0x263d)
362 # - dicom file, with a recognition code of ACR-NEMA1
363 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],
364 ["Recognition Code (RET)", "ACR-NEMA 1.0"],
366 ["Photometric Interpretation", "MONOCHROME2"],
369 ["Bits Stored", "12"],
370 ["Bits Allocated", "16"],
372 ["Pixel Representation", "0"],
373 ["Manufacturer", "Philips Medical Systems"],
374 ["Manufacturer's Model Name", "Gyroscan Intera"],
375 ["Sequence Variant", "OTHER"],
376 ["Pixel Data", "gdcm::NotLoaded. Address:35846 Length:32768 x(8000)"]
378 ["gdcm-MR-PHILIPS-16-NonRectPix.dcm",
379 # Interest: - pixels are non rectangular
380 # - private elements are in explicit VR (which is normal)
381 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE
383 ["Photometric Interpretation", "MONOCHROME2"],
386 ["Bits Stored", "12"],
387 ["Bits Allocated", "16"],
389 ["Pixel Representation", "0"],
390 ["Manufacturer", "Philips Medical Systems"],
391 ["Manufacturer's Model Name", "Gyroscan Intera"],
392 ["Pixel Spacing", "0.487416\\0.194966"],
393 ["Pixel Data", "gdcm::NotLoaded. Address:5010 Length:20480 x(5000)"]
395 ["gdcm-CR-DCMTK-16-NonSamplePerPix.dcm",
396 # Interest: - Misses the "Samples Per Pixel" element which prevents
397 # e-film from reading it.
398 # - Misses the Manufacturer related info
399 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE
401 ["Photometric Interpretation", "MONOCHROME2"],
404 ["Bits Stored", "8"],
405 ["Bits Allocated", "8"],
407 ["Pixel Representation", "0"],
408 ["Implementation Version Name", "OFFIS_DCMTK_341"],
409 ["Pixel Data", "gdcm::NotLoaded. Address:740 Length:562500 x(89544)"]
414 ["gdcm-JPEG-Extended.dcm",
415 # Interest: Jpeg compression [Extended (2,4)]
416 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.51"],
418 ["Photometric Interpretation", "MONOCHROME2"],
421 ["Bits Stored", "12"],
422 ["Bits Allocated", "16"],
424 ["Pixel Representation", "0"],
425 ["Manufacturer", "SIEMENS"],
426 ["Manufacturer's Model Name", "Volume Zoom"],
427 ["Pixel Data", "gdcm::NotLoaded. Address:2946 Length:192218 x(2eeda)"]
429 ["MR-MONO2-12-shoulder.dcm",
430 # Interest: Jpeg compression [Lossless, non-hierar. (14)]
431 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.57"],
433 ["Photometric Interpretation", "MONOCHROME2"],
436 ["Bits Stored", "12"],
437 ["Bits Allocated", "16"],
439 ["Pixel Representation", "0"],
440 ["Manufacturer", "Philips Medical Systems"],
441 ["Manufacturer's Model Name", "Gyroscan NT"],
442 ["Pixel Data", "gdcm::NotLoaded. Address:1580 Length:718948 x(af864)"]
444 ["gdcm-JPEG-LossLess3a.dcm",
445 # Interest: - Jpeg compression [Lossless, hierar., first-order
446 # pred. 14, Select. Val. 1]
447 # - contains a sequence [circa (0008,2112)]
448 # - contains additional data after the pixels ???
449 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
451 ["Photometric Interpretation", "MONOCHROME2"],
454 ["Bits Stored", "12"],
455 ["Bits Allocated", "16"],
457 ["Pixel Representation", "0"],
458 ["Manufacturer", "SIEMENS"],
459 ["Manufacturer's Model Name", "Volume Zoom"] ] ],
460 # FIXME: the pixel data looks like corrupted. As stated by "od -A d -c"
461 # 0002528 à 177 020 \0 O B \0 \0 ÿ ÿ ÿ ÿ þ ÿ \0 à
462 # 0002544 \0 \0 \0 \0 þ ÿ \0 à 202 ? 003 \0 ÿ Ø ÿ Ã
463 # which we interpret as follows:
464 # - 2528: (à 177, 020 \0) = (0x7fe0, 0x0010) i.e. Pixel Data tag,
465 # - 2532: OB i.e. encapsulated encoded Pixel Data,
466 # - 2534: Two bytes reserved,
467 # - 2536: ÿ ÿ ÿ ÿ = 0xffffffff i.e. data element length is undefined.
468 # - 2540: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. basic offset table
470 # - 2544: \0 \0 \0 \0 i.e. offset table as length zero, i.e. no
471 # item value for offset table.
472 # - 2548: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. item tag of first
473 # fragment of (encoded) pixel data.
474 # - 2552: 202 ? 003 \0 = 212866 bytes i.e. length of first fragment
475 # of (encoded) pixel data.
476 # and so the next item tag should be found at the 2556+212866 th
477 # octet i.e. at address 215422. But, as stated by od, we find:
478 # 0215408 E u Ö 026 Î É 7 ¬ Ã ¸ ó ¿ ÿ Ù \f °
479 # 0215424 ¶ 016 P Ñ 002 016
480 # and (\f °, ¶ 016) is NOT an OB item TAG which is required to be
481 # present (at least there should be a sequence delimiter), refer to
482 # PS 3.5-2001 page 50.
485 # at 9ec : ItemTag : fffe,e000
486 # at 9f0 : Basic Offset Table Item Lentgh (??) 0 x(00000000)
487 # at 9f4 : ItemTag : fffe,e000
488 # at 9f8 : fragment length 212866 x(00033f82)
489 # at 3497e : ItemTag b00c,0eb6 (should be fffe,e000 or fffe,e0dd):
491 ["gdcm-JPEG-LossLessThoravision.dcm",
492 # Interest: - Jpeg compression [Lossless, hierar., first-order
493 # pred. 14, Select. Val. 1]
494 # - encoding is sligthly different from LossLess3a.dcm ???
495 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
497 ["Photometric Interpretation", "MONOCHROME2"],
500 ["Bits Stored", "15"],
501 ["Bits Allocated", "16"],
503 ["Pixel Representation", "0"],
504 ["Manufacturer", "Philips Medical Systems"],
505 ["Manufacturer's Model Name", "Cassette Holder Type 9840 500 35201"],
506 ["Pixel Data", "gdcm::NotLoaded. Address:3144 Length:4795668 x(492d14)"]
510 def _BaseTest(self, FileSet):
511 for entry in FileSet:
512 fileName = os.path.join(GDCM_TEST_DATA_PATH, entry[0])
513 reader = gdcmHeader(fileName)
514 assert reader.IsReadable(),\
515 "File '%s' is not readable by gdcmHeader" % fileName
517 valDict = reader.GetEntry()
518 for subEntry in entry[1]:
519 element = subEntry[0]
521 self.assertEqual(valDict[element], value,
522 ("Wrong %s for file %s (got %s, shoud be %s)"
523 % (element,fileName, valDict[element], value)) )
526 gdcmTestCase._BaseTest(self, gdcmTestCase.BarreFiles)
528 def testMultiFram(self):
529 gdcmTestCase._BaseTest(self, gdcmTestCase.MultiFrameFiles)
532 gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmFiles)
535 gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmJpegFiles)
537 def ZOBtestWrite(self):
539 SourceFileName = os.path.join(GDCM_TEST_DATA_PATH,
540 'gdcm-MR-PHILIPS-16-Multi-Seq.dcm')
541 Source = gdcmFile(SourceFileName);
542 Source.GetImageData()
543 TargetFileName = "junk"
544 Target = Source.WriteDcmImplVR(TargetFileName)
545 # Sign = 'a1e2abdc2f6abedd86b93c8b88db5203' # new signature (found on Win)
546 Sign = '849e722e004d3bb37b87ab6006509b8f' # new signature without field strip
547 ComputeSign = md5.new(open(TargetFileName).read()).hexdigest()
548 self.assertEqual(ComputeSign, Sign,
549 ("Wrong signature for file %s (got %s, shoud be %s)"
550 % (SourceFileName, ComputeSign, Sign)) )
551 os.unlink(TargetFileName)
553 if __name__ == '__main__':
554 if not GDCM_TEST_DATA_PATH:
555 print "GDCM_TEST_DATA_PATH (internal variable) is not setup properly."
556 print " This test suite requires that some Dicom reference files be "
558 print " For further details on installation of gdcmData, please"
559 print " refer to the developper's section of page "
560 print " http://www.creatis.insa-lyon.fr/Public/Gdcm"
562 print "gdcmData directory (used in the test suite) must be placed in"
563 print "the gdcm directory. The gdcm tree must be :"
567 print " |____gdcmData (not in gdcm by default)"
568 print " |____gdcmPython"