4 # Where all the test images are
5 TestFileDir = os.path.join("..", "Data")
7 ### Defaulting the path to the dictionaries
8 # WARNING: this needs to be done before importation of gdcm !
9 # FIXME: this needs to be put in a wrapper of the swig generated
10 # shadow classes (say Pygdcm.py?)
12 os.environ["GDCM_DICT_PATH"]
14 os.environ["GDCM_DICT_PATH"] = os.path.join("..", "Dicts/")
16 ### When not properly installed (like in a cvs hierachy) try
17 # to handle properly the import of gdcm
22 PreInstallPath = os.path.join(os.getcwd(), "..")
23 sys.path.append(PreInstallPath)
27 raise ImportError, "gdcm extension module not found"
30 class gdcmTestCase(unittest.TestCase):
31 # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm)
32 # come from Sebastien Barre's Dicom2 highly recommendable site
33 # http://www.barre.nom.fr/medical/samples/index.html
35 ####################################
36 # CR modality examples:
37 ####################################
38 ["CR-MONO1-10-chest.dcm",
40 #"Transfer Syntax UID" is absent.
43 ["Bits Stored", "10"],
44 ["Bits Allocated", "16"],
46 ["Pixel Representation", "0"],
47 ["Manufacturer", "FUJI PHOTO FILM CO. LTD."],
48 ["Manufacturer Model Name", "9000"],
49 ["7fe0|0010", "gdcm::NotLoaded. Address:776 Length:387200"] ] ],
50 ####################################
51 # CT modality examples:
52 ####################################
53 ["CT-MONO2-16-brain.dcm",
54 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE
58 ["Bits Stored", "16"],
59 ["Bits Allocated", "16"],
61 ["Pixel Representation", "1"],
62 ["Manufacturer", "Picker International, Inc."],
63 ["Manufacturer Model Name", "PQ5000"],
64 ["7fe0|0010", "gdcm::NotLoaded. Address:1680 Length:524288"] ] ],
65 ["CT-MONO2-16-ort.dcm",
66 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
70 ["Bits Stored", "16"],
71 ["Bits Allocated", "16"],
73 ["Pixel Representation", "1"],
74 ["Manufacturer", "GE MEDICAL SYSTEMS"],
75 ["Manufacturer Model Name", "HiSpeed CT/i"],
76 ["7fe0|0010", "gdcm::NotLoaded. Address:1674 Length:524288"] ] ],
77 ["CT-MONO2-16-ankle.dcm",
78 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little
82 ["Bits Stored", "16"],
83 ["Bits Allocated", "16"],
85 ["Pixel Representation", "1"],
86 ["Manufacturer", "GE MEDICAL SYSTEMS"],
87 ["Manufacturer Model Name", "GENESIS_ZEUS"],
88 ["7fe0|0010", "gdcm::NotLoaded. Address:1148 Length:524288"] ] ],
89 ["CT-MONO2-8-abdo.dcm",
90 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit, little
95 ["Bits Allocated", "8"],
97 ["Pixel Representation", "0"],
98 ["Manufacturer", "FUJI"],
99 ["7fe0|0010", "gdcm::NotLoaded. Address:796 Length:262144"] ] ],
100 ["CT-MONO2-12-lomb-an2.acr2",
101 [ ["Modality", "CT"],
102 #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
105 ["Bits Stored", "12"],
106 ["Bits Allocated", "16"],
108 ["Pixel Representation", "0"],
109 ["Manufacturer", "SIEMENS"],
110 ["7fe0|0010", "gdcm::NotLoaded. Address:1230 Length:524288"] ] ],
111 ["CT-MONO2-16-chest.dcm",
112 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg...
114 ["Photometric Interpretation", "MONOCHROME2"],
117 ["Bits Stored", "16"],
118 ["Bits Allocated", "16"],
120 ["Pixel Representation", "1"],
121 ["Manufacturer", "GE MEDICAL SYSTEMS"],
122 ["7fe0|0010", "gdcm::NotLoaded. Address:1638 Length:143498"] ] ],
123 ####################################
124 ### MR modality examples:
125 ####################################
126 ["MR-MONO2-12-angio-an1.acr1",
127 [ ["Recognition Code", "ACR-NEMA 1.0"],
129 #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
132 ["Bits Stored", "12"],
133 ["Bits Allocated", "12"],
135 ["Pixel Representation", "0"],
136 ["Manufacturer", "Philips"],
137 # Note: 256*256*12/8 = 98304
138 ["7fe0|0010", "gdcm::NotLoaded. Address:650 Length:98304"] ] ],
139 ["MR-MONO2-12-an2.acr2",
140 [ ["Modality", "MR"],
141 ["Photometric Interpretation", "MONOCHROME2"],
144 ["Bits Stored", "12"],
145 ["Bits Allocated", "16"],
147 ["Pixel Representation", "0"],
148 ["Manufacturer", "SIEMENS"],
149 ["Manufacturer Model Name", "MAGNETOM VISION"],
150 ["7fe0|0010", "gdcm::NotLoaded. Address:1866 Length:131072"] ] ],
151 ["MR-MONO2-16-head.dcm",
152 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Imp VR, LE
154 ["Photometric Interpretation", "MONOCHROME2"],
157 ["Bits Stored", "16"],
158 ["Bits Allocated", "16"],
160 ["Pixel Representation", "1"],
161 ["Manufacturer", "GE MEDICAL SYSTEMS"],
162 ["Manufacturer Model Name", "GENESIS_SIGNA"],
163 ["7fe0|0010", "gdcm::NotLoaded. Address:1804 Length:131072"] ] ],
164 # MR-MONO2-12-shoulder example is present in the Jpeg section.
165 # MR-MONO2-16-knee is not present in the test suite since it is too
166 # closely related to MR-MONO2-16-head.dcm to be of interest.
167 ####################################
168 # OT modality examples:
169 ####################################
170 # OT-MONO2-8-hip is not present in the test suite since it is too
171 # closely related to OT-MONO2-8-a7 to be of interest.
172 ["OT-PAL-8-face.dcm",
173 # Interest: has a color palette
174 [#"Transfer Syntax UID", and "Manufacturer" are absent.
176 ["Photometric Interpretation", "PALETTE COLOR"],
179 ["Bits Stored", "8"],
180 ["Bits Allocated", "8"],
182 ["Pixel Representation", "0"],
183 ["7fe0|0010", "gdcm::NotLoaded. Address:1654 Length:307200"] ] ],
184 # OT-MONO2-8-colon is not present in the test suite since it is too
185 # closely related to OT-MONO2-8-a7 to be of interest.
186 ["OT-MONO2-8-a7.dcm",
187 [#"Transfer Syntax UID" is absent.
189 ["Photometric Interpretation", "MONOCHROME2"],
192 ["Bits Stored", "8"],
193 ["Bits Allocated", "8"],
195 ["Pixel Representation", "0"],
196 ["Manufacturer", "Philips Medical Systems"],
197 ["7fe0|0010", "gdcm::NotLoaded. Address:438 Length:262144"] ] ],
198 ####################################
199 # US (Ultra Sound) modality examples:
200 ####################################
201 ["US-RGB-8-esopecho.dcm",
202 # Interest: RGB image
203 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Exp VR, LE
205 ["Photometric Interpretation", "RGB"],
208 ["Bits Stored", "8"],
209 ["Bits Allocated", "8"],
211 ["Pixel Representation", "0"],
212 ["Manufacturer", "Acme Products"],
213 # FIXME: 92160 / (120*256) = 3 bytes per pixel NOT 1. Maybe
214 # it has something to do with [Samples Per Pixel] = [3] ???
215 ["7fe0|0010", "gdcm::NotLoaded. Address:904 Length:92160"] ] ],
216 ["US-RGB-8-epicard.dcm",
217 # Interest: Big endian transfert syntax
218 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.2"], # Big endian
220 ["Photometric Interpretation", "RGB"],
223 ["Bits Stored", "8"],
224 ["Bits Allocated", "8"],
226 ["Pixel Representation", "0"],
227 ["Manufacturer", "G.E. Medical Systems"],
228 ["Manufacturer Model Name", "LOGIQ 700"],
229 # FIXME: 921600/(480*640) = 3 bytes per pixel NOT 1. Maybe
230 # it has something to do with [Samples Per Pixel] = [3] ???
231 ["Implementation Version Name", "OFFIS-DCMTK-311"],
232 ["7fe0|0010", "gdcm::NotLoaded. Address:1012 Length:921600"] ] ],
236 # The number of images is contained in the "Number of Frames" element
237 ["MR-MONO2-8-16x-heart.dcm",
238 # Interest: multi-frame
239 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
240 ["Number of Frames", "16"],
242 ["Photometric Interpretation", "MONOCHROME2"],
245 ["Bits Stored", "8"],
246 ["Bits Allocated", "8"],
248 ["Pixel Representation", "0"],
249 ["Manufacturer", "Philips"],
250 # Note: 256*256*16=1048576 (16 is the number of Frames)
251 ["7fe0|0010", "gdcm::NotLoaded. Address:920 Length:1048576"] ] ],
252 ["NM-MONO2-16-13x-heart.dcm",
253 # Interest: NM modality, multi-frame
254 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
255 ["Number of Frames", "13"],
257 ["Photometric Interpretation", "MONOCHROME2"],
260 ["Bits Stored", "16"],
261 ["Bits Allocated", "16"],
263 ["Pixel Representation", "0"],
264 ["Manufacturer", "ACME Products"],
265 # Note: 64*64*13*2=106496
266 ["7fe0|0010", "gdcm::NotLoaded. Address:1234 Length:106496"] ] ],
267 ["US-MONO2-8-8x-execho.dcm",
268 # Interest: multi-frame
269 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
270 ["Number of Frames", "8"],
272 ["Photometric Interpretation", "MONOCHROME2"],
275 ["Bits Stored", "8"],
276 ["Bits Allocated", "8"],
278 ["Pixel Representation", "0"],
279 ["Manufacturer", "Acme Products"],
280 ["7fe0|0010", "gdcm::NotLoaded. Address:976 Length:122880"] ] ],
281 ["US-PAL-8-10x-echo.dcm",
282 # Interest: RLE (Run Length Encoded) compression, multiframe
283 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.5"], # RLE
284 ["Number of Frames", "10"],
286 ["Photometric Interpretation", "PALETTE COLOR"],
289 ["Bits Stored", "8"],
290 ["Bits Allocated", "8"],
292 ["Pixel Representation", "0"],
293 ["Manufacturer", "ACME Products"],
294 ["7fe0|0010", "gdcm::NotLoaded. Address:2428 Length:481182"] ] ],
295 ["XA-MONO2-8-12x-catheter.dcm",
296 # Interest: XA modality, multi-frame
297 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg
298 ["Number of Frames", "12"], # 12 images
300 ["Photometric Interpretation", "MONOCHROME2"],
303 ["Bits Stored", "8"],
304 ["Bits Allocated", "8"],
306 ["Pixel Representation", "0"],
307 ["Manufacturer", "Acme Products"],
308 ["7fe0|0010", "gdcm::NotLoaded. Address:1006 Length:920072"] ] ],
312 ["gdcm-MR-SIEMENS-16.acr1",
313 # Interest: good old Acr-Nema Version 1, see also Oddities below
314 [ ["Recognition Code", "ACR-NEMA 1.0"],
318 ["Bits Stored", "12"],
319 ["Bits Allocated", "16"],
321 ["Pixel Representation", "0"],
322 ["Manufacturer", "SIEMENS"],
323 ["Manufacturer Model Name", "GBS III"],
324 # FIXME: this image looks padded at the end. The length of the file
325 # is 140288. Notice that, 256*256*2 + 1024 = 131072 + 1024 = 132096
326 ["7fe0|0010", "gdcm::NotLoaded. Address:8192 Length:132096"],
327 # Oddities: "Study ID" and "Series Number" are empty
329 ["Series Number", ""] ] ],
330 # Oddities: "Study" and "Serie Instance UID" are not present
331 ["gdcm-MR-SIEMENS-16.acr2",
332 # Interest: Acr-Nema Version 2
333 [ ["Recognition Code", "ACR-NEMA 2.0"],
337 ["Bits Stored", "12"],
338 ["Bits Allocated", "16"],
340 ["Pixel Representation", "0"],
341 ["Manufacturer", "SIEMENS"],
342 ["Manufacturer Model Name", "MAGNETOM VISION"],
343 ["Study Instance UID",
344 "1.3.12.2.1107.5.2.4.7630.20000918174641000"],
346 ["Series Instance UID",
347 "1.3.12.2.1107.5.2.4.7630.20000918175714000007"],
348 ["Series Number", "7"],
349 ["7fe0|0010", "gdcm::NotLoaded. Address:6052 Length:524288"] ] ],
350 ["gdcm-US-ALOKA-16.dcm",
351 # Interest: - possesses 3 LUTS: a Green (checked), a Red and BLue.
352 # - announced as implicit VR, but really explicit VR.
353 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
355 ["Photometric Interpretation", "PALETTE COLOR"],
356 ["Segmented Green Palette Color LUT Data",
357 "gdcm::NotLoaded. Address:89576 Length:113784"],
360 ["Bits Stored", "16"],
361 ["Bits Allocated", "16"],
363 ["Pixel Representation", "0"],
364 ["Manufacturer", "ALOKA CO., LTD."],
365 ["Manufacturer Model Name", "SSD-4000"],
366 ["7fe0|0010", "gdcm::NotLoaded. Address:258740 Length:614400"] ] ],
367 ["gdcm-MR-PHILIPS-16.dcm",
368 # Interest: - possesses a sequence
369 # - dicom file, with a recognition code of ACR-NEMA1
370 [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Implicit VR, LE
371 ["Recognition Code", "ACR-NEMA 1.0"],
373 ["Photometric Interpretation", "MONOCHROME2"],
376 ["Bits Stored", "8"],
377 ["Bits Allocated", "16"],
379 ["Pixel Representation", "0"],
380 ["Manufacturer", "Philips Medical Systems"],
381 ["Manufacturer Model Name", "Gyroscan Intera"],
382 ["Sequence Variant", "OTHER"],
383 ["7fe0|0010", "gdcm::NotLoaded. Address:6584 Length:131072"] ] ],
384 ["gdcm-MR-PHILIPS-16-NonRectPix.dcm",
385 # Interest: - pixels are non rectangular
386 # - private elements are in explicit VR (which is normal)
387 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE
389 ["Photometric Interpretation", "MONOCHROME2"],
392 ["Bits Stored", "12"],
393 ["Bits Allocated", "16"],
395 ["Pixel Representation", "0"],
396 ["Manufacturer", "Philips Medical Systems"],
397 ["Manufacturer Model Name", "Gyroscan Intera"],
398 ["Pixel Spacing", "0.487416\\0.194966"],
399 ["7fe0|0010", "gdcm::NotLoaded. Address:5010 Length:20480"] ] ],
400 ["gdcm-CR-DCMTK-16-NonSamplePerPix.dcm",
401 # Interest: - Misses the "Samples Per Pixel" element which prevents
402 # e-film from reading it.
403 # - Misses the Manufacturer related info
404 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # Explicit VR, LE
406 ["Photometric Interpretation", "MONOCHROME2"],
409 ["Bits Stored", "8"],
410 ["Bits Allocated", "8"],
412 ["Pixel Representation", "0"],
413 ["Implementation Version Name", "OFFIS_DCMTK_341"],
414 ["7fe0|0010", "gdcm::NotLoaded. Address:740 Length:562500"] ] ],
418 ["gdcm-JPEG-Extended.dcm",
419 # Interest: Jpeg compression [Extended (2,4)]
420 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.51"],
422 ["Photometric Interpretation", "MONOCHROME2"],
425 ["Bits Stored", "12"],
426 ["Bits Allocated", "16"],
428 ["Pixel Representation", "0"],
429 ["Manufacturer", "SIEMENS"],
430 ["Manufacturer Model Name", "Volume Zoom"],
431 ["7fe0|0010", "gdcm::NotLoaded. Address:2946 Length:192218"] ] ],
432 ["MR-MONO2-12-shoulder.dcm",
433 # Interest: Jpeg compression [Lossless, non-hierar. (14)]
434 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.57"],
436 ["Photometric Interpretation", "MONOCHROME2"],
439 ["Bits Stored", "12"],
440 ["Bits Allocated", "16"],
442 ["Pixel Representation", "0"],
443 ["Manufacturer", "Philips Medical Systems"],
444 ["Manufacturer Model Name", "Gyroscan NT"],
445 ["7fe0|0010", "gdcm::NotLoaded. Address:1580 Length:718948"] ] ],
446 ["gdcm-JPEG-LossLess3a.dcm",
447 # Interest: - Jpeg compression [Lossless, hierar., first-order
448 # pred. 14, Select. Val. 1]
449 # - contains a sequence [circa (0008,2112)]
450 # - contains additional data after the pixels ???
451 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
453 ["Photometric Interpretation", "MONOCHROME2"],
456 ["Bits Stored", "12"],
457 ["Bits Allocated", "16"],
459 ["Pixel Representation", "0"],
460 ["Manufacturer", "SIEMENS"],
461 ["Manufacturer Model Name", "Volume Zoom"] ] ],
462 # FIXME: the pixel data looks like corrupted. As stated by "od -A d -c"
463 # 0002528 à 177 020 \0 O B \0 \0 ÿ ÿ ÿ ÿ þ ÿ \0 à
464 # 0002544 \0 \0 \0 \0 þ ÿ \0 à 202 ? 003 \0 ÿ Ø ÿ Ã
465 # which we interpret as follows:
466 # - 2528: (à 177, 020 \0) = (0x7fe0, 0x0010) i.e. Pixel Data tag,
467 # - 2532: OB i.e. encapsulated encoded Pixel Data,
468 # - 2534: Two bytes reserved,
469 # - 2536: ÿ ÿ ÿ ÿ = 0xffffffff i.e. data element length is undefined.
470 # - 2540: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. basic offset table
472 # - 2544: \0 \0 \0 \0 i.e. offset table as length zero, i.e. no
473 # item value for offset table.
474 # - 2548: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. item tag of first
475 # fragment of (encoded) pixel data.
476 # - 2552: 202 ? 003 \0 = 212866 bytes i.e. length of first fragment
477 # of (encoded) pixel data.
478 # and so the next item tag should be found at the 2556+212866 th
479 # octet i.e. at address 215422. But, as stated by od, we find:
480 # 0215408 E u Ö 026 Î É 7 ¬ Ã ¸ ó ¿ ÿ Ù \f °
481 # 0215424 ¶ 016 P Ñ 002 016
482 # and (\f °, ¶ 016) is NOT an OB item TAG which is required to be
483 # present (at least there should be a sequence delimiter), refer to
484 # PS 3.5-2001 page 50.
485 ["gdcm-JPEG-LossLess3b.dcm",
486 # Interest: - Jpeg compression [Lossless, hierar., first-order
487 # pred. 14, Select. Val. 1]
488 # - encoding is sligthly different from LossLess3a.dcm ???
489 [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
491 ["Photometric Interpretation", "MONOCHROME2"],
494 ["Bits Stored", "15"],
495 ["Bits Allocated", "16"],
497 ["Pixel Representation", "0"],
498 ["Manufacturer", "Philips Medical Systems"],
499 ["Manufacturer Model Name", "Cassette Holder Type 9840 500 35201"],
500 ["7fe0|0010", "gdcm::NotLoaded. Address:3144 Length:4795668"] ] ],
503 def _BaseTest(self, FileSet):
504 for entry in FileSet:
505 fileName = os.path.join(TestFileDir, entry[0])
506 toRead = gdcm.gdcmHeader(fileName)
507 toRead.LoadElements()
508 valDict = toRead.GetPubElVal()
509 for subEntry in entry[1]:
510 element = subEntry[0]
512 self.assertEqual(valDict[element], value,
513 ("Wrong %s for file %s (got %s, shoud be %s)"
514 % (element,fileName, valDict[element], value)) )
517 gdcmTestCase._BaseTest(self, gdcmTestCase.BarreFiles)
519 def testMultiFram(self):
520 gdcmTestCase._BaseTest(self, gdcmTestCase.MultiFrameFiles)
523 gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmFiles)
526 gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmJpegFiles)
528 if __name__ == '__main__':