comparison Tests/Tests.py @ 14:ed9a9fe66002

cont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 18 Jun 2015 17:38:31 +0200
parents 7b69a561f4d3
children 2e5dbbbe3889
comparison
equal deleted inserted replaced
13:7b69a561f4d3 14:ed9a9fe66002
14 # 14 #
15 # You should have received a copy of the GNU General Public License 15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 18
19 import tempfile
19 import unittest 20 import unittest
20 21
21 from PIL import ImageChops 22 from PIL import ImageChops
22 from Toolbox import * 23 from Toolbox import *
23 from xml.dom import minidom 24 from xml.dom import minidom
28 29
29 def SetOrthancParameters(local, remote): 30 def SetOrthancParameters(local, remote):
30 global _LOCAL, _REMOTE 31 global _LOCAL, _REMOTE
31 _LOCAL = local 32 _LOCAL = local
32 _REMOTE = remote 33 _REMOTE = remote
34
35
36 def ExtractDicomTags(rawDicom, tags):
37 with tempfile.NamedTemporaryFile(delete = True) as f:
38 f.write(rawDicom)
39 f.flush()
40 data = subprocess.check_output([ 'dcm2xml', f.name ])
41
42 result = []
43 for tag in tags:
44 match = re.search('<element[^>]+name="%s">([^>]*)</element>' % tag, data)
45 if match == None:
46 result.append('')
47 else:
48 result.append(match.group(1))
49
50 return result
33 51
34 52
35 class Orthanc(unittest.TestCase): 53 class Orthanc(unittest.TestCase):
36 def setUp(self): 54 def setUp(self):
37 DropOrthanc(_LOCAL) 55 DropOrthanc(_LOCAL)
1311 1329
1312 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Series', 1330 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Series',
1313 'CaseSensitive' : True, 1331 'CaseSensitive' : True,
1314 'Query' : { 'StationName' : 'SMR4-MP3' }}) 1332 'Query' : { 'StationName' : 'SMR4-MP3' }})
1315 self.assertEqual(1, len(a)) 1333 self.assertEqual(1, len(a))
1334
1335
1336 def test_rest_find(self):
1337 # Upload 8 instances
1338 for i in range(2):
1339 UploadInstance(_REMOTE, 'Brainix/Flair/IM-0001-000%d.dcm' % (i + 1))
1340 UploadInstance(_REMOTE, 'Brainix/Epi/IM-0001-000%d.dcm' % (i + 1))
1341 UploadInstance(_REMOTE, 'Knee/T1/IM-0001-000%d.dcm' % (i + 1))
1342 UploadInstance(_REMOTE, 'Knee/T2/IM-0001-000%d.dcm' % (i + 1))
1343
1344 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Patient',
1345 'CaseSensitive' : False,
1346 'Query' : { 'PatientName' : '*n*' }})
1347 self.assertEqual(2, len(a))
1348
1349 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Patient',
1350 'CaseSensitive' : True,
1351 'Query' : { 'PatientName' : '*n*' }})
1352 self.assertEqual(0, len(a))
1353
1354 a = DoPost(_REMOTE, '/tools/find', { 'Expand' : True,
1355 'Level' : 'Patient',
1356 'CaseSensitive' : False,
1357 'Query' : { 'PatientName' : '*ne*' }})
1358 self.assertEqual(1, len(a))
1359 self.assertEqual('20080822', a[0]['MainDicomTags']['PatientBirthDate'])
1360
1361 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Patient',
1362 'CaseSensitive' : True,
1363 'Query' : { 'PatientName' : '*ne*' }})
1364 self.assertEqual(0, len(a))
1365
1366 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Study',
1367 'CaseSensitive' : True,
1368 'Query' : { 'PatientName' : '*NE*' }})
1369 self.assertEqual(1, len(a))
1370
1371 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Series',
1372 'CaseSensitive' : True,
1373 'Query' : { 'PatientName' : '*NE*' }})
1374 self.assertEqual(2, len(a))
1375
1376 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Instance',
1377 'CaseSensitive' : True,
1378 'Query' : { 'PatientName' : '*NE*' }})
1379 self.assertEqual(4, len(a))
1380
1381 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Patient', 'Query' : { }})
1382 self.assertEqual(2, len(a))
1383
1384 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Study', 'Query' : { }})
1385 self.assertEqual(2, len(a))
1386
1387 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Series', 'Query' : { }})
1388 self.assertEqual(4, len(a))
1389
1390 a = DoPost(_REMOTE, '/tools/find', { 'Level' : 'Instance', 'Query' : { }})
1391 self.assertEqual(8, len(a))
1392
1393
1394 def test_rest_query_retrieve(self):
1395 self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
1396
1397 # Upload 8 instances
1398 for i in range(2):
1399 UploadInstance(_REMOTE, 'Brainix/Flair/IM-0001-000%d.dcm' % (i + 1))
1400 UploadInstance(_REMOTE, 'Brainix/Epi/IM-0001-000%d.dcm' % (i + 1))
1401 UploadInstance(_REMOTE, 'Knee/T1/IM-0001-000%d.dcm' % (i + 1))
1402 UploadInstance(_REMOTE, 'Knee/T2/IM-0001-000%d.dcm' % (i + 1))
1403
1404 self.assertEqual(2, len(DoGet(_REMOTE, '/patients')))
1405 for p in DoGet(_REMOTE, '/patients'):
1406 DoPost(_REMOTE, '/modalities/orthanctest/store', p)
1407 DoDelete(_REMOTE, '/patients/%s' % p)
1408
1409 for q in DoGet(_REMOTE, '/queries'):
1410 DoDelete(_REMOTE, '/queries/%s' % q)
1411
1412 self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
1413 self.assertEqual(0, len(DoGet(_REMOTE, '/queries')))
1414 a = DoPost(_REMOTE, '/modalities/orthanctest/query', { 'Level' : 'Series',
1415 'Query' : { 'PatientName' : '*NE*' }})['ID']
1416 self.assertEqual(1, len(DoGet(_REMOTE, '/queries')))
1417
1418 b = DoGet(_REMOTE, '/queries/%s' % a)
1419 self.assertTrue('answers' in b)
1420 self.assertTrue('level' in b)
1421 self.assertTrue('modality' in b)
1422 self.assertTrue('query' in b)
1423 self.assertTrue('retrieve' in b)
1424 self.assertEqual('Series', DoGet(_REMOTE, '/queries/%s/level' % a))
1425 self.assertEqual('orthanctest', DoGet(_REMOTE, '/queries/%s/modality' % a))
1426
1427 q = DoGet(_REMOTE, '/queries/%s/query?simplify' % a)
1428 self.assertEqual(1, len(q))
1429 self.assertTrue('PatientName' in q)
1430 self.assertEqual('*NE*', q['PatientName'])
1431
1432 self.assertEqual(2, len(DoGet(_REMOTE, '/queries/%s/answers' % a)))
1433
1434 s = DoGet(_REMOTE, '/queries/%s/answers/0' % a)
1435 self.assertTrue('content' in s)
1436 self.assertTrue('retrieve' in s)
1437
1438 s = DoGet(_REMOTE, '/queries/%s/answers/0/content?simplify' % a)
1439 self.assertEqual('887', s['PatientID'])
1440 self.assertEqual('2.16.840.1.113669.632.20.121711.10000160881', s['StudyInstanceUID'])
1441
1442 self.assertEqual(0, len(DoGet(_REMOTE, '/patients')))
1443 DoPost(_REMOTE, '/queries/%s/answers/0/retrieve' % a, 'ORTHANC')
1444 self.assertEqual(1, len(DoGet(_REMOTE, '/patients')))
1445 self.assertEqual(1, len(DoGet(_REMOTE, '/studies')))
1446 self.assertEqual(1, len(DoGet(_REMOTE, '/series')))
1447 self.assertEqual(2, len(DoGet(_REMOTE, '/instances')))
1448
1449 DoPost(_REMOTE, '/queries/%s/answers/1/retrieve' % a, 'ORTHANC')
1450 self.assertEqual(1, len(DoGet(_REMOTE, '/patients')))
1451 self.assertEqual(1, len(DoGet(_REMOTE, '/studies')))
1452 self.assertEqual(2, len(DoGet(_REMOTE, '/series')))
1453 self.assertEqual(4, len(DoGet(_REMOTE, '/instances')))
1454
1455 DoDelete(_REMOTE, '/queries/%s' % a)
1456 self.assertEqual(0, len(DoGet(_REMOTE, '/queries')))
1457
1458
1459 def test_parent(self):
1460 u = UploadInstance(_REMOTE, 'DummyCT.dcm')['ID']
1461 patient = '6816cb19-844d5aee-85245eba-28e841e6-2414fae2'
1462 study = 'b9c08539-26f93bde-c81ab0d7-bffaf2cb-a4d0bdd0'
1463 series = 'f2635388-f01d497a-15f7c06b-ad7dba06-c4c599fe'
1464 instance = '66a662ce-7430e543-bad44d47-0dc5a943-ec7a538d'
1465 self.assertEqual(instance, u);
1466
1467 a = DoGet(_REMOTE, '/studies/%s/patient' % study)
1468 self.assertEqual('Patient', a['Type'])
1469 self.assertEqual(patient, a['ID'])
1470
1471 a = DoGet(_REMOTE, '/series/%s/patient' % series)
1472 self.assertEqual('Patient', a['Type'])
1473 self.assertEqual(patient, a['ID'])
1474
1475 a = DoGet(_REMOTE, '/series/%s/study' % series)
1476 self.assertEqual('Study', a['Type'])
1477 self.assertEqual(study, a['ID'])
1478
1479 a = DoGet(_REMOTE, '/instances/%s/patient' % instance)
1480 self.assertEqual('Patient', a['Type'])
1481 self.assertEqual(patient, a['ID'])
1482
1483 a = DoGet(_REMOTE, '/instances/%s/study' % instance)
1484 self.assertEqual('Study', a['Type'])
1485 self.assertEqual(study, a['ID'])
1486
1487 a = DoGet(_REMOTE, '/instances/%s/series' % instance)
1488 self.assertEqual('Series', a['Type'])
1489 self.assertEqual(series, a['ID'])
1490
1491
1492 def test_shanon(self):
1493 def Anonymize(instance, replacements = {}):
1494 return DoPost(_REMOTE, '/instances/%s/anonymize' % instance, { 'Replace' : replacements }, 'application/json')
1495
1496 self.assertEqual(0, len(DoGet(_REMOTE, '/instances')))
1497 u = UploadInstance(_REMOTE, 'DummyCT.dcm')['ID']
1498 self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
1499
1500 tags = [ 'PatientID', 'StudyInstanceUID', 'SeriesInstanceUID', 'SOPInstanceUID', 'DeidentificationMethod' ]
1501 ids = [ 'ozp00SjY2xG',
1502 '1.2.840.113619.2.176.2025.1499492.7391.1171285944.390',
1503 '1.2.840.113619.2.176.2025.1499492.7391.1171285944.394',
1504 '1.2.840.113619.2.176.2025.1499492.7040.1171286242.109' ]
1505
1506 a = ExtractDicomTags(Anonymize(u), tags)
1507 for i in range(4):
1508 self.assertNotEqual(ids[i], a[i])
1509 self.assertTrue(a[4].startswith('Orthanc'))
1510
1511 a = ExtractDicomTags(Anonymize(u, { 'PatientName' : 'toto' }), tags)
1512 for i in range(4):
1513 self.assertNotEqual(ids[i], a[i])
1514 self.assertFalse(a[4].startswith('Orthanc'))
1515
1516 a = ExtractDicomTags(Anonymize(u, { 'SOPInstanceUID' : 'instance' }), tags)
1517 self.assertEqual('instance', a[3])
1518 self.assertFalse(a[4].startswith('Orthanc'))
1519
1520 a = ExtractDicomTags(Anonymize(u, { 'SeriesInstanceUID' : 'series' }), tags)
1521 self.assertEqual('series', a[2])
1522 self.assertFalse(a[4].startswith('Orthanc'))
1523
1524 a = ExtractDicomTags(Anonymize(u, { 'StudyInstanceUID' : 'study' }), tags)
1525 self.assertEqual('study', a[1])
1526 self.assertFalse(a[4].startswith('Orthanc'))
1527
1528 a = ExtractDicomTags(Anonymize(u, { 'PatientID' : 'patient' }), tags)
1529 self.assertEqual('patient', a[0])
1530 self.assertFalse(a[4].startswith('Orthanc'))
1531
1532 a = ExtractDicomTags(Anonymize(u, { 'PatientID' : 'patient',
1533 'StudyInstanceUID' : 'study',
1534 'SeriesInstanceUID' : 'series',
1535 'SOPInstanceUID' : 'instance' }), tags)
1536 self.assertEqual('patient', a[0])
1537 self.assertFalse(a[4].startswith('Orthanc'))
1538
1539 self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
1540
1541
1542 def test_shanon_2(self):
1543 def Modify(instance, replacements = {}):
1544 return DoPost(_REMOTE, '/instances/%s/modify' % instance, { 'Replace' : replacements }, 'application/json')
1545
1546 self.assertEqual(0, len(DoGet(_REMOTE, '/instances')))
1547 u = UploadInstance(_REMOTE, 'DummyCT.dcm')['ID']
1548 self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
1549
1550 tags = [ 'PatientID', 'StudyInstanceUID', 'SeriesInstanceUID', 'SOPInstanceUID', 'DeidentificationMethod' ]
1551 ids = [ 'ozp00SjY2xG',
1552 '1.2.840.113619.2.176.2025.1499492.7391.1171285944.390',
1553 '1.2.840.113619.2.176.2025.1499492.7391.1171285944.394',
1554 '1.2.840.113619.2.176.2025.1499492.7040.1171286242.109' ]
1555
1556 a = ExtractDicomTags(Modify(u), tags)
1557 self.assertEqual(ids[0], a[0])
1558 self.assertEqual(ids[1], a[1])
1559 self.assertEqual(ids[2], a[2])
1560 self.assertNotEqual(ids[3], a[3])
1561 self.assertEqual(0, len(a[4]))
1562
1563 a = ExtractDicomTags(Modify(u, { 'SOPInstanceUID' : 'instance' }), tags)
1564 self.assertEqual(ids[0], a[0])
1565 self.assertEqual(ids[1], a[1])
1566 self.assertEqual(ids[2], a[2])
1567 self.assertEqual('instance', a[3])
1568
1569 a = ExtractDicomTags(Modify(u, { 'SeriesInstanceUID' : 'series' }), tags)
1570 self.assertEqual(ids[0], a[0])
1571 self.assertEqual(ids[1], a[1])
1572 self.assertEqual('series', a[2])
1573 self.assertNotEqual(ids[3], a[3])
1574
1575 a = ExtractDicomTags(Modify(u, { 'StudyInstanceUID' : 'study' }), tags)
1576 self.assertEqual(ids[0], a[0])
1577 self.assertEqual('study', a[1])
1578 self.assertNotEqual(ids[2], a[2])
1579 self.assertNotEqual(ids[3], a[3])
1580
1581 a = ExtractDicomTags(Modify(u, { 'PatientID' : 'patient' }), tags)
1582 self.assertEqual('patient', a[0])
1583 self.assertNotEqual(ids[1], a[1])
1584 self.assertNotEqual(ids[2], a[2])
1585 self.assertNotEqual(ids[3], a[3])
1586
1587 a = ExtractDicomTags(Modify(u, { 'PatientID' : 'patient',
1588 'StudyInstanceUID' : 'study',
1589 'SeriesInstanceUID' : 'series',
1590 'SOPInstanceUID' : 'instance' }), tags)
1591 self.assertEqual('patient', a[0])
1592 self.assertEqual('study', a[1])
1593 self.assertEqual('series', a[2])
1594 self.assertEqual('instance', a[3])
1595
1596 self.assertEqual(1, len(DoGet(_REMOTE, '/instances')))
1597
1598
1599 def test_instances_tags(self):
1600 a = UploadInstance(_REMOTE, 'Knee/T1/IM-0001-0001.dcm')['ID']
1601 b = UploadInstance(_REMOTE, 'Knee/T2/IM-0001-0001.dcm')['ID']
1602 #a = UploadInstance(_REMOTE, 'Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386937.676343')['ID']
1603 #b = UploadInstance(_REMOTE, 'Cardiac/MR.X.1.2.276.0.7230010.3.1.4.2831157719.2256.1336386925.676329')['ID']
1604
1605 i = DoGet(_REMOTE, '/patients/%s/instances-tags?simplify' % DoGet(_REMOTE, '/patients')[0])
1606 self.assertEqual(2, len(i))
1607 self.assertEqual('887', i[i.keys()[0]]['PatientID'])
1608 self.assertEqual('887', i[i.keys()[1]]['PatientID'])
1609
1610 i = DoGet(_REMOTE, '/patients/%s/instances-tags?simplify' % DoGet(_REMOTE, '/studies')[0])
1611 self.assertEqual(2, len(i))
1612 self.assertEqual('887', i[i.keys()[0]]['PatientID'])
1613 self.assertEqual('887', i[i.keys()[1]]['PatientID'])
1614
1615 self.assertEqual(2, len(DoGet(_REMOTE, '/series')))
1616 i = DoGet(_REMOTE, '/patients/%s/instances-tags?simplify' % DoGet(_REMOTE, '/series')[0])
1617 self.assertEqual(1, len(i))
1618 self.assertEqual('887', i[i.keys()[0]]['PatientID'])
1619
1620 i = DoGet(_REMOTE, '/patients/%s/instances-tags?simplify' % DoGet(_REMOTE, '/series')[1])
1621 self.assertEqual(1, len(i))
1622 self.assertEqual('887', i[i.keys()[0]]['PatientID'])
1623
1624
1625 def test_lookup(self):
1626 a = DoPost(_REMOTE, '/tools/lookup', 'ozp00SjY2xG')
1627 self.assertEqual(0, len(a))
1628
1629 UploadInstance(_REMOTE, 'DummyCT.dcm')
1630
1631 a = DoPost(_REMOTE, '/tools/lookup', 'ozp00SjY2xG')
1632 self.assertEqual(1, len(a))
1633 self.assertEqual('Patient', a[0]['Type'])
1634 self.assertEqual('6816cb19-844d5aee-85245eba-28e841e6-2414fae2', a[0]['ID'])
1635 self.assertEqual('/patients/%s' % a[0]['ID'], a[0]['Path'])
1636
1637 a = DoPost(_REMOTE, '/tools/lookup', '1.2.840.113619.2.176.2025.1499492.7391.1171285944.390')
1638 self.assertEqual(1, len(a))
1639 self.assertEqual('Study', a[0]['Type'])
1640 self.assertEqual('b9c08539-26f93bde-c81ab0d7-bffaf2cb-a4d0bdd0', a[0]['ID'])
1641 self.assertEqual('/studies/%s' % a[0]['ID'], a[0]['Path'])
1642
1643 a = DoPost(_REMOTE, '/tools/lookup', '1.2.840.113619.2.176.2025.1499492.7391.1171285944.394')
1644 self.assertEqual(1, len(a))
1645 self.assertEqual('Series', a[0]['Type'])
1646 self.assertEqual('f2635388-f01d497a-15f7c06b-ad7dba06-c4c599fe', a[0]['ID'])
1647 self.assertEqual('/series/%s' % a[0]['ID'], a[0]['Path'])
1648
1649 a = DoPost(_REMOTE, '/tools/lookup', '1.2.840.113619.2.176.2025.1499492.7040.1171286242.109')
1650 self.assertEqual(1, len(a))
1651 self.assertEqual('Instance', a[0]['Type'])
1652 self.assertEqual('66a662ce-7430e543-bad44d47-0dc5a943-ec7a538d', a[0]['ID'])
1653 self.assertEqual('/instances/%s' % a[0]['ID'], a[0]['Path'])
1654
1655 DropOrthanc(_REMOTE)
1656 a = DoPost(_REMOTE, '/tools/lookup', '3113719P')
1657 self.assertEqual(0, len(a))
1658