dbdicom 0.2.6__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbdicom might be problematic. Click here for more details.
- dbdicom-0.3.0/PKG-INFO +28 -0
- dbdicom-0.3.0/README.rst +71 -0
- dbdicom-0.3.0/pyproject.toml +65 -0
- dbdicom-0.3.0/src/dbdicom/__init__.py +1 -0
- dbdicom-0.3.0/src/dbdicom/api.py +267 -0
- dbdicom-0.3.0/src/dbdicom/const.py +144 -0
- dbdicom-0.3.0/src/dbdicom/dataset.py +752 -0
- dbdicom-0.3.0/src/dbdicom/dbd.py +719 -0
- dbdicom-0.3.0/src/dbdicom/external/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom-0.3.0/src/dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom-0.3.0/src/dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom-0.3.0/src/dbdicom/register.py +527 -0
- {dbdicom-0.2.6/src/dbdicom/ds/types → dbdicom-0.3.0/src/dbdicom/sop_classes}/ct_image.py +2 -16
- {dbdicom-0.2.6/src/dbdicom/ds/types → dbdicom-0.3.0/src/dbdicom/sop_classes}/enhanced_mr_image.py +153 -26
- {dbdicom-0.2.6/src/dbdicom/ds/types → dbdicom-0.3.0/src/dbdicom/sop_classes}/mr_image.py +185 -140
- dbdicom-0.3.0/src/dbdicom/sop_classes/parametric_map.py +307 -0
- dbdicom-0.3.0/src/dbdicom/sop_classes/secondary_capture.py +140 -0
- dbdicom-0.3.0/src/dbdicom/sop_classes/segmentation.py +311 -0
- {dbdicom-0.2.6/src/dbdicom/ds/types → dbdicom-0.3.0/src/dbdicom/sop_classes}/ultrasound_multiframe_image.py +1 -15
- {dbdicom-0.2.6/src/dbdicom/ds/types → dbdicom-0.3.0/src/dbdicom/sop_classes}/xray_angiographic_image.py +2 -17
- dbdicom-0.3.0/src/dbdicom/utils/arrays.py +36 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/utils/files.py +0 -20
- dbdicom-0.3.0/src/dbdicom/utils/image.py +117 -0
- dbdicom-0.3.0/src/dbdicom.egg-info/PKG-INFO +28 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom.egg-info/SOURCES.txt +19 -38
- dbdicom-0.3.0/src/dbdicom.egg-info/requires.txt +8 -0
- dbdicom-0.2.6/PKG-INFO +0 -72
- dbdicom-0.2.6/README.md +0 -35
- dbdicom-0.2.6/pyproject.toml +0 -102
- dbdicom-0.2.6/src/dbdicom/__init__.py +0 -28
- dbdicom-0.2.6/src/dbdicom/create.py +0 -457
- dbdicom-0.2.6/src/dbdicom/dro.py +0 -174
- dbdicom-0.2.6/src/dbdicom/ds/__init__.py +0 -10
- dbdicom-0.2.6/src/dbdicom/ds/create.py +0 -63
- dbdicom-0.2.6/src/dbdicom/ds/dataset.py +0 -869
- dbdicom-0.2.6/src/dbdicom/ds/dictionaries.py +0 -620
- dbdicom-0.2.6/src/dbdicom/ds/types/parametric_map.py +0 -226
- dbdicom-0.2.6/src/dbdicom/extensions/__init__.py +0 -9
- dbdicom-0.2.6/src/dbdicom/extensions/dipy.py +0 -448
- dbdicom-0.2.6/src/dbdicom/extensions/elastix.py +0 -503
- dbdicom-0.2.6/src/dbdicom/extensions/matplotlib.py +0 -107
- dbdicom-0.2.6/src/dbdicom/extensions/numpy.py +0 -271
- dbdicom-0.2.6/src/dbdicom/extensions/scipy.py +0 -1512
- dbdicom-0.2.6/src/dbdicom/extensions/skimage.py +0 -1030
- dbdicom-0.2.6/src/dbdicom/extensions/sklearn.py +0 -243
- dbdicom-0.2.6/src/dbdicom/extensions/vreg.py +0 -1390
- dbdicom-0.2.6/src/dbdicom/manager.py +0 -2132
- dbdicom-0.2.6/src/dbdicom/message.py +0 -119
- dbdicom-0.2.6/src/dbdicom/pipelines.py +0 -66
- dbdicom-0.2.6/src/dbdicom/record.py +0 -1893
- dbdicom-0.2.6/src/dbdicom/types/database.py +0 -107
- dbdicom-0.2.6/src/dbdicom/types/instance.py +0 -231
- dbdicom-0.2.6/src/dbdicom/types/patient.py +0 -40
- dbdicom-0.2.6/src/dbdicom/types/series.py +0 -2874
- dbdicom-0.2.6/src/dbdicom/types/study.py +0 -58
- dbdicom-0.2.6/src/dbdicom/utils/image.py +0 -736
- dbdicom-0.2.6/src/dbdicom.egg-info/PKG-INFO +0 -72
- dbdicom-0.2.6/src/dbdicom.egg-info/requires.txt +0 -17
- dbdicom-0.2.6/tests/test_dataset.py +0 -281
- dbdicom-0.2.6/tests/test_dro.py +0 -60
- dbdicom-0.2.6/tests/test_extensions.py +0 -165
- dbdicom-0.2.6/tests/test_manager.py +0 -1350
- dbdicom-0.2.6/tests/test_record.py +0 -1434
- dbdicom-0.2.6/tests/test_series.py +0 -1295
- {dbdicom-0.2.6 → dbdicom-0.3.0}/LICENSE +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/MANIFEST.in +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/setup.cfg +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/README.md +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/bin/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/bin/deidentify +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/bin/deidentify.bat +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/bin/emf2sf +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/bin/emf2sf.bat +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/etc/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/etc/emf2sf/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/etc/emf2sf/log4j.properties +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/__init__.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/commons-cli-1.4.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/dcm4che-core-5.23.1.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/dcm4che-emf-5.23.1.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/dcm4che-tool-common-5.23.1.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/dcm4che-tool-emf2sf-5.23.1.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/log4j-1.2.17.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/macosx-x86-64/libopencv_java.jnilib +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/slf4j-api-1.7.30.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/slf4j-log4j12-1.7.30.jar +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio.dll +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_sse2.dll +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_util.dll +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/utils/dcm4che.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom/utils/variables.py +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom.egg-info/dependency_links.txt +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/src/dbdicom.egg-info/top_level.txt +0 -0
- {dbdicom-0.2.6 → dbdicom-0.3.0}/tests/test_dcm4che.py +0 -0
dbdicom-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dbdicom
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A pythonic interface for reading and writing DICOM databases
|
|
5
|
+
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>, Ebony Gunwhy <e.gunwhy@sheffield.ac.uk>
|
|
6
|
+
Project-URL: Homepage, https://openmiblab.github.io/dbdicom/
|
|
7
|
+
Keywords: python,medical imaging,DICOM
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Requires-Python: >=3.6
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: tqdm
|
|
21
|
+
Requires-Dist: importlib-resources
|
|
22
|
+
Requires-Dist: numpy
|
|
23
|
+
Requires-Dist: pandas
|
|
24
|
+
Requires-Dist: vreg
|
|
25
|
+
Requires-Dist: pydicom
|
|
26
|
+
Requires-Dist: python-gdcm
|
|
27
|
+
Requires-Dist: pylibjpeg-libjpeg
|
|
28
|
+
Dynamic: license-file
|
dbdicom-0.3.0/README.rst
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
dbdicom
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
.. image:: https://img.shields.io/badge/License-Apache_2.0-blue.svg
|
|
5
|
+
:target: https://opensource.org/licenses/Apache-2.0
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
A python interface for reading and writing DICOM databases
|
|
9
|
+
----------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
- **Documentation:** https://openmiblab.github.io/dbdicom/
|
|
12
|
+
- **Source code:** https://github.com/openmiblab/dbdicom
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Installation
|
|
16
|
+
------------
|
|
17
|
+
|
|
18
|
+
.. code-block:: console
|
|
19
|
+
|
|
20
|
+
pip install dbdicom
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Aim
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
Simplify import and export of medical imaging data in DICOM format,
|
|
27
|
+
increase the transparancy of post-processing pipelines for medical
|
|
28
|
+
imaging biomarkers and improving standardization by avoiding the
|
|
29
|
+
need for multiple data formats.
|
|
30
|
+
|
|
31
|
+
Status
|
|
32
|
+
------
|
|
33
|
+
|
|
34
|
+
`dbdicom` version 0.2 (lates 0.2.6) is stable and has been rolled
|
|
35
|
+
out in image processing pipelines of ongoing studies
|
|
36
|
+
`iBEAt <https://bmcnephrol.biomedcentral.com/articles/10.1186/s12882-020-01901-x>`_
|
|
37
|
+
and
|
|
38
|
+
`AFiRM <ttps://www.uhdb.nhs.uk/afirm-study/>`_,
|
|
39
|
+
but is no longer supported and will be phased out.
|
|
40
|
+
|
|
41
|
+
Version 0.3 is a major rewrite based on these experiences aiming to
|
|
42
|
+
simplify the code base and the API, and improve efficiency and
|
|
43
|
+
coverage of DICOM SOP classes. Version 0.3 is currently *work in
|
|
44
|
+
progress* and changes are not backwards compatible with version 0.2.
|
|
45
|
+
|
|
46
|
+
The API reference shows version 0.3 functionality but the user guide
|
|
47
|
+
is for version 0.2. Updates are expected shortly.
|
|
48
|
+
|
|
49
|
+
Citing
|
|
50
|
+
------
|
|
51
|
+
|
|
52
|
+
When you use ``dbdicom``, please cite:
|
|
53
|
+
|
|
54
|
+
Steven Sourbron, Joao Almeida e Sousa, Alexander Daniel,
|
|
55
|
+
Charlotte Buchanan, Ebony Gunwhy, Eve Lennie, Kevin Teh,
|
|
56
|
+
Steve Shillitoe, David Morris, Andrew Priest, David Thomas, and
|
|
57
|
+
Susan Francis. dbdicom: an open-source python interface for reading
|
|
58
|
+
and writing DICOM databases. `Proc Intl Soc Mag Reson Med
|
|
59
|
+
(Toronto, Canada) <https://www.ismrm.org/23m/>`_, #3248, 2023.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
License
|
|
63
|
+
-------
|
|
64
|
+
|
|
65
|
+
``dbdicom`` is distributed under the
|
|
66
|
+
`Apache 2.0 <https://www.apache.org/licenses/LICENSE-2.0>`_ license - a
|
|
67
|
+
permissive, free license that allows users to use, modify, and
|
|
68
|
+
distribute the software without restrictions::
|
|
69
|
+
|
|
70
|
+
Copyright (C) 2023-2025 dbdicom developers
|
|
71
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# https://python-poetry.org/docs/pyproject
|
|
2
|
+
# minimal required information
|
|
3
|
+
|
|
4
|
+
[build-system]
|
|
5
|
+
build-backend = 'setuptools.build_meta'
|
|
6
|
+
requires = ['setuptools>=61.2']
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "dbdicom"
|
|
10
|
+
version = "0.3.0"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"tqdm",
|
|
13
|
+
"importlib-resources",
|
|
14
|
+
"numpy",
|
|
15
|
+
"pandas", # make obsolete
|
|
16
|
+
'vreg',
|
|
17
|
+
"pydicom",
|
|
18
|
+
"python-gdcm",
|
|
19
|
+
"pylibjpeg-libjpeg",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# optional information
|
|
23
|
+
|
|
24
|
+
description = "A pythonic interface for reading and writing DICOM databases"
|
|
25
|
+
readme = "README.md"
|
|
26
|
+
authors = [
|
|
27
|
+
{ name = "Steven Sourbron", email = "s.sourbron@sheffield.ac.uk" },
|
|
28
|
+
{ name = "Ebony Gunwhy", email = "e.gunwhy@sheffield.ac.uk" },
|
|
29
|
+
]
|
|
30
|
+
#license = "Apache-2.0"
|
|
31
|
+
classifiers = [
|
|
32
|
+
# How mature is this project? Common values are
|
|
33
|
+
# 3 - Alpha
|
|
34
|
+
# 4 - Beta
|
|
35
|
+
# 5 - Production/Stable
|
|
36
|
+
'Development Status :: 3 - Alpha',
|
|
37
|
+
|
|
38
|
+
# Indicate who your project is intended for
|
|
39
|
+
'Intended Audience :: Developers',
|
|
40
|
+
'Intended Audience :: Science/Research',
|
|
41
|
+
'Topic :: Scientific/Engineering',
|
|
42
|
+
'Environment :: Console',
|
|
43
|
+
'Operating System :: OS Independent',
|
|
44
|
+
|
|
45
|
+
'License :: OSI Approved :: Apache Software License',
|
|
46
|
+
"Programming Language :: Python",
|
|
47
|
+
"Programming Language :: Python :: 3"
|
|
48
|
+
]
|
|
49
|
+
keywords = ['python', "medical imaging", "DICOM"]
|
|
50
|
+
|
|
51
|
+
requires-python = ">=3.6"
|
|
52
|
+
|
|
53
|
+
[project.urls]
|
|
54
|
+
"Homepage" = "https://openmiblab.github.io/dbdicom/"
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.packages.find]
|
|
57
|
+
where = ["src"]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from dbdicom.api import *
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
import vreg
|
|
4
|
+
|
|
5
|
+
from dbdicom.dbd import DataBaseDicom
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def open(path:str) -> DataBaseDicom:
|
|
9
|
+
"""Open a DICOM database
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
path (str): path to the DICOM folder
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
DataBaseDicom: database instance.
|
|
16
|
+
"""
|
|
17
|
+
return DataBaseDicom(path)
|
|
18
|
+
|
|
19
|
+
def print(path):
|
|
20
|
+
"""Print the contents of the DICOM folder
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
path (str): path to the DICOM folder
|
|
24
|
+
"""
|
|
25
|
+
dbd = open(path)
|
|
26
|
+
dbd.print()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def summary(path) -> dict:
|
|
30
|
+
"""Return a summary of the contents of the database.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
path (str): path to the DICOM folder
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
dict: Nested dictionary with summary information on the database.
|
|
37
|
+
"""
|
|
38
|
+
dbd = open(path)
|
|
39
|
+
return dbd.summary()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def patients(path, name:str=None, contains:str=None, isin:list=None)->list:
|
|
43
|
+
"""Return a list of patients in the DICOM folder.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
path (str): path to the DICOM folder
|
|
47
|
+
name (str, optional): value of PatientName, to search for
|
|
48
|
+
individuals with a given name. Defaults to None.
|
|
49
|
+
contains (str, optional): substring of PatientName, to
|
|
50
|
+
search for individuals based on part of their name.
|
|
51
|
+
Defaults to None.
|
|
52
|
+
isin (list, optional): List of PatientName values, to search
|
|
53
|
+
for patients whose name is in the list. Defaults to None.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
list: list of patients fulfilling the criteria.
|
|
57
|
+
"""
|
|
58
|
+
dbd = open(path)
|
|
59
|
+
return dbd.patients(name, contains, isin)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def studies(entity:str | list, name:str=None, contains:str=None, isin:list=None)->list:
|
|
63
|
+
"""Return a list of studies in the DICOM folder.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
entity (str or list): path to a DICOM folder (to search in
|
|
67
|
+
the whole folder), or a two-element list identifying a
|
|
68
|
+
patient (to search studies of a given patient).
|
|
69
|
+
name (str, optional): value of StudyDescription, to search for
|
|
70
|
+
studies with a given description. Defaults to None.
|
|
71
|
+
contains (str, optional): substring of StudyDescription, to
|
|
72
|
+
search for studies based on part of their description.
|
|
73
|
+
Defaults to None.
|
|
74
|
+
isin (list, optional): List of StudyDescription values, to search
|
|
75
|
+
for studies whose description is in a list. Defaults to None.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
list: list of studies fulfilling the criteria.
|
|
79
|
+
"""
|
|
80
|
+
if isinstance(entity, str): # path = folder
|
|
81
|
+
dbd = open(entity)
|
|
82
|
+
return dbd.studies(entity, name, contains, isin)
|
|
83
|
+
elif len(entity)==2: # path = patient
|
|
84
|
+
dbd = open(entity[0])
|
|
85
|
+
return dbd.studies(entity, name, contains, isin)
|
|
86
|
+
else:
|
|
87
|
+
raise ValueError(
|
|
88
|
+
"The path must be a folder or a 2-element list "
|
|
89
|
+
"with a folder and a patient name."
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def series(entity:str | list, name:str=None, contains:str=None, isin:list=None)->list:
|
|
93
|
+
"""Return a list of series in the DICOM folder.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
entity (str or list): path to a DICOM folder (to search in
|
|
97
|
+
the whole folder), or a list identifying a
|
|
98
|
+
patient or a study (to search series of a given patient
|
|
99
|
+
or study).
|
|
100
|
+
name (str, optional): value of SeriesDescription, to search for
|
|
101
|
+
series with a given description. Defaults to None.
|
|
102
|
+
contains (str, optional): substring of SeriesDescription, to
|
|
103
|
+
search for series based on part of their description.
|
|
104
|
+
Defaults to None.
|
|
105
|
+
isin (list, optional): List of SeriesDescription values, to search
|
|
106
|
+
for series whose description is in a list. Defaults to None.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
list: list of series fulfilling the criteria.
|
|
110
|
+
"""
|
|
111
|
+
if isinstance(entity, str): # path = folder
|
|
112
|
+
dbd = open(entity)
|
|
113
|
+
return dbd.series(entity, name, contains, isin)
|
|
114
|
+
elif len(entity) in [2,3]:
|
|
115
|
+
dbd = open(entity[0])
|
|
116
|
+
return dbd.series(entity, name, contains, isin)
|
|
117
|
+
else:
|
|
118
|
+
raise ValueError(
|
|
119
|
+
"To retrieve a series, the entity must be a database, patient or study."
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def copy(from_entity:list, to_entity:list):
|
|
123
|
+
"""Copy a DICOM entity (patient, study or series)
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
from_entity (list): entity to copy
|
|
127
|
+
to_entity (list): entity after copying.
|
|
128
|
+
"""
|
|
129
|
+
dbd = open(from_entity[0])
|
|
130
|
+
dbd.copy(from_entity, to_entity)
|
|
131
|
+
dbd.close()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def delete(entity:list):
|
|
135
|
+
"""Delete a DICOM entity
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
entity (list): entity to delete
|
|
139
|
+
"""
|
|
140
|
+
dbd = open(entity[0])
|
|
141
|
+
dbd.delete(entity)
|
|
142
|
+
dbd.close()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def move(from_entity:list, to_entity:list):
|
|
146
|
+
"""Move a DICOM entity
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
entity (list): entity to move
|
|
150
|
+
"""
|
|
151
|
+
dbd = open(from_entity[0])
|
|
152
|
+
dbd.copy(from_entity, to_entity)
|
|
153
|
+
dbd.delete(from_entity)
|
|
154
|
+
dbd.close()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def volume(series:list, dims:list=None, multislice=False) -> vreg.Volume3D:
|
|
158
|
+
"""Read a vreg.Volume3D from a DICOM series
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
series (list): DICOM series to read
|
|
162
|
+
dims (list, optional): Non-spatial dimensions of the volume. Defaults to None.
|
|
163
|
+
multislice (bool, optional): Whether the data are to be read
|
|
164
|
+
as multislice or not. In multislice data the voxel size
|
|
165
|
+
is taken from the slice gap rather thsan the slice thickness. Defaults to False.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
vreg.Volume3D: vole read from the series.
|
|
169
|
+
"""
|
|
170
|
+
dbd = open(series[0])
|
|
171
|
+
return dbd.volume(series, dims, multislice)
|
|
172
|
+
|
|
173
|
+
def write_volume(vol:vreg.Volume3D, series:list, ref:list=None,
|
|
174
|
+
multislice=False):
|
|
175
|
+
"""Write a vreg.Volume3D to a DICOM series
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
vol (vreg.Volume3D): Volume to write to the series.
|
|
179
|
+
series (list): DICOM series to read
|
|
180
|
+
dims (list, optional): Non-spatial dimensions of the volume. Defaults to None.
|
|
181
|
+
multislice (bool, optional): Whether the data are to be read
|
|
182
|
+
as multislice or not. In multislice data the voxel size
|
|
183
|
+
is taken from the slice gap rather thsan the slice thickness. Defaults to False.
|
|
184
|
+
"""
|
|
185
|
+
dbd = open(series[0])
|
|
186
|
+
dbd.write_volume(vol, series, ref, multislice)
|
|
187
|
+
dbd.close()
|
|
188
|
+
|
|
189
|
+
def to_nifti(series:list, file:str, dims:list=None, multislice=False):
|
|
190
|
+
"""Save a DICOM series in nifti format.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
series (list): DICOM series to read
|
|
194
|
+
file (str): file path of the nifti file.
|
|
195
|
+
dims (list, optional): Non-spatial dimensions of the volume.
|
|
196
|
+
Defaults to None.
|
|
197
|
+
multislice (bool, optional): Whether the data are to be read
|
|
198
|
+
as multislice or not. In multislice data the voxel size
|
|
199
|
+
is taken from the slice gap rather thaan the slice thickness. Defaults to False.
|
|
200
|
+
"""
|
|
201
|
+
dbd = open(series[0])
|
|
202
|
+
dbd.to_nifti(series, file, dims, multislice)
|
|
203
|
+
|
|
204
|
+
def from_nifti(file:str, series:list, ref:list=None, multislice=False):
|
|
205
|
+
"""Create a DICOM series from a nifti file.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
file (str): file path of the nifti file.
|
|
209
|
+
series (list): DICOM series to create
|
|
210
|
+
ref (list): DICOM series to use as template.
|
|
211
|
+
multislice (bool, optional): Whether the data are to be written
|
|
212
|
+
as multislice or not. In multislice data the voxel size
|
|
213
|
+
is written in the slice gap rather thaan the slice thickness. Defaults to False.
|
|
214
|
+
"""
|
|
215
|
+
dbd = open(series[0])
|
|
216
|
+
dbd.from_nifti(file, series, ref, multislice)
|
|
217
|
+
dbd.close()
|
|
218
|
+
|
|
219
|
+
def pixel_data(series:list, dims:list=None, include:list=None) -> tuple:
|
|
220
|
+
"""Read the pixel data from a DICOM series
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
series (list): DICOM series to read
|
|
224
|
+
dims (list, optional): Dimensions of the array.
|
|
225
|
+
include (list, optional): list of DICOM attributes that are
|
|
226
|
+
read on the fly to avoid reading the data twice.
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
tuple: numpy array with pixel values and an array with
|
|
230
|
+
coordinates of the slices according to dims. If include
|
|
231
|
+
is provide these are returned as a dictionary in a third
|
|
232
|
+
return value.
|
|
233
|
+
"""
|
|
234
|
+
dbd = open(series[0])
|
|
235
|
+
return dbd.pixel_data(series, dims, include)
|
|
236
|
+
|
|
237
|
+
# write_pixel_data()
|
|
238
|
+
# values()
|
|
239
|
+
# write_values()
|
|
240
|
+
# to_png(series, folder, dims)
|
|
241
|
+
# to_npy(series, folder, dims)
|
|
242
|
+
# split(series, attribute)
|
|
243
|
+
# extract(series, *kwargs) # subseries
|
|
244
|
+
|
|
245
|
+
# zeros(series, shape, dims)
|
|
246
|
+
|
|
247
|
+
def unique(pars:list, entity:list) -> dict:
|
|
248
|
+
"""Return a list of unique values for a DICOM entity
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
pars (list): attributes to return.
|
|
252
|
+
entity (list): DICOM entity to search (Patient, Study or Series)
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
dict: dictionary with unique values for each attribute.
|
|
256
|
+
"""
|
|
257
|
+
dbd = open(entity[0])
|
|
258
|
+
return dbd.unique(pars, entity)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
if __name__=='__main__':
|
|
266
|
+
|
|
267
|
+
pass
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
PATIENT_MODULE = [
|
|
4
|
+
'ReferencedPatientSequence',
|
|
5
|
+
'PatientName',
|
|
6
|
+
'PatientID',
|
|
7
|
+
'IssuerOfPatientID',
|
|
8
|
+
'TypeOfPatientID',
|
|
9
|
+
'IssuerOfPatientIDQualifiersSequence',
|
|
10
|
+
'SourcePatientGroupIdentificationSequence',
|
|
11
|
+
'GroupOfPatientsIdentificationSequence',
|
|
12
|
+
'PatientBirthDate',
|
|
13
|
+
'PatientBirthTime',
|
|
14
|
+
'PatientBirthDateInAlternativeCalendar',
|
|
15
|
+
'PatientDeathDateInAlternativeCalendar',
|
|
16
|
+
'PatientAlternativeCalendar',
|
|
17
|
+
'PatientSex',
|
|
18
|
+
'QualityControlSubject',
|
|
19
|
+
'StrainDescription',
|
|
20
|
+
'StrainNomenclature',
|
|
21
|
+
'StrainStockSequence',
|
|
22
|
+
'StrainAdditionalInformation',
|
|
23
|
+
'StrainCodeSequence',
|
|
24
|
+
'GeneticModificationsSequence',
|
|
25
|
+
'OtherPatientNames',
|
|
26
|
+
'OtherPatientIDsSequence',
|
|
27
|
+
'ReferencedPatientPhotoSequence',
|
|
28
|
+
'EthnicGroup',
|
|
29
|
+
'PatientSpeciesDescription',
|
|
30
|
+
'PatientSpeciesCodeSequence',
|
|
31
|
+
'PatientBreedDescription',
|
|
32
|
+
'PatientBreedCodeSequence',
|
|
33
|
+
'BreedRegistrationSequence',
|
|
34
|
+
'ResponsiblePerson',
|
|
35
|
+
'ResponsiblePersonRole',
|
|
36
|
+
'ResponsibleOrganization',
|
|
37
|
+
'PatientComments',
|
|
38
|
+
'PatientIdentityRemoved',
|
|
39
|
+
'DeidentificationMethod',
|
|
40
|
+
'DeidentificationMethodCodeSequence',
|
|
41
|
+
'ClinicalTrialSponsorName',
|
|
42
|
+
'ClinicalTrialProtocolID',
|
|
43
|
+
'ClinicalTrialProtocolName',
|
|
44
|
+
'ClinicalTrialSiteID',
|
|
45
|
+
'ClinicalTrialSiteName',
|
|
46
|
+
'ClinicalTrialSubjectID',
|
|
47
|
+
'ClinicalTrialSubjectReadingID',
|
|
48
|
+
'ClinicalTrialProtocolEthicsCommitteeName',
|
|
49
|
+
'ClinicalTrialProtocolEthicsCommitteeApprovalNumber',
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
STUDY_MODULE = [
|
|
55
|
+
'StudyDate',
|
|
56
|
+
'StudyTime',
|
|
57
|
+
'AccessionNumber',
|
|
58
|
+
'IssuerOfAccessionNumberSequence',
|
|
59
|
+
'ReferringPhysicianName',
|
|
60
|
+
'ReferringPhysicianIdentificationSequence',
|
|
61
|
+
'ConsultingPhysicianName',
|
|
62
|
+
'ConsultingPhysicianIdentificationSequence',
|
|
63
|
+
'StudyDescription',
|
|
64
|
+
'ProcedureCodeSequence',
|
|
65
|
+
'PhysiciansOfRecord',
|
|
66
|
+
'PhysiciansOfRecordIdentificationSequence',
|
|
67
|
+
'NameOfPhysiciansReadingStudy',
|
|
68
|
+
'PhysiciansReadingStudyIdentificationSequence',
|
|
69
|
+
'ReferencedStudySequence',
|
|
70
|
+
'StudyInstanceUID',
|
|
71
|
+
'StudyID',
|
|
72
|
+
'RequestingService',
|
|
73
|
+
'RequestingServiceCodeSequence',
|
|
74
|
+
'ReasonForPerformedProcedureCodeSequence',
|
|
75
|
+
'AdmittingDiagnosesDescription',
|
|
76
|
+
'AdmittingDiagnosesCodeSequence',
|
|
77
|
+
'PatientAge',
|
|
78
|
+
'PatientSize',
|
|
79
|
+
'PatientSizeCodeSequence',
|
|
80
|
+
'PatientBodyMassIndex',
|
|
81
|
+
'MeasuredAPDimension',
|
|
82
|
+
'MeasuredLateralDimension',
|
|
83
|
+
'PatientWeight',
|
|
84
|
+
'MedicalAlerts',
|
|
85
|
+
'Allergies',
|
|
86
|
+
'Occupation',
|
|
87
|
+
'SmokingStatus',
|
|
88
|
+
'AdditionalPatientHistory',
|
|
89
|
+
'PregnancyStatus',
|
|
90
|
+
'LastMenstrualDate',
|
|
91
|
+
'PatientSexNeutered',
|
|
92
|
+
'ReasonForVisit',
|
|
93
|
+
'ReasonForVisitCodeSequence',
|
|
94
|
+
'AdmissionID',
|
|
95
|
+
'IssuerOfAdmissionIDSequence',
|
|
96
|
+
'ServiceEpisodeID',
|
|
97
|
+
'ServiceEpisodeDescription',
|
|
98
|
+
'IssuerOfServiceEpisodeIDSequence',
|
|
99
|
+
'PatientState',
|
|
100
|
+
'ClinicalTrialTimePointID',
|
|
101
|
+
'ClinicalTrialTimePointDescription',
|
|
102
|
+
'LongitudinalTemporalOffsetFromEvent',
|
|
103
|
+
'LongitudinalTemporalEventType',
|
|
104
|
+
'ConsentForClinicalTrialUseSequence',
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
SERIES_MODULE = [
|
|
110
|
+
'SeriesDate',
|
|
111
|
+
'SeriesTime',
|
|
112
|
+
'Modality',
|
|
113
|
+
'SeriesDescription',
|
|
114
|
+
'SeriesDescriptionCodeSequence',
|
|
115
|
+
'PerformingPhysicianName',
|
|
116
|
+
'PerformingPhysicianIdentificationSequence',
|
|
117
|
+
'OperatorsName',
|
|
118
|
+
'OperatorIdentificationSequence',
|
|
119
|
+
'ReferencedPerformedProcedureStepSequence',
|
|
120
|
+
'RelatedSeriesSequence',
|
|
121
|
+
'AnatomicalOrientationType',
|
|
122
|
+
'BodyPartExamined',
|
|
123
|
+
'ProtocolName',
|
|
124
|
+
'PatientPosition',
|
|
125
|
+
'ReferencedDefinedProtocolSequence',
|
|
126
|
+
'ReferencedPerformedProtocolSequence',
|
|
127
|
+
'SeriesInstanceUID',
|
|
128
|
+
'SeriesNumber',
|
|
129
|
+
'Laterality',
|
|
130
|
+
'SmallestPixelValueInSeries',
|
|
131
|
+
'LargestPixelValueInSeries',
|
|
132
|
+
'PerformedProcedureStepStartDate',
|
|
133
|
+
'PerformedProcedureStepStartTime',
|
|
134
|
+
'PerformedProcedureStepEndDate',
|
|
135
|
+
'PerformedProcedureStepEndTime',
|
|
136
|
+
'PerformedProcedureStepID',
|
|
137
|
+
'PerformedProcedureStepDescription',
|
|
138
|
+
'PerformedProtocolCodeSequence',
|
|
139
|
+
'RequestAttributesSequence',
|
|
140
|
+
'CommentsOnThePerformedProcedureStep',
|
|
141
|
+
'ClinicalTrialCoordinatingCenterName',
|
|
142
|
+
'ClinicalTrialSeriesID',
|
|
143
|
+
'ClinicalTrialSeriesDescription',
|
|
144
|
+
]
|