dbdicom 0.3.1__py3-none-any.whl → 0.3.3__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.

Potentially problematic release.


This version of dbdicom might be problematic. Click here for more details.

@@ -1,8 +1,5 @@
1
- # Coded version of DICOM file
2
- # 'RIDER Neuro MRI-3369019796\03-21-1904-BRAINRESEARCH-00598\14.000000-sag 3d gre c-04769\1-010.dcm'
3
- # Produced by pydicom codify utility script
4
1
  import os
5
- import struct
2
+
6
3
  import numpy as np
7
4
  import pydicom
8
5
  from pydicom.dataset import FileMetaDataset, Dataset, FileDataset
@@ -14,7 +11,6 @@ from pydicom.uid import (
14
11
  )
15
12
 
16
13
  from datetime import datetime
17
- import tempfile
18
14
 
19
15
  import dbdicom.utils.image as image
20
16
 
@@ -22,168 +18,64 @@ import dbdicom.utils.image as image
22
18
  def pixel_data(ds):
23
19
  """Read the pixel array from an MR image"""
24
20
 
25
- #array = ds.pixel_array.astype(np.float64)
26
- #array = ds.pixel_array
27
- #array = np.frombuffer(ds.PixelData, dtype=np.uint16).reshape(ds.Rows, ds.Columns)
28
- #array = array.astype(np.float32)
29
-
30
21
  array = ds.pixel_array
31
22
  array = array.astype(np.float32)
32
23
  if [0x2005, 0x100E] in ds: # 'Philips Rescale Slope'
33
24
  slope = ds[(0x2005, 0x100E)].value
34
25
  intercept = ds[(0x2005, 0x100D)].value
35
- array -= intercept
36
- array /= slope
26
+ if (intercept == 0) and (slope == 1):
27
+ array = array.astype(np.int16)
28
+ else:
29
+ array = array.astype(np.float32)
30
+ array -= intercept
31
+ array /= slope
37
32
  else:
38
33
  slope = float(getattr(ds, 'RescaleSlope', 1))
39
34
  intercept = float(getattr(ds, 'RescaleIntercept', 0))
40
- array *= slope
41
- array += intercept
35
+ if (intercept == 0) and (slope == 1):
36
+ array = array.astype(np.int16)
37
+ else:
38
+ array = array.astype(np.float32)
39
+ array *= slope
40
+ array += intercept
42
41
  return np.transpose(array)
43
42
 
44
43
 
45
44
  def set_pixel_data(ds, array):
46
45
 
46
+ # Delete 'Philips Rescale Slope'
47
47
  if (0x2005, 0x100E) in ds:
48
- del ds[0x2005, 0x100E] # Delete 'Philips Rescale Slope'
48
+ del ds[0x2005, 0x100E]
49
49
  if (0x2005, 0x100D) in ds:
50
50
  del ds[0x2005, 0x100D]
51
51
 
52
+ ds.BitsAllocated = 16
53
+ ds.BitsStored = 16
54
+ ds.HighBit = 15
55
+
52
56
  # clipping may slow down a lot
53
- array = image.clip(array.astype(np.float32))
54
- array, slope, intercept = image.scale_to_range(array, ds.BitsAllocated)
55
- array = np.transpose(array)
57
+ #array = image.clip(array.astype(np.float32))
58
+ array = image.clip(array) # remove nan and infs
59
+ if array.dtype==np.int16:
60
+ ds.PixelRepresentation = 1
61
+ ds.RescaleSlope = 1
62
+ ds.RescaleIntercept = 0
63
+ elif array.dtype==np.uint16:
64
+ ds.PixelRepresentation = 0
65
+ ds.RescaleSlope = 1
66
+ ds.RescaleIntercept = 0
67
+ else:
68
+ array, slope, intercept = image.scale_to_range(array, ds.BitsStored)
69
+ ds.PixelRepresentation = 0
70
+ ds.RescaleSlope = 1 / slope
71
+ ds.RescaleIntercept = - intercept / slope
56
72
 
57
- ds.PixelRepresentation = 0
58
- ds.RescaleSlope = 1 / slope
59
- ds.RescaleIntercept = - intercept / slope
60
- # ds.WindowCenter = (maximum + minimum) / 2
61
- # ds.WindowWidth = maximum - minimum
73
+ array = np.transpose(array)
62
74
  ds.Rows = array.shape[0]
63
75
  ds.Columns = array.shape[1]
64
76
  ds.PixelData = array.tobytes()
65
77
 
66
78
 
67
-
68
- def chat_gpt_3d(num_frames=10, rows=256, columns=256):
69
-
70
- # File meta info
71
- file_meta = FileMetaDataset()
72
- file_meta.MediaStorageSOPClassUID = MRImageStorage
73
- file_meta.MediaStorageSOPInstanceUID = generate_uid()
74
- file_meta.ImplementationClassUID = generate_uid()
75
- file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
76
-
77
- # Create FileDataset in memory
78
- ds = FileDataset(
79
- filename_or_obj=None,
80
- dataset=Dataset(),
81
- file_meta=file_meta,
82
- preamble=b"\0" * 128,
83
- )
84
-
85
- # Transfer syntax
86
- ds.is_little_endian = True
87
- ds.is_implicit_VR = False
88
-
89
- now = datetime.now()
90
-
91
- # Required fields
92
- ds.SOPClassUID = MRImageStorage
93
- ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
94
- ds.PatientName = "Multi^Frame"
95
- ds.PatientID = "999999"
96
- ds.StudyInstanceUID = generate_uid()
97
- ds.SeriesInstanceUID = generate_uid()
98
- ds.StudyDate = now.strftime("%Y%m%d")
99
- ds.StudyTime = now.strftime("%H%M%S")
100
- ds.Modality = "MR"
101
- ds.Manufacturer = "PythonPACS"
102
- ds.StudyID = "1"
103
- ds.SeriesNumber = "1"
104
- ds.InstanceNumber = "1"
105
-
106
- # Image geometry
107
- ds.Rows = rows
108
- ds.Columns = columns
109
- ds.PixelSpacing = [1.0, 1.0]
110
- ds.ImagePositionPatient = [0.0, 0.0, 0.0]
111
- ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
112
- ds.FrameOfReferenceUID = generate_uid()
113
- ds.PositionReferenceIndicator = ""
114
-
115
- # Multi-frame specific
116
- ds.NumberOfFrames = str(num_frames)
117
- ds.InstanceNumber = "1"
118
-
119
- # Pixel data requirements
120
- ds.SamplesPerPixel = 1
121
- ds.PhotometricInterpretation = "MONOCHROME2"
122
- ds.BitsAllocated = 16
123
- ds.BitsStored = 12
124
- ds.HighBit = 11
125
- ds.PixelRepresentation = 0 # unsigned
126
-
127
- # Create dummy image data (e.g., black frames)
128
- pixel_array = np.zeros((num_frames, rows, columns), dtype=np.uint16)
129
- ds.PixelData = pixel_array.tobytes()
130
-
131
- return ds
132
-
133
-
134
-
135
- def chat_gpt_2d():
136
- # Basic identifiers
137
- file_meta = FileMetaDataset()
138
- file_meta.MediaStorageSOPClassUID = MRImageStorage
139
- file_meta.MediaStorageSOPInstanceUID = generate_uid()
140
- file_meta.ImplementationClassUID = generate_uid()
141
-
142
- # Create the main dataset
143
- ds = FileDataset(
144
- filename_or_obj=None,
145
- dataset=Dataset(),
146
- file_meta=file_meta,
147
- preamble=b"\0" * 128,
148
- )
149
-
150
- # Set transfer syntax
151
- ds.is_little_endian = True
152
- ds.is_implicit_VR = False
153
-
154
- # Required DICOM tags for MR Image Storage
155
- now = datetime.now()
156
- ds.SOPClassUID = MRImageStorage
157
- ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
158
- ds.PatientName = "Anonymous^Patient"
159
- ds.PatientID = "123456"
160
- ds.StudyInstanceUID = generate_uid()
161
- ds.SeriesInstanceUID = generate_uid()
162
- ds.StudyDate = now.strftime("%Y%m%d")
163
- ds.StudyTime = now.strftime("%H%M%S")
164
- ds.Modality = "MR"
165
- ds.Manufacturer = "PythonPACS"
166
- ds.StudyID = "1"
167
- ds.SeriesNumber = "1"
168
- ds.InstanceNumber = "1"
169
- ds.ImagePositionPatient = [0.0, 0.0, 0.0]
170
- ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
171
- ds.FrameOfReferenceUID = generate_uid()
172
- ds.PositionReferenceIndicator = ""
173
- ds.Rows = 256
174
- ds.Columns = 256
175
- ds.PixelSpacing = [1.0, 1.0]
176
- ds.BitsAllocated = 16
177
- ds.BitsStored = 12
178
- ds.HighBit = 11
179
- ds.PixelRepresentation = 0 # unsigned
180
- ds.SamplesPerPixel = 1
181
- ds.PhotometricInterpretation = "MONOCHROME2"
182
- ds.PixelData = (b"\0" * (ds.Rows * ds.Columns * 2)) # Dummy black image
183
-
184
- return ds
185
-
186
-
187
79
  def default(): # from the RIDER dataset
188
80
 
189
81
  # File meta info data elements
@@ -309,6 +201,127 @@ def default(): # from the RIDER dataset
309
201
  return ds
310
202
 
311
203
 
204
+ def chat_gpt_3d(num_frames=10, rows=256, columns=256):
205
+
206
+ # File meta info
207
+ file_meta = FileMetaDataset()
208
+ file_meta.MediaStorageSOPClassUID = MRImageStorage
209
+ file_meta.MediaStorageSOPInstanceUID = generate_uid()
210
+ file_meta.ImplementationClassUID = generate_uid()
211
+ file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
212
+
213
+ # Create FileDataset in memory
214
+ ds = FileDataset(
215
+ filename_or_obj=None,
216
+ dataset=Dataset(),
217
+ file_meta=file_meta,
218
+ preamble=b"\0" * 128,
219
+ )
220
+
221
+ # Transfer syntax
222
+ ds.is_little_endian = True
223
+ ds.is_implicit_VR = False
224
+
225
+ now = datetime.now()
226
+
227
+ # Required fields
228
+ ds.SOPClassUID = MRImageStorage
229
+ ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
230
+ ds.PatientName = "Multi^Frame"
231
+ ds.PatientID = "999999"
232
+ ds.StudyInstanceUID = generate_uid()
233
+ ds.SeriesInstanceUID = generate_uid()
234
+ ds.StudyDate = now.strftime("%Y%m%d")
235
+ ds.StudyTime = now.strftime("%H%M%S")
236
+ ds.Modality = "MR"
237
+ ds.Manufacturer = "PythonPACS"
238
+ ds.StudyID = "1"
239
+ ds.SeriesNumber = "1"
240
+ ds.InstanceNumber = "1"
241
+
242
+ # Image geometry
243
+ ds.Rows = rows
244
+ ds.Columns = columns
245
+ ds.PixelSpacing = [1.0, 1.0]
246
+ ds.ImagePositionPatient = [0.0, 0.0, 0.0]
247
+ ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
248
+ ds.FrameOfReferenceUID = generate_uid()
249
+ ds.PositionReferenceIndicator = ""
250
+
251
+ # Multi-frame specific
252
+ ds.NumberOfFrames = str(num_frames)
253
+ ds.InstanceNumber = "1"
254
+
255
+ # Pixel data requirements
256
+ ds.SamplesPerPixel = 1
257
+ ds.PhotometricInterpretation = "MONOCHROME2"
258
+ ds.BitsAllocated = 16
259
+ ds.BitsStored = 12
260
+ ds.HighBit = 11
261
+ ds.PixelRepresentation = 0 # unsigned
262
+
263
+ # Create dummy image data (e.g., black frames)
264
+ pixel_array = np.zeros((num_frames, rows, columns), dtype=np.uint16)
265
+ ds.PixelData = pixel_array.tobytes()
266
+
267
+ return ds
268
+
269
+
270
+
271
+ def chat_gpt_2d():
272
+ # Basic identifiers
273
+ file_meta = FileMetaDataset()
274
+ file_meta.MediaStorageSOPClassUID = MRImageStorage
275
+ file_meta.MediaStorageSOPInstanceUID = generate_uid()
276
+ file_meta.ImplementationClassUID = generate_uid()
277
+
278
+ # Create the main dataset
279
+ ds = FileDataset(
280
+ filename_or_obj=None,
281
+ dataset=Dataset(),
282
+ file_meta=file_meta,
283
+ preamble=b"\0" * 128,
284
+ )
285
+
286
+ # Set transfer syntax
287
+ ds.is_little_endian = True
288
+ ds.is_implicit_VR = False
289
+
290
+ # Required DICOM tags for MR Image Storage
291
+ now = datetime.now()
292
+ ds.SOPClassUID = MRImageStorage
293
+ ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
294
+ ds.PatientName = "Anonymous^Patient"
295
+ ds.PatientID = "123456"
296
+ ds.StudyInstanceUID = generate_uid()
297
+ ds.SeriesInstanceUID = generate_uid()
298
+ ds.StudyDate = now.strftime("%Y%m%d")
299
+ ds.StudyTime = now.strftime("%H%M%S")
300
+ ds.Modality = "MR"
301
+ ds.Manufacturer = "PythonPACS"
302
+ ds.StudyID = "1"
303
+ ds.SeriesNumber = "1"
304
+ ds.InstanceNumber = "1"
305
+ ds.ImagePositionPatient = [0.0, 0.0, 0.0]
306
+ ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
307
+ ds.FrameOfReferenceUID = generate_uid()
308
+ ds.PositionReferenceIndicator = ""
309
+ ds.Rows = 256
310
+ ds.Columns = 256
311
+ ds.PixelSpacing = [1.0, 1.0]
312
+ ds.BitsAllocated = 16
313
+ ds.BitsStored = 12
314
+ ds.HighBit = 11
315
+ ds.PixelRepresentation = 0 # unsigned
316
+ ds.SamplesPerPixel = 1
317
+ ds.PhotometricInterpretation = "MONOCHROME2"
318
+ ds.PixelData = (b"\0" * (ds.Rows * ds.Columns * 2)) # Dummy black image
319
+
320
+ return ds
321
+
322
+
323
+
324
+
312
325
 
313
326
 
314
327
 
@@ -6,13 +6,12 @@ from pydicom.uid import generate_uid, ParametricMapStorage
6
6
  from datetime import datetime
7
7
 
8
8
 
9
- def from_volume(vol):
10
- pass
11
9
 
10
+ def default():
12
11
 
13
- def create_parametric_map(rows=64, cols=64, frames=1):
14
- # Create dummy pixel data (floating point)
15
- pixel_array = np.random.rand(frames, rows, cols).astype(np.float32)
12
+ rows=16
13
+ cols=16
14
+ frames=1
16
15
 
17
16
  # File Meta Information
18
17
  file_meta = Dataset()
@@ -35,8 +34,11 @@ def create_parametric_map(rows=64, cols=64, frames=1):
35
34
  ds.PatientID = "123456"
36
35
  ds.StudyDate = datetime.now().strftime("%Y%m%d")
37
36
  ds.StudyTime = datetime.now().strftime("%H%M%S")
37
+ ds.ContentDate = datetime.now().strftime("%Y%m%d")
38
+ ds.ContentTime = datetime.now().strftime("%H%M%S")
38
39
  ds.Modality = "OT"
39
40
  ds.Manufacturer = "SyntheticGenerator"
41
+ ds.SeriesDescription = 'Minimal parametric map'
40
42
 
41
43
  # General Image
42
44
  ds.SeriesNumber = 1
@@ -46,38 +48,107 @@ def create_parametric_map(rows=64, cols=64, frames=1):
46
48
  ds.ImageType = ['DERIVED', 'PRIMARY']
47
49
  ds.ContentLabel = "PMAP"
48
50
  ds.ContentDescription = "Synthetic Parametric Map"
49
- ds.ContentCreatorName = "OpenAI"
51
+ ds.ContentCreatorName = "dbdicom"
50
52
 
51
53
  # Pixel Data
52
- ds.Rows = rows
53
- ds.Columns = cols
54
54
  ds.NumberOfFrames = frames
55
- ds.PixelData = pixel_array.tobytes()
56
55
  ds.SamplesPerPixel = 1
57
56
  ds.PhotometricInterpretation = "MONOCHROME2"
57
+
58
+ ds.Rows = rows
59
+ ds.Columns = cols
58
60
  ds.BitsAllocated = 32
59
61
  ds.BitsStored = 32
60
62
  ds.HighBit = 31
61
63
  ds.PixelRepresentation = 1 # 1 = signed, 0 = unsigned
62
- ds.FloatPixelData = pixel_array.astype(np.float32).tobytes()
63
- ds.PixelData = b"\0" * rows * cols * frames # Actual data goes in FloatPixelData
64
+ ds.FloatPixelData = np.zeros((rows, cols), dtype=np.float32).tobytes()
65
+ #ds.PixelData = np.zeros((rows, cols), dtype=np.int16).tobytes()
66
+
67
+ # Required Parametric Map Attributes
68
+ ds.PixelMeasuresSequence = [Dataset()]
69
+ ds.PixelMeasuresSequence[0].SliceThickness = 1.0
70
+ ds.PixelMeasuresSequence[0].PixelSpacing = [1.0, 1.0]
71
+
72
+ ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
64
73
 
65
74
  # Functional Group Sequences (minimal dummy values)
66
75
  ds.SharedFunctionalGroupsSequence = [Dataset()]
67
- ds.PerFrameFunctionalGroupsSequence = [Dataset() for _ in range(frames)]
76
+ ds.SharedFunctionalGroupsSequence[0].PixelMeasuresSequence = [Dataset()]
77
+ ds.SharedFunctionalGroupsSequence[0].PixelMeasuresSequence[0].PixelSpacing = [1.0, 1.0]
78
+ ds.SharedFunctionalGroupsSequence[0].PlaneOrientationSequence = [Dataset()]
79
+ ds.SharedFunctionalGroupsSequence[0].PlaneOrientationSequence[0].ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
80
+
81
+ ds.PerFrameFunctionalGroupsSequence = []
82
+ for i in range(ds.NumberOfFrames):
83
+ frame = Dataset()
84
+ frame.PlanePositionSequence = [Dataset()]
85
+ frame.PlanePositionSequence[0].ImagePositionPatient = [0.0, 0.0, float(i)]
86
+ ds.PerFrameFunctionalGroupsSequence.append(frame)
87
+
88
+ return ds
89
+
90
+
91
+
92
+ def set_pixel_data(ds, array):
93
+
94
+ array = np.transpose(array)
95
+ ds.RescaleSlope = 1
96
+ ds.RescaleIntercept = 0
97
+ ds.Rows = array.shape[0]
98
+ ds.Columns = array.shape[1]
99
+
100
+ if array.dtype==np.int16:
101
+ ds.BitsAllocated = 16
102
+ ds.BitsStored = 16
103
+ ds.HighBit = 15
104
+ ds.PixelRepresentation = 1 # signed
105
+ ds.PixelData = array.tobytes()
106
+ elif array.dtype==np.float32:
107
+ ds.BitsAllocated = 32
108
+ ds.BitsStored = 32
109
+ ds.HighBit = 31
110
+ ds.PixelRepresentation = 1 # signed
111
+ ds.FloatPixelData = array.tobytes()
112
+ elif array.dtype==np.float64:
113
+ ds.BitsAllocated = 64
114
+ ds.BitsStored = 64
115
+ ds.HighBit = 63
116
+ ds.PixelRepresentation = 1 # signed
117
+ ds.DoubleFloatPixelData = array.tobytes()
118
+ else:
119
+ raise ValueError(
120
+ f"Parametric map storage currently only available for "
121
+ f"32-bit float, 64-bit float or 16-bit int."
122
+ )
123
+
124
+
125
+ def pixel_data(ds):
126
+
127
+ try:
128
+ array = ds.pixel_array
129
+ except:
130
+ raise ValueError("Dataset has no pixel data.")
131
+
132
+ if ds.PixelRepresentation != 1:
133
+ raise ValueError(
134
+ "Currently only signed integer or floating point supported."
135
+ )
136
+
137
+ slope = float(getattr(ds, 'RescaleSlope', 1))
138
+ intercept = float(getattr(ds, 'RescaleIntercept', 0))
139
+ array *= slope
140
+ array += intercept
141
+ if hasattr(ds, 'PixelData'):
142
+ array = array.astype(np.int16)
143
+ elif hasattr(ds, 'FloatPixelData'):
144
+ array = array.astype(np.float32)
145
+ elif hasattr(ds, 'DoubleFloatPixelData'):
146
+ array = array.astype(np.float64)
147
+ return np.transpose(array)
148
+
68
149
 
69
- # Add dummy Dimension Organization
70
- ds.DimensionOrganizationSequence = [Dataset()]
71
- ds.DimensionOrganizationSequence[0].DimensionOrganizationUID = generate_uid()
72
150
 
73
- ds.DimensionIndexSequence = [
74
- Dataset() for _ in range(1)
75
- ]
76
- ds.DimensionIndexSequence[0].DimensionOrganizationUID = ds.DimensionOrganizationSequence[0].DimensionOrganizationUID
77
- ds.DimensionIndexSequence[0].DimensionIndexPointer = (0x0020, 0x9157) # In-stack position
78
- ds.DimensionIndexSequence[0].FunctionalGroupPointer = (0x0020, 0x9116)
79
151
 
80
- return ds
81
152
 
82
153
 
83
154
 
dbdicom/utils/image.py CHANGED
@@ -16,9 +16,10 @@ def affine_matrix( # single slice function
16
16
  column_cosine = np.array(image_orientation[3:])
17
17
  slice_cosine = np.cross(row_cosine, column_cosine)
18
18
 
19
- # The coronal orientation has a left-handed reference frame
20
- if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
21
- slice_cosine = -slice_cosine
19
+ # This should not be addressed here
20
+ # # The coronal orientation has a left-handed reference frame
21
+ # if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
22
+ # slice_cosine = -slice_cosine
22
23
 
23
24
  affine = np.identity(4, dtype=np.float32)
24
25
  affine[:3, 0] = row_cosine * column_spacing
@@ -39,9 +40,9 @@ def slice_location(
39
40
  column_cosine = np.array(image_orientation[3:])
40
41
  slice_cosine = np.cross(row_cosine, column_cosine)
41
42
 
42
- # The coronal orientation has a left-handed reference frame
43
- if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
44
- slice_cosine = -slice_cosine
43
+ # # The coronal orientation has a left-handed reference frame
44
+ # if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
45
+ # slice_cosine = -slice_cosine
45
46
 
46
47
  return np.dot(np.array(image_position), slice_cosine)
47
48
 
@@ -53,14 +54,13 @@ def dismantle_affine_matrix(affine):
53
54
  # ImagePositionPatient_i = ImagePositionPatient + i * SpacingBetweenSlices * slice_cosine
54
55
  column_spacing = np.linalg.norm(affine[:3, 0])
55
56
  row_spacing = np.linalg.norm(affine[:3, 1])
56
- slice_thickness = np.linalg.norm(affine[:3, 2])
57
+ slice_spacing = np.linalg.norm(affine[:3, 2])
57
58
  row_cosine = affine[:3, 0] / column_spacing
58
59
  column_cosine = affine[:3, 1] / row_spacing
59
- slice_cosine = affine[:3, 2] / slice_thickness
60
+ slice_cosine = affine[:3, 2] / slice_spacing
60
61
  return {
61
62
  'PixelSpacing': [row_spacing, column_spacing],
62
- # 'SpacingBetweenSlices': slice_thickness, # Obsolete
63
- 'SliceThickness': slice_thickness,
63
+ 'SpacingBetweenSlices': slice_spacing,
64
64
  'ImageOrientationPatient': row_cosine.tolist() + column_cosine.tolist(),
65
65
  'ImagePositionPatient': affine[:3, 3].tolist(), # first slice for a volume
66
66
  'slice_cosine': slice_cosine.tolist()}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbdicom
3
- Version: 0.3.1
3
+ Version: 0.3.3
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
@@ -1,20 +1,21 @@
1
1
  dbdicom/__init__.py,sha256=DyogeTraV6o-FgWdBCbtVEaMmdkMQHkYkraDIE0t8OA,25
2
- dbdicom/api.py,sha256=sxQYjNu4q0gGAQ5jcE2yCpMKJnMjniTGsqwrGSQdMsU,9275
2
+ dbdicom/api.py,sha256=MHJBHY_ikUj93T8Vt0GAjvjLFJL-2IdIFKhr8T-bvVI,8871
3
3
  dbdicom/const.py,sha256=BqBiRRjeiSqDr1W6YvaayD8WKCjG4Cny2NT0GeLM6bI,4269
4
- dbdicom/dataset.py,sha256=fPKemmsJSaoyZHO-xdxvVtd4Rlh5m6rR63YkKuIFYAo,22874
5
- dbdicom/dbd.py,sha256=Y4BMR9QATz1Y4HhvPOw-pB8ps4D7Z8584PKOJQE9tzM,29768
6
- dbdicom/register.py,sha256=Nt-Q3Nvb72qRqSL1ervuunp2LBuOZEs-K8YUqihR_oQ,21210
4
+ dbdicom/database.py,sha256=_LUbH7gc9l7j_63AC71DjwxgTUwbEjHSy5kuvRw75Hw,4764
5
+ dbdicom/dataset.py,sha256=hLAyFlN7zQ-dOzI9V67aHfTq3VtpvCI7_83tnBqXObE,21880
6
+ dbdicom/dbd.py,sha256=ZUXmLcQ2C6L9UTanGzTSte1XIJAcQoNNsEpweXW8N50,29921
7
+ dbdicom/register.py,sha256=VPxS2oTlONxx5eNdGRbvFeEfQo69jo5YDp7L_Vb4x28,23676
7
8
  dbdicom/external/__init__.py,sha256=XNQqfspyf6vFGedXlRKZsUB8k8E-0W19Uamwn8Aioxo,316
8
- dbdicom/external/__pycache__/__init__.cpython-311.pyc,sha256=cIySrImYKo1fJP3-0ZMV-5ZKcZEEDX-uwfZ7I4U-jRs,534
9
+ dbdicom/external/__pycache__/__init__.cpython-311.pyc,sha256=pXAQ35ixd92fm6YcuHgzR1t6RcASQ-cHhU1wOA5b8sw,542
9
10
  dbdicom/external/dcm4che/README.md,sha256=0aAGRs36W3_0s5LzWHRGf_tqariS_JP4iJggaxnD4Xw,8987
10
11
  dbdicom/external/dcm4che/__init__.py,sha256=YwpeMCLrxffGOkchsGjgAuB6ia3VX_tx9Y7ru9EWtoY,35
11
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc,sha256=QsnVh0zH1ZSOoNwtTqiirWH8CB0b2eJ0DEvgVoVhZ0Y,248
12
+ dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc,sha256=FB8wyWqXDUt_1P-QmE4yt9uD6dDm5YqYWjqVuRwGdSo,256
12
13
  dbdicom/external/dcm4che/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  dbdicom/external/dcm4che/bin/deidentify,sha256=64MNIEpp-CWzFSb6TV0KtyCBvD7XyEsovRjBeyxDqSc,1698
14
15
  dbdicom/external/dcm4che/bin/deidentify.bat,sha256=kVXUkcy1C4Y3KjC2NJwmmR0pufSJWmaof_LR5CTAxMg,1455
15
16
  dbdicom/external/dcm4che/bin/emf2sf,sha256=svCzkZ-QhdVTV0NNHOpBiwNBMODVWZHJIFA7cWaN2bM,1622
16
17
  dbdicom/external/dcm4che/bin/emf2sf.bat,sha256=Vh0ry9KNJX_WXcyCrLSxbJ_6Crot9rjmwi__u2GZqLY,1375
17
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc,sha256=M2mla4vNW1gSUWQps3dx4g8NRd4BaQJLP1OKQHmi6Sk,195
18
+ dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc,sha256=GYcm47ETjYvRUN5RPTe5R-c0prd14GP8gm96eJcy0uQ,203
18
19
  dbdicom/external/dcm4che/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
20
  dbdicom/external/dcm4che/etc/emf2sf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
21
  dbdicom/external/dcm4che/etc/emf2sf/log4j.properties,sha256=3hHcBFt2oNRjvHtix5bfuEsnKfdv5IYOkbsyoY9g7cM,223
@@ -35,8 +36,8 @@ dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll,sha256=QanyzLy0Cd79-aOV
35
36
  dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll,sha256=TmjW2SbG4MR3GQ95T8xCVVDLgsdKukgaHBPUvWkfXp8,11039232
36
37
  dbdicom/sop_classes/ct_image.py,sha256=16PNv_0e1_7cfxE12JWlx5YQeaTAQVzwtXTjxs3aonk,2812
37
38
  dbdicom/sop_classes/enhanced_mr_image.py,sha256=13j4EGXniBpJxpzzL3Xa4y3g5OKhMd5Ct7cjPGOYQY4,35496
38
- dbdicom/sop_classes/mr_image.py,sha256=6V2OyjwkaZxoljImNREU0Du4NJLHHsY_GgOe2XQsmNg,10683
39
- dbdicom/sop_classes/parametric_map.py,sha256=ayNMpeBbc-neVGDjEAe5ww_UYJvbRmk46rHa_CjwZao,10280
39
+ dbdicom/sop_classes/mr_image.py,sha256=kNcrWXZ3VC3hhfqjMRjrlZOVqZH3Q5KfWXYLfLD-bEY,10913
40
+ dbdicom/sop_classes/parametric_map.py,sha256=2OKBuC2bo03OEpKqimQS-nVGFp1cKRPYwVgmDGVf1JU,12288
40
41
  dbdicom/sop_classes/secondary_capture.py,sha256=wgNRX8qyhV7HR7Jq2tQWPPuGpiRzYl6qPOgK6qFbPUc,4541
41
42
  dbdicom/sop_classes/segmentation.py,sha256=I8-PciIoIz27_-dZ4esBZSw0TBBbO8KbNYTiTmVe62g,11465
42
43
  dbdicom/sop_classes/ultrasound_multiframe_image.py,sha256=j3KN5R90j6WwPMy01hAN2_XSum5TvksF2MYoNGfX_yE,2797
@@ -44,10 +45,10 @@ dbdicom/sop_classes/xray_angiographic_image.py,sha256=nWysCGaEWKVNItnOgyJfcGMpS3
44
45
  dbdicom/utils/arrays.py,sha256=wiqCczLXlNl0qIePVOwCYvbAJhPveNorplkhtGleS48,1121
45
46
  dbdicom/utils/dcm4che.py,sha256=Vxq8NYWWK3BuqJkzhBQ89oMqzJlnxqTxgsgTo_Frznc,2317
46
47
  dbdicom/utils/files.py,sha256=qhWNJqeWnRjDNbERpC6Mz962_TW9mFdvd2lnBbK3xt4,2259
47
- dbdicom/utils/image.py,sha256=s1P8m-s64ygKSh_X4DdV96LC4DvCe3KO3_71l72zWoU,4057
48
+ dbdicom/utils/image.py,sha256=D46CD_ezpp2uq8VMqug5Z09fAyoJ9U6VwuxIFNJK8zg,4048
48
49
  dbdicom/utils/variables.py,sha256=vUh5cDnmCft5hoXDYXUvfkg5Cy5WlgMAogU38Y_BKRo,5753
49
- dbdicom-0.3.1.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
50
- dbdicom-0.3.1.dist-info/METADATA,sha256=97Xgzc6BE9N3ygBO59psUqmVs9TTZ9iw7o2dUMJSFfQ,1075
51
- dbdicom-0.3.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
52
- dbdicom-0.3.1.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
53
- dbdicom-0.3.1.dist-info/RECORD,,
50
+ dbdicom-0.3.3.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
51
+ dbdicom-0.3.3.dist-info/METADATA,sha256=aMYhKPS907fOj0pgSkQh7vbFeYspNvJP5-ZYNZ6LpMs,1030
52
+ dbdicom-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ dbdicom-0.3.3.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
54
+ dbdicom-0.3.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5