DEV Community

Muneeb Ahmad
Muneeb Ahmad

Posted on

My GSoC Journey with InVesalius: Bringing PACS Integration to InVesalius

My GSoC Journey with InVesalius: Bringing PACS Integration to InVesalius

For the past three months I have been contributing at Invesalius as a GSOC contributor. It has been quite a fun summer and now that I have finally completed the project I wanted to share a sneak peak of what I did and learnt and about the org.

InVesalius

Invesalisus

A well-established open-source medical imaging software developed in Brazil. It enables the generation of physical models through 3D printing using two-dimensional (2D) images acquired from CT or MRI. By converting these 2D images into 3D anatomical representations, healthcare professionals can utilize the resulting models for various medical purposes.

The Problem

Invesalius did not support remote connections with hospital servers (PACS) so to exchange data external tools were required, which is an overhead.

The Solution

Use libraries like pynetdicom and pydicom to build methods that support querying Hospital servers (PACS) for image search and retrieval over the network, without the manual effort.

A quick introduction to PACS and DICOM

PACS i.e. Picture Archiving and Communication System does exactly what it sounds like, it helps us manage pictures by communicating with the systems.

Which systems you say? DICOM systems.

Now what are DICOMs?

DICOM is the standard used for storing, communicating, querying and retrieving medical images and related information. DICOM servers are the systems that implement this standard and host/manage these images, acting as a centralized picture archive/storage for a hospital. Some examples are Orthanc and dcm4chee.

Architecture

Architecture

How the DICOM Operations Fit Together

Pacs Flow

The basic flow is:

Connectivity → Search → Retrieval → Local Storage

  • C-ECHO: to check if the server is connected
  • C-FIND: to search patients across available nodes/servers
  • C-MOVE: to retrieve/download images
  • C-GET: to retrieve/download images, used as a fallback
  • C-STORE: to store retrieved images in a pre-specified folder

Patient → Study → Series → Image

DICOM Data Hierarchy

The images in a DICOM server are organized hierarchically:
Patient → Study → Series → Image
This also allowed the user to download patient images at different hierarchy levels like patient, study, series.

What I Did

DICOM Networking

Implemented querying methods like:

  • c-echo: to check if the server is connected
  • c-find: to search patients across available nodes/servers
  • c-move: to retrieve/download images
  • c-get: to retrieve/download images - used as a fallback
  • c-store: to store retrieved images in a pre-specified folder

User Interface

PACS UI

Implemented ui for user interaction that includes:

  • Search bar and associated dialogs for searching
  • UI to manage nodes/servers for image retrieval.
  • Option to download patient images at different hierarchy levels like: patient, study, series.
  • Cancellation option to stop download, and clean up the directory.
  • Preferences dialog for network options to set download directory, choose download method, and application configuration.
  • Checking if the specific images are already downloaded to prevent duplicates.

Preference Dialog

Backend best practices and optimizations

  • Graceful error handling: if c-move fails automatically falls back to c-get.
  • Type hinting for type safety.
  • Clear logging for easier debugging.
  • Query methods wrapped with async methods to prevent ui-freeze.

Engineering Challenges

This is the section I would give the most attention to. These are actual problems you encountered rather than simply features you implemented.

1. Falling back from C-MOVE to C-GET

One of the challenges was to use c-get as fallback if c-move was to fail.
I had to think of a creative way, so I came up with a less creative simple solution and that was to handle it as an error and also support the user to choose his preffered method.
So what I did was to create one orchestrator for both methods and handle error gracefully like if the choice was cmove and an error occurs then move to orchestrate c-get, pretty simple i know but i was happy when i came up with it.

Fall Back

2. Cancellation, Cleanup and Progress Tracking

Second challenge would be to handle the actual cancelling the c-move, cleaning the downloaded ones and not fallback to c-get and also deal with the download dialog without ui freeze.
I used wx.Callafter functions for this, raised error “CANCELLED”.. and tracked at orchestrator, removing all the downloaded images.

Cancellation Flow

Cancellation Dialog

The main problem was the progress dialog.
I used initially a progress dialog with exact downloaded count and boy that was tough to continually update it after each image, and then there was another problem was that orthanc sent one image per response so tracking was easier, but when i tried dcm4chee it sent all the images at once, so i had to track it in the cg-store.
So I went with an easier solution and that was to fallback to a simpler progress dialog without the exact image count.

Previous Progress Dialog

Current Progress Dialog

3. Preventing UI Freeze

The third issue was actually the ui-freeze problem for these c-queries.
The solution for that was rather simple too and that was to wrap these sync functions into functions which would then call these in the background(as async) using thread executors.

Testing

For initial queries I added manual tests, but then with UI - inclusion etc. We stuck with manual verification / testing.
Checking multiple combinations of steps etc. And paulo was a big help here.

Technology Used

  • Language: Python
  • Libraries: pynetdicom, pydicom, wx, logging
  • Tools: docker, Orthanc, dcm4chee, git

What I Learned

  • Learned the docker yml structure and docker commands.
  • Learned how medical networks work with the top layer using application entities along with ip: ports and how under the hood tcp is used.
  • Learned how different DICOM servers work and how they are configured.
  • Learned how DICOM servers are queried for different needs and what context does each require.
  • Learned how to skim through documentation to understand new technology and to understand the error codes etc.
  • Learned how important logs are for documentation.
  • Learned how to better handle the errors.
  • And a lot more.

Open Source

So my journey consists of:

  • Being confused
  • Starting from an existing stale PR (#644).
  • Being confused
  • understanding the previous implementation and the existing codebase before continuing.
  • Adapted/extended the work to fit the current codebase.
  • Debugging
  • Debugging again
  • going through mentor/code review and iteration.
  • Getting my PR merged (oh the joy of it)

Future Work

  • Querying multiple nodes/servers at once.
  • Editing nodes information

Final Thoughts

So this project took me from being completely unaware of what DICOM was to implementing PACS integration for InVesalius, handling edge cases and cancellation flows, understanding status codes from different servers, reading documentation, debugging issues, and a lot more along the way. It was a great experience and I would say everyone should contribute to OSS to the software they use and enjoy.

Well, if you reached this point consider commenting :)

PR

Merged PR

PR Link: https://github.com/invesalius/invesalius3/pull/1261

Special Mentions

Special thanks to my mentor Paulo for his continued guidance.

Socials

Linkedin
Github

Top comments (0)