dbdicom 0.2.0__py3-none-any.whl → 0.3.16__py3-none-any.whl
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.
- dbdicom/__init__.py +3 -25
- dbdicom/api.py +496 -0
- dbdicom/const.py +144 -0
- dbdicom/database.py +133 -0
- dbdicom/dataset.py +471 -0
- dbdicom/dbd.py +1290 -0
- dbdicom/external/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/bin/emf2sf +57 -57
- dbdicom/register.py +402 -0
- dbdicom/{ds/types → sop_classes}/ct_image.py +2 -16
- dbdicom/{ds/types → sop_classes}/enhanced_mr_image.py +206 -160
- dbdicom/sop_classes/mr_image.py +338 -0
- dbdicom/sop_classes/parametric_map.py +381 -0
- dbdicom/sop_classes/secondary_capture.py +140 -0
- dbdicom/sop_classes/segmentation.py +311 -0
- dbdicom/{ds/types → sop_classes}/ultrasound_multiframe_image.py +1 -15
- dbdicom/{ds/types → sop_classes}/xray_angiographic_image.py +2 -17
- dbdicom/utils/arrays.py +142 -0
- dbdicom/utils/files.py +0 -20
- dbdicom/utils/image.py +43 -466
- dbdicom/utils/pydicom_dataset.py +386 -0
- dbdicom-0.3.16.dist-info/METADATA +26 -0
- dbdicom-0.3.16.dist-info/RECORD +54 -0
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/WHEEL +1 -1
- dbdicom/create.py +0 -450
- dbdicom/ds/__init__.py +0 -10
- dbdicom/ds/create.py +0 -63
- dbdicom/ds/dataset.py +0 -841
- dbdicom/ds/dictionaries.py +0 -620
- dbdicom/ds/types/mr_image.py +0 -267
- dbdicom/ds/types/parametric_map.py +0 -226
- dbdicom/external/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/lib/linux-x86/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/linux-x86-64/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/linux-x86-64/libopencv_java.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis2.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis2.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-x86/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-x86-64/libclib_jiio.so +0 -0
- dbdicom/manager.py +0 -2077
- dbdicom/message.py +0 -119
- dbdicom/record.py +0 -1526
- dbdicom/types/database.py +0 -107
- dbdicom/types/instance.py +0 -184
- dbdicom/types/patient.py +0 -40
- dbdicom/types/series.py +0 -816
- dbdicom/types/study.py +0 -58
- dbdicom/utils/variables.py +0 -155
- dbdicom/utils/vreg.py +0 -2626
- dbdicom/wrappers/__init__.py +0 -7
- dbdicom/wrappers/dipy.py +0 -462
- dbdicom/wrappers/elastix.py +0 -855
- dbdicom/wrappers/numpy.py +0 -119
- dbdicom/wrappers/scipy.py +0 -1413
- dbdicom/wrappers/skimage.py +0 -1030
- dbdicom/wrappers/sklearn.py +0 -151
- dbdicom/wrappers/vreg.py +0 -273
- dbdicom-0.2.0.dist-info/METADATA +0 -276
- dbdicom-0.2.0.dist-info/RECORD +0 -81
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info/licenses}/LICENSE +0 -0
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import datetime
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pydicom
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_values(ds, tags):
|
|
10
|
+
"""Return a list of values for a dataset"""
|
|
11
|
+
|
|
12
|
+
# https://pydicom.github.io/pydicom/stable/guides/element_value_types.html
|
|
13
|
+
if np.isscalar(tags):
|
|
14
|
+
return get_values(ds, [tags])[0]
|
|
15
|
+
|
|
16
|
+
row = []
|
|
17
|
+
for tag in tags:
|
|
18
|
+
value = None
|
|
19
|
+
|
|
20
|
+
# If the tag is provided as string
|
|
21
|
+
if isinstance(tag, str):
|
|
22
|
+
if hasattr(ds, tag):
|
|
23
|
+
pydcm_value = ds[tag].value
|
|
24
|
+
try:
|
|
25
|
+
VR = pydicom.datadict.dictionary_VR(tag)
|
|
26
|
+
except:
|
|
27
|
+
VR = None
|
|
28
|
+
value = to_set_type(pydcm_value, VR) # ELIMINATE THIS STEP - return pydicom datatypes
|
|
29
|
+
|
|
30
|
+
# If the tag is a tuple of hexadecimal values
|
|
31
|
+
else:
|
|
32
|
+
if tag in ds:
|
|
33
|
+
try:
|
|
34
|
+
VR = pydicom.datadict.dictionary_VR(tag)
|
|
35
|
+
except:
|
|
36
|
+
VR = None
|
|
37
|
+
value = to_set_type(ds[tag].value, VR)
|
|
38
|
+
|
|
39
|
+
# If a tag is not present in the dataset, check if it can be derived
|
|
40
|
+
if value is None:
|
|
41
|
+
value = derive_data_element(ds, tag)
|
|
42
|
+
|
|
43
|
+
row.append(value)
|
|
44
|
+
return row
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def set_values(ds, tags, values, VR=None, coords=None):
|
|
48
|
+
|
|
49
|
+
if np.isscalar(tags):
|
|
50
|
+
tags = [tags]
|
|
51
|
+
values = [values]
|
|
52
|
+
VR = [VR]
|
|
53
|
+
elif VR is None:
|
|
54
|
+
VR = [None] * len(tags)
|
|
55
|
+
|
|
56
|
+
if coords is not None: # obsolete
|
|
57
|
+
tags += list(coords.keys())
|
|
58
|
+
values += list(coords.values())
|
|
59
|
+
|
|
60
|
+
for i, tag in enumerate(tags):
|
|
61
|
+
|
|
62
|
+
if values[i] is None:
|
|
63
|
+
if isinstance(tag, str):
|
|
64
|
+
if hasattr(ds, tag):
|
|
65
|
+
del ds[tag]
|
|
66
|
+
else: # hexadecimal tuple
|
|
67
|
+
if tag in ds:
|
|
68
|
+
del ds[tag]
|
|
69
|
+
|
|
70
|
+
elif isinstance(tag, str):
|
|
71
|
+
if hasattr(ds, tag):
|
|
72
|
+
ds[tag].value = format_value(values[i], tag=tag)
|
|
73
|
+
else:
|
|
74
|
+
_add_new(ds, tag, values[i], VR=VR[i])
|
|
75
|
+
|
|
76
|
+
else: # hexadecimal tuple
|
|
77
|
+
if tag in ds:
|
|
78
|
+
ds[tag].value = format_value(values[i], tag=tag)
|
|
79
|
+
else:
|
|
80
|
+
_add_new(ds, tag, values[i], VR=VR[i])
|
|
81
|
+
|
|
82
|
+
#_set_derived_data_element(ds, tag, values[i])
|
|
83
|
+
|
|
84
|
+
return ds
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def value(ds, tags):
|
|
88
|
+
# Same as get_values but without VR lookup
|
|
89
|
+
|
|
90
|
+
# https://pydicom.github.io/pydicom/stable/guides/element_value_types.html
|
|
91
|
+
if np.isscalar(tags):
|
|
92
|
+
return get_values(ds, [tags])[0]
|
|
93
|
+
|
|
94
|
+
row = []
|
|
95
|
+
for tag in tags:
|
|
96
|
+
value = None
|
|
97
|
+
|
|
98
|
+
# If the tag is provided as string
|
|
99
|
+
if isinstance(tag, str):
|
|
100
|
+
|
|
101
|
+
if hasattr(ds, tag):
|
|
102
|
+
value = to_set_type(ds[tag].value)
|
|
103
|
+
|
|
104
|
+
# If the tag is a tuple of hexadecimal values
|
|
105
|
+
else:
|
|
106
|
+
if tag in ds:
|
|
107
|
+
value = to_set_type(ds[tag].value)
|
|
108
|
+
|
|
109
|
+
# If a tag is not present in the dataset, check if it can be derived
|
|
110
|
+
if value is None:
|
|
111
|
+
value = derive_data_element(ds, tag)
|
|
112
|
+
|
|
113
|
+
row.append(value)
|
|
114
|
+
return row
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def set_value(ds, tags, values):
|
|
118
|
+
# Same as set_values but without VR lookup
|
|
119
|
+
# This excludes new private tags - set those using add_private()
|
|
120
|
+
if np.isscalar(tags):
|
|
121
|
+
tags = [tags]
|
|
122
|
+
values = [values]
|
|
123
|
+
|
|
124
|
+
for i, tag in enumerate(tags):
|
|
125
|
+
|
|
126
|
+
if values[i] is None:
|
|
127
|
+
if isinstance(tag, str):
|
|
128
|
+
if hasattr(ds, tag):
|
|
129
|
+
del ds[tag]
|
|
130
|
+
else: # hexadecimal tuple
|
|
131
|
+
if tag in ds:
|
|
132
|
+
del ds[tag]
|
|
133
|
+
|
|
134
|
+
elif isinstance(tag, str):
|
|
135
|
+
if hasattr(ds, tag):
|
|
136
|
+
ds[tag].value = check_value(values[i], tag)
|
|
137
|
+
else:
|
|
138
|
+
add_new(ds, tag, values[i])
|
|
139
|
+
|
|
140
|
+
else: # hexadecimal tuple
|
|
141
|
+
if tag in ds:
|
|
142
|
+
ds[tag].value = check_value(values[i], tag)
|
|
143
|
+
else:
|
|
144
|
+
add_new(ds, tag, values[i])
|
|
145
|
+
|
|
146
|
+
return ds
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def check_value(value, tag):
|
|
150
|
+
|
|
151
|
+
# If the change below is made (TM, DA, DT) then this needs to
|
|
152
|
+
# convert those to string before setting
|
|
153
|
+
|
|
154
|
+
LO = [
|
|
155
|
+
'SeriesDescription',
|
|
156
|
+
'StudyDescription',
|
|
157
|
+
]
|
|
158
|
+
TM = [
|
|
159
|
+
'AcquisitionTime',
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
if tag in LO:
|
|
163
|
+
if len(value) > 64:
|
|
164
|
+
return value[-64:]
|
|
165
|
+
if tag in TM:
|
|
166
|
+
return seconds_to_str(value)
|
|
167
|
+
|
|
168
|
+
return value
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def add_new(ds, tag, value):
|
|
172
|
+
if not isinstance(tag, pydicom.tag.BaseTag):
|
|
173
|
+
tag = pydicom.tag.Tag(tag)
|
|
174
|
+
if tag.is_private:
|
|
175
|
+
raise ValueError("if you want to add a private data element, use "
|
|
176
|
+
"dataset.add_private()")
|
|
177
|
+
# Add a new data element
|
|
178
|
+
value_repr = pydicom.datadict.dictionary_VR(tag)
|
|
179
|
+
if value_repr == 'US or SS':
|
|
180
|
+
if value >= 0:
|
|
181
|
+
value_repr = 'US'
|
|
182
|
+
else:
|
|
183
|
+
value_repr = 'SS'
|
|
184
|
+
elif value_repr == 'OB or OW':
|
|
185
|
+
value_repr = 'OW'
|
|
186
|
+
ds.add_new(tag, value_repr, format_value(value, value_repr))
|
|
187
|
+
|
|
188
|
+
def _add_new(ds, tag, value, VR='OW'):
|
|
189
|
+
if not isinstance(tag, pydicom.tag.BaseTag):
|
|
190
|
+
tag = pydicom.tag.Tag(tag)
|
|
191
|
+
if not tag.is_private: # Add a new data element
|
|
192
|
+
value_repr = pydicom.datadict.dictionary_VR(tag)
|
|
193
|
+
if value_repr == 'US or SS':
|
|
194
|
+
if value >= 0:
|
|
195
|
+
value_repr = 'US'
|
|
196
|
+
else:
|
|
197
|
+
value_repr = 'SS'
|
|
198
|
+
elif value_repr == 'OB or OW':
|
|
199
|
+
value_repr = 'OW'
|
|
200
|
+
ds.add_new(tag, value_repr, format_value(value, value_repr))
|
|
201
|
+
else:
|
|
202
|
+
if (tag.group, 0x0010) not in ds:
|
|
203
|
+
ds.private_block(tag.group, 'dbdicom ' + str(tag.group), create=True)
|
|
204
|
+
ds.add_new(tag, VR, format_value(value, VR))
|
|
205
|
+
|
|
206
|
+
def format_value(value, VR=None, tag=None):
|
|
207
|
+
|
|
208
|
+
# If the change below is made (TM, DA, DT) then this needs to
|
|
209
|
+
# convert those to string before setting
|
|
210
|
+
|
|
211
|
+
# Slow - dictionary lookup for every value write
|
|
212
|
+
|
|
213
|
+
if VR is None:
|
|
214
|
+
VR = pydicom.datadict.dictionary_VR(tag)
|
|
215
|
+
|
|
216
|
+
if VR == 'LO':
|
|
217
|
+
if len(value) > 64:
|
|
218
|
+
return value[-64:]
|
|
219
|
+
#return value[:64]
|
|
220
|
+
if VR == 'TM':
|
|
221
|
+
return seconds_to_str(value)
|
|
222
|
+
if VR == 'DA':
|
|
223
|
+
if not is_valid_dicom_date(value):
|
|
224
|
+
return '99991231'
|
|
225
|
+
|
|
226
|
+
return value
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def is_valid_dicom_date(da_str: str) -> bool:
|
|
230
|
+
if not isinstance(da_str, str) or len(da_str) != 8 or not da_str.isdigit():
|
|
231
|
+
return False
|
|
232
|
+
try:
|
|
233
|
+
datetime.datetime.strptime(da_str, "%Y%m%d")
|
|
234
|
+
return True
|
|
235
|
+
except ValueError:
|
|
236
|
+
return False
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def to_set_type(value, VR=None):
|
|
240
|
+
"""
|
|
241
|
+
Convert pydicom datatypes to the python datatypes used to set the parameter.
|
|
242
|
+
"""
|
|
243
|
+
# Not a good idea to modify pydicom set/get values. confusing and requires extra VR lookups
|
|
244
|
+
|
|
245
|
+
if VR == 'TM':
|
|
246
|
+
# pydicom sometimes returns string values for TM data types
|
|
247
|
+
if isinstance(value, str):
|
|
248
|
+
return str_to_seconds(value)
|
|
249
|
+
|
|
250
|
+
if value.__class__.__name__ == 'MultiValue':
|
|
251
|
+
return [to_set_type(v, VR) for v in value]
|
|
252
|
+
if value.__class__.__name__ == 'PersonName':
|
|
253
|
+
return str(value)
|
|
254
|
+
if value.__class__.__name__ == 'Sequence':
|
|
255
|
+
return [ds for ds in value]
|
|
256
|
+
if value.__class__.__name__ == 'TM':
|
|
257
|
+
return time_to_seconds(value) # return datetime.time
|
|
258
|
+
if value.__class__.__name__ == 'UID':
|
|
259
|
+
return str(value)
|
|
260
|
+
if value.__class__.__name__ == 'IS':
|
|
261
|
+
return int(value)
|
|
262
|
+
if value.__class__.__name__ == 'DT':
|
|
263
|
+
return datetime_to_str(value) # return datetime.datetime
|
|
264
|
+
if value.__class__.__name__ == 'DA': # return datetime.date
|
|
265
|
+
return date_to_str(value)
|
|
266
|
+
if value.__class__.__name__ == 'DSfloat':
|
|
267
|
+
return float(value)
|
|
268
|
+
if value.__class__.__name__ == 'DSdecimal':
|
|
269
|
+
return int(value)
|
|
270
|
+
|
|
271
|
+
return value
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def derive_data_element(ds, tag):
|
|
275
|
+
"""Tags that are not required but can be derived from other required tags"""
|
|
276
|
+
|
|
277
|
+
if tag == 'SliceLocation' or tag == (0x0020, 0x1041):
|
|
278
|
+
if 'ImageOrientationPatient' in ds and 'ImagePositionPatient' in ds:
|
|
279
|
+
image_orientation = ds['ImageOrientationPatient'].value
|
|
280
|
+
image_position = ds['ImagePositionPatient'].value
|
|
281
|
+
row_cosine = np.array(image_orientation[:3])
|
|
282
|
+
column_cosine = np.array(image_orientation[3:])
|
|
283
|
+
slice_cosine = np.cross(row_cosine, column_cosine)
|
|
284
|
+
return np.dot(np.array(image_position), slice_cosine)
|
|
285
|
+
# To be extended ad hoc with other tags that can be derived
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def add_private(ds, tag, value, VR):
|
|
289
|
+
if not isinstance(tag, pydicom.tag.BaseTag):
|
|
290
|
+
tag = pydicom.tag.Tag(tag)
|
|
291
|
+
if (tag.group, 0x0010) not in ds:
|
|
292
|
+
ds.private_block(tag.group, 'dbdicom ' + str(tag.group), create=True)
|
|
293
|
+
ds.add_new(tag, VR, format_value(value, VR))
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def str_to_seconds(dicom_tm):
|
|
297
|
+
if dicom_tm is None:
|
|
298
|
+
return None
|
|
299
|
+
if dicom_tm == '':
|
|
300
|
+
return None
|
|
301
|
+
# dicom_tm is of the form 'HHMMSS.FFFFFF'
|
|
302
|
+
# Split the seconds into seconds and fractional seconds
|
|
303
|
+
seconds, fractional_seconds = dicom_tm.split('.')
|
|
304
|
+
# Convert the hours, minutes, and seconds to integers
|
|
305
|
+
hours = int(seconds[:2])
|
|
306
|
+
minutes = int(seconds[2:4])
|
|
307
|
+
seconds = int(seconds[4:])
|
|
308
|
+
# Convert the fractional seconds to a decimal
|
|
309
|
+
fractional_seconds = float('.' + fractional_seconds)
|
|
310
|
+
# Create a datetime object representing the time
|
|
311
|
+
seconds_since_midnight = (hours * 3600) + (minutes * 60) + seconds + fractional_seconds
|
|
312
|
+
return seconds_since_midnight
|
|
313
|
+
|
|
314
|
+
def seconds_to_str(seconds_since_midnight):
|
|
315
|
+
# if not isinstance(seconds_since_midnight, float):
|
|
316
|
+
# return None
|
|
317
|
+
if seconds_since_midnight is None:
|
|
318
|
+
return None
|
|
319
|
+
seconds_since_midnight = float(seconds_since_midnight)
|
|
320
|
+
hours = math.floor(seconds_since_midnight/3600)
|
|
321
|
+
minutes = math.floor((seconds_since_midnight-hours*3600)/60)
|
|
322
|
+
seconds = math.floor(seconds_since_midnight-hours*3600-minutes*60)
|
|
323
|
+
fractional_seconds = round(seconds_since_midnight-hours*3600-minutes*60-seconds, 6)
|
|
324
|
+
hours = str(hours).zfill(2)
|
|
325
|
+
minutes = str(minutes).zfill(2)
|
|
326
|
+
seconds = str(seconds).zfill(2)
|
|
327
|
+
fractional_seconds = str(fractional_seconds)
|
|
328
|
+
fractional_seconds = fractional_seconds.split('.')
|
|
329
|
+
if len(fractional_seconds) == 2:
|
|
330
|
+
fractional_seconds = fractional_seconds[1].ljust(6,'0')
|
|
331
|
+
else:
|
|
332
|
+
fractional_seconds = '0'.ljust(6,'0')
|
|
333
|
+
return hours + minutes + seconds + '.' + fractional_seconds
|
|
334
|
+
|
|
335
|
+
def time_to_seconds(tm):
|
|
336
|
+
if tm is None:
|
|
337
|
+
return None
|
|
338
|
+
hours = tm.hour
|
|
339
|
+
minutes = tm.minute
|
|
340
|
+
seconds = tm.second
|
|
341
|
+
fractional_seconds = tm.microsecond / 1000000.0
|
|
342
|
+
seconds_since_midnight = (hours * 3600) + (minutes * 60) + seconds + fractional_seconds
|
|
343
|
+
return seconds_since_midnight
|
|
344
|
+
|
|
345
|
+
def seconds_to_time(seconds_since_midnight):
|
|
346
|
+
# if not isinstance(seconds_since_midnight, float):
|
|
347
|
+
# return None
|
|
348
|
+
if seconds_since_midnight is None:
|
|
349
|
+
return None
|
|
350
|
+
seconds_since_midnight = float(seconds_since_midnight)
|
|
351
|
+
hours = math.floor(seconds_since_midnight/3600)
|
|
352
|
+
minutes = math.floor((seconds_since_midnight-hours*3600)/60)
|
|
353
|
+
seconds = math.floor(seconds_since_midnight-hours*3600-minutes*60)
|
|
354
|
+
fractional_seconds = round(seconds_since_midnight-hours*3600-minutes*60-seconds, 6)
|
|
355
|
+
microseconds = fractional_seconds*1000000.0
|
|
356
|
+
return datetime.time(int(hours), int(minutes), int(seconds), int(microseconds))
|
|
357
|
+
|
|
358
|
+
def time_to_str(tm):
|
|
359
|
+
if tm is None:
|
|
360
|
+
return None
|
|
361
|
+
hours = tm.hour
|
|
362
|
+
minutes = tm.minute
|
|
363
|
+
seconds = tm.second
|
|
364
|
+
fractional_seconds = tm.microsecond / 1000000.0
|
|
365
|
+
hours = str(hours).zfill(2)
|
|
366
|
+
minutes = str(minutes).zfill(2)
|
|
367
|
+
seconds = str(seconds).zfill(2)
|
|
368
|
+
fractional_seconds = str(fractional_seconds)
|
|
369
|
+
_, fractional_seconds = fractional_seconds.split('.')
|
|
370
|
+
fractional_seconds = fractional_seconds.ljust(6,'0')
|
|
371
|
+
return hours + minutes + seconds + '.' + fractional_seconds
|
|
372
|
+
|
|
373
|
+
def date_to_str(tm):
|
|
374
|
+
if tm is None:
|
|
375
|
+
return None
|
|
376
|
+
year = str(tm.year).rjust(4, '0')
|
|
377
|
+
month = str(tm.month).rjust(2, '0')
|
|
378
|
+
day = str(tm.day).rjust(2, '0')
|
|
379
|
+
return year + month + day
|
|
380
|
+
|
|
381
|
+
def datetime_to_str(dt):
|
|
382
|
+
if dt is None:
|
|
383
|
+
return None
|
|
384
|
+
date = date_to_str(dt.date())
|
|
385
|
+
time = time_to_str(dt.time())
|
|
386
|
+
return date + time
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dbdicom
|
|
3
|
+
Version: 0.3.16
|
|
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>=3.0
|
|
26
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
dbdicom/__init__.py,sha256=dW5aezonmMc_41Dp1PuYmXQlr307RkyJxsJuetkpWso,87
|
|
2
|
+
dbdicom/api.py,sha256=H64gVaa91svWQXwmcLdvZRhJz8m3ZY_dh1sn-zaEnfo,16273
|
|
3
|
+
dbdicom/const.py,sha256=BqBiRRjeiSqDr1W6YvaayD8WKCjG4Cny2NT0GeLM6bI,4269
|
|
4
|
+
dbdicom/database.py,sha256=Sdbh9m-aOzRNdXJBbZM5PS3tEO1RmswNnoPcC_G9oMQ,5113
|
|
5
|
+
dbdicom/dataset.py,sha256=Hgn3IDcSmIlSI5MiZ9991QWI5yABKiCfWseAeA9ARf4,15419
|
|
6
|
+
dbdicom/dbd.py,sha256=hjl2Vos1f9J0aaTaHfv0tzXnQE6Jn-FyeSEeVCwAYns,49722
|
|
7
|
+
dbdicom/register.py,sha256=52W6vogr4KVRL9vpbbLMWtiElrXD2ochvWKew-f-dFY,16319
|
|
8
|
+
dbdicom/external/__init__.py,sha256=XNQqfspyf6vFGedXlRKZsUB8k8E-0W19Uamwn8Aioxo,316
|
|
9
|
+
dbdicom/external/__pycache__/__init__.cpython-311.pyc,sha256=pXAQ35ixd92fm6YcuHgzR1t6RcASQ-cHhU1wOA5b8sw,542
|
|
10
|
+
dbdicom/external/dcm4che/README.md,sha256=0aAGRs36W3_0s5LzWHRGf_tqariS_JP4iJggaxnD4Xw,8987
|
|
11
|
+
dbdicom/external/dcm4che/__init__.py,sha256=YwpeMCLrxffGOkchsGjgAuB6ia3VX_tx9Y7ru9EWtoY,35
|
|
12
|
+
dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc,sha256=FB8wyWqXDUt_1P-QmE4yt9uD6dDm5YqYWjqVuRwGdSo,256
|
|
13
|
+
dbdicom/external/dcm4che/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
dbdicom/external/dcm4che/bin/deidentify,sha256=64MNIEpp-CWzFSb6TV0KtyCBvD7XyEsovRjBeyxDqSc,1698
|
|
15
|
+
dbdicom/external/dcm4che/bin/deidentify.bat,sha256=kVXUkcy1C4Y3KjC2NJwmmR0pufSJWmaof_LR5CTAxMg,1455
|
|
16
|
+
dbdicom/external/dcm4che/bin/emf2sf,sha256=svCzkZ-QhdVTV0NNHOpBiwNBMODVWZHJIFA7cWaN2bM,1622
|
|
17
|
+
dbdicom/external/dcm4che/bin/emf2sf.bat,sha256=Vh0ry9KNJX_WXcyCrLSxbJ_6Crot9rjmwi__u2GZqLY,1375
|
|
18
|
+
dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc,sha256=GYcm47ETjYvRUN5RPTe5R-c0prd14GP8gm96eJcy0uQ,203
|
|
19
|
+
dbdicom/external/dcm4che/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
dbdicom/external/dcm4che/etc/emf2sf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
dbdicom/external/dcm4che/etc/emf2sf/log4j.properties,sha256=3hHcBFt2oNRjvHtix5bfuEsnKfdv5IYOkbsyoY9g7cM,223
|
|
22
|
+
dbdicom/external/dcm4che/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
dbdicom/external/dcm4che/lib/commons-cli-1.4.jar,sha256=_Tx8lUWpzbIFHR-RVcT3ax5KxaVzBEBKbu21eP-6cyg,53820
|
|
24
|
+
dbdicom/external/dcm4che/lib/dcm4che-core-5.23.1.jar,sha256=UEnSQwDE1IHv5kGtK8vkdaQ9OF_cNwOsxB5NSIMkS2s,506505
|
|
25
|
+
dbdicom/external/dcm4che/lib/dcm4che-emf-5.23.1.jar,sha256=fcspodANPlRz-3EIx3TEZWU45JDP4RXzLuWbFoQEPMY,13418
|
|
26
|
+
dbdicom/external/dcm4che/lib/dcm4che-tool-common-5.23.1.jar,sha256=3SN3NSTf4AIHuUCsk_5E2wXd3MuFvQZIYSSq1PHcgNM,21301
|
|
27
|
+
dbdicom/external/dcm4che/lib/dcm4che-tool-emf2sf-5.23.1.jar,sha256=pkpJRD00HQ4sEjaL7_iQ_8lBeQPttHelNAxcT-rMIVQ,7332
|
|
28
|
+
dbdicom/external/dcm4che/lib/log4j-1.2.17.jar,sha256=HTFpZEVpdyBScJF1Q2kIKmZRvUl4G2AF3rlOVnU0Bvk,489884
|
|
29
|
+
dbdicom/external/dcm4che/lib/slf4j-api-1.7.30.jar,sha256=zboHlk0btAoHYUhcax6ML4_Z6x0ZxTkorA1_lRAQXFc,41472
|
|
30
|
+
dbdicom/external/dcm4che/lib/slf4j-log4j12-1.7.30.jar,sha256=TUHgHEDK-KbHSt0rBzBV2KTOHDDlgVQXexPxLXirvns,12211
|
|
31
|
+
dbdicom/external/dcm4che/lib/macosx-x86-64/libopencv_java.jnilib,sha256=A2uOWIUQX3KcG850ElpW4lVtn2uyPpJHZq9cPlpJjMY,15137664
|
|
32
|
+
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio.dll,sha256=C2dAjNyefOm3POrUxorEF6T-FTztpo0nfGAsUrDyQyg,720896
|
|
33
|
+
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_sse2.dll,sha256=uD9GLN_hPf9mM9APzlp9j6770awKP6xnlaooMrxHpkg,1089536
|
|
34
|
+
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_util.dll,sha256=wi4yyrI1gTRo_bBpj0E097BQBiHZd8IqVifKr6kfkRE,40960
|
|
35
|
+
dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll,sha256=QanyzLy0Cd79-aOVPwOcXwikUYeutne0Au-Um91_B4M,8505856
|
|
36
|
+
dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll,sha256=TmjW2SbG4MR3GQ95T8xCVVDLgsdKukgaHBPUvWkfXp8,11039232
|
|
37
|
+
dbdicom/sop_classes/ct_image.py,sha256=16PNv_0e1_7cfxE12JWlx5YQeaTAQVzwtXTjxs3aonk,2812
|
|
38
|
+
dbdicom/sop_classes/enhanced_mr_image.py,sha256=6x4CEd982i64e90ZlFDKNSc83XHC2k2DVit1iyjXjCU,33368
|
|
39
|
+
dbdicom/sop_classes/mr_image.py,sha256=1biIw7R26Fc38FAeSlWxd29VO17e8cEQdDIdLbeXTzw,10959
|
|
40
|
+
dbdicom/sop_classes/parametric_map.py,sha256=2OKBuC2bo03OEpKqimQS-nVGFp1cKRPYwVgmDGVf1JU,12288
|
|
41
|
+
dbdicom/sop_classes/secondary_capture.py,sha256=wgNRX8qyhV7HR7Jq2tQWPPuGpiRzYl6qPOgK6qFbPUc,4541
|
|
42
|
+
dbdicom/sop_classes/segmentation.py,sha256=I8-PciIoIz27_-dZ4esBZSw0TBBbO8KbNYTiTmVe62g,11465
|
|
43
|
+
dbdicom/sop_classes/ultrasound_multiframe_image.py,sha256=j3KN5R90j6WwPMy01hAN2_XSum5TvksF2MYoNGfX_yE,2797
|
|
44
|
+
dbdicom/sop_classes/xray_angiographic_image.py,sha256=nWysCGaEWKVNItnOgyJfcGMpS3oEK1T0_uNR2D7p0Ls,3270
|
|
45
|
+
dbdicom/utils/arrays.py,sha256=yYy35MNGgD3vUHn3VPYLMhVc-CQb5131Uy0uqJw2HZY,4944
|
|
46
|
+
dbdicom/utils/dcm4che.py,sha256=Vxq8NYWWK3BuqJkzhBQ89oMqzJlnxqTxgsgTo_Frznc,2317
|
|
47
|
+
dbdicom/utils/files.py,sha256=qhWNJqeWnRjDNbERpC6Mz962_TW9mFdvd2lnBbK3xt4,2259
|
|
48
|
+
dbdicom/utils/image.py,sha256=CD8F08IHnn5akgT8l5NRtPEWWJuiiL8FSnhDuxhwc7A,3897
|
|
49
|
+
dbdicom/utils/pydicom_dataset.py,sha256=XM3EERsCWPlEaUzVaFQSbPNiNbEGwxIbf-sUKKf_YxA,12755
|
|
50
|
+
dbdicom-0.3.16.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
51
|
+
dbdicom-0.3.16.dist-info/METADATA,sha256=IBBLvhauK-eW8dyJhXYfybQioaBE3n7G-aJKkWLmKWk,1019
|
|
52
|
+
dbdicom-0.3.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
dbdicom-0.3.16.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
|
|
54
|
+
dbdicom-0.3.16.dist-info/RECORD,,
|