Mercurial > hg > orthanc
diff OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | Resources/Samples/Python/HighPerformanceAutoRouting.py@94f4a18a79cc |
children | d9473bd5ed43 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/Resources/Samples/Python/HighPerformanceAutoRouting.py Wed Jun 10 20:30:34 2020 +0200 @@ -0,0 +1,163 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Orthanc - A Lightweight, RESTful DICOM Store +# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics +# Department, University Hospital of Liege, Belgium +# Copyright (C) 2017-2020 Osimis S.A., Belgium +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + + +URL = 'http://127.0.0.1:8042' +TARGET = 'sample' + + +# +# This sample code shows how to setup a simple, high-performance DICOM +# auto-routing. All the DICOM instances that arrive inside Orthanc +# will be sent to a remote modality. A producer-consumer pattern is +# used. The target modality is specified by the TARGET variable above: +# It must match an entry in the Orthanc configuration file inside the +# "DicomModalities" section. +# +# NOTE: This sample only works with Orthanc >= 0.5.2. Make sure that +# Orthanc was built with "-DCMAKE_BUILD_TYPE=Release" to get the best +# performance. +# + +import Queue +import sys +import time +import threading + +import RestToolbox + + +# +# Queue that is shared between the producer and the consumer +# threads. It holds the instances that are still to be sent. +# + +queue = Queue.Queue() + + +# +# The producer thread. It monitors the arrival of new instances into +# Orthanc, and pushes their ID into the shared queue. This code is +# based upon the "ChangesLoop.py" sample code. +# + +def Producer(queue): + current = 0 + + while True: + r = RestToolbox.DoGet(URL + '/changes', { + 'since' : current, + 'limit' : 4 # Retrieve at most 4 changes at once + }) + + for change in r['Changes']: + # We are only interested in the arrival of new instances + if change['ChangeType'] == 'NewInstance': + queue.put(change['ID']) + + current = r['Last'] + + if r['Done']: + time.sleep(1) + + +# +# The consumer thread. It continuously reads the instances from the +# queue, and send them to the remote modality. Each time a packet of +# instances is sent, a single DICOM connexion is used, hence improving +# the performance. +# + +def Consumer(queue): + TIMEOUT = 0.1 + + while True: + instances = [] + + while True: + try: + # Block for a while, waiting for the arrival of a new + # instance + instance = queue.get(True, TIMEOUT) + + # A new instance has arrived: Record its ID + instances.append(instance) + queue.task_done() + + except Queue.Empty: + # Timeout: No more data was received + break + + if len(instances) > 0: + print('Sending a packet of %d instances' % len(instances)) + start = time.time() + + # Send all the instances with a single DICOM connexion + RestToolbox.DoPost('%s/modalities/sample/store' % URL, instances) + + # Remove all the instances from Orthanc + for instance in instances: + RestToolbox.DoDelete('%s/instances/%s' % (URL, instance)) + + # Clear the log of the exported instances (to prevent the + # SQLite database from growing indefinitely). More simply, + # you could also set the "LogExportedResources" option to + # "false" in the configuration file since Orthanc 0.8.3. + RestToolbox.DoDelete('%s/exports' % URL) + + end = time.time() + print('The packet of %d instances has been sent in %d seconds' % (len(instances), end - start)) + + +# +# Thread to display the progress +# + +def PrintProgress(queue): + while True: + print('Current queue size: %d' % (queue.qsize())) + time.sleep(1) + + +# +# Start the various threads +# + +progress = threading.Thread(None, PrintProgress, None, (queue, )) +progress.daemon = True +progress.start() + +producer = threading.Thread(None, Producer, None, (queue, )) +producer.daemon = True +producer.start() + +consumer = threading.Thread(None, Consumer, None, (queue, )) +consumer.daemon = True +consumer.start() + + +# +# Active waiting for Ctrl-C +# + +while True: + time.sleep(0.1)