dbdicom 0.3.2__py3-none-any.whl → 0.3.4__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.
- dbdicom/api.py +46 -36
- dbdicom/database.py +4 -0
- dbdicom/dataset.py +19 -26
- dbdicom/dbd.py +251 -119
- 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/register.py +146 -404
- dbdicom/sop_classes/mr_image.py +34 -13
- dbdicom/utils/image.py +3 -4
- {dbdicom-0.3.2.dist-info → dbdicom-0.3.4.dist-info}/METADATA +1 -1
- {dbdicom-0.3.2.dist-info → dbdicom-0.3.4.dist-info}/RECORD +15 -15
- {dbdicom-0.3.2.dist-info → dbdicom-0.3.4.dist-info}/WHEEL +0 -0
- {dbdicom-0.3.2.dist-info → dbdicom-0.3.4.dist-info}/licenses/LICENSE +0 -0
- {dbdicom-0.3.2.dist-info → dbdicom-0.3.4.dist-info}/top_level.txt +0 -0
dbdicom/register.py
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
class AmbiguousError(Exception):
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def add_instance(dbtree:list, attr, rel_path):
|
|
5
9
|
|
|
6
10
|
# Get patient and create if needed
|
|
7
|
-
pts = [pt for pt in dbtree if pt['PatientID']==
|
|
11
|
+
pts = [pt for pt in sorted(dbtree, key=lambda pt: pt['PatientID']) if pt['PatientID']==attr['PatientID']]
|
|
8
12
|
if pts==[]:
|
|
9
13
|
pt = {
|
|
10
|
-
'PatientName':
|
|
11
|
-
'PatientID':
|
|
14
|
+
'PatientName': attr['PatientName'],
|
|
15
|
+
'PatientID': attr['PatientID'],
|
|
12
16
|
'studies': [],
|
|
13
17
|
}
|
|
14
18
|
dbtree.append(pt)
|
|
@@ -16,12 +20,12 @@ def add_instance(dbtree:list, instance, rel_path):
|
|
|
16
20
|
pt = pts[0]
|
|
17
21
|
|
|
18
22
|
# Get study and create if needed
|
|
19
|
-
sts = [st for st in pt['studies'] if st['StudyInstanceUID']==
|
|
23
|
+
sts = [st for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']) if st['StudyInstanceUID']==attr['StudyInstanceUID']]
|
|
20
24
|
if sts==[]:
|
|
21
25
|
st = {
|
|
22
|
-
'StudyDescription':
|
|
23
|
-
'
|
|
24
|
-
'StudyInstanceUID':
|
|
26
|
+
'StudyDescription': attr['StudyDescription'],
|
|
27
|
+
'StudyID': attr['StudyID'],
|
|
28
|
+
'StudyInstanceUID': attr['StudyInstanceUID'],
|
|
25
29
|
'series': [],
|
|
26
30
|
}
|
|
27
31
|
pt['studies'].append(st)
|
|
@@ -29,12 +33,12 @@ def add_instance(dbtree:list, instance, rel_path):
|
|
|
29
33
|
st = sts[0]
|
|
30
34
|
|
|
31
35
|
# Get series and create if needed
|
|
32
|
-
srs = [sr for sr in st['series'] if sr['SeriesInstanceUID']==
|
|
36
|
+
srs = [sr for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']) if sr['SeriesInstanceUID']==attr['SeriesInstanceUID']]
|
|
33
37
|
if srs==[]:
|
|
34
38
|
sr = {
|
|
35
|
-
'SeriesNumber':
|
|
36
|
-
'SeriesDescription':
|
|
37
|
-
'SeriesInstanceUID':
|
|
39
|
+
'SeriesNumber': attr['SeriesNumber'],
|
|
40
|
+
'SeriesDescription': attr['SeriesDescription'],
|
|
41
|
+
'SeriesInstanceUID': attr['SeriesInstanceUID'],
|
|
38
42
|
'instances': {},
|
|
39
43
|
}
|
|
40
44
|
st['series'].append(sr)
|
|
@@ -42,7 +46,7 @@ def add_instance(dbtree:list, instance, rel_path):
|
|
|
42
46
|
sr = srs[0]
|
|
43
47
|
|
|
44
48
|
# Add instance
|
|
45
|
-
sr['instances'][
|
|
49
|
+
sr['instances'][attr['InstanceNumber']] = rel_path
|
|
46
50
|
|
|
47
51
|
return dbtree
|
|
48
52
|
|
|
@@ -61,42 +65,42 @@ def files(dbtree, entity):
|
|
|
61
65
|
def index(dbtree, entity):
|
|
62
66
|
if isinstance(entity, str):
|
|
63
67
|
idx = []
|
|
64
|
-
for pt in dbtree:
|
|
65
|
-
for st in pt['studies']:
|
|
66
|
-
for sr in st['series']:
|
|
68
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
69
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
70
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
67
71
|
idx += list(sr['instances'].values())
|
|
68
72
|
return idx
|
|
69
73
|
elif len(entity)==2:
|
|
70
|
-
patient_id =
|
|
74
|
+
patient_id = entity[1]
|
|
71
75
|
idx = []
|
|
72
|
-
for pt in dbtree:
|
|
76
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
73
77
|
if pt['PatientID'] == patient_id:
|
|
74
|
-
for st in pt['studies']:
|
|
75
|
-
for sr in st['series']:
|
|
78
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
79
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
76
80
|
idx += list(sr['instances'].values())
|
|
77
81
|
return idx
|
|
78
82
|
elif len(entity)==3:
|
|
79
83
|
study_uid = uid(dbtree, entity)
|
|
80
84
|
idx = []
|
|
81
|
-
for pt in dbtree:
|
|
82
|
-
for st in pt['studies']:
|
|
85
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
86
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
83
87
|
if st['StudyInstanceUID'] == study_uid:
|
|
84
|
-
for sr in st['series']:
|
|
88
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
85
89
|
idx += list(sr['instances'].values())
|
|
86
90
|
return idx
|
|
87
91
|
elif len(entity)==4:
|
|
88
92
|
series_uid = uid(dbtree, entity)
|
|
89
|
-
for pt in dbtree:
|
|
90
|
-
for st in pt['studies']:
|
|
91
|
-
for sr in st['series']:
|
|
93
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
94
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
95
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
92
96
|
if sr['SeriesInstanceUID'] == series_uid:
|
|
93
97
|
return list(sr['instances'].values())
|
|
94
98
|
|
|
95
99
|
|
|
96
100
|
def drop(dbtree, relpaths):
|
|
97
|
-
for pt in dbtree[:]:
|
|
98
|
-
for st in pt['studies'][:]:
|
|
99
|
-
for sr in st['series'][:]:
|
|
101
|
+
for pt in sorted(dbtree[:], key=lambda pt: pt['PatientID']):
|
|
102
|
+
for st in sorted(pt['studies'][:], key=lambda st: st['StudyInstanceUID']):
|
|
103
|
+
for sr in sorted(st['series'][:], key=lambda sr: sr['SeriesNumber']):
|
|
100
104
|
for nr, relpath in list(sr['instances'].items()):
|
|
101
105
|
if relpath in relpaths:
|
|
102
106
|
del sr['instances'][nr]
|
|
@@ -107,96 +111,24 @@ def drop(dbtree, relpaths):
|
|
|
107
111
|
return dbtree
|
|
108
112
|
|
|
109
113
|
|
|
110
|
-
# def entity(df, path, uid):# information entity from uid
|
|
111
|
-
# dbtree = tree(df)
|
|
112
|
-
# patient_idx = {}
|
|
113
|
-
# for pt in dbtree:
|
|
114
|
-
# patient_name = pt['PatientName']
|
|
115
|
-
# uid_patient = pt['PatientID']
|
|
116
|
-
# if patient_name in patient_idx:
|
|
117
|
-
# patient_idx[patient_name] += 1
|
|
118
|
-
# else:
|
|
119
|
-
# patient_idx[patient_name] = 0
|
|
120
|
-
# patient_desc = (patient_name, patient_idx[patient_name])
|
|
121
|
-
# if uid == uid_patient:
|
|
122
|
-
# return [path, patient_desc]
|
|
123
|
-
|
|
124
|
-
# else:
|
|
125
|
-
|
|
126
|
-
# study_idx = {}
|
|
127
|
-
# for st in pt['studies']:
|
|
128
|
-
# study_name = st['StudyDescription']
|
|
129
|
-
# uid_study = st['StudyInstanceUID']
|
|
130
|
-
# if study_name in study_idx:
|
|
131
|
-
# study_idx[study_name] += 1
|
|
132
|
-
# else:
|
|
133
|
-
# study_idx[study_name] = 0
|
|
134
|
-
# study_desc = (study_name, study_idx[study_name])
|
|
135
|
-
# if uid == uid_study:
|
|
136
|
-
# return [path, patient_desc, study_desc]
|
|
137
|
-
|
|
138
|
-
# else:
|
|
139
|
-
|
|
140
|
-
# series_idx = {}
|
|
141
|
-
# for sr in st['series']:
|
|
142
|
-
# series_name = sr['SeriesDescription']
|
|
143
|
-
# uid_series = sr['SeriesInstanceUID']
|
|
144
|
-
# if series_name in series_idx:
|
|
145
|
-
# series_idx[series_name] += 1
|
|
146
|
-
# else:
|
|
147
|
-
# series_idx[series_name] = 0
|
|
148
|
-
# series_desc = (series_name, series_idx[series_name])
|
|
149
|
-
# if uid == uid_series:
|
|
150
|
-
# return [path, patient_desc, study_desc, series_desc]
|
|
151
|
-
|
|
152
|
-
# raise ValueError(f"No information entity with UID {uid} was found.")
|
|
153
|
-
|
|
154
114
|
|
|
155
115
|
def uid(dbtree, entity): # uid from entity
|
|
156
116
|
if len(entity)==2:
|
|
157
|
-
return
|
|
117
|
+
return entity[1]
|
|
158
118
|
if len(entity)==3:
|
|
159
|
-
return
|
|
119
|
+
return study_uid(dbtree, entity)
|
|
160
120
|
if len(entity)==4:
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def _patient_uid(dbtree, patient):
|
|
165
|
-
patient = patient[1]
|
|
166
|
-
patients = {}
|
|
167
|
-
patient_idx = {}
|
|
168
|
-
for pt in dbtree:
|
|
169
|
-
patient_name = pt['PatientName']
|
|
170
|
-
uid_patient = pt['PatientID']
|
|
171
|
-
if patient_name in patient_idx:
|
|
172
|
-
patient_idx[patient_name] += 1
|
|
173
|
-
else:
|
|
174
|
-
patient_idx[patient_name] = 0
|
|
175
|
-
patient_desc = (patient_name, patient_idx[patient_name])
|
|
176
|
-
if patient == patient_desc:
|
|
177
|
-
return uid_patient
|
|
178
|
-
patients[patient_desc] = uid_patient
|
|
179
|
-
if isinstance(patient, str):
|
|
180
|
-
patient_list = [p for p in patients.keys() if p[0]==patient]
|
|
181
|
-
if len(patient_list) == 1:
|
|
182
|
-
return patients[(patient, 0)]
|
|
183
|
-
elif len(patient_list) > 1:
|
|
184
|
-
raise ValueError(
|
|
185
|
-
f"Multiple patients with name {patient}."
|
|
186
|
-
f"Please specify the index in the call to patient_uid(). "
|
|
187
|
-
f"For instance ({patient}, {len(patients)-1})'. "
|
|
188
|
-
)
|
|
189
|
-
raise ValueError(f"Patient {patient} not found in database.")
|
|
121
|
+
return series_uid(dbtree, entity)
|
|
190
122
|
|
|
191
123
|
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
124
|
+
def study_uid(dbtree, study):
|
|
125
|
+
patient_id, study = study[1], study[2]
|
|
126
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
127
|
+
if pt['PatientID'] == patient_id:
|
|
128
|
+
|
|
129
|
+
uid_studies = {}
|
|
198
130
|
study_idx = {}
|
|
199
|
-
for st in pt['studies']:
|
|
131
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
200
132
|
study_desc = st['StudyDescription']
|
|
201
133
|
uid_study = st['StudyInstanceUID']
|
|
202
134
|
if study_desc in study_idx:
|
|
@@ -206,29 +138,31 @@ def _study_uid(dbtree, study):
|
|
|
206
138
|
study_desc = (study_desc, study_idx[study_desc])
|
|
207
139
|
if study == study_desc:
|
|
208
140
|
return uid_study
|
|
209
|
-
|
|
141
|
+
uid_studies[study_desc] = uid_study
|
|
142
|
+
|
|
210
143
|
if isinstance(study, str):
|
|
211
|
-
studies_list = [s for s in
|
|
144
|
+
studies_list = [s for s in uid_studies.keys() if s[0]==study]
|
|
212
145
|
if len(studies_list) == 1:
|
|
213
|
-
return
|
|
146
|
+
return uid_studies[(study, 0)]
|
|
214
147
|
elif len(studies_list) > 1:
|
|
215
|
-
raise
|
|
216
|
-
f"Multiple studies with name {study}."
|
|
217
|
-
f"Please specify the index
|
|
218
|
-
f"For instance ({study}, {len(
|
|
148
|
+
raise AmbiguousError(
|
|
149
|
+
f"Multiple studies with name {study}. "
|
|
150
|
+
f"Please specify the index along with the description. "
|
|
151
|
+
f"For instance ({study}, {len(uid_studies)-1})'. "
|
|
219
152
|
)
|
|
220
|
-
raise ValueError(f"Study {study} not found in patient {
|
|
153
|
+
raise ValueError(f"Study {study} not found in patient {patient_id}.")
|
|
221
154
|
|
|
222
155
|
|
|
223
|
-
def
|
|
224
|
-
uid_study =
|
|
156
|
+
def series_uid(dbtree, series): # absolute path to series
|
|
157
|
+
uid_study = study_uid(dbtree, series[:-1])
|
|
225
158
|
study, sery = series[2], series[3]
|
|
226
|
-
for pt in dbtree:
|
|
227
|
-
for st in pt['studies']:
|
|
159
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
160
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
228
161
|
if st['StudyInstanceUID'] == uid_study:
|
|
162
|
+
|
|
229
163
|
series = {}
|
|
230
164
|
series_idx = {}
|
|
231
|
-
for sr in st['series']:
|
|
165
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
232
166
|
series_desc = sr['SeriesDescription']
|
|
233
167
|
uid_series = sr['SeriesInstanceUID']
|
|
234
168
|
if series_desc in series_idx:
|
|
@@ -239,160 +173,75 @@ def _series_uid(dbtree, series): # absolute path to series
|
|
|
239
173
|
if sery == series_desc:
|
|
240
174
|
return uid_series
|
|
241
175
|
series[series_desc] = uid_series
|
|
176
|
+
|
|
242
177
|
if isinstance(sery, str):
|
|
243
178
|
series_list = [s for s in series.keys() if s[0]==sery]
|
|
244
179
|
if len(series_list) == 1:
|
|
245
180
|
return series[(sery, 0)]
|
|
246
181
|
elif len(series_list) > 1:
|
|
247
|
-
raise
|
|
248
|
-
f"Multiple series with name {sery}."
|
|
249
|
-
f"Please specify the index
|
|
182
|
+
raise AmbiguousError(
|
|
183
|
+
f"Multiple series with name {sery}. "
|
|
184
|
+
f"Please specify the index along with the description. "
|
|
250
185
|
f"For instance ({sery}, {len(series)-1})'. "
|
|
251
186
|
)
|
|
252
187
|
raise ValueError(f"Series {sery} not found in study {study}.")
|
|
253
188
|
|
|
254
189
|
|
|
255
190
|
def patients(dbtree, database, name=None, contains=None, isin=None):
|
|
256
|
-
simplified_patients = []
|
|
257
|
-
patients = []
|
|
258
|
-
patient_idx = {}
|
|
259
|
-
for pt in dbtree:
|
|
260
|
-
patient_name = pt['PatientName']
|
|
261
|
-
if patient_name in patient_idx:
|
|
262
|
-
patient_idx[patient_name] += 1
|
|
263
|
-
else:
|
|
264
|
-
patient_idx[patient_name] = 0
|
|
265
|
-
patients.append((patient_name, patient_idx[patient_name]))
|
|
266
|
-
for patient in patients:
|
|
267
|
-
if patient_idx[patient[0]] == 0:
|
|
268
|
-
simplified_patients.append(patient[0])
|
|
269
|
-
else:
|
|
270
|
-
simplified_patients.append(patient)
|
|
271
|
-
if name is not None:
|
|
272
|
-
patients_result = []
|
|
273
|
-
for s in simplified_patients:
|
|
274
|
-
if isinstance(s, str):
|
|
275
|
-
if s == name:
|
|
276
|
-
patients_result.append(s)
|
|
277
|
-
elif s[0] == name:
|
|
278
|
-
patients_result.append(s)
|
|
279
|
-
return [[database, p] for p in patients_result]
|
|
280
|
-
elif contains is not None:
|
|
281
|
-
patients_result = []
|
|
282
|
-
for s in simplified_patients:
|
|
283
|
-
if isinstance(s, str):
|
|
284
|
-
if contains in s:
|
|
285
|
-
patients_result.append(s)
|
|
286
|
-
elif contains in s[0]:
|
|
287
|
-
patients_result.append(s)
|
|
288
|
-
return [[database, p] for p in patients_result]
|
|
289
|
-
elif isin is not None:
|
|
290
|
-
patients_result = []
|
|
291
|
-
for s in simplified_patients:
|
|
292
|
-
if isinstance(s, str):
|
|
293
|
-
if s in isin:
|
|
294
|
-
patients_result.append(s)
|
|
295
|
-
elif s[0] in isin:
|
|
296
|
-
patients_result.append(s)
|
|
297
|
-
return [[database, p] for p in patients_result]
|
|
298
|
-
else:
|
|
299
|
-
return [[database, p] for p in simplified_patients]
|
|
300
|
-
|
|
301
191
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
patient_as_str = isinstance(patient, str)
|
|
305
|
-
if patient_as_str:
|
|
306
|
-
patient = (patient, 0)
|
|
307
|
-
simplified_studies = []
|
|
308
|
-
patient_idx = {}
|
|
309
|
-
for pt in dbtree:
|
|
192
|
+
patients = []
|
|
193
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
310
194
|
patient_name = pt['PatientName']
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
195
|
+
append = True
|
|
196
|
+
if name is not None:
|
|
197
|
+
append = append and (patient_name==name)
|
|
198
|
+
if contains is not None:
|
|
199
|
+
append = append and (contains in patient_name)
|
|
200
|
+
if isin is not None:
|
|
201
|
+
append = append and (patient_name in isin)
|
|
202
|
+
if append:
|
|
203
|
+
patients.append(pt['PatientID'])
|
|
204
|
+
|
|
205
|
+
return [[database, p] for p in patients]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def studies(dbtree, pat, desc=None, contains=None, isin=None):
|
|
209
|
+
database, patient_id = pat[0], pat[1]
|
|
210
|
+
studies = []
|
|
211
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
212
|
+
if pt['PatientID'] == patient_id:
|
|
324
213
|
study_idx = {}
|
|
325
|
-
for st in pt['studies']:
|
|
214
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
326
215
|
study_desc = st['StudyDescription']
|
|
327
216
|
if study_desc in study_idx:
|
|
328
217
|
study_idx[study_desc] += 1
|
|
329
218
|
else:
|
|
330
219
|
study_idx[study_desc] = 0
|
|
331
220
|
studies.append((study_desc, study_idx[study_desc]))
|
|
332
|
-
for study in studies:
|
|
333
|
-
if study_idx[study[0]] == 0:
|
|
334
|
-
simplified_studies.append(study[0])
|
|
335
|
-
else:
|
|
336
|
-
simplified_studies.append(study)
|
|
337
|
-
if not patient_as_str:
|
|
338
|
-
break
|
|
339
|
-
if name is not None:
|
|
340
|
-
studies_result = []
|
|
341
|
-
for s in simplified_studies:
|
|
342
|
-
if isinstance(s, str):
|
|
343
|
-
if s == name:
|
|
344
|
-
studies_result.append(s)
|
|
345
|
-
elif s[0] == name:
|
|
346
|
-
studies_result.append(s)
|
|
347
|
-
return [[database, patient, study] for study in studies_result]
|
|
348
|
-
elif contains is not None:
|
|
349
|
-
studies_result = []
|
|
350
|
-
for s in simplified_studies:
|
|
351
|
-
if isinstance(s, str):
|
|
352
|
-
if contains in s:
|
|
353
|
-
studies_result.append(s)
|
|
354
|
-
elif contains in s[0]:
|
|
355
|
-
studies_result.append(s)
|
|
356
|
-
return [[database, patient, study] for study in studies_result]
|
|
357
|
-
elif isin is not None:
|
|
358
|
-
studies_result = []
|
|
359
|
-
for s in simplified_studies:
|
|
360
|
-
if isinstance(s, str):
|
|
361
|
-
if s in isin:
|
|
362
|
-
studies_result.append(s)
|
|
363
|
-
elif s[0] in isin:
|
|
364
|
-
studies_result.append(s)
|
|
365
|
-
return [[database, patient, study] for study in studies_result]
|
|
366
|
-
else:
|
|
367
|
-
return [[database, patient, study] for study in simplified_studies]
|
|
368
221
|
|
|
222
|
+
# Apply filters
|
|
223
|
+
if desc is not None:
|
|
224
|
+
studies = [s for s in studies if s[0]==desc]
|
|
225
|
+
if contains is not None:
|
|
226
|
+
studies = [s for s in studies if contains in s[0]]
|
|
227
|
+
if isin is not None:
|
|
228
|
+
studies = [s for s in studies if s[0] in isin]
|
|
369
229
|
|
|
230
|
+
# Return result
|
|
231
|
+
return [[database, patient_id, study] for study in studies]
|
|
370
232
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
patient = (patient, 0)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def series(dbtree, stdy, desc=None, contains=None, isin=None):
|
|
236
|
+
database, patient_id, study = stdy[0], stdy[1], stdy[2]
|
|
376
237
|
study_as_str = isinstance(study, str)
|
|
377
238
|
if study_as_str:
|
|
378
239
|
study = (study, 0)
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
patient_name = pt['PatientName']
|
|
383
|
-
if patient_name in patient_idx:
|
|
384
|
-
patient_idx[patient_name] += 1
|
|
385
|
-
else:
|
|
386
|
-
patient_idx[patient_name] = 0
|
|
387
|
-
if patient[0] == patient_name:
|
|
388
|
-
if patient_as_str:
|
|
389
|
-
if patient_idx[patient_name] > 0:
|
|
390
|
-
raise ValueError(
|
|
391
|
-
f"Multiple patients named {patient_name}. Please provide an index along with the patient name."
|
|
392
|
-
)
|
|
393
|
-
if patient == (patient_name, patient_idx[patient_name]):
|
|
240
|
+
series = []
|
|
241
|
+
for pt in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
242
|
+
if pt['PatientID'] == patient_id:
|
|
394
243
|
study_idx = {}
|
|
395
|
-
for st in pt['studies']:
|
|
244
|
+
for st in sorted(pt['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
396
245
|
study_desc = st['StudyDescription']
|
|
397
246
|
if study_desc in study_idx:
|
|
398
247
|
study_idx[study_desc] += 1
|
|
@@ -401,125 +250,62 @@ def series(dbtree, stdy, name=None, contains=None, isin=None):
|
|
|
401
250
|
if study[0] == study_desc:
|
|
402
251
|
if study_as_str:
|
|
403
252
|
if study_idx[study_desc] > 0:
|
|
404
|
-
raise
|
|
405
|
-
f"Multiple studies named {study_desc} in patient {
|
|
253
|
+
raise AmbiguousError(
|
|
254
|
+
f"Multiple studies named {study_desc} in patient {patient_id}. Please provide an index along with the study description."
|
|
406
255
|
)
|
|
407
256
|
if study == (study_desc, study_idx[study_desc]):
|
|
408
|
-
series = []
|
|
409
257
|
series_idx = {}
|
|
410
|
-
for sr in st['series']:
|
|
258
|
+
for sr in sorted(st['series'], key=lambda sr: sr['SeriesNumber']):
|
|
411
259
|
series_desc = sr['SeriesDescription']
|
|
412
260
|
if series_desc in series_idx:
|
|
413
261
|
series_idx[series_desc] += 1
|
|
414
262
|
else:
|
|
415
263
|
series_idx[series_desc] = 0
|
|
416
264
|
series.append((series_desc, series_idx[series_desc]))
|
|
417
|
-
|
|
418
|
-
if series_idx[sery[0]] == 0:
|
|
419
|
-
simplified_series.append(sery[0])
|
|
420
|
-
else:
|
|
421
|
-
simplified_series.append(sery)
|
|
422
|
-
if not (patient_as_str or study_as_str):
|
|
265
|
+
if not study_as_str:
|
|
423
266
|
break
|
|
424
|
-
if name is not None:
|
|
425
|
-
series_result = []
|
|
426
|
-
for s in simplified_series:
|
|
427
|
-
if isinstance(s, str):
|
|
428
|
-
if s == name:
|
|
429
|
-
series_result.append(s)
|
|
430
|
-
elif s[0] == name:
|
|
431
|
-
series_result.append(s)
|
|
432
|
-
return [[database, patient, study, series] for series in series_result]
|
|
433
|
-
elif contains is not None:
|
|
434
|
-
series_result = []
|
|
435
|
-
for s in simplified_series:
|
|
436
|
-
if isinstance(s, str):
|
|
437
|
-
if contains in s:
|
|
438
|
-
series_result.append(s)
|
|
439
|
-
elif contains in s[0]:
|
|
440
|
-
series_result.append(s)
|
|
441
|
-
return [[database, patient, study, series] for series in series_result]
|
|
442
|
-
elif isin is not None:
|
|
443
|
-
series_result = []
|
|
444
|
-
for s in simplified_series:
|
|
445
|
-
if isinstance(s, str):
|
|
446
|
-
if s in isin:
|
|
447
|
-
series_result.append(s)
|
|
448
|
-
elif s[0] in isin:
|
|
449
|
-
series_result.append(s)
|
|
450
|
-
return [[database, patient, study, series] for series in series_result]
|
|
451
|
-
else:
|
|
452
|
-
return [[database, patient, study, series] for series in simplified_series]
|
|
453
|
-
|
|
454
267
|
|
|
268
|
+
# Apply filters (if any)
|
|
269
|
+
if desc is not None:
|
|
270
|
+
series = [s for s in series if s[0]==desc]
|
|
271
|
+
if contains is not None:
|
|
272
|
+
series = [s for s in series if contains in s[0]]
|
|
273
|
+
if isin is not None:
|
|
274
|
+
series = [s for s in series if s[0] in isin]
|
|
455
275
|
|
|
276
|
+
# Return result
|
|
277
|
+
return [[database, patient_id, study, s] for s in series]
|
|
278
|
+
|
|
456
279
|
|
|
457
|
-
def append(dbtree, parent, child_name):
|
|
458
|
-
if len(parent) == 1:
|
|
459
|
-
return _new_patient(dbtree, parent, child_name)
|
|
460
|
-
elif len(parent) == 2:
|
|
461
|
-
return _new_study(dbtree, parent, child_name)
|
|
462
|
-
elif len(parent) == 3:
|
|
463
|
-
return _new_series(dbtree, parent, child_name)
|
|
464
280
|
|
|
465
|
-
def
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
281
|
+
# def append(dbtree, parent, child_name):
|
|
282
|
+
# if len(parent) == 1:
|
|
283
|
+
# return _new_patient(dbtree, parent, child_name)
|
|
284
|
+
# elif len(parent) == 2:
|
|
285
|
+
# return _new_study(dbtree, parent, child_name)
|
|
286
|
+
# elif len(parent) == 3:
|
|
287
|
+
# return _new_series(dbtree, parent, child_name)
|
|
288
|
+
|
|
289
|
+
# def _new_patient(dbtree, database, patient_id):
|
|
290
|
+
# if patient_id in patients(dbtree, database):
|
|
291
|
+
# raise ValueError(
|
|
292
|
+
# f"Cannot create a new patient with id {patient_id}."
|
|
293
|
+
# f"The ID is already taken."
|
|
294
|
+
# )
|
|
295
|
+
# return [database, patient_id]
|
|
474
296
|
|
|
475
|
-
def
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
if cnt==0:
|
|
481
|
-
return patient + [desc]
|
|
482
|
-
else:
|
|
483
|
-
return patient + [(desc, cnt+1)]
|
|
297
|
+
# def new_study(dbtree, patient, study): #len(patient)=2
|
|
298
|
+
# desc = study if isinstance(study, str) else study[0]
|
|
299
|
+
# studies_in_patient = studies(dbtree, patient, desc=desc)
|
|
300
|
+
# cnt = len(studies_in_patient)
|
|
301
|
+
# return patient + [(desc, cnt)]
|
|
484
302
|
|
|
485
|
-
def
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if cnt==0:
|
|
491
|
-
return study + [desc]
|
|
492
|
-
else:
|
|
493
|
-
return study + [(desc, cnt+1)]
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
# def uid_tree(df, path, depth=3):
|
|
303
|
+
# def new_series(dbtree, study, sery): #len(study)=3
|
|
304
|
+
# desc = sery if isinstance(sery, str) else sery[0]
|
|
305
|
+
# series_in_study = series(dbtree, study, desc=desc)
|
|
306
|
+
# cnt = len(series_in_study)
|
|
307
|
+
# return study + [(desc, cnt)]
|
|
497
308
|
|
|
498
|
-
# dbtree = summary(df)
|
|
499
|
-
|
|
500
|
-
# database = {'uid': path}
|
|
501
|
-
# database['patients'] = []
|
|
502
|
-
# for pat in dbtree:
|
|
503
|
-
# patient = {'uid': pat['PatientID']}
|
|
504
|
-
# database['patients'].append(patient)
|
|
505
|
-
# if depth >= 1:
|
|
506
|
-
# df_patient = df[df.PatientID == pat['PatientID']]
|
|
507
|
-
# patient['key'] = df_patient.index[0]
|
|
508
|
-
# patient['studies'] = []
|
|
509
|
-
# for stdy in pat['studies']:
|
|
510
|
-
# study = {'uid': stdy['StudyInstanceUID']}
|
|
511
|
-
# patient['studies'].append(study)
|
|
512
|
-
# if depth >= 2:
|
|
513
|
-
# df_study = df_patient[df_patient.StudyInstanceUID == stdy['StudyInstanceUID']]
|
|
514
|
-
# study['key'] = df_study.index[0]
|
|
515
|
-
# study['series'] = []
|
|
516
|
-
# for sery in stdy['series']:
|
|
517
|
-
# series = {'uid': sery['SeriesInstanceUID']}
|
|
518
|
-
# study['series'].append(series)
|
|
519
|
-
# if depth == 3:
|
|
520
|
-
# df_series = df_study[df_study.SeriesInstanceUID == sery['SeriesInstanceUID']]
|
|
521
|
-
# series['key'] = df_series.index[0]
|
|
522
|
-
# return database
|
|
523
309
|
|
|
524
310
|
|
|
525
311
|
def print_tree(dbtree):
|
|
@@ -532,76 +318,32 @@ def print_tree(dbtree):
|
|
|
532
318
|
print(f" Series: ({s[0]}, {s[1]})")
|
|
533
319
|
|
|
534
320
|
|
|
535
|
-
# def summary(df):
|
|
536
|
-
# # A human-readable summary tree
|
|
537
|
-
|
|
538
|
-
# df = _prep(df)
|
|
539
|
-
# summary = {}
|
|
540
|
-
|
|
541
|
-
# patient_idx = {}
|
|
542
|
-
# for uid_patient in df.PatientID.dropna().unique():
|
|
543
|
-
# df_patient = df[df.PatientID == uid_patient]
|
|
544
|
-
# patient_name = df_patient.PatientName.values[0]
|
|
545
|
-
# if patient_name in patient_idx:
|
|
546
|
-
# patient_idx[patient_name] += 1
|
|
547
|
-
# else:
|
|
548
|
-
# patient_idx[patient_name] = 0
|
|
549
|
-
# summary[patient_name, patient_idx[patient_name]] = {}
|
|
550
|
-
|
|
551
|
-
# study_idx = {}
|
|
552
|
-
# for uid_study in df_patient.StudyInstanceUID.dropna().unique():
|
|
553
|
-
# df_study = df_patient[df_patient.StudyInstanceUID == uid_study]
|
|
554
|
-
# study_desc = df_study.StudyDescription.values[0]
|
|
555
|
-
# if study_desc in study_idx:
|
|
556
|
-
# study_idx[study_desc] += 1
|
|
557
|
-
# else:
|
|
558
|
-
# study_idx[study_desc] = 0
|
|
559
|
-
# summary[patient_name, patient_idx[patient_name]][study_desc, study_idx[study_desc]] = []
|
|
560
|
-
|
|
561
|
-
# series_idx = {}
|
|
562
|
-
# for uid_sery in df_study.SeriesInstanceUID.dropna().unique():
|
|
563
|
-
# df_series = df_study[df_study.SeriesInstanceUID == uid_sery]
|
|
564
|
-
# series_desc = df_series.SeriesDescription.values[0]
|
|
565
|
-
# if series_desc in series_idx:
|
|
566
|
-
# series_idx[series_desc] += 1
|
|
567
|
-
# else:
|
|
568
|
-
# series_idx[series_desc] = 0
|
|
569
|
-
# summary[patient_name, patient_idx[patient_name]][study_desc, study_idx[study_desc]].append((series_desc, series_idx[series_desc]))
|
|
570
|
-
|
|
571
|
-
# return summary
|
|
572
|
-
|
|
573
|
-
|
|
574
321
|
def summary(dbtree):
|
|
575
322
|
# A human-readable summary tree
|
|
576
323
|
|
|
577
324
|
summary = {}
|
|
578
325
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
if patient_name in patient_idx:
|
|
583
|
-
patient_idx[patient_name] += 1
|
|
584
|
-
else:
|
|
585
|
-
patient_idx[patient_name] = 0
|
|
586
|
-
summary[patient_name, patient_idx[patient_name]] = {}
|
|
326
|
+
for patient in sorted(dbtree, key=lambda pt: pt['PatientID']):
|
|
327
|
+
pat_id, pat_name = patient['PatientID'], patient['PatientName']
|
|
328
|
+
summary[pat_id, pat_name] = {}
|
|
587
329
|
|
|
588
330
|
study_idx = {}
|
|
589
|
-
for study in patient['studies']:
|
|
331
|
+
for study in sorted(patient['studies'], key=lambda st: st['StudyInstanceUID']):
|
|
590
332
|
study_desc = study['StudyDescription']
|
|
591
333
|
if study_desc in study_idx:
|
|
592
334
|
study_idx[study_desc] += 1
|
|
593
335
|
else:
|
|
594
336
|
study_idx[study_desc] = 0
|
|
595
|
-
summary[
|
|
337
|
+
summary[pat_id, pat_name][study_desc, study_idx[study_desc]] = []
|
|
596
338
|
|
|
597
339
|
series_idx = {}
|
|
598
|
-
for series in study['series']:
|
|
340
|
+
for series in sorted(study['series'], key=lambda sr: sr['SeriesNumber']):
|
|
599
341
|
series_desc = series['SeriesDescription']
|
|
600
342
|
if series_desc in series_idx:
|
|
601
343
|
series_idx[series_desc] += 1
|
|
602
344
|
else:
|
|
603
345
|
series_idx[series_desc] = 0
|
|
604
|
-
summary[
|
|
346
|
+
summary[pat_id, pat_name][study_desc, study_idx[study_desc]].append((series_desc, series_idx[series_desc]))
|
|
605
347
|
|
|
606
348
|
return summary
|
|
607
349
|
|