Metadata-Version: 2.4
Name: pacsifier
Version: 1.0.0
Summary: PACSIFIER: batch DICOM query/retrieve tool for PACS systems
Home-page: https://github.com/TranslationalML/pacsifier
Author: Translational Machine Learning Lab
Author-email: translationalML@gmail.com
License: Apache License, Version 2.0
Project-URL: Documentation, https://translationalml.github.io/pacsifier
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.10
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8
License-File: LICENSE
Requires-Dist: pandas==2.2
Requires-Dist: Cerberus==1.3.5
Requires-Dist: nibabel==5.2
Requires-Dist: pydicom==2.4
Requires-Dist: progressbar2==3.55
Requires-Dist: beautifulsoup4==4.12
Requires-Dist: jsonschema==4.21
Requires-Dist: requests==2.32.5
Provides-Extra: doc
Requires-Dist: pydot==2.0; extra == "doc"
Requires-Dist: sphinx==7.2; extra == "doc"
Requires-Dist: sphinx-argparse==0.4; extra == "doc"
Requires-Dist: sphinx_rtd_theme==2.0; extra == "doc"
Requires-Dist: recommonmark==0.7; extra == "doc"
Requires-Dist: sphinxcontrib-apidoc==0.5; extra == "doc"
Requires-Dist: sphinxcontrib-mermaid==0.9; extra == "doc"
Requires-Dist: sphinxemoji==0.3; extra == "doc"
Requires-Dist: mock==5.1; extra == "doc"
Requires-Dist: myst-parser==4.0; extra == "doc"
Requires-Dist: docutils==0.20; extra == "doc"
Requires-Dist: commonmark==0.9; extra == "doc"
Provides-Extra: dev
Requires-Dist: black==24.2; extra == "dev"
Requires-Dist: pre-commit==3.6; extra == "dev"
Requires-Dist: isort==5.13; extra == "dev"
Provides-Extra: docs
Requires-Dist: pydot==2.0; extra == "docs"
Requires-Dist: sphinx==7.2; extra == "docs"
Requires-Dist: sphinx-argparse==0.4; extra == "docs"
Requires-Dist: sphinx_rtd_theme==2.0; extra == "docs"
Requires-Dist: recommonmark==0.7; extra == "docs"
Requires-Dist: sphinxcontrib-apidoc==0.5; extra == "docs"
Requires-Dist: sphinxcontrib-mermaid==0.9; extra == "docs"
Requires-Dist: sphinxemoji==0.3; extra == "docs"
Requires-Dist: mock==5.1; extra == "docs"
Requires-Dist: myst-parser==4.0; extra == "docs"
Requires-Dist: docutils==0.20; extra == "docs"
Requires-Dist: commonmark==0.9; extra == "docs"
Provides-Extra: test
Requires-Dist: pytest==7.4; extra == "test"
Requires-Dist: pytest-console-scripts==1.4; extra == "test"
Requires-Dist: pytest-cov==4.1; extra == "test"
Requires-Dist: pytest-order==1.2; extra == "test"
Requires-Dist: hypothesis==6.98; extra == "test"
Provides-Extra: all
Requires-Dist: pydot==2.0; extra == "all"
Requires-Dist: sphinx==7.2; extra == "all"
Requires-Dist: sphinx-argparse==0.4; extra == "all"
Requires-Dist: sphinx_rtd_theme==2.0; extra == "all"
Requires-Dist: recommonmark==0.7; extra == "all"
Requires-Dist: sphinxcontrib-apidoc==0.5; extra == "all"
Requires-Dist: sphinxcontrib-mermaid==0.9; extra == "all"
Requires-Dist: sphinxemoji==0.3; extra == "all"
Requires-Dist: mock==5.1; extra == "all"
Requires-Dist: myst-parser==4.0; extra == "all"
Requires-Dist: docutils==0.20; extra == "all"
Requires-Dist: commonmark==0.9; extra == "all"
Requires-Dist: black==24.2; extra == "all"
Requires-Dist: pre-commit==3.6; extra == "all"
Requires-Dist: isort==5.13; extra == "all"
Requires-Dist: pytest==7.4; extra == "all"
Requires-Dist: pytest-console-scripts==1.4; extra == "all"
Requires-Dist: pytest-cov==4.1; extra == "all"
Requires-Dist: pytest-order==1.2; extra == "all"
Requires-Dist: hypothesis==6.98; extra == "all"
Dynamic: license-file

# PACSIFIER

PACSIFIER is an open-source tool written in Python to query, retrieve, and edit data in DICOM format from a radiological PACS server. It can be run directly or via a Docker container.

[![Build](https://img.shields.io/github/actions/workflow/status/TranslationalML/pacsifier/build-test-deploy.yml?branch=master&label=build)](https://github.com/TranslationalML/pacsifier/actions/workflows/build-test-deploy.yml)
[![Docs](https://img.shields.io/github/actions/workflow/status/TranslationalML/pacsifier/docs.yml?branch=master&label=docs)](https://github.com/TranslationalML/pacsifier/actions/workflows/docs.yml)
[![License](https://img.shields.io/github/license/TranslationalML/pacsifier)](https://github.com/TranslationalML/pacsifier/blob/master/LICENSE)
[![Python Version](https://img.shields.io/badge/python-%3E%3D3.10-blue)](https://www.python.org/)
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://translationalml.github.io/pacsifier)

<!-- Uncomment these once you publish a GitHub Release:
[![Latest GitHub Release](https://img.shields.io/github/v/release/TranslationalML/pacsifier)](https://github.com/TranslationalML/pacsifier/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date/TranslationalML/pacsifier)](https://github.com/TranslationalML/pacsifier/releases)
-->

> **Full documentation**: [https://translationalml.github.io/pacsifier](https://translationalml.github.io/pacsifier)

> **Windows users:** We strongly recommend using [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) to run PACSIFIER. Linux is the recommended environment.

## Quick Start

### Option 1: Pre-built Docker Image (Recommended)

Pull the latest release from Quay.io — no cloning, no building, no dependency installation required:

```bash
docker pull quay.io/translationalml/pacsifier:latest
```

Run PACSIFIER:

```bash
docker run --rm --net=host \
    -v /path/to/my_dir:/base \
    quay.io/translationalml/pacsifier:latest \
    pacsifier --save --info --queryfile /base/my_query.csv \
    --config /base/my_config.json --out_directory /base/my_output_dir
```

> **Tip:** You can pin to a specific version (e.g. `pacsifier:1.0.0`) instead of `latest`. See [available tags on Quay.io](https://quay.io/repository/translationalml/pacsifier?tab=tags).

Or use the convenience [Docker wrapper scripts](https://translationalml.github.io/pacsifier/docker_wrappers.html):

```bash
pip install pacsifier  # installs the wrapper scripts
docker_pacsifier -c config.json -i -s -q query.csv -d /output
```

### Option 2: Install via pip

```bash
pip install pacsifier
```

> **Note:** When installing via pip, you also need [DCMTK](https://dicom.offis.de/en/dcmtk/dcmtk-tools/) installed on your system (`sudo apt install dcmtk` on Ubuntu).

## Features

- Query and retrieve DICOM images from PACS servers
- Move DICOM images between PACS nodes
- Upload DICOM images to PACS servers
- Anonymize DICOM files (directly or via Karnak gateway)
- Get pseudonyms from the De-ID API
- Create DICOMDIR files
- Extract Carestream reports
- Docker wrapper scripts for simplified usage
- Resume interrupted extractions

## Usage

PACSIFIER provides several CLI commands. How you run them depends on your installation method:

| Install method | How to run commands |
|---|---|
| **Docker** (no install) | `docker run --rm --net=host quay.io/translationalml/pacsifier:latest pacsifier ...` |
| **Docker wrappers** (`pip install pacsifier`) | `docker_pacsifier ...`, `docker_anonymize_dicoms ...` |
| **pip / source** (`pip install pacsifier`) | `pacsifier ...`, `pacsifier-anonymize ...` |

### Available commands

| Command | Docker wrapper | Description |
|---|---|---|
| `pacsifier` | `docker_pacsifier` | Query, retrieve, and move DICOM images |
| `pacsifier-anonymize` | `docker_anonymize_dicoms` | Anonymize DICOM files |
| `pacsifier-get-pseudonyms` | `docker_get_pseudonyms` | Get pseudonyms from De-ID API or custom mapping |
| `pacsifier-add-karnak-tags` | `docker_add_karnak_tags` | Tag DICOM files for Karnak de-identification |
| `pacsifier-create-dicomdir` | `docker_create_dicomdir` | Create a DICOMDIR file |
| `pacsifier-move-csv` | `docker_move_dumps` | Move info CSV dumps to a separate folder |
| `pacsifier-extract-carestream-report` | `docker_extract_carestream_report` | Extract text from Carestream SR reports |

### Common examples

**With pip/source install** (requires DCMTK on your system):

```bash
# Query and save DICOM images locally
pacsifier --save --info -q query.csv -c config.json -d ./output

# Query and move images to a remote DICOM node
pacsifier --move -q query.csv -c config.json

# Upload DICOM images to a PACS server
pacsifier --upload --upload_directory ./dicoms -c config.json

# Resume an interrupted download (skips already downloaded series)
pacsifier --save --resume -q query.csv -c config.json -d ./output

# Anonymize DICOM files
pacsifier-anonymize -d ./data -o ./anonymized --fuzz_acq_dates --remove_private_tags
```

**With Docker** (no DCMTK or Python needed):

```bash
# Using wrapper scripts (pip install pacsifier for the wrappers only)
docker_pacsifier -c config.json -s -i -q query.csv -d ./output
docker_anonymize_dicoms -d ./data -o ./anonymized -a -p

# Or directly with docker run
docker run --rm --net=host \
    -v /path/to/my_dir:/base \
    quay.io/translationalml/pacsifier:latest \
    pacsifier --save --info -q /base/query.csv -c /base/config.json -d /base/output
```

Run any command with `--help` for the full list of options. See [Docker Wrappers](https://translationalml.github.io/pacsifier/docker_wrappers.html) for more details on the wrapper scripts.

## Configuration

### Config File

PACSIFIER requires a JSON configuration file:

```json
{
    "server_address": "PACS server IP/URL",
    "port": 4242,
    "server_AET": "SERVER_AET",
    "AET": "YOUR_AET",
    "move_AET": "MOVE_DESTINATION_AET",
    "move_port": 11112,
    "batch_size": 30,
    "batch_wait_time": 10
}
```

#### Migrating from PACSMAN

If you are migrating a PACSMAN `config.json`, update the key names and types:
- `server_ip` → `server_address`
- `port`: string → integer
- `move_port`: string → integer
- `batch_size`: string → integer
- `batch_wait_time`: string → integer

### Query File

The query file is a `.csv` file with columns matching DICOM attributes. Supported columns include:
`StudyDate`, `PatientID`, `SeriesDescription`, `Modality`, `ProtocolName`, `StudyInstanceUID`, `SeriesInstanceUID`, `PatientName`, `PatientBirthDate`, `AcquisitionDate`, `DeviceSerialNumber`, `SeriesNumber`, `StudyDescription`, `AccessionNumber`, `SequenceName`, `StudyTime`, `ImageType`.

See the [full documentation](https://translationalml.github.io/pacsifier/usage.html) for query file format, examples, and all CLI options.

## Documentation

Full documentation is available at **[https://translationalml.github.io/pacsifier](https://translationalml.github.io/pacsifier)**, including:

- [Installation Guide](https://translationalml.github.io/pacsifier/installation.html)
- [Command-Line Usage](https://translationalml.github.io/pacsifier/usage.html)
- [Docker Wrappers](https://translationalml.github.io/pacsifier/docker_wrappers.html)
- [Developer Guide](https://translationalml.github.io/pacsifier/developer.html)
- [API Reference](https://translationalml.github.io/pacsifier/api/generated/modules.html)

## Building the Documentation

```bash
make build-docs
```

This generates the HTML documentation in `docs/_build/html`.

## Running Tests

### Via Docker (recommended)

```bash
make build-docker
make test
```

### Locally

#### Install from Source (For Developers)

```bash
git clone https://github.com/TranslationalML/pacsifier.git
cd pacsifier
conda create -n pacsifier_minimal python=3.10
conda activate pacsifier_minimal
pip install -e ".[all]"
```

> **Note:** Source installations require [DCMTK](https://dicom.offis.de/en/dcmtk/dcmtk-tools/) to be installed on your system.

See the [full installation guide](https://translationalml.github.io/pacsifier/installation.html) for all options and details.

#### Run the tests

See the [Developer Guide](https://translationalml.github.io/pacsifier/developer.html) for instructions on running tests locally with a mock DICOM server.

## Contributing

See the [Contributing Guide](https://translationalml.github.io/pacsifier/contributing.html) for guidelines on reporting bugs, requesting features, and submitting pull requests.

## License

Apache License 2.0. See [LICENSE](LICENSE) for details.

## Citation

If you use PACSIFIER in your work, please cite it. See [How to Cite](https://translationalml.github.io/pacsifier/citing.html).

## Acknowledgments

This project received funding from the Lausanne University Hospital and the Lundin Family Brain Tumour Research Center.

