/pl-dicommake

Create new DICOM images from an existing DICOM and a new image

Primary LanguagePythonMIT LicenseMIT

DICOM image make

Version MIT License ci

pl-dicommake is a ChRIS DS plugin that makes new DICOM files from existing DICOM files and separate image files. Each new DICOM is simply the result of packing the existing image file into the corresponding existing DICOM base, with necessary updates to the DICOM header.

Abstract

Creating new DICOM files requires two fundamental preconditions: an image and metadata. For this plugin, inputs are an image and an existing DICOM file. The output is a new DICOM file with the image embedded using most of the metadata from the supplied DICOM. Where required, the new file's DICOM tags are changed to properly describe the image. Note that this plugin can operate over sets of input images -- one set of input DICOM files and a corresponding set of input image files. It is a required precondition that the file stem of each file in the DICOM set corresponds to a similar file stem in the image set.

Installation

pl-dicommake is a ChRIS plugin, meaning it can run from either within ChRIS or the command-line.

Preconditions / assumptions

dicommake has a few somewhat brittle preconditions on the nature of its inputdir space:

  • inputdir contains I >= 1 image files (typically png or jpg) -- moreover there is only one type of image file (no mixing of png and jpg, for example);
  • inputdir contains D >= 1 DICOM files;
  • importantly, the number of elements in each set of files is identical, i.e. D = I
  • sorting the lists of I and D result in matched pairs such that the file stems (names without extensions) of paired image and DICOM files are identical:
    • forEach iI and dD : stem(i) == stem(d);

Local Usage

To get started with local command-line usage, use Apptainer (a.k.a. Singularity) to run pl-dicommake as a container:

apptainer exec docker://fnndsc/pl-dicommake dicommake [--args values...] input/ output/

Alternatively, create a singularity sif file:

apptainer build pl-dicommake.sif docker://fnndsc/pl-dicommake

To print its available options, run:

apptainer exec docker://fnndsc/pl-dicommake dicommake --help

Examples

dicommake requires two positional arguments: a directory containing input data, and a directory where to create output data. First, create the input directory and move input data into it.

mkdir incoming/ outgoing/
mv image.png file.dcm incoming/
apptainer exec docker://fnndsc/pl-dicommake:latest dicommake --inputImageFilter '**/*png' \
        incoming/ outgoing/

Development

Instructions for developers.

Building

Build a local container image:

docker build -t localhost/fnndsc/pl-dicommake .

Running

Mount the source code dicommake.py into a container to try out changes without rebuild.

docker run --rm -it --userns=host -u $(id -u):$(id -g) \
    -v $PWD/dicommake.py:/usr/local/lib/python3.11/site-packages/dicommake.py:ro \
    -v $PWD/in:/incoming:ro -v $PWD/out:/outgoing:rw -w /outgoing \
    localhost/fnndsc/pl-dicommake dicommake /incoming /outgoing

Testing

Run unit tests using pytest. It's recommended to rebuild the image to ensure that sources are up-to-date. Use the option --build-arg extras_require=dev to install extra dependencies for testing.

docker build -t localhost/fnndsc/pl-dicommake:dev --build-arg extras_require=dev .
docker run --rm -it localhost/fnndsc/pl-dicommake:dev pytest

Release

Steps for release can be automated by Github Actions. This section is about how to do those steps manually.

Increase Version Number

Increase the version number in setup.py and commit this file.

Push Container Image

Build and push an image tagged by the version. For example, for version 1.2.3:

docker build -t docker.io/fnndsc/pl-dicommake:1.2.3 .
docker push docker.io/fnndsc/pl-dicommake:1.2.3

Get JSON Representation

Run chris_plugin_info to produce a JSON description of this plugin, which can be uploaded to a ChRIS Store.

docker run --rm localhost/fnndsc/pl-dicommake:dev \
    chris_plugin_info > chris_plugin_info.json