Experiment with Orthanc

Issue #635 resolved
Ed McDonagh created an issue

Look at Orthanc as an alternative DICOM store server.

0.8.0 docs need a robust set of instructions for the store server, and Conquest is proving to be more difficult to install than I had realised.

Comments (93)

  1. Ed McDonagh reporter

    @dplatten - I think Orthanc would be an easy enough install to Linux. The script I have written would need the temp location to be factored out and the logic regarding which objects to launch with which script and which ones to delete needs to be added, but it all looks very doable.

    I see that the binaries for Windows require filling in a form and having the prospect of the commercial backer contacting you. Does that present an issue? Or is it fairly painless?

    By the way, I tried using the path to the virtualenv python in that script and it works as I'd hoped.

    There was an initial issue with my orthanc install, but it was due to an issue it had with the DCMTK private dictionary - I don't know yet if that was specific to my install or a more generic problem. I can work around it in the docs if necessary.

  2. David Platten

    I haven't tried installing it yet. I have downloaded the Windows binaries, and that was painless enough.

    Perhaps this should wait until the next release of OpenREM. Have you managed to iron out the issues with Conquest installation on Linux? I haven't tried the latest version of the Windows release yet.

  3. Ed McDonagh reporter

    Not entirely. Part of the problem is that if you aren't using the Ubuntu 16.04 packaged version of Conquest, the install requires the software to be built from source and folders are created all over the place. It is generally automated, but prompts for sudo to give itself permissions which is bad practice for something downloaded off the internet! I don't like to encourage such activity! You then need to add some scripts to get it started automatically, which means more documentation to write.

    I would really like to say 'yes', leave this to the next release. But we need docs that work for this release. So I need to either write them for Conquest, aware that it is messy and the current release is broken for linux so needs to be patched (or delay the release further to wait for the patch to be incorporated), or we offer basic instructions for Conquest or for Orthanc and let the user decide. Another problem I guess is that we haven't actually used Orthanc in anger.

  4. Ed McDonagh reporter

    Now drops any non SR/CT/MG/CR/DX modality objects, and processes what's left against the appropriate import script. Doesn't cater for Toshiba CT. Refs #635

    → <<cset 6c2a0a996f95>>

  5. Ed McDonagh reporter

    Links for sorting out the Toshiba bit:

    From this question: https://groups.google.com/forum/m/#!topic/orthanc-users/hUEt93SPUfM

    This is a python script that I think is run manually against the Orthanc server to copy it's contents to disk: https://bitbucket.org/sjodogne/orthanc/src/default/Resources/Samples/Python/AutoClassify.py?fileviewer=file-view-default

    And this is a lua function that does it when the series is stable: https://bitbucket.org/sjodogne/orthanc/src/b97aa579e85bc57652d5ac8a2e45ce77a1e203d7/Resources/Samples/Lua/WriteToDisk.lua?at=default&fileviewer=file-view-default

    Problem with the second one is the platform specific call to make directory.

  6. David Platten

    @edmcdonagh, in your openrem.lua script, what folder should openrem_exe_path point to on my Windows system (running OpenREM in a virtualenv)?

  7. David Platten

    I've answered my own question: it's the folder that contains the import scripts. For me, this is the same folder that the virtualenv python.exe is in.

  8. Ed McDonagh reporter

    Likewise for me. But I thought it wouldn't hurt to have both! And partly because I'd already decided to have the full path to python as a variable.

  9. David Platten

    I've installed Orthanc on my Windows test system. I edited the orthanc.json file in C:\Program Files\Orthanc Server\Configuration\ to include the openrem.lua file that @edmcdonagh has created. Note the double backslashes:

      // List of paths to the custom Lua scripts that are to be loaded
      // into this instance of Orthanc
      "LuaScripts" : [
        "D:\\David\\Documents\\Code\\Python\\OpenREM\\BitBucket\\openrem\\stuff\\openrem.lua"
      ],
    

    I then created a temp folder on my hard drive (D:\David\Temp\) and edited the openrem.lua file to reflect my virtualenv and the new temp folder:

    local python_path = 'D:\\David\\Documents\\Code\\Python\\OpenREM\\testbed\\openrem_develop\\Scripts\\python.exe'
    local openrem_exe_path = 'D:\\David\\Documents\\Code\\Python\\OpenREM\\testbed\\openrem_develop\\Scripts\\'
    local temp_path = 'D:\\David\\Temp\\'
    

    I then moved to the OpenREM folder that contains the test DICOM files and used the DCMTK storescu command to send some of the test files to Orthanc (which would hopefully use the Lua script to import them into OpenREM):

    storescu -aec ORTHANC localhost 4242 DX-Im-Carestream_DR7500-1.dcm
    
    storescu -aec ORTHANC localhost 4242 MG-Im-GE_Seno_1_ForPresentation.dcm
    
    storescu -aec ORTHANC localhost 4242 RF-RDSR-Siemens-Zee.dcm
    

    This worked perfectly - the studies are now in OpenREM.

    I don't have access to a Toshiba study to play about with importing that right now.

  10. David Platten

    RE the mkdir platform-specific issue. I don't know if we can install additional Lua libraries to work with Orthanc. However, we could have an additional variable at the top of the openrem.lua script called mkdir_cmd that is platform-specific:

    -- Windows mkdir_cmd; creates directory trees by default
    -- mkdir_cmd = 'mkdir '
    
    -- Linux mkdir_cmd; requires the -p switch to create directory trees
    -- mkdir_cmd = 'mkdir -p '
    
  11. David Platten

    Updated file so that it should work for Toshiba CT studies. Tested with test for Tosh CT removed on simple Dx study and works. Not tested the actual Toshiba import or the bit that removes the instances from Orthanc [skip ci]. References issue #635

    → <<cset 63bdfbb55d5a>>

  12. David Platten

    The time for a study to be considered stable defaults to 60 s. This is set in the StableAge item in the configuration.

    It may be wise to increase this for the Toshiba CT extractor to work in case some images are slow to retrieve.

  13. David Platten

    Corrected instance variable; made Philips import more explicit, as I think the Toshiba dose summary iamges are the same type [skip ci]. References issue 635

    → <<cset bf6ccf47b89c>>

  14. David Platten

    Amended Toshiba CT section so that it now works. Not fully tested yet. I can also confirm that this imports DR/DX correctly. I have changed the user-defined local variables as on my live system python.exe is in a different folder to the python scripts [skip ci]. References issue #635

    → <<cset b0b623cb699c>>

  15. David Platten

    Amended Toshiba CT section so that it creates a single folder rather than a nest of folders. This enables the Toshiba CT extractor to cleanly remove it once imported into OpenREM. I can confirm that this imports DR/DX, RDSR, Philips CT objects and older Toshiba CT data correctly. One of the issues I can see is that any non-Toshiba, non-Philips, non-RDSR CT data is currently deleted. Some of these can be imported with the Toshiba CT extractor [skip ci]. References issue #635

    → <<cset 0f68ea998e40>>

  16. David Platten

    Amended Toshiba CT section so that it keeps physics studies. Also enabled Toshiba CT extractor for a range of CT systems that I know have worked with the extractor in the past. I think that the check for physics studies may fail if either the patient name or id are blank - need to check for nil in the script before using the values [skip ci]. References issue #635

    → <<cset c9c3d5198a98>>

  17. David Platten

    Large changes to the file. The user can configure lists of manufacturer, model, station name, software version and serial numbers of systems to be ignored. This is useful to avoid importing things like computed radiography and specimen cabinet images into OpenREM. The user can now also configure a folder to keep physics test images in, and set a list of strings that are used in the patient name or id that indicate it is a physics test. There is also now a list of make/model pairs of CT scanners whose data can be successfully extracted with the Toshiba CT extractor [skip ci]. References issue #635

    → <<cset f1457193408c>>

  18. David Platten

    The Orthanc openrem.lua script is now working well on my live system.

    • The modalities are imported
    • The "ignore" lists are adhered to
    • The "physics" list works, saving physics files to the specified folder in a sensible structure

    I have set the StableAge in orthanc.json to 600 s on my install because when I retrieve old studies there are sometimes delays in some images being sent from PACS.

    As an aside, the automatic export of physics images to a folder may become unnecessary if I can work out how to use the Orthanc ImageJ plugin functionality on a 64-bit Windows installation (https://www.orthanc-server.com/static.php?page=imagej). I've got it to work on Ubuntu 16.04, but my live system is 64-bit Windows - I think it requires the Orthanc plugin to be compiled from source.

  19. Ed McDonagh reporter

    Thanks for all the work you've put in there.

    Can we re-merge the python path and python executable variables?

  20. Ed McDonagh reporter

    Regarding physics images, would you propose that the imageJ plugin would allow you to leave your Physics images in the orthanc database, then use the imageJ browser to find and analyse your QA images?

  21. Ed McDonagh reporter

    Does having a scanner match in the Tosh section not mean it won't be imported via RDSR?

  22. David Platten

    From my experience so far I think Orthanc is easier to use than Conquest.

    I'll merge the python_executable_path and python_executable together into one variable.

    For my install I'm concerned that I don't have enough storage space to start collecting physics images; I may set up OpenREM's Orthanc to forward any physics images to another Orthanc install on a different computer. I'm not sure how useful the ImageJ plugin will be, but I think it would simplify things for our testing here.

    On the Tosh question: you're right. My logic is flawed for the case where an RDSR arrives in Orthanc that matches the Toshiba CT criteria. In that case the RDSR is never imported in the usual way, and instead the Toshiba CT extractor will be run (I don't deal with any Toshiba RDSRs, so hadn't thought of this). I'll need to put the Toshiba extractor in a

    if import_script == ''
        ...
    end
    

    block, so it's only used if there's been no match earier.

  23. David Platten

    I've had all manner of CT models pulled into OpenREM from PACS - even some systems from the Royal Marsden. The result from the Toshiba extractor is just the RDSR that pixelmed.jar creates. So I think the Toshiba extractor will work for any CT make / model that pixelmed.jar can produce an RDSR for (it just won't include all the detail that you'd get with an RDSR created by the CT scanner itself).

  24. Ed McDonagh reporter

    That's the hazard of using QR to the PACS! My PACS team put 'imported' in the study description, which makes it relatively easy to filter out.

  25. Ed McDonagh reporter

    Corrected link to raw version. Cut out some of the more obvious bus now you can see the original with comments. Need to do more along those lines, and increase the explanations. Also need to remove some of the examples that aren't useful for @dplatten, but might be useful elsewhere (eg Afga). Refs #635. [skip ci]

    → <<cset 690129f269be>>

  26. David Platten

    It's possible to obtain data from a Lua table in two ways:

    local tags = {["AcquisitionDate"] = "20140620", ["AcquisitionTime"] = "105152"}
    
    -- Access using the name in quotes, surrounded by square brackets:
    print(tags['AcquisitionDate'])
    
    -- Access using .name (only works if no spaces in the name):
    print(tags.AcquisitionDate)
    

    We're using the quotes inside square brackets method in the openrem.lua file at the moment. The dot method results in shorter code. I don't think that the DICOM elements we're accessing ever have spaces in the names.

    I think it's also worth noting that local variables in Lua have a scope that is restricted to the current block of code. If you declare a local variable inside an if statement then you can't access it outside that statement. This is new to me.

  27. Ed McDonagh reporter

    All DICOM tags have a no space version. And I noticed the scope issue because of how PyCharm highlighted them!

  28. David Platten

    Changed syntax from table['x'] to table.x when accessing items in tables - I think it is tidier. I've also removed unused function parameters. These changes are untested. I wonder if we should enclose the OnStoredInstance code in an if origin['RequestOrigin'] ~= 'Lua' then block. This is used in an example to avoid infinite loops (http://book.orthanc-server.com/users/lua.html#important-remarks-about-auto-routing) [skip ci]. References issue #635

    → <<cset f757275971d5>>

  29. David Platten

    Added some checks for nil Manufacturer and ManufacturerModelName tags; this has tripeed up my live Orthanc install (a Secondary Capture image of a contrast enhancement chart was the culprit) [skip ci]. References issue #635

    → <<cset 11dc4d2550a0>>

  30. Ed McDonagh reporter

    What's the best way @dplatten of allowing a user to disable the physics_to_keep functionality and probably the toshiba_extractor_systems too, as installing the extra stuff is optional?

    Set the following?

    local physics_to_keep_folder = ''
    local zip_executable = ''
    local rmdir_cmd = ''
    local physics_to_keep = {}
    local toshiba_extractor_systems = {}
    
  31. David Platten

    Just the following will work:

    local physics_to_keep = {}
    local toshiba_extractor_systems = {}
    

    Commit to follow in a minute.

  32. David Platten

    Corrected an earlier error (tried to delete instance rather than study). Physics images now only kept if element [1] of physics_to_keep is present. Toshiba CT extractor now only run if element [1][1] of toshiba_extractor_systems is present [skip ci]. References issue #635

    → <<cset 9a17bca62fa9>>

  33. Ed McDonagh reporter

    Thanks. Which user does Orthanc on Windows use? Is there a permissions issue with the temp files location or the logs?

  34. David Platten

    Orthanc required administrator rights to be installed on my Windows server. As part of the installation it installs itself as a service called Orthanc which runs under the Local System user. It is automatically started during install, and is set to autostart when the computer boots. There's been no issue with the Orthanc logs (they do require admin rights to delete); I created the temp files location as a normal user: there's been no issue with Orthanc being able to put images in it, or to delete them.

    All-in-all I feel the install and set up is much easier than Conquest, but that could just be me.

  35. David Platten

    @edmcdonagh, I think we should perhaps have boolean enable_toshiba_CT_extractor and enable_physics_filtering variables to control whether these two features are active. This would be clearer to the user.

  36. David Platten

    Added variables to enable/disable physics studies and Toshiba CT extractor sections. Changed a couple of variables to boolean where appropriate [skip ci]. References issue #635

    → <<cset 964d1bdfc2ae>>

  37. David Platten

    Replaced the i and j key variables in several loops with a placeholder (_). Removes the final PyCharm criticisms of the code - I now have a green tick [skip ci]. References issue #635

    → <<cset f2c005ece3c3>>

  38. David Platten

    Updated Windows service restart section, and included a Toshiba scanner in the tosh list. Documentation changes only [skip ci]. References issue #635

    → <<cset 6a2ffebc6dfc>>

  39. David Platten

    Added some checks for nil when writing reject message to log. This failed due to a missing software versions tag in some CT images [skip ci]. References issue #635

    → <<cset bdf5eaa94d65>>

  40. David Platten

    Added to zip command comment to make it clear that any switches required to create an archive must be included here [skip ci]. References issue #635

    → <<cset 742e3390c4a7>>

  41. David Platten

    Clarified some parts of the DICOM store documentation. Tried to add a link to the section. Documentation changes only [skip ci]. References issue #635

    → <<cset 4839e20acedf>>

  42. Log in to comment