dbdicom 0.3.1__tar.gz → 0.3.2__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.1/src/dbdicom.egg-info → dbdicom-0.3.2}/PKG-INFO +2 -4
- {dbdicom-0.3.1 → dbdicom-0.3.2}/pyproject.toml +4 -4
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/api.py +24 -1
- dbdicom-0.3.2/src/dbdicom/database.py +122 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/dataset.py +16 -34
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/dbd.py +92 -167
- dbdicom-0.3.2/src/dbdicom/register.py +608 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/mr_image.py +122 -130
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/parametric_map.py +93 -22
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/utils/image.py +7 -6
- {dbdicom-0.3.1 → dbdicom-0.3.2/src/dbdicom.egg-info}/PKG-INFO +2 -4
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom.egg-info/SOURCES.txt +2 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom.egg-info/requires.txt +1 -3
- dbdicom-0.3.2/tests/test_api.py +25 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/tests/test_dcm4che.py +2 -4
- dbdicom-0.3.1/src/dbdicom/register.py +0 -527
- {dbdicom-0.3.1 → dbdicom-0.3.2}/LICENSE +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/MANIFEST.in +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/README.rst +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/setup.cfg +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/const.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/__pycache__/__init__.cpython-311.pyc +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/README.md +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/deidentify +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/deidentify.bat +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/emf2sf +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/bin/emf2sf.bat +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/etc/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/etc/emf2sf/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/etc/emf2sf/log4j.properties +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/__init__.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/commons-cli-1.4.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/dcm4che-core-5.23.1.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/dcm4che-emf-5.23.1.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/dcm4che-tool-common-5.23.1.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/dcm4che-tool-emf2sf-5.23.1.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/log4j-1.2.17.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/macosx-x86-64/libopencv_java.jnilib +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/slf4j-api-1.7.30.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/slf4j-log4j12-1.7.30.jar +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio.dll +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_sse2.dll +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_util.dll +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/ct_image.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/enhanced_mr_image.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/secondary_capture.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/segmentation.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/ultrasound_multiframe_image.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/sop_classes/xray_angiographic_image.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/utils/arrays.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/utils/dcm4che.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/utils/files.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom/utils/variables.py +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom.egg-info/dependency_links.txt +0 -0
- {dbdicom-0.3.1 → dbdicom-0.3.2}/src/dbdicom.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbdicom
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A pythonic interface for reading and writing DICOM databases
|
|
5
5
|
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>, Ebony Gunwhy <e.gunwhy@sheffield.ac.uk>
|
|
6
6
|
Project-URL: Homepage, https://openmiblab.github.io/dbdicom/
|
|
@@ -22,7 +22,5 @@ Requires-Dist: importlib-resources
|
|
|
22
22
|
Requires-Dist: numpy
|
|
23
23
|
Requires-Dist: pandas
|
|
24
24
|
Requires-Dist: vreg
|
|
25
|
-
Requires-Dist: pydicom
|
|
26
|
-
Requires-Dist: python-gdcm
|
|
27
|
-
Requires-Dist: pylibjpeg-libjpeg
|
|
25
|
+
Requires-Dist: pydicom[basic,pixeldata]
|
|
28
26
|
Dynamic: license-file
|
|
@@ -7,16 +7,16 @@ requires = ['setuptools>=61.2']
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "dbdicom"
|
|
10
|
-
version = "0.3.
|
|
10
|
+
version = "0.3.2"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"tqdm",
|
|
13
13
|
"importlib-resources",
|
|
14
14
|
"numpy",
|
|
15
15
|
"pandas", # make obsolete
|
|
16
16
|
'vreg',
|
|
17
|
-
"pydicom",
|
|
18
|
-
"python-gdcm",
|
|
19
|
-
"pylibjpeg-libjpeg",
|
|
17
|
+
"pydicom[basic,pixeldata]",
|
|
18
|
+
#"python-gdcm",
|
|
19
|
+
#"pylibjpeg-libjpeg",
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
# optional information
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
import numpy as np
|
|
3
2
|
import vreg
|
|
4
3
|
|
|
5
4
|
from dbdicom.dbd import DataBaseDicom
|
|
@@ -16,6 +15,15 @@ def open(path:str) -> DataBaseDicom:
|
|
|
16
15
|
"""
|
|
17
16
|
return DataBaseDicom(path)
|
|
18
17
|
|
|
18
|
+
def to_json(path):
|
|
19
|
+
"""Summarise the contents of the DICOM folder in a json file
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
path (str): path to the DICOM folder
|
|
23
|
+
"""
|
|
24
|
+
dbd = open(path)
|
|
25
|
+
dbd.close()
|
|
26
|
+
|
|
19
27
|
def print(path):
|
|
20
28
|
"""Print the contents of the DICOM folder
|
|
21
29
|
|
|
@@ -42,6 +50,21 @@ def summary(path) -> dict:
|
|
|
42
50
|
return s
|
|
43
51
|
|
|
44
52
|
|
|
53
|
+
def tree(path) -> dict:
|
|
54
|
+
"""Return the structure of the database as a dictionary tree.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
path (str): path to the DICOM folder
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
dict: Nested dictionary with summary information on the database.
|
|
61
|
+
"""
|
|
62
|
+
dbd = open(path)
|
|
63
|
+
s = dbd.register
|
|
64
|
+
dbd.close()
|
|
65
|
+
return s
|
|
66
|
+
|
|
67
|
+
|
|
45
68
|
def patients(path, name:str=None, contains:str=None, isin:list=None)->list:
|
|
46
69
|
"""Return a list of patients in the DICOM folder.
|
|
47
70
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from tqdm import tqdm
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import pydicom
|
|
7
|
+
|
|
8
|
+
import dbdicom.utils.dcm4che as dcm4che
|
|
9
|
+
import dbdicom.utils.files as filetools
|
|
10
|
+
import dbdicom.dataset as dbdataset
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
COLUMNS = [
|
|
14
|
+
# Identifiers (unique)
|
|
15
|
+
'PatientID',
|
|
16
|
+
'StudyInstanceUID',
|
|
17
|
+
'SeriesInstanceUID',
|
|
18
|
+
'SOPInstanceUID',
|
|
19
|
+
# Human-readable identifiers (not unique)
|
|
20
|
+
'PatientName',
|
|
21
|
+
'StudyDescription',
|
|
22
|
+
'StudyDate',
|
|
23
|
+
'SeriesDescription',
|
|
24
|
+
'SeriesNumber',
|
|
25
|
+
'InstanceNumber',
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
def read(path):
|
|
29
|
+
files = filetools.all_files(path)
|
|
30
|
+
tags = COLUMNS + ['NumberOfFrames'] # + ['SOPClassUID']
|
|
31
|
+
array = []
|
|
32
|
+
dicom_files = []
|
|
33
|
+
for i, file in tqdm(enumerate(files), total=len(files), desc='Reading DICOM folder'):
|
|
34
|
+
try:
|
|
35
|
+
ds = pydicom.dcmread(file, force=True, specific_tags=tags+['Rows'])
|
|
36
|
+
except:
|
|
37
|
+
pass
|
|
38
|
+
else:
|
|
39
|
+
if isinstance(ds, pydicom.dataset.FileDataset):
|
|
40
|
+
if 'TransferSyntaxUID' in ds.file_meta:
|
|
41
|
+
if not 'Rows' in ds: # Image only
|
|
42
|
+
continue
|
|
43
|
+
row = dbdataset.get_values(ds, tags)
|
|
44
|
+
array.append(row)
|
|
45
|
+
index = os.path.relpath(file, path)
|
|
46
|
+
dicom_files.append(index)
|
|
47
|
+
df = pd.DataFrame(array, index = dicom_files, columns = tags)
|
|
48
|
+
df = _multiframe_to_singleframe(path, df)
|
|
49
|
+
dbtree = _tree(df)
|
|
50
|
+
return dbtree
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _multiframe_to_singleframe(path, df):
|
|
54
|
+
"""Converts all multiframe files in the folder into single-frame files.
|
|
55
|
+
|
|
56
|
+
Reads all the multi-frame files in the folder,
|
|
57
|
+
converts them to singleframe files, and delete the original multiframe file.
|
|
58
|
+
"""
|
|
59
|
+
singleframe = df.NumberOfFrames.isnull()
|
|
60
|
+
multiframe = singleframe == False
|
|
61
|
+
nr_multiframe = multiframe.sum()
|
|
62
|
+
if nr_multiframe != 0:
|
|
63
|
+
for relpath in tqdm(df[multiframe].index.values, desc="Converting multiframe file " + relpath):
|
|
64
|
+
filepath = os.path.join(path, relpath)
|
|
65
|
+
singleframe_files = dcm4che.split_multiframe(filepath)
|
|
66
|
+
if singleframe_files != []:
|
|
67
|
+
# add the single frame files to the dataframe
|
|
68
|
+
dfnew = read(singleframe_files, df.columns, path)
|
|
69
|
+
df = pd.concat([df, dfnew])
|
|
70
|
+
# delete the original multiframe
|
|
71
|
+
os.remove(filepath)
|
|
72
|
+
# drop the file also if the conversion has failed
|
|
73
|
+
df.drop(index=relpath, inplace=True)
|
|
74
|
+
df.drop('NumberOfFrames', axis=1, inplace=True)
|
|
75
|
+
return df
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _tree(df):
|
|
79
|
+
# A human-readable summary tree
|
|
80
|
+
|
|
81
|
+
df.sort_values(['PatientID','StudyInstanceUID','SeriesNumber'], inplace=True)
|
|
82
|
+
df = df.fillna('None')
|
|
83
|
+
summary = []
|
|
84
|
+
|
|
85
|
+
for uid_patient in df.PatientID.unique():
|
|
86
|
+
df_patient = df[df.PatientID == uid_patient]
|
|
87
|
+
patient_name = df_patient.PatientName.values[0]
|
|
88
|
+
patient = {
|
|
89
|
+
'PatientName': patient_name,
|
|
90
|
+
'PatientID': uid_patient,
|
|
91
|
+
'studies': [],
|
|
92
|
+
}
|
|
93
|
+
summary.append(patient)
|
|
94
|
+
for uid_study in df_patient.StudyInstanceUID.unique():
|
|
95
|
+
df_study = df_patient[df_patient.StudyInstanceUID == uid_study]
|
|
96
|
+
study_desc = df_study.StudyDescription.values[0]
|
|
97
|
+
study_date = df_study.StudyDate.values[0]
|
|
98
|
+
study = {
|
|
99
|
+
'StudyDescription': study_desc,
|
|
100
|
+
'StudyDate': study_date,
|
|
101
|
+
'StudyInstanceUID': uid_study,
|
|
102
|
+
'series': [],
|
|
103
|
+
}
|
|
104
|
+
patient['studies'].append(study)
|
|
105
|
+
for uid_sery in df_study.SeriesInstanceUID.unique():
|
|
106
|
+
df_series = df_study[df_study.SeriesInstanceUID == uid_sery]
|
|
107
|
+
series_desc = df_series.SeriesDescription.values[0]
|
|
108
|
+
series_nr = int(df_series.SeriesNumber.values[0])
|
|
109
|
+
series = {
|
|
110
|
+
'SeriesNumber': series_nr,
|
|
111
|
+
'SeriesDescription': series_desc,
|
|
112
|
+
'SeriesInstanceUID': uid_sery,
|
|
113
|
+
'instances': {},
|
|
114
|
+
}
|
|
115
|
+
study['series'].append(series)
|
|
116
|
+
for uid_instance in df_series.SOPInstanceUID.unique():
|
|
117
|
+
df_instance = df_series[df_series.SOPInstanceUID == uid_instance]
|
|
118
|
+
instance_nr = int(df_instance.InstanceNumber.values[0])
|
|
119
|
+
relpath = df_instance.index[0]
|
|
120
|
+
series['instances'][instance_nr]=relpath
|
|
121
|
+
|
|
122
|
+
return summary
|
|
@@ -7,13 +7,12 @@ import struct
|
|
|
7
7
|
from tqdm import tqdm
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
|
-
import pandas as pd
|
|
11
10
|
import pydicom
|
|
12
11
|
from pydicom.util.codify import code_file
|
|
13
12
|
import pydicom.config
|
|
14
|
-
from pydicom.dataset import Dataset
|
|
15
13
|
import vreg
|
|
16
14
|
|
|
15
|
+
|
|
17
16
|
import dbdicom.utils.image as image
|
|
18
17
|
import dbdicom.utils.variables as variables
|
|
19
18
|
from dbdicom.sop_classes import (
|
|
@@ -74,6 +73,8 @@ def new_dataset(sop_class):
|
|
|
74
73
|
return xray_angiographic_image.default()
|
|
75
74
|
if sop_class == 'UltrasoundMultiFrameImage':
|
|
76
75
|
return ultrasound_multiframe_image.default()
|
|
76
|
+
if sop_class == 'ParametricMap':
|
|
77
|
+
return parametric_map.default()
|
|
77
78
|
else:
|
|
78
79
|
raise ValueError(
|
|
79
80
|
f"DICOM class {sop_class} is not currently supported"
|
|
@@ -238,7 +239,7 @@ def codify(source_file, save_file, **kwargs):
|
|
|
238
239
|
file.close()
|
|
239
240
|
|
|
240
241
|
|
|
241
|
-
def read_data(files, tags, path=None, images_only=False):
|
|
242
|
+
def read_data(files, tags, path=None, images_only=False): # obsolete??
|
|
242
243
|
|
|
243
244
|
if np.isscalar(files):
|
|
244
245
|
files = [files]
|
|
@@ -266,34 +267,6 @@ def read_data(files, tags, path=None, images_only=False):
|
|
|
266
267
|
|
|
267
268
|
|
|
268
269
|
|
|
269
|
-
def read_dataframe(files, tags, path=None, images_only=False):
|
|
270
|
-
if np.isscalar(files):
|
|
271
|
-
files = [files]
|
|
272
|
-
if np.isscalar(tags):
|
|
273
|
-
tags = [tags]
|
|
274
|
-
array = []
|
|
275
|
-
dicom_files = []
|
|
276
|
-
for i, file in tqdm(enumerate(files), desc='Reading DICOM folder'):
|
|
277
|
-
try:
|
|
278
|
-
ds = pydicom.dcmread(file, force=True, specific_tags=tags+['Rows'])
|
|
279
|
-
except:
|
|
280
|
-
pass
|
|
281
|
-
else:
|
|
282
|
-
if isinstance(ds, pydicom.dataset.FileDataset):
|
|
283
|
-
if 'TransferSyntaxUID' in ds.file_meta:
|
|
284
|
-
if images_only:
|
|
285
|
-
if not 'Rows' in ds:
|
|
286
|
-
continue
|
|
287
|
-
row = get_values(ds, tags)
|
|
288
|
-
array.append(row)
|
|
289
|
-
if path is None:
|
|
290
|
-
index = file
|
|
291
|
-
else:
|
|
292
|
-
index = os.path.relpath(file, path)
|
|
293
|
-
dicom_files.append(index)
|
|
294
|
-
df = pd.DataFrame(array, index = dicom_files, columns = tags)
|
|
295
|
-
return df
|
|
296
|
-
|
|
297
270
|
|
|
298
271
|
def _add_new(ds, tag, value, VR='OW'):
|
|
299
272
|
if not isinstance(tag, pydicom.tag.BaseTag):
|
|
@@ -586,7 +559,7 @@ def pixel_data(ds):
|
|
|
586
559
|
try:
|
|
587
560
|
array = ds.pixel_array
|
|
588
561
|
except:
|
|
589
|
-
|
|
562
|
+
raise ValueError("Dataset has no pixel data.")
|
|
590
563
|
array = array.astype(np.float32)
|
|
591
564
|
slope = float(getattr(ds, 'RescaleSlope', 1))
|
|
592
565
|
intercept = float(getattr(ds, 'RescaleIntercept', 0))
|
|
@@ -595,7 +568,7 @@ def pixel_data(ds):
|
|
|
595
568
|
return np.transpose(array)
|
|
596
569
|
|
|
597
570
|
|
|
598
|
-
def set_pixel_data(ds, array
|
|
571
|
+
def set_pixel_data(ds, array):
|
|
599
572
|
if array is None:
|
|
600
573
|
raise ValueError('The pixel array cannot be set to an empty value.')
|
|
601
574
|
|
|
@@ -611,7 +584,7 @@ def set_pixel_data(ds, array, value_range=None):
|
|
|
611
584
|
# if array.ndim >= 3: # remove spurious dimensions of 1
|
|
612
585
|
# array = np.squeeze(array)
|
|
613
586
|
|
|
614
|
-
array = image.clip(array.astype(np.float32)
|
|
587
|
+
array = image.clip(array.astype(np.float32))
|
|
615
588
|
array, slope, intercept = image.scale_to_range(array, ds.BitsAllocated)
|
|
616
589
|
array = np.transpose(array)
|
|
617
590
|
|
|
@@ -635,6 +608,15 @@ def volume(ds, multislice=False):
|
|
|
635
608
|
def set_volume(ds, volume:vreg.Volume3D, multislice=False):
|
|
636
609
|
if volume is None:
|
|
637
610
|
raise ValueError('The volume cannot be set to an empty value.')
|
|
611
|
+
try:
|
|
612
|
+
mod = SOPCLASSMODULE[ds.SOPClassUID]
|
|
613
|
+
except KeyError:
|
|
614
|
+
raise ValueError(
|
|
615
|
+
f"DICOM class {ds.SOPClassUID} is not currently supported."
|
|
616
|
+
)
|
|
617
|
+
if hasattr(mod, 'set_volume'):
|
|
618
|
+
return getattr(mod, 'set_volume')(ds, volume)
|
|
619
|
+
|
|
638
620
|
image = np.squeeze(volume.values)
|
|
639
621
|
if image.ndim != 2:
|
|
640
622
|
raise ValueError("Can only write 2D images to a dataset.")
|