comparison Resources/Samples/Python/AutoClassify.py @ 1183:6ef2c81581cd

more fault-tolerant sample
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 10 Oct 2014 08:52:56 +0200
parents d74ac5d0bcaf
children 4e9d517503ae
comparison
equal deleted inserted replaced
1182:d74ac5d0bcaf 1183:6ef2c81581cd
41 parser.add_argument('--remove', action = 'store_true', 41 parser.add_argument('--remove', action = 'store_true',
42 help = 'Remove DICOM files from Orthanc once classified (disabled by default)') 42 help = 'Remove DICOM files from Orthanc once classified (disabled by default)')
43 parser.set_defaults(remove = False) 43 parser.set_defaults(remove = False)
44 44
45 45
46 def FixPath(p):
47 return p.encode('ascii', 'ignore').strip()
48
49 def GetTag(resource, tag):
50 if ('MainDicomTags' in resource and
51 tag in resource['MainDicomTags']):
52 return resource['MainDicomTags'][tag]
53 else:
54 return 'No' + tag
55
56 def ClassifyInstance(instanceId):
57 # Extract the patient, study, series and instance information
58 instance = RestToolbox.DoGet('%s/instances/%s' % (URL, instanceId))
59 series = RestToolbox.DoGet('%s/series/%s' % (URL, instance['ParentSeries']))
60 study = RestToolbox.DoGet('%s/studies/%s' % (URL, series['ParentStudy']))
61 patient = RestToolbox.DoGet('%s/patients/%s' % (URL, study['ParentPatient']))
62
63 # Construct a target path
64 a = '%s - %s' % (GetTag(patient, 'PatientID'),
65 GetTag(patient, 'PatientName'))
66 b = GetTag(study, 'StudyDescription')
67 c = '%s - %s' % (GetTag(series, 'Modality'),
68 GetTag(series, 'SeriesDescription'))
69 d = '%s.dcm' % GetTag(instance, 'SOPInstanceUID')
70
71 p = os.path.join(args.target, FixPath(a), FixPath(b), FixPath(c))
72 f = os.path.join(p, FixPath(d))
73
74 # Copy the DICOM file to the target path
75 print('Writing new DICOM file: %s' % f)
76
77 try:
78 os.makedirs(p)
79 except:
80 # Already existing directory, ignore the error
81 pass
82
83 dcm = RestToolbox.DoGet('%s/instances/%s/file' % (URL, instanceId))
84 with open(f, 'wb') as g:
85 g.write(dcm)
86
87
46 # Parse the arguments 88 # Parse the arguments
47 args = parser.parse_args() 89 args = parser.parse_args()
48 URL = 'http://%s:%d' % (args.host, args.port) 90 URL = 'http://%s:%d' % (args.host, args.port)
49 print 'Connecting to Orthanc on address: %s' % URL 91 print('Connecting to Orthanc on address: %s' % URL)
50 92
51 # Compute the starting point for the changes loop 93 # Compute the starting point for the changes loop
52 if args.all: 94 if args.all:
53 current = 0 95 current = 0
54 else: 96 else:
55 current = RestToolbox.DoGet(URL + '/changes?last')['Last'] 97 current = RestToolbox.DoGet(URL + '/changes?last')['Last']
56 98
57 # Polling loop using the "changes" API of Orthanc, waiting for the 99 # Polling loop using the 'changes' API of Orthanc, waiting for the
58 # incoming of new DICOM files 100 # incoming of new DICOM files
59 while True: 101 while True:
60 r = RestToolbox.DoGet(URL + '/changes', { 102 r = RestToolbox.DoGet(URL + '/changes', {
61 'since' : current, 103 'since' : current,
62 'limit' : 4 # Retrieve at most 4 changes at once 104 'limit' : 4 # Retrieve at most 4 changes at once
63 }) 105 })
64 106
65 for change in r['Changes']: 107 for change in r['Changes']:
66 # We are only interested interested in the arrival of new instances 108 # We are only interested interested in the arrival of new instances
67 if change['ChangeType'] == 'NewInstance': 109 if change['ChangeType'] == 'NewInstance':
68 # Extract the patient, study, series and instance information 110 try:
69 instance = RestToolbox.DoGet('%s/instances/%s' % (URL, change['ID'])) 111 ClassifyInstance(change['ID'])
70 series = RestToolbox.DoGet('%s/series/%s' % (URL, instance['ParentSeries'])) 112 except:
71 study = RestToolbox.DoGet('%s/studies/%s' % (URL, series['ParentStudy'])) 113 print('Unable to write instance %s to the disk' % change['ID'])
72 patient = RestToolbox.DoGet('%s/patients/%s' % (URL, study['ParentPatient']))
73 114
74 # Construct a target path
75 a = '%s - %s' % (patient['MainDicomTags']['PatientID'],
76 patient['MainDicomTags']['PatientName'])
77 b = study['MainDicomTags']['StudyDescription']
78 c = '%s - %s' % (series['MainDicomTags']['Modality'],
79 series['MainDicomTags']['SeriesDescription'])
80 d = '%s.dcm' % instance['MainDicomTags']['SOPInstanceUID']
81
82 p = os.path.join(
83 args.target,
84 a.encode('ascii', 'ignore'),
85 b.encode('ascii', 'ignore'),
86 c.encode('ascii', 'ignore')
87 )
88
89 f = os.path.join(p, d.encode('ascii', 'ignore'))
90
91
92 # Copy the DICOM file to the target path
93 print('Writing new DICOM file: %s' % f)
94
95 try:
96 os.makedirs(p)
97 except:
98 # Already existing directory, ignore the error
99 pass
100
101 dcm = RestToolbox.DoGet('%s/instances/%s/file' % (URL, change['ID']))
102 with open(f, 'wb') as g:
103 g.write(dcm)
104
105 # If requested, remove the instance once it has been copied 115 # If requested, remove the instance once it has been copied
106 if args.remove: 116 if args.remove:
107 RestToolbox.DoDelete('%s/instances/%s' % (URL, change['ID'])) 117 RestToolbox.DoDelete('%s/instances/%s' % (URL, change['ID']))
108 118
109 current = r['Last'] 119 current = r['Last']
110 120
111 if r['Done']: 121 if r['Done']:
112 print "Everything has been processed: Waiting..." 122 print('Everything has been processed: Waiting...')
113 time.sleep(1) 123 time.sleep(1)