# 10.30. Clara Deploy Series Selector

## 10.30. Clara Deploy Series Selector

CAUTION: This is NOT for diagnostics use.

## 10.30.1.Overview

This example operator, in the form of a Docker container, selects the relevant series using the configurable series matching rules, and saves the series instance UID to image file mappings in a JSON file in the output folder, for those selected series.

This operator depends on the DICOM metadata as well as the series to image file mappings, both in JSON files in the output of the Clara Deploy DICOM Parser. The series selection rules are loaded by default from a JSON file within the container, when running as an example, but a user’s rules file path must be provided via a well-known environment variable, or alternatively, selection rules can be Base64 encoded and set via another well-known environment variable. More details are provided in the following section.

The output of this operator is expected to be consumed by the downstream operators in the pipeline, so that they can deterministically select and arrange image files as input to their processing steps, e.g. a multi-channel AI inference operator.

This operator in the form of a Docker container, loads DICOM metadata from a JSON file as well as the mapping from series to image files from another JSON file. Both of these files are the output from Clara Deploy DICOM Parser operator, and the default names are dicom-metadata.json and series-images.json respectively. It also loads the series selection rules from a JSON configuration file, selects the series using the configurable series matching rules, and finally saves the image file paths for those series in a JSON file in the output folder.

It is important to note that both the series matching rules and the rule processor are very simple, and serve as a placeholder for more advanced and sophisticated rule engine.

## 10.30.2.Inputs

This operator expects by default an input folder, /input, which contains DICOM metadata JSON file, and the series to image mapping file. Both of these files are the output from Clara Deploy DICOM Parser operator, and the default names are dicom-metadata.json and series-images.json respectively.

This operator also loads the series selection rules from a JSON configuration file, by default from ./config/selection-rules.json, but the actual file path must be provided via the well-known environment variable, NVIDIA_CLARA_SELECTION_RULES_FILE. Alternatively, and to take the highest precedence, the rules can be Base64 encoded and set via another environment variable, NVIDIA_CLARA_SELECTION_RULES_BASE64. A empty string as rules will select all converted series and its image, with the series instance UID as the selection name.

Multiple selections can be specified in the selection rules, each with a unique name. For each selection, multiple conditions can be specified, interpreted as logical and. Each condition’s attribute name corresponds to the DICOM series attribute JSON name, and the value is expected to match the actual DICOM series attribute, with regular expression supported for string types. Below is an example of the selection rules,

Copy
Copied!

{
"selections": [
{
"name": "MR Series 1",
"conditions": {
"Modality": "(?i)^MR",
"StudyDescription": "(?i)MRI Prostate WP",
"ImageType": [
"ORIGINAL",
"PRIMARY"
],
"SeriesDescription": "MRI prostate"
}
},
{
"name": "MR Series 2",
"conditions": {
"Modality": "MR",
"ImageType": [
"ORIGINAL",
"PRIMARY",
"AXIAL"
],
"SeriesDescription" : "Not Matched"
}
}
]
}


## 10.30.3.Outputs

This application saves the matched selection’s series instance UID to image file name in a JSON file, selected-images.json, stored in the output folder /output by default. For each matched selection, the selection name is the attribute, and the value is a dictionary with matched series instance UID as attribute and the value being the image file name.

Below is an example of the selected image file,

Copy
Copied!

{
"MR Series 1":{
"1.2.826.0.1.3680043.2.1125.1.48532560258338587890405155270906492":"1.2.826.0.1.3680043.2.1125.1.48532560258338587890405155270906492.mhd"
}
}


Logs generated by the application is saved in a folder, /logs by default, which similarly must be mapped to a host folder.

## 10.30.4.Directory Structure

The directories in the container are shown below. The core of the application code is under the folder selector.

Copy
Copied!

.
├── config
│   └── selection-rules.json
├── __init__.py
├── logging_config.json
├── main.py
├── ngc
│   └── overview.md
├── public
│   └── docs
├── requirements.txt
├── run_app_docker.sh
├── selector
│   ├── app.py
│   ├── __init__.py
│   ├── runtime_envs.py
│   └── series_selector.py
└── test-data
└── series-images.json


## 10.30.5.Executing Operator in Docker

### 10.30.5.1.Prerequisites

1. Ensure there are DICOM metadata and series to image mapping files, which can be copied from within the Docker image.

### 10.30.5.2.Step 1

Change to your working directory, e.g. my_test.

### 10.30.5.3.Step 2

Create, if they do not exist, the following directories under your working directory:

• input, and copy over the DICOM metadata and series to image mapping files.

• output for the selected image files.

• logs for log files.

### 10.30.5.4.Step 3

In your working directory, create a shell script, e.g. run_app_docker.sh or other name if you prefer, copy the sample content below, save it, and make sure the variable APP_NAME has the same value as the actual container, e.g. nvcr.io/ea-nvidia-clara/clara/series-selector:0.6.0-2004.4,

Copy
Copied!

SCRIPT_DIR=$(dirname "$(readlink -f "$0")") APP_NAME="series-selector" # Pull Docker image if not already, example below # docker pull nvcr.io/ea-nvidia-clara/clara/series-selector:<TAG> # docker tag nvcr.io/ea-nvidia-clara/clara/series-selector:<TAG> dicom-parser:latest # Run${APP_NAME} container.
docker run --name test -t --rm \
-v ${SCRIPT_DIR}/input:/input \ -v${SCRIPT_DIR}/output:/output \
-v ${SCRIPT_DIR}/logs:/logs \ -e DEBUG_VSCODE \ -e DEBUG_VSCODE_PORT \ -e NVIDIA_CLARA_NOSYNCLOCK=TRUE \ -e NVIDIA_CLARA_SELECTION_RULES_FILE="./config/selection-rules.json" \${APP_NAME}

echo "\${APP_NAME}has finished."


### 10.30.5.5.Step 4

Execute the script below, and wait for the application container to finish,

./run_app_docker.sh.

### 10.30.5.6.Step 5

Check for the following output files:

1. Metadata files in the output directory, selected-images.json

## 10.30.6.Executing Operator Locally

If you want to see the internals of the container and want to manually run the application, follow these steps.

1. Start the container in interactive mode. See the next section on how to run the container, and replace the docker run command with docker run -i --entrypoint /bin/bash

2. Once in the Docker terminal, ensure the current directory is series-selector.

3. Copy test-data/* to /input

4. Create folders /output and /logs

5. Type in command python ./main.py"

6. Once finished, type exit.

## 10.30.7.Customizing Series Matching Rules

This requires replacing the config/selection-rules.json file in the Docker image and building a new custom Docker image. Even though it is simple to provide a configuration file when running the Docker image standalone, building a custom Docker image makes it simpler to deploy a pipeline on Clara Deploy.

• Tag the pulled series selector Docker image, e.g. .. code-block:: bash

docker tag nvcr.io/ea-nvidia-clara/clara/series-selector:0.6.0-2004.4 series-selector:latest

• Use the existing selection-rules.json as a basis to customize the matching rule, and build your custom Docker image using the following Dockerfile as an example. bash # Build upon the pulled container; version tag can be used if known. FROM series-selector

## 10.31. Copy customized rules file overwriting the default one.

COPY ./selection-rules.json ./config/selection-rules.json
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.3038709759712219, "perplexity": 7095.576725210115}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2023-14/segments/1679296950363.89/warc/CC-MAIN-20230401221921-20230402011921-00573.warc.gz"}