Mercurial > hg > orthanc
annotate Resources/Samples/Python/HighPerformanceAutoRouting.py @ 445:7816aaa5db17
merge
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 17 May 2013 17:32:16 +0200 |
parents | 47d63c941902 |
children | 44382c8bcd15 |
rev | line source |
---|---|
404 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 | |
5 URL = 'http://localhost:8042' | |
6 TARGET = 'sample' | |
7 | |
8 | |
9 # | |
10 # This sample code shows how to setup a simple, high-performance DICOM | |
11 # auto-routing. All the DICOM instances that arrive inside Orthanc | |
12 # will be sent to a remote modality. A producer-consumer pattern is | |
13 # used. The target modality is specified by the TARGET variable above: | |
14 # It must match an entry in the Orthanc configuration file inside the | |
15 # "DicomModalities" section. | |
16 # | |
17 # NOTE: This sample only works with Orthanc >= 0.5.2. Make sure that | |
18 # Orthanc was built with "-DCMAKE_BUILD_TYPE=Release" to get the best | |
19 # performance. | |
20 # | |
21 | |
22 import Queue | |
23 import sys | |
24 import time | |
25 import threading | |
26 | |
27 import RestToolbox | |
28 | |
29 | |
30 # | |
31 # Queue that is shared between the producer and the consumer | |
32 # threads. It holds the instances that are still to be sent. | |
33 # | |
34 | |
35 queue = Queue.Queue() | |
36 | |
37 | |
38 # | |
39 # The producer thread. It monitors the arrival of new instances into | |
40 # Orthanc, and pushes their ID into the shared queue. This code is | |
41 # based upon the "ChangesLoop.py" sample code. | |
42 # | |
43 | |
44 def Producer(queue): | |
45 current = 0 | |
46 | |
47 while True: | |
48 r = RestToolbox.DoGet(URL + '/changes', { | |
49 'since' : current, | |
50 'limit' : 4 # Retrieve at most 4 changes at once | |
51 }) | |
52 | |
53 for change in r['Changes']: | |
54 # We are only interested interested in the arrival of new instances | |
55 if change['ChangeType'] == 'NewInstance': | |
56 queue.put(change['ID']) | |
57 | |
58 current = r['Last'] | |
59 | |
60 if r['Done']: | |
61 time.sleep(1) | |
62 | |
63 | |
64 # | |
65 # The consumer thread. It continuously reads the instances from the | |
66 # queue, and send them to the remote modality. Each time a packet of | |
67 # instances is sent, a single DICOM connexion is used, hence improving | |
68 # the performance. | |
69 # | |
70 | |
71 def Consumer(queue): | |
72 TIMEOUT = 0.1 | |
73 | |
74 while True: | |
75 instances = [] | |
76 | |
77 while True: | |
78 try: | |
79 # Block for a while, waiting for the arrival of a new | |
80 # instance | |
81 instance = queue.get(True, TIMEOUT) | |
82 | |
83 # A new instance has arrived: Record its ID | |
84 instances.append(instance) | |
85 queue.task_done() | |
86 | |
87 except Queue.Empty: | |
88 # Timeout: No more data was received | |
89 break | |
90 | |
91 if len(instances) > 0: | |
92 print 'Sending a packet of %d instances' % len(instances) | |
93 start = time.time() | |
94 | |
95 # Send all the instances with a single DICOM connexion | |
96 RestToolbox.DoPost('%s/modalities/sample/store' % URL, instances) | |
97 | |
98 # Remove all the instances from Orthanc | |
99 for instance in instances: | |
100 RestToolbox.DoDelete('%s/instances/%s' % (URL, instance)) | |
101 | |
413
47d63c941902
clearing /exports and /changes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
404
diff
changeset
|
102 # Clear the log of the exported instances (to prevent the |
47d63c941902
clearing /exports and /changes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
404
diff
changeset
|
103 # SQLite database from growing indefinitely) |
47d63c941902
clearing /exports and /changes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
404
diff
changeset
|
104 RestToolbox.DoDelete('%s/exports' % URL) |
47d63c941902
clearing /exports and /changes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
404
diff
changeset
|
105 |
404 | 106 end = time.time() |
107 print 'The packet of %d instances has been sent in %d seconds' % (len(instances), end - start) | |
108 | |
109 | |
110 # | |
111 # Thread to display the progress | |
112 # | |
113 | |
114 def PrintProgress(queue): | |
115 while True: | |
116 print 'Current queue size: %d' % (queue.qsize()) | |
117 time.sleep(1) | |
118 | |
119 | |
120 # | |
121 # Start the various threads | |
122 # | |
123 | |
124 progress = threading.Thread(None, PrintProgress, None, (queue, )) | |
125 progress.daemon = True | |
126 progress.start() | |
127 | |
128 producer = threading.Thread(None, Producer, None, (queue, )) | |
129 producer.daemon = True | |
130 producer.start() | |
131 | |
132 consumer = threading.Thread(None, Consumer, None, (queue, )) | |
133 consumer.daemon = True | |
134 consumer.start() | |
135 | |
136 | |
137 # | |
138 # Active waiting for Ctrl-C | |
139 # | |
140 | |
141 while True: | |
142 time.sleep(0.1) |