Retrieve medical images via WADO, MINT and DICOM-QR
- Requires python 3.7, 3.8 or 3.9
- Uses
pydicom
andpynetdicom
. Images and query results arepydicom.Dataset
instances - Multi-threaded downloading using
requests-futures
pip install dicomtrolley
# Create a logged-in http session
session = VitreaConnection(
"https://server/login").log_in(user,password,realm)
# Use this session to create a trolley using MINT and WADO
trolley = Trolley(searcher=Mint(session, "https://server/mint"),
wado=Wado(session, "https://server/wado"]))
# find some studies (using MINT)
studies = trolley.find_studies(MintQuery(patientName='B*'))
# download the fist one (using WADO)
trolley.download(studies[0], output_dir='/tmp/trolley')
studies = trolley.find_studies(MintQuery(patientName='B*'))
Query parameters can be found in mint.Query. Valid include fields (which information gets sent back) can be found in fields.py:
studies = trolley.find_studies_mint(
MintQuery(modalitiesInStudy='CT*',
patientSex="F",
minStudyDate=datetime(year=2015, month=3, day=1),
maxStudyDate=datetime(year=2020, month=3, day=1),
includeFields=['PatientBirthDate', 'SOPClassesInStudy']))
To include series and instance level information as well, use the queryLevel
parameter
studies = trolley.find_studies( # find studies series and instances
MintQuery(studyInstanceID='B*',
queryLevel=QueryLevels.INSTANCE)
a_series = studies.series[0] # studies now contain series
an_instance = a_series.instances[0] # and series contain instances
Any study, series or instance can be downloaded
studies = trolley.find_studies(MintQuery(patientName='B*',
queryLevel=QueryLevels.INSTANCE))
path = '/tmp/trolley'
trolley.download(studies, path) # all studies
trolley.download(studies[0]), path # a single study
trolley.download(studies[0].series[0], path) # a single series
trolley.download(studies[0].series[0].instances[:3], path) # first 3 instances
More control over download: obtain pydicom.Dataset
instances directly
studies = trolley.find_studies( # find study including instances
Query(PatientID='1234',
queryLevel=QueryLevels.INSTANCE)
for ds in trolley.get_dataset(studies): # obtain Dataset for each instance
ds.save_as(f'/tmp/{ds.SOPInstanceUID}.dcm')
Multi-threaded downloading
trolley.download(studies, path,
use_async=True, # enable multi-threaded downloading
max_workers=4) # optionally set number of concurrent workers
# defaults to None which lets python decide
Using WADO only, without search
from dicomtrolley.wado import InstanceReference, Wado
instance = InstanceReference(
series_instance_uid='1.2.1',
study_instance_uid='1.2.2',
sop_instance_uid='1.2.3')
wado = Wado(session, wado_url)
for ds in wado.datasets([instance]):
ds.save_as(f'/tmp/{ds.SOPInstanceUID}.dcm')
Trolley
can use DICOM-QR instead of MINT as a search method. See dicom_qr.DICOMQuery for query details.
dicom_qr = DICOMQR(host,port,aet,aec)
trolley = Trolley(searcher=dicom_qr, wado=wado)
# Finding is similar to MINT, but a DICOMQuery is used instead
trolley.find_studies(
query=DICOMQuery(PatientName="BAL*",
minStudyDate=datetime(year=2015, month=3, day=1),
maxStudyDate=datetime(year=2015, month=4, day=1),
includeFields=["PatientBirthDate", "SOPClassesInStudy"],
QueryRetrieveLevel=QueryRetrieveLevels.STUDY))
- dicomweb-client - Active library supporting QIDO-RS, WADO-RS and STOW-RS.
- pynetdicom - dicomtrolley's DICOM-QR support is based on pynetdicom. Pynetdicom supports a broad range of DICOM networking interactions and can be used as a stand alone application.
Dicomtrolley has been developed for and tested on a Vitrea Connection 8.2.0.1 system. This claims to be consistent with WADO and MINT 1.2 interfaces, but does not implement all parts of these standards.
Certain query parameter values and restraints might be specific to Vitrea Connection 8.2.0.1. For example, the exact list of DICOM elements that can be returned from a query might be different for different servers.
You can contribute in different ways
Report bugs at https://github.com/sjoerdk/clockify_api_client/issues.
Fork this repo, create a feature branch
dicomtrolley uses poetry for dependency and package management
- Install poetry (see poetry docs)
- Create a virtual env. Go to the folder where cloned dicomtrolley and use
poetry install
- Install pre-commit hooks.
pre-commit install
Make your code contributions. Make sure document and add tests for new features. To automatically publish to pypi, increment the version number. See below.
- Run all tests
- Run pre-commit:
pre-commit run
Create a pull request
A merged pull request will only be published to pypi if it has a new version number. To bump dicomtrolley's version, do the following.
-
dicomtrolley uses semantic versioning Check whether your addition is a PATCH, MINOR or MAJOR version.
-
Manually increment the version number in the following places:
pyproject.toml
->version = "v0.1.2"
dicomtrolley/__init__.py
->__version__ = "v0.1.2"
-
Add a brief description of your updates new version to
HISTORY.md