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