biomedisa 24.5.23__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 (44) hide show
  1. biomedisa/__init__.py +49 -0
  2. biomedisa/__main__.py +18 -0
  3. biomedisa/deeplearning.py +529 -0
  4. biomedisa/features/DataGenerator.py +299 -0
  5. biomedisa/features/DataGeneratorCrop.py +121 -0
  6. biomedisa/features/PredictDataGenerator.py +87 -0
  7. biomedisa/features/PredictDataGeneratorCrop.py +74 -0
  8. biomedisa/features/__init__.py +0 -0
  9. biomedisa/features/active_contour.py +430 -0
  10. biomedisa/features/amira_to_np/__init__.py +0 -0
  11. biomedisa/features/amira_to_np/amira_data_stream.py +980 -0
  12. biomedisa/features/amira_to_np/amira_grammar.py +369 -0
  13. biomedisa/features/amira_to_np/amira_header.py +290 -0
  14. biomedisa/features/amira_to_np/amira_helper.py +72 -0
  15. biomedisa/features/assd.py +167 -0
  16. biomedisa/features/biomedisa_helper.py +842 -0
  17. biomedisa/features/create_slices.py +277 -0
  18. biomedisa/features/crop_helper.py +581 -0
  19. biomedisa/features/curvop_numba.py +149 -0
  20. biomedisa/features/django_env.py +171 -0
  21. biomedisa/features/keras_helper.py +1195 -0
  22. biomedisa/features/nc_reader.py +179 -0
  23. biomedisa/features/pid.py +52 -0
  24. biomedisa/features/process_image.py +251 -0
  25. biomedisa/features/pycuda_test.py +85 -0
  26. biomedisa/features/random_walk/__init__.py +0 -0
  27. biomedisa/features/random_walk/gpu_kernels.py +184 -0
  28. biomedisa/features/random_walk/pycuda_large.py +826 -0
  29. biomedisa/features/random_walk/pycuda_large_allx.py +806 -0
  30. biomedisa/features/random_walk/pycuda_small.py +414 -0
  31. biomedisa/features/random_walk/pycuda_small_allx.py +493 -0
  32. biomedisa/features/random_walk/pyopencl_large.py +760 -0
  33. biomedisa/features/random_walk/pyopencl_small.py +441 -0
  34. biomedisa/features/random_walk/rw_large.py +389 -0
  35. biomedisa/features/random_walk/rw_small.py +307 -0
  36. biomedisa/features/remove_outlier.py +396 -0
  37. biomedisa/features/split_volume.py +167 -0
  38. biomedisa/interpolation.py +369 -0
  39. biomedisa/mesh.py +403 -0
  40. biomedisa-24.5.23.dist-info/LICENSE +191 -0
  41. biomedisa-24.5.23.dist-info/METADATA +261 -0
  42. biomedisa-24.5.23.dist-info/RECORD +44 -0
  43. biomedisa-24.5.23.dist-info/WHEEL +5 -0
  44. biomedisa-24.5.23.dist-info/top_level.txt +1 -0
@@ -0,0 +1,389 @@
1
+ ##########################################################################
2
+ ## ##
3
+ ## Copyright (c) 2019-2024 Philipp Lösel. All rights reserved. ##
4
+ ## ##
5
+ ## This file is part of the open source project biomedisa. ##
6
+ ## ##
7
+ ## Licensed under the European Union Public Licence (EUPL) ##
8
+ ## v1.2, or - as soon as they will be approved by the ##
9
+ ## European Commission - subsequent versions of the EUPL; ##
10
+ ## ##
11
+ ## You may redistribute it and/or modify it under the terms ##
12
+ ## of the EUPL v1.2. You may not use this work except in ##
13
+ ## compliance with this Licence. ##
14
+ ## ##
15
+ ## You can obtain a copy of the Licence at: ##
16
+ ## ##
17
+ ## https://joinup.ec.europa.eu/page/eupl-text-11-12 ##
18
+ ## ##
19
+ ## Unless required by applicable law or agreed to in ##
20
+ ## writing, software distributed under the Licence is ##
21
+ ## distributed on an "AS IS" basis, WITHOUT WARRANTIES ##
22
+ ## OR CONDITIONS OF ANY KIND, either express or implied. ##
23
+ ## ##
24
+ ## See the Licence for the specific language governing ##
25
+ ## permissions and limitations under the Licence. ##
26
+ ## ##
27
+ ##########################################################################
28
+
29
+ from biomedisa.features.remove_outlier import clean, fill
30
+ from biomedisa.features.active_contour import activeContour
31
+ from biomedisa.features.biomedisa_helper import (_get_device, save_data, _error_, unique_file_path,
32
+ splitlargedata, read_labeled_slices_allx_large, read_labeled_slices_large, sendToChildLarge,
33
+ Dice_score)
34
+ from mpi4py import MPI
35
+ import numpy as np
36
+ import time
37
+ import socket
38
+ import os
39
+
40
+ def _diffusion_child(comm, bm=None):
41
+
42
+ rank = comm.Get_rank()
43
+ ngpus = comm.Get_size()
44
+
45
+ nodename = socket.gethostname()
46
+ name = '%s %s' %(nodename, rank)
47
+ print(name)
48
+
49
+ if rank == 0:
50
+
51
+ # initialize results
52
+ results = {}
53
+
54
+ # reduce blocksize
55
+ bm.data = np.copy(bm.data[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x], order='C')
56
+ bm.labelData = np.copy(bm.labelData[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x], order='C')
57
+
58
+ # domain decomposition
59
+ sizeofblocks = (bm.argmax_z - bm.argmin_z) // ngpus
60
+ blocks = [0]
61
+ for k in range(ngpus-1):
62
+ block_temp = blocks[-1] + sizeofblocks
63
+ blocks.append(block_temp)
64
+ blocks.append(bm.argmax_z - bm.argmin_z)
65
+ print('blocks =', blocks)
66
+
67
+ # read labeled slices
68
+ if bm.allaxis:
69
+ tmp = np.swapaxes(bm.labelData, 0, 1)
70
+ tmp = np.ascontiguousarray(tmp)
71
+ indices_01, _ = read_labeled_slices_allx_large(tmp)
72
+ tmp = np.swapaxes(tmp, 0, 2)
73
+ tmp = np.ascontiguousarray(tmp)
74
+ indices_02, _ = read_labeled_slices_allx_large(tmp)
75
+
76
+ # send data to childs
77
+ for destination in range(ngpus-1,-1,-1):
78
+
79
+ # ghost blocks
80
+ blockmin = blocks[destination]
81
+ blockmax = blocks[destination+1]
82
+ datablockmin = blockmin - 100
83
+ datablockmax = blockmax + 100
84
+ datablockmin = 0 if datablockmin < 0 else datablockmin
85
+ datablockmax = (bm.argmax_z - bm.argmin_z) if datablockmax > (bm.argmax_z - bm.argmin_z) else datablockmax
86
+ datablock = np.copy(bm.data[datablockmin:datablockmax], order='C')
87
+ labelblock = np.copy(bm.labelData[datablockmin:datablockmax], order='C')
88
+
89
+ # read labeled slices
90
+ if bm.allaxis:
91
+ labelblock = labelblock.astype(np.int32)
92
+ labelblock[:blockmin - datablockmin] = -1
93
+ labelblock[blockmax - datablockmin:] = -1
94
+ indices_child, labels_child = [], []
95
+ indices_00, labels_00 = read_labeled_slices_allx_large(labelblock)
96
+ indices_child.append(indices_00)
97
+ labels_child.append(labels_00)
98
+ tmp = np.swapaxes(labelblock, 0, 1)
99
+ tmp = np.ascontiguousarray(tmp)
100
+ labels_01 = np.zeros((0, tmp.shape[1], tmp.shape[2]), dtype=np.int32)
101
+ for slcIndex in indices_01:
102
+ labels_01 = np.append(labels_01, [tmp[slcIndex]], axis=0)
103
+ indices_child.append(indices_01)
104
+ labels_child.append(labels_01)
105
+ tmp = np.swapaxes(tmp, 0, 2)
106
+ tmp = np.ascontiguousarray(tmp)
107
+ labels_02 = np.zeros((0, tmp.shape[1], tmp.shape[2]), dtype=np.int32)
108
+ for slcIndex in indices_02:
109
+ labels_02 = np.append(labels_02, [tmp[slcIndex]], axis=0)
110
+ indices_child.append(indices_02)
111
+ labels_child.append(labels_02)
112
+ else:
113
+ labelblock[:blockmin - datablockmin] = 0
114
+ labelblock[blockmax - datablockmin:] = 0
115
+ indices_child, labels_child = read_labeled_slices_large(labelblock)
116
+
117
+ # print indices of labels
118
+ print('indices child %s:' %(destination), indices_child)
119
+
120
+ if destination > 0:
121
+ blocks_temp = blocks[:]
122
+ blocks_temp[destination] = blockmin - datablockmin
123
+ blocks_temp[destination+1] = blockmax - datablockmin
124
+ dataListe = splitlargedata(datablock)
125
+ sendToChildLarge(comm, indices_child, destination, dataListe, labels_child,
126
+ bm.nbrw, bm.sorw, blocks_temp, bm.allaxis,
127
+ bm.allLabels, bm.smooth, bm.uncertainty, bm.platform)
128
+
129
+ else:
130
+
131
+ # select platform
132
+ if bm.platform == 'cuda':
133
+ import pycuda.driver as cuda
134
+ cuda.init()
135
+ dev = cuda.Device(rank)
136
+ ctx, queue = dev.make_context(), None
137
+ if bm.allaxis:
138
+ from biomedisa.features.random_walk.pycuda_large_allx import walk
139
+ else:
140
+ from biomedisa.features.random_walk.pycuda_large import walk
141
+ else:
142
+ ctx, queue = _get_device(bm.platform, rank)
143
+ from biomedisa.features.random_walk.pyopencl_large import walk
144
+
145
+ # run random walks
146
+ tic = time.time()
147
+ memory_error, final, final_uncertainty, final_smooth = walk(comm, datablock,
148
+ labels_child, indices_child, bm.nbrw, bm.sorw,
149
+ blockmin-datablockmin, blockmax-datablockmin, name,
150
+ bm.allLabels, bm.smooth, bm.uncertainty,
151
+ ctx, queue, bm.platform)
152
+ tac = time.time()
153
+ print('Walktime_%s: ' %(name) + str(int(tac - tic)) + ' ' + 'seconds')
154
+
155
+ # free device
156
+ if bm.platform == 'cuda':
157
+ ctx.pop()
158
+ del ctx
159
+
160
+ if memory_error:
161
+ bm = _error_(bm, 'GPU out of memory. Image too large.')
162
+ return results
163
+
164
+ else:
165
+
166
+ # gather data
167
+ for source in range(1, ngpus):
168
+ lendataListe = comm.recv(source=source, tag=0)
169
+ for l in range(lendataListe):
170
+ data_z, data_y, data_x = comm.recv(source=source, tag=10+(2*l))
171
+ receivedata = np.empty((data_z, data_y, data_x), dtype=np.uint8)
172
+ comm.Recv([receivedata, MPI.BYTE], source=source, tag=10+(2*l+1))
173
+ final = np.append(final, receivedata, axis=0)
174
+
175
+ # validate result and check for allaxis
176
+ mask = bm.labelData>0
177
+ dice = Dice_score(bm.labelData, final*mask)
178
+ if dice < 0.3:
179
+ print('Warning: Bad result! Use "--allaxis" if you labeled axes other than the xy-plane.')
180
+
181
+ # regular result
182
+ final_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
183
+ final_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final
184
+ final_result = final_result[1:-1, 1:-1, 1:-1]
185
+ results['regular'] = final_result
186
+ if bm.django_env and not bm.remote:
187
+ bm.path_to_final = unique_file_path(bm.path_to_final)
188
+ if bm.path_to_data:
189
+ save_data(bm.path_to_final, final_result, bm.header, bm.final_image_type, bm.compression)
190
+
191
+ # uncertainty
192
+ if final_uncertainty is not None:
193
+ final_uncertainty *= 255
194
+ final_uncertainty = final_uncertainty.astype(np.uint8)
195
+ for source in range(1, ngpus):
196
+ lendataListe = comm.recv(source=source, tag=0)
197
+ for l in range(lendataListe):
198
+ data_z, data_y, data_x = comm.recv(source=source, tag=10+(2*l))
199
+ receivedata = np.empty((data_z, data_y, data_x), dtype=np.uint8)
200
+ comm.Recv([receivedata, MPI.BYTE], source=source, tag=10+(2*l+1))
201
+ final_uncertainty = np.append(final_uncertainty, receivedata, axis=0)
202
+ # save finals
203
+ uncertainty_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
204
+ uncertainty_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_uncertainty
205
+ uncertainty_result = uncertainty_result[1:-1, 1:-1, 1:-1]
206
+ results['uncertainty'] = uncertainty_result
207
+ if bm.django_env and not bm.remote:
208
+ bm.path_to_uq = unique_file_path(bm.path_to_uq)
209
+ if bm.path_to_data:
210
+ save_data(bm.path_to_uq, uncertainty_result, compress=bm.compression)
211
+ else:
212
+ bm.uncertainty = False
213
+
214
+ # smooth
215
+ if final_smooth is not None:
216
+ for source in range(1, ngpus):
217
+ lendataListe = comm.recv(source=source, tag=0)
218
+ for l in range(lendataListe):
219
+ data_z, data_y, data_x = comm.recv(source=source, tag=10+(2*l))
220
+ receivedata = np.empty((data_z, data_y, data_x), dtype=np.uint8)
221
+ comm.Recv([receivedata, MPI.BYTE], source=source, tag=10+(2*l+1))
222
+ final_smooth = np.append(final_smooth, receivedata, axis=0)
223
+ # save finals
224
+ smooth_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
225
+ smooth_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_smooth
226
+ smooth_result = smooth_result[1:-1, 1:-1, 1:-1]
227
+ results['smooth'] = smooth_result
228
+ if bm.django_env and not bm.remote:
229
+ bm.path_to_smooth = unique_file_path(bm.path_to_smooth)
230
+ if bm.path_to_data:
231
+ save_data(bm.path_to_smooth, smooth_result, bm.header, bm.final_image_type, bm.compression)
232
+ else:
233
+ bm.smooth = 0
234
+
235
+ # remove outliers
236
+ if bm.clean:
237
+ cleaned_result = clean(final_result, bm.clean)
238
+ results['cleaned'] = cleaned_result
239
+ if bm.path_to_data:
240
+ save_data(bm.path_to_cleaned, cleaned_result, bm.header, bm.final_image_type, bm.compression)
241
+ if bm.smooth:
242
+ smooth_cleaned = clean(smooth_result, bm.clean)
243
+ results['smooth_cleaned'] = smooth_cleaned
244
+ if bm.path_to_data:
245
+ save_data(bm.path_to_smooth_cleaned, smooth_cleaned, bm.header, bm.final_image_type, bm.compression)
246
+ if bm.fill:
247
+ filled_result = fill(final_result, bm.fill)
248
+ results['filled'] = filled_result
249
+ if bm.path_to_data:
250
+ save_data(bm.path_to_filled, filled_result, bm.header, bm.final_image_type, bm.compression)
251
+ if bm.clean and bm.fill:
252
+ cleaned_filled_result = cleaned_result + (filled_result - final_result)
253
+ results['cleaned_filled'] = cleaned_filled_result
254
+ if bm.path_to_data:
255
+ save_data(bm.path_to_cleaned_filled, cleaned_filled_result, bm.header, bm.final_image_type, bm.compression)
256
+
257
+ # post-processing with active contour
258
+ if bm.acwe:
259
+ data = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=bm.data.dtype)
260
+ data[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = bm.data
261
+ acwe_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, bm.acwe_alpha, bm.acwe_smooth, bm.acwe_steps)
262
+ refined_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, simple=True)
263
+ results['acwe'] = acwe_result
264
+ results['refined'] = refined_result
265
+ if bm.path_to_data:
266
+ save_data(bm.path_to_acwe, acwe_result, bm.header, bm.final_image_type, bm.compression)
267
+ save_data(bm.path_to_refined, refined_result, bm.header, bm.final_image_type, bm.compression)
268
+
269
+ # computation time
270
+ t = int(time.time() - bm.TIC)
271
+ if t < 60:
272
+ time_str = str(t) + ' sec'
273
+ elif 60 <= t < 3600:
274
+ time_str = str(t // 60) + ' min ' + str(t % 60) + ' sec'
275
+ elif 3600 < t:
276
+ time_str = str(t // 3600) + ' h ' + str((t % 3600) // 60) + ' min ' + str(t % 60) + ' sec'
277
+ print('Computation time:', time_str)
278
+
279
+ # post processing
280
+ if bm.django_env:
281
+ from biomedisa_app.config import config
282
+ from biomedisa.features.django_env import post_processing
283
+ post_processing(bm.path_to_final, time_str, config['SERVER_ALIAS'], bm.remote, bm.queue,
284
+ dice=dice, uncertainty=bm.uncertainty, smooth=bm.smooth,
285
+ path_to_uq=bm.path_to_uq, path_to_smooth=bm.path_to_smooth,
286
+ img_id=bm.img_id, label_id=bm.label_id)
287
+
288
+ # write in logfile
289
+ with open(bm.path_to_time, 'a') as timefile:
290
+ print('%s %s %s %s MB %s on %s' %(time.ctime(), bm.username, bm.shortfilename, bm.imageSize, time_str, config['SERVER_ALIAS']), file=timefile)
291
+
292
+ # return results
293
+ return results
294
+
295
+ else:
296
+
297
+ lendataListe = comm.recv(source=0, tag=0)
298
+ for k in range(lendataListe):
299
+ data_z, data_y, data_x, data_dtype = comm.recv(source=0, tag=10+(2*k))
300
+ if k==0: data = np.zeros((0, data_y, data_x), dtype=data_dtype)
301
+ data_temp = np.empty((data_z, data_y, data_x), dtype=data_dtype)
302
+ if data_dtype == 'uint8':
303
+ comm.Recv([data_temp, MPI.BYTE], source=0, tag=10+(2*k+1))
304
+ else:
305
+ comm.Recv([data_temp, MPI.FLOAT], source=0, tag=10+(2*k+1))
306
+ data = np.append(data, data_temp, axis=0)
307
+
308
+ nbrw, sorw, allx, smooth, uncertainty, platform = comm.recv(source=0, tag=1)
309
+
310
+ if allx:
311
+ labels = []
312
+ for k in range(3):
313
+ lenlabelsListe = comm.recv(source=0, tag=2+k)
314
+ for l in range(lenlabelsListe):
315
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=100+(2*k))
316
+ if l==0: labels_tmp = np.zeros((0, labels_y, labels_x), dtype=np.int32)
317
+ tmp = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
318
+ comm.Recv([tmp, MPI.INT], source=0, tag=100+(2*k+1))
319
+ labels_tmp = np.append(labels_tmp, tmp, axis=0)
320
+ labels.append(labels_tmp)
321
+ else:
322
+ lenlabelsListe = comm.recv(source=0, tag=2)
323
+ for k in range(lenlabelsListe):
324
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=100+(2*k))
325
+ if k==0: labels = np.zeros((0, labels_y, labels_x), dtype=np.int32)
326
+ tmp = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
327
+ comm.Recv([tmp, MPI.INT], source=0, tag=100+(2*k+1))
328
+ labels = np.append(labels, tmp, axis=0)
329
+
330
+ allLabels = comm.recv(source=0, tag=99)
331
+ indices = comm.recv(source=0, tag=8)
332
+ blocks = comm.recv(source=0, tag=9)
333
+
334
+ blockmin = blocks[rank]
335
+ blockmax = blocks[rank+1]
336
+
337
+ # select platform
338
+ if platform == 'cuda':
339
+ import pycuda.driver as cuda
340
+ cuda.init()
341
+ dev = cuda.Device(rank % cuda.Device.count())
342
+ ctx, queue = dev.make_context(), None
343
+ if allx:
344
+ from biomedisa.features.random_walk.pycuda_large_allx import walk
345
+ else:
346
+ from biomedisa.features.random_walk.pycuda_large import walk
347
+ else:
348
+ ctx, queue = _get_device(platform, rank)
349
+ from biomedisa.features.random_walk.pyopencl_large import walk
350
+
351
+ # run random walks
352
+ tic = time.time()
353
+ memory_error, final, final_uncertainty, final_smooth = walk(comm, data, labels, indices, nbrw, sorw,
354
+ blockmin, blockmax, name, allLabels, smooth, uncertainty, ctx, queue, platform)
355
+ tac = time.time()
356
+ print('Walktime_%s: ' %(name) + str(int(tac - tic)) + ' ' + 'seconds')
357
+
358
+ # free device
359
+ if platform == 'cuda':
360
+ ctx.pop()
361
+ del ctx
362
+
363
+ # send finals
364
+ if not memory_error:
365
+ dataListe = splitlargedata(final)
366
+ comm.send(len(dataListe), dest=0, tag=0)
367
+ for k, dataTemp in enumerate(dataListe):
368
+ dataTemp = dataTemp.copy(order='C')
369
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
370
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
371
+
372
+ if final_uncertainty is not None:
373
+ final_uncertainty *= 255
374
+ final_uncertainty = final_uncertainty.astype(np.uint8)
375
+ dataListe = splitlargedata(final_uncertainty)
376
+ comm.send(len(dataListe), dest=0, tag=0)
377
+ for k, dataTemp in enumerate(dataListe):
378
+ dataTemp = dataTemp.copy(order='C')
379
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
380
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
381
+
382
+ if final_smooth is not None:
383
+ dataListe = splitlargedata(final_smooth)
384
+ comm.send(len(dataListe), dest=0, tag=0)
385
+ for k, dataTemp in enumerate(dataListe):
386
+ dataTemp = dataTemp.copy(order='C')
387
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
388
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
389
+