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.
Files changed (72) hide show
  1. dbdicom/__init__.py +3 -25
  2. dbdicom/api.py +496 -0
  3. dbdicom/const.py +144 -0
  4. dbdicom/database.py +133 -0
  5. dbdicom/dataset.py +471 -0
  6. dbdicom/dbd.py +1290 -0
  7. dbdicom/external/__pycache__/__init__.cpython-311.pyc +0 -0
  8. dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc +0 -0
  9. dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc +0 -0
  10. dbdicom/external/dcm4che/bin/emf2sf +57 -57
  11. dbdicom/register.py +402 -0
  12. dbdicom/{ds/types → sop_classes}/ct_image.py +2 -16
  13. dbdicom/{ds/types → sop_classes}/enhanced_mr_image.py +206 -160
  14. dbdicom/sop_classes/mr_image.py +338 -0
  15. dbdicom/sop_classes/parametric_map.py +381 -0
  16. dbdicom/sop_classes/secondary_capture.py +140 -0
  17. dbdicom/sop_classes/segmentation.py +311 -0
  18. dbdicom/{ds/types → sop_classes}/ultrasound_multiframe_image.py +1 -15
  19. dbdicom/{ds/types → sop_classes}/xray_angiographic_image.py +2 -17
  20. dbdicom/utils/arrays.py +142 -0
  21. dbdicom/utils/files.py +0 -20
  22. dbdicom/utils/image.py +43 -466
  23. dbdicom/utils/pydicom_dataset.py +386 -0
  24. dbdicom-0.3.16.dist-info/METADATA +26 -0
  25. dbdicom-0.3.16.dist-info/RECORD +54 -0
  26. {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/WHEEL +1 -1
  27. dbdicom/create.py +0 -450
  28. dbdicom/ds/__init__.py +0 -10
  29. dbdicom/ds/create.py +0 -63
  30. dbdicom/ds/dataset.py +0 -841
  31. dbdicom/ds/dictionaries.py +0 -620
  32. dbdicom/ds/types/mr_image.py +0 -267
  33. dbdicom/ds/types/parametric_map.py +0 -226
  34. dbdicom/external/__pycache__/__init__.cpython-310.pyc +0 -0
  35. dbdicom/external/__pycache__/__init__.cpython-37.pyc +0 -0
  36. dbdicom/external/dcm4che/__pycache__/__init__.cpython-310.pyc +0 -0
  37. dbdicom/external/dcm4che/__pycache__/__init__.cpython-37.pyc +0 -0
  38. dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-310.pyc +0 -0
  39. dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-37.pyc +0 -0
  40. dbdicom/external/dcm4che/lib/linux-x86/libclib_jiio.so +0 -0
  41. dbdicom/external/dcm4che/lib/linux-x86-64/libclib_jiio.so +0 -0
  42. dbdicom/external/dcm4che/lib/linux-x86-64/libopencv_java.so +0 -0
  43. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio.so +0 -0
  44. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis.so +0 -0
  45. dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis2.so +0 -0
  46. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio.so +0 -0
  47. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis.so +0 -0
  48. dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis2.so +0 -0
  49. dbdicom/external/dcm4che/lib/solaris-x86/libclib_jiio.so +0 -0
  50. dbdicom/external/dcm4che/lib/solaris-x86-64/libclib_jiio.so +0 -0
  51. dbdicom/manager.py +0 -2077
  52. dbdicom/message.py +0 -119
  53. dbdicom/record.py +0 -1526
  54. dbdicom/types/database.py +0 -107
  55. dbdicom/types/instance.py +0 -184
  56. dbdicom/types/patient.py +0 -40
  57. dbdicom/types/series.py +0 -816
  58. dbdicom/types/study.py +0 -58
  59. dbdicom/utils/variables.py +0 -155
  60. dbdicom/utils/vreg.py +0 -2626
  61. dbdicom/wrappers/__init__.py +0 -7
  62. dbdicom/wrappers/dipy.py +0 -462
  63. dbdicom/wrappers/elastix.py +0 -855
  64. dbdicom/wrappers/numpy.py +0 -119
  65. dbdicom/wrappers/scipy.py +0 -1413
  66. dbdicom/wrappers/skimage.py +0 -1030
  67. dbdicom/wrappers/sklearn.py +0 -151
  68. dbdicom/wrappers/vreg.py +0 -273
  69. dbdicom-0.2.0.dist-info/METADATA +0 -276
  70. dbdicom-0.2.0.dist-info/RECORD +0 -81
  71. {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info/licenses}/LICENSE +0 -0
  72. {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/top_level.txt +0 -0
@@ -1,267 +0,0 @@
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
- import struct
5
- import numpy as np
6
- import pydicom
7
- from pydicom.dataset import Dataset, FileMetaDataset
8
- from pydicom.sequence import Sequence
9
-
10
- from dbdicom.ds.dataset import DbDataset
11
- import dbdicom.utils.image as image
12
-
13
-
14
- class MRImage(DbDataset):
15
-
16
- def __init__(self, dataset=None, template=None):
17
- super().__init__()
18
-
19
- if (dataset is None) and (template is None):
20
- template = 'RIDER'
21
-
22
- if dataset is not None:
23
- self.__dict__ = dataset.__dict__
24
-
25
- if template == 'RIDER':
26
- rider(self)
27
-
28
- def get_pixel_array(self):
29
- return get_pixel_array(self)
30
-
31
- def set_pixel_array(self, array):
32
- set_pixel_array(self, array)
33
-
34
- def get_attribute_image_type(self):
35
- return get_attribute_image_type(self)
36
-
37
- def set_attribute_image_type(self, value):
38
- set_attribute_image_type(self, value)
39
-
40
- def get_attribute_signal_type(self):
41
- return get_attribute_signal_type(self)
42
-
43
- def set_attribute_signal_type(self, value):
44
- set_attribute_signal_type(self, value)
45
-
46
-
47
-
48
- def rider(ds): # required only - check
49
-
50
- # File meta info data elements
51
- ds.file_meta = FileMetaDataset()
52
- ds.file_meta.FileMetaInformationGroupLength = 190
53
- ds.file_meta.FileMetaInformationVersion = b'\x00\x01'
54
- ds.file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
55
- ds.file_meta.MediaStorageSOPInstanceUID = '1.3.6.1.4.1.9328.50.16.175333593952805976694548436931998383940'
56
- ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
57
- ds.file_meta.ImplementationClassUID = '1.2.40.0.13.1.1'
58
- ds.file_meta.ImplementationVersionName = 'dcm4che-1.4.27'
59
-
60
- ds.is_implicit_VR = True
61
- ds.is_little_endian = True
62
-
63
- # Main data elements
64
- ds.SpecificCharacterSet = 'ISO_IR 100'
65
- ds.ImageType = ['ORIGINAL', 'PRIMARY', 'M', 'ND', 'NORM']
66
- ds.SOPClassUID = '1.2.840.10008.5.1.4.1.1.4'
67
- ds.SOPInstanceUID = pydicom.uid.generate_uid()
68
- ds.StudyDate = '19040321'
69
- ds.ContentDate = '19040321'
70
- ds.StudyTime = ''
71
- ds.AcquisitionTime = '075649.057496'
72
- ds.ContentTime = ''
73
- ds.AccessionNumber = '2819497684894126'
74
- ds.Modality = 'MR'
75
- ds.Manufacturer = 'SIEMENS'
76
- ds.ReferringPhysicianName = ''
77
- ds.StationName = ''
78
- ds.StudyDescription = 'BRAIN^RESEARCH'
79
- ds.SeriesDescription = 'sag 3d gre +c'
80
- ds.ManufacturerModelName = ''
81
- ds.ReferencedSOPClassUID = '1.3.6.1.4.1.9328.50.16.295504506656781074046411123909869020125'
82
- ds.ReferencedSOPInstanceUID = '1.3.6.1.4.1.9328.50.16.303143938897288157958328401346374476407'
83
- ds.PatientName = '281949'
84
- ds.PatientID = pydicom.uid.generate_uid()
85
- ds.PatientBirthDate = ''
86
- ds.PatientSex = ''
87
- ds.PatientIdentityRemoved = 'YES'
88
- ds.DeidentificationMethod = 'CTP:NBIA Default w/ extra date removal:20100323:172722'
89
- ds.ContrastBolusAgent = 'Magnevist'
90
- ds.BodyPartExamined = 'FAKE'
91
- ds.ScanningSequence = 'GR'
92
- ds.SequenceVariant = 'SP'
93
- ds.ScanOptions = ''
94
- ds.MRAcquisitionType = '3D'
95
- ds.SequenceName = '*fl3d1'
96
- ds.AngioFlag = 'N'
97
- ds.SliceThickness = '1.0'
98
- ds.RepetitionTime = '8.6'
99
- ds.EchoTime = '4.11'
100
- ds.NumberOfAverages = '1.0'
101
- ds.ImagingFrequency = '63.676701'
102
- ds.ImagedNucleus = '1H'
103
- ds.EchoNumbers = '0'
104
- ds.MagneticFieldStrength = '1.4939999580383'
105
- ds.NumberOfPhaseEncodingSteps = '224'
106
- ds.EchoTrainLength = '1'
107
- ds.PercentSampling = '100.0'
108
- ds.PercentPhaseFieldOfView = '100.0'
109
- ds.PixelBandwidth = '150.0'
110
- ds.DeviceSerialNumber = '25445'
111
- ds.SoftwareVersions = 'syngo MR 2004V 4VB11D'
112
- ds.ProtocolName = 'sag 3d gre +c'
113
- ds.ContrastBolusVolume = '20.0'
114
- ds.DateOfLastCalibration = '19031229'
115
- ds.TimeOfLastCalibration = '155156.000000'
116
- ds.TransmitCoilName = 'Body'
117
- ds.InPlanePhaseEncodingDirection = 'ROW'
118
- ds.FlipAngle = '20.0'
119
- ds.VariableFlipAngleFlag = 'N'
120
- ds.SAR = '0.09494107961655'
121
- ds.dBdt = '0.0'
122
- ds.PatientPosition = 'HFS'
123
- ds.StudyInstanceUID = pydicom.uid.generate_uid()
124
- ds.SeriesInstanceUID = pydicom.uid.generate_uid()
125
- ds.StudyID = ''
126
- ds.SeriesNumber = '14'
127
- ds.AcquisitionNumber = '1'
128
- ds.InstanceNumber = '1'
129
- ds.ImagePositionPatient = [75.561665058136, -163.6216506958, 118.50172901154]
130
- ds.ImageOrientationPatient = [0, 1, 0, 0, 0, -1]
131
- ds.FrameOfReferenceUID = '1.3.6.1.4.1.9328.50.16.22344679587635360510174487884943834158'
132
- ds.PositionReferenceIndicator = ''
133
- ds.SliceLocation = '75.561665058136'
134
- ds.SamplesPerPixel = 1
135
- ds.PhotometricInterpretation = 'MONOCHROME2'
136
- ds.Rows = 64
137
- ds.Columns = 64
138
- ds.PixelSpacing = [1, 1]
139
- ds.BitsAllocated = 16
140
- ds.BitsStored = 16
141
- ds.HighBit = 15
142
- ds.PixelRepresentation = 0
143
- ds.SmallestImagePixelValue = 0
144
- ds.LargestImagePixelValue = 913
145
- ds.WindowCenter = '136.0'
146
- ds.WindowWidth = '380.0'
147
- ds.RescaleIntercept = '0.0'
148
- ds.RescaleSlope = '1.0'
149
- ds.RescaleType = 'PIXELVALUE'
150
- ds.WindowCenterWidthExplanation = 'Algo1'
151
- ds.RequestedProcedureDescription = 'MRI BRAIN W/WO ENHANCEMENT'
152
- ds.ScheduledProcedureStepDescription = 'MRI BRAIN W/WO ENHANCEMENT'
153
- ds.ScheduledProcedureStepID = '5133240'
154
- ds.PerformedProcedureStepStartDate = '19040611'
155
- ds.PerformedProcedureStepDescription = 'MRI BRAIN W/WO ENHANCEMENT'
156
- ds.RequestAttributesSequence = Sequence()
157
- ds.RequestedProcedureID = '5133240'
158
- ds.StorageMediaFileSetUID = '1.3.6.1.4.1.9328.50.16.162890465625511526068665093825399871205'
159
- ds.PixelData = np.arange(ds.Rows*ds.Columns, dtype=np.uint16)*ds.LargestImagePixelValue/(ds.Rows*ds.Columns)
160
-
161
- return ds
162
-
163
-
164
- def get_pixel_array(ds):
165
- """Read the pixel array from an MR image"""
166
-
167
- #array = ds.pixel_array.astype(np.float64)
168
- #array = ds.pixel_array
169
- #array = np.frombuffer(ds.PixelData, dtype=np.uint16).reshape(ds.Rows, ds.Columns)
170
- #array = array.astype(np.float32)
171
-
172
- array = ds.pixel_array
173
- array = array.astype(np.float32)
174
- if [0x2005, 0x100E] in ds: # 'Philips Rescale Slope'
175
- slope = ds[(0x2005, 0x100E)].value
176
- intercept = ds[(0x2005, 0x100D)].value
177
- array -= intercept
178
- array /= slope
179
- else:
180
- slope = float(getattr(ds, 'RescaleSlope', 1))
181
- intercept = float(getattr(ds, 'RescaleIntercept', 0))
182
- array *= slope
183
- array += intercept
184
- return np.transpose(array)
185
-
186
-
187
- def set_pixel_array(ds, array):
188
-
189
- if (0x2005, 0x100E) in ds:
190
- del ds[0x2005, 0x100E] # Delete 'Philips Rescale Slope'
191
- if (0x2005, 0x100D) in ds:
192
- del ds[0x2005, 0x100D]
193
-
194
- # clipping may slow down a lot
195
- array = image.clip(array.astype(np.float32))
196
- array, slope, intercept = image.scale_to_range(array, ds.BitsAllocated)
197
- array = np.transpose(array)
198
-
199
- ds.PixelRepresentation = 0
200
- ds.set_values('SmallestImagePixelValue', int(0))
201
- ds.set_values('LargestImagePixelValue', int(2**ds.BitsAllocated - 1))
202
- ds.RescaleSlope = 1 / slope
203
- ds.RescaleIntercept = - intercept / slope
204
- # ds.WindowCenter = (maximum + minimum) / 2
205
- # ds.WindowWidth = maximum - minimum
206
- ds.Rows = array.shape[0]
207
- ds.Columns = array.shape[1]
208
- ds.PixelData = array.tobytes()
209
-
210
-
211
- def get_attribute_image_type(ds):
212
- """Determine if an image is Magnitude, Phase, Real or Imaginary image or None"""
213
-
214
- if (0x0043, 0x102f) in ds:
215
- private_ge = ds[0x0043, 0x102f]
216
- try:
217
- value = struct.unpack('h', private_ge.value)[0]
218
- except:
219
- value = private_ge.value
220
- if value == 0:
221
- return 'MAGNITUDE'
222
- if value == 1:
223
- return 'PHASE'
224
- if value == 2:
225
- return 'REAL'
226
- if value == 3:
227
- return 'IMAGINARY'
228
-
229
- if 'ImageType' in ds:
230
- type = set(ds.ImageType)
231
- if set(['M', 'MAGNITUDE']).intersection(type):
232
- return 'MAGNITUDE'
233
- if set(['P', 'PHASE']).intersection(type):
234
- return 'PHASE'
235
- if set(['R', 'REAL']).intersection(type):
236
- return 'REAL'
237
- if set(['I', 'IMAGINARY']).intersection(type):
238
- return 'IMAGINARY'
239
-
240
- if 'ComplexImageComponent' in ds:
241
- return ds.ComplexImageComponent
242
-
243
- return 'UNKNOWN'
244
-
245
-
246
- def set_attribute_image_type(ds, value):
247
- ds.ImageType = value
248
-
249
-
250
- def get_attribute_signal_type(ds):
251
- """Determine if an image is Water, Fat, In-Phase, Out-phase image or None"""
252
-
253
- if hasattr(ds, 'ImageType'):
254
- type = set(ds.ImageType)
255
- if set(['W', 'WATER']).intersection(type):
256
- return 'WATER'
257
- elif set(['F', 'FAT']).intersection(type):
258
- return 'FAT'
259
- elif set(['IP', 'IN_PHASE']).intersection(type):
260
- return 'IN_PHASE'
261
- elif set(['OP', 'OUT_PHASE']).intersection(type):
262
- return 'OP_PHASE'
263
- return 'UNKNOWN'
264
-
265
-
266
- def set_attribute_signal_type(ds, value):
267
- ds.ImageType = value
@@ -1,226 +0,0 @@
1
- """Remnant code from old version - saved here for now"""
2
-
3
- from pydicom.dataset import Dataset
4
- import numpy as np
5
- import datetime
6
-
7
-
8
-
9
- class ParametricMap(object):
10
- def selectParametricMap(self, dicom, imageArray, argument):
11
- methodName = argument
12
- method = getattr(self, methodName, lambda: "No valid Parametric Map chosen")
13
- return method(dicom, imageArray)
14
-
15
- def RGB(self, dicom, imageArray):
16
- dicom.PhotometricInterpretation = 'RGB'
17
- dicom.SamplesPerPixel = 3
18
- dicom.BitsAllocated = 8
19
- dicom.BitsStored = 8
20
- dicom.HighBit = 7
21
- dicom.add_new(0x00280006, 'US', 0) # Planar Configuration
22
- dicom.RescaleSlope = 1
23
- dicom.RescaleIntercept = 0
24
- pixelArray = imageArray.astype(np.uint8) # Should we multiply by 255?
25
- dicom.WindowCenter = int((np.amax(imageArray) - np.amin(imageArray)) / 2)
26
- dicom.WindowWidth = np.absolute(int(np.amax(imageArray) - np.amin(imageArray)))
27
- dicom.PixelData = pixelArray.tobytes()
28
- return
29
-
30
- def ADC(self, dicom, imageArray):
31
- # The commented parts are to apply when we decide to include Parametric Map IOD. No readers can deal with this yet
32
- # dicom.SOPClassUID = '1.2.840.10008.5.1.4.1.1.67'
33
- dicom.SeriesDescription = "Apparent Diffusion Coefficient (um2/s)"
34
- dicom.Modality = "RWV"
35
- dicom.FrameLaterality = "U"
36
- dicom.DerivedPixelContrast = "ADC"
37
- dicom.BitsAllocated = 32
38
- dicom.PixelRepresentation = 1
39
- dicom.PhotometricInterpretation = "MONOCHROME2"
40
- dicom.PixelAspectRatio = ["1", "1"] # Need to have a better look at this
41
- dicom.RescaleSlope = 1
42
- dicom.RescaleIntercept = 0
43
- # Rotate the image back to the original orientation
44
- imageArray = np.transpose(imageArray)
45
- dicom.Rows = np.shape(imageArray)[-2]
46
- dicom.Columns = np.shape(imageArray)[-1]
47
- dicom.WindowCenter = int((np.amax(imageArray) - np.amin(imageArray)) / 2)
48
- dicom.WindowWidth = np.absolute(int(np.amax(imageArray) - np.amin(imageArray)))
49
- dicom.FloatPixelData = bytes(imageArray.astype(np.float32).flatten())
50
- del dicom.PixelData, dicom.BitsStored, dicom.HighBit
51
-
52
- dicom.RealWorldValueMappingSequence = [Dataset(), Dataset(), Dataset(), Dataset()]
53
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence = [Dataset(), Dataset()]
54
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence[0].ValueType = "CODE"
55
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence[1].ConceptCodeSequence = [Dataset(), Dataset(), Dataset()]
56
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence[1].ConceptCodeSequence[0].CodeValue = "113041"
57
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence[1].ConceptCodeSequence[1].CodingSchemeDesignator = "DCM"
58
- dicom.RealWorldValueMappingSequence[0].QuantityDefinitionSequence[1].ConceptCodeSequence[2].CodeMeaning = "Apparent Diffusion Coefficient"
59
- dicom.RealWorldValueMappingSequence[1].MeasurementUnitsCodeSequence = [Dataset(), Dataset(), Dataset()]
60
- dicom.RealWorldValueMappingSequence[1].MeasurementUnitsCodeSequence[0].CodeValue = "um2/s"
61
- dicom.RealWorldValueMappingSequence[1].MeasurementUnitsCodeSequence[1].CodingSchemeDesignator = "UCUM"
62
- dicom.RealWorldValueMappingSequence[1].MeasurementUnitsCodeSequence[2].CodeMeaning = "um2/s"
63
- dicom.RealWorldValueMappingSequence[2].RealWorldValueSlope = 1
64
-
65
- anatomyString = dicom.BodyPartExamined
66
- saveAnatomicalInfo(anatomyString, dicom.RealWorldValueMappingSequence[3])
67
-
68
- return
69
-
70
- def T2Star(self, dicom, imageArray):
71
- dicom.PixelSpacing = [3, 3] # find a mechanism to pass reconstruct pixel here
72
- return
73
-
74
- def SEG(self, dicom, imageArray):
75
- #dicom.SOPClassUID = '1.2.840.10008.5.1.4.1.1.66.4' # WILL NOT BE USED HERE - This is for PACS. There will be another one for DICOM Standard
76
- # The commented parts are to apply when we decide to include SEG IOD. No readers can deal with this yet
77
- dicom.BitsAllocated = 8 # According to Federov DICOM Standard this should be 1-bit
78
- dicom.BitsStored = 8
79
- dicom.HighBit = 7
80
- #dicom.SmallestImagePixelValue = 0
81
- #dicom.LargestImagePixelValue = int(np.amax(imageArray)) # max 255
82
- dicom.add_new('0x00280106', 'US', 0) # Minimum
83
- dicom.add_new('0x00280107', 'US', int(np.amax(imageArray))) # Maximum
84
- dicom.PixelRepresentation = 0
85
- dicom.SamplesPerPixel = 1
86
- #dicom.WindowCenter = 0.5
87
- #dicom.WindowWidth = 1.1
88
- dicom.add_new('0x00281050', 'DS', 0.5) # WindowCenter
89
- dicom.add_new('0x00281051', 'DS', 1.1) # WindowWidth
90
- #dicom.RescaleIntercept = 0
91
- #dicom.RescaleSlope = 1
92
- dicom.add_new('0x00281052', 'DS', 0) # RescaleIntercept
93
- dicom.add_new('0x00281053', 'DS', 1) # RescaleSlope
94
- dicom.LossyImageCompression = '00'
95
- pixelArray = np.transpose(imageArray.astype(np.uint8)) # Should we multiply by 255?
96
- dicom.PixelData = pixelArray.tobytes()
97
-
98
- dicom.Modality = 'SEG'
99
- dicom.SegmentationType = 'FRACTIONAL'
100
- dicom.MaximumFractionalValue = int(np.amax(imageArray)) # max 255
101
- dicom.SegmentationFractionalType = 'OCCUPANCY'
102
-
103
- # Segment Labels
104
- if hasattr(dicom, "ImageComments"):
105
- dicom.ContentDescription = dicom.ImageComments.split('_')[-1] # 'Image segmentation'
106
- segment_numbers = np.unique(pixelArray)
107
- segment_dictionary = dict(list(enumerate(segment_numbers)))
108
- segment_label = dicom.ImageComments.split('_')[-1]
109
- segment_dictionary[0] = 'Background'
110
- segment_dictionary[1] = segment_label
111
- for key in segment_dictionary:
112
- dicom.SegmentSequence = [Dataset(), Dataset(), Dataset(), Dataset(), Dataset(), Dataset()]
113
- dicom.SegmentSequence[0].SegmentAlgorithmType = 'MANUAL'
114
- dicom.SegmentSequence[1].SegmentNumber = key
115
- dicom.SegmentSequence[2].SegmentDescription = str(segment_dictionary[key])
116
- dicom.SegmentSequence[3].SegmentLabel = str(segment_dictionary[key])
117
- dicom.SegmentSequence[4].SegmentAlgorithmName = "Weasel"
118
- if hasattr(dicom, "BodyPartExamined"):
119
- anatomyString = dicom.BodyPartExamined
120
- saveAnatomicalInfo(anatomyString, dicom.SegmentSequence[5])
121
- else:
122
- dicom.ContentDescription = "Mask with no label"
123
-
124
- return
125
-
126
- def Registration(self, dicom, imageArray):
127
- dicom.Modality = "REG"
128
- return
129
-
130
- def Signal(self, dicom, imageArray):
131
- dicom.Modality = "RWV"
132
- dicom.DerivedPixelContrast = "GraphPlot"
133
- dicom.PhotometricInterpretation = "MONOCHROME2"
134
- dicom.RescaleSlope = 1
135
- dicom.RescaleIntercept = 0
136
- imageArray = np.transpose(imageArray.astype(np.float32))
137
- center = (np.amax(imageArray) + np.amin(imageArray)) / 2
138
- width = np.amax(imageArray) - np.amin(imageArray)
139
- dicom.add_new('0x00281050', 'DS', center)
140
- dicom.add_new('0x00281051', 'DS', width)
141
- dicom.BitsAllocated = 32
142
- dicom.Rows = np.shape(imageArray)[0]
143
- dicom.Columns = np.shape(imageArray)[1]
144
- dicom.FloatPixelData = bytes(imageArray.flatten())
145
- del dicom.PixelData, dicom.BitsStored, dicom.HighBit
146
- return
147
-
148
- # Could insert a method regarding ROI colours, like in ITK-SNAP???
149
- def saveAnatomicalInfo(anatomyString, dicom):
150
- try:
151
- # FOR NOW, THE PRIORITY WILL BE ON KIDNEY
152
- if "KIDNEY" or "ABDOMEN" in anatomyString.upper():
153
- dicom.AnatomicRegionSequence = [Dataset(), Dataset(), Dataset()]
154
- dicom.AnatomicRegionSequence[0].CodeValue = "T-71000"
155
- dicom.AnatomicRegionSequence[1].CodingSchemeDesignator = "SRT"
156
- dicom.AnatomicRegionSequence[2].CodeMeaning = "Kidney"
157
- elif "LIVER" in anatomyString.upper():
158
- dicom.AnatomicRegionSequence = [Dataset(), Dataset(), Dataset()]
159
- dicom.AnatomicRegionSequence[0].CodeValue = "T-62000"
160
- dicom.AnatomicRegionSequence[1].CodingSchemeDesignator = "SRT"
161
- dicom.AnatomicRegionSequence[2].CodeMeaning = "Liver"
162
- elif "PROSTATE" in anatomyString.upper():
163
- dicom.AnatomicRegionSequence = [Dataset(), Dataset(), Dataset()]
164
- dicom.AnatomicRegionSequence[0].CodeValue = "T-9200B"
165
- dicom.AnatomicRegionSequence[1].CodingSchemeDesignator = "SRT"
166
- dicom.AnatomicRegionSequence[2].CodeMeaning = "Prostate"
167
- elif "BODY" in anatomyString.upper():
168
- dicom.AnatomicRegionSequence = [Dataset(), Dataset(), Dataset()]
169
- dicom.AnatomicRegionSequence[0].CodeValue = "P5-0905E"
170
- dicom.AnatomicRegionSequence[1].CodingSchemeDesignator = "LN"
171
- dicom.AnatomicRegionSequence[2].CodeMeaning = "MRI whole body"
172
- except:
173
- pass
174
- return
175
-
176
- def editDicom(newDicom, imageArray, parametricMap):
177
-
178
- callCase = ParametricMap()
179
- callCase.selectParametricMap(newDicom, imageArray, parametricMap)
180
-
181
- dt = datetime.datetime.now()
182
- timeStr = dt.strftime('%H%M%S') # long format with micro seconds
183
- newDicom.PerformedProcedureStepStartDate = dt.strftime('%Y%m%d')
184
- newDicom.PerformedProcedureStepStartTime = timeStr
185
- newDicom.PerformedProcedureStepDescription = "Post-processing application"
186
-
187
- return newDicom
188
-
189
- # Series, Instance and Class for Reference
190
- #newDicom.ReferencedSeriesSequence = [Dataset(), Dataset()]
191
- #newDicom.ReferencedSeriesSequence[0].SeriesInstanceUID = dicom_data.SeriesInstanceUID
192
- #newDicom.ReferencedSeriesSequence[1].ReferencedInstanceSequence = [Dataset(), Dataset()]
193
- #newDicom.ReferencedSeriesSequence[1].ReferencedInstanceSequence[0].ReferencedSOPClassUID = dicom_data.SOPClassUID
194
- #newDicom.ReferencedSeriesSequence[1].ReferencedInstanceSequence[1].ReferencedSOPInstanceUID = dicom_data.SOPInstanceUID
195
-
196
- # rwv_sequence = Sequence()
197
- # dicom.RealWorldValueMappingSequence = rwv_sequence
198
- # rwv_slope = Dataset()
199
- # rwv_slope.RealWorldValueSlope = 1
200
- # rwv_sequence.append(rwv_slope)
201
-
202
- # quantity_def = Dataset()
203
- # quantity_def_sequence = Sequence()
204
- # quantity_def.QuantityDefinitionSequence = quantity_def_sequence
205
- # value_type = Dataset()
206
- # value_type.ValueType = "CODE"
207
- # quantity_def_sequence.append(value_type)
208
- # concept_code = Dataset()
209
- # concept_code_sequence = Sequence()
210
- # concept_code.ConceptCodeSequence = concept_code_sequence
211
- # code_code = Dataset()
212
- # code_code.CodeValue = "113041"
213
- # code_code.CodingSchemeDesignator = "DCM"
214
- # code_code.CodeMeaning = "Apparent Diffusion Coefficient"
215
- # concept_code_sequence.append(code_code)
216
- # rwv_sequence.append(quantity_def)
217
-
218
- # measure_units = Dataset()
219
- # measure_units_sequence = Sequence()
220
- # measure_units.MeasurementUnitsCodeSequence = measure_units_sequence
221
- # measure_code = Dataset()
222
- # measure_code.CodeValue = "um2/s"
223
- # measure_code.CodingSchemeDesignator = "UCUM"
224
- # measure_code.CodeMeaning = "um2/s"
225
- # measure_units_sequence.append(measure_code)
226
- # rwv_sequence.append(measure_units)