biomedisa 2024.5.14__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 +53 -0
  2. biomedisa/__main__.py +18 -0
  3. biomedisa/biomedisa_features/DataGenerator.py +299 -0
  4. biomedisa/biomedisa_features/DataGeneratorCrop.py +121 -0
  5. biomedisa/biomedisa_features/PredictDataGenerator.py +87 -0
  6. biomedisa/biomedisa_features/PredictDataGeneratorCrop.py +74 -0
  7. biomedisa/biomedisa_features/__init__.py +0 -0
  8. biomedisa/biomedisa_features/active_contour.py +434 -0
  9. biomedisa/biomedisa_features/amira_to_np/__init__.py +0 -0
  10. biomedisa/biomedisa_features/amira_to_np/amira_data_stream.py +980 -0
  11. biomedisa/biomedisa_features/amira_to_np/amira_grammar.py +369 -0
  12. biomedisa/biomedisa_features/amira_to_np/amira_header.py +290 -0
  13. biomedisa/biomedisa_features/amira_to_np/amira_helper.py +72 -0
  14. biomedisa/biomedisa_features/assd.py +167 -0
  15. biomedisa/biomedisa_features/biomedisa_helper.py +801 -0
  16. biomedisa/biomedisa_features/create_slices.py +286 -0
  17. biomedisa/biomedisa_features/crop_helper.py +586 -0
  18. biomedisa/biomedisa_features/curvop_numba.py +149 -0
  19. biomedisa/biomedisa_features/django_env.py +172 -0
  20. biomedisa/biomedisa_features/keras_helper.py +1219 -0
  21. biomedisa/biomedisa_features/nc_reader.py +179 -0
  22. biomedisa/biomedisa_features/pid.py +52 -0
  23. biomedisa/biomedisa_features/process_image.py +253 -0
  24. biomedisa/biomedisa_features/pycuda_test.py +84 -0
  25. biomedisa/biomedisa_features/random_walk/__init__.py +0 -0
  26. biomedisa/biomedisa_features/random_walk/gpu_kernels.py +183 -0
  27. biomedisa/biomedisa_features/random_walk/pycuda_large.py +826 -0
  28. biomedisa/biomedisa_features/random_walk/pycuda_large_allx.py +806 -0
  29. biomedisa/biomedisa_features/random_walk/pycuda_small.py +414 -0
  30. biomedisa/biomedisa_features/random_walk/pycuda_small_allx.py +493 -0
  31. biomedisa/biomedisa_features/random_walk/pyopencl_large.py +760 -0
  32. biomedisa/biomedisa_features/random_walk/pyopencl_small.py +441 -0
  33. biomedisa/biomedisa_features/random_walk/rw_large.py +390 -0
  34. biomedisa/biomedisa_features/random_walk/rw_small.py +310 -0
  35. biomedisa/biomedisa_features/remove_outlier.py +399 -0
  36. biomedisa/biomedisa_features/split_volume.py +274 -0
  37. biomedisa/deeplearning.py +519 -0
  38. biomedisa/interpolation.py +371 -0
  39. biomedisa/mesh.py +406 -0
  40. biomedisa-2024.5.14.dist-info/LICENSE +191 -0
  41. biomedisa-2024.5.14.dist-info/METADATA +306 -0
  42. biomedisa-2024.5.14.dist-info/RECORD +44 -0
  43. biomedisa-2024.5.14.dist-info/WHEEL +5 -0
  44. biomedisa-2024.5.14.dist-info/top_level.txt +1 -0
@@ -0,0 +1,310 @@
1
+ ##########################################################################
2
+ ## ##
3
+ ## Copyright (c) 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,
32
+ sendToChild, _split_indices, get_labels, Dice_score)
33
+ from mpi4py import MPI
34
+ import numpy as np
35
+ import time
36
+ import socket
37
+ import os
38
+
39
+ def _diffusion_child(comm, bm=None):
40
+
41
+ rank = comm.Get_rank()
42
+ ngpus = comm.Get_size()
43
+
44
+ nodename = socket.gethostname()
45
+ name = '%s %s' %(nodename, rank)
46
+ print(name)
47
+
48
+ if rank == 0:
49
+
50
+ # initialize results
51
+ results = {}
52
+
53
+ # split indices on GPUs
54
+ indices_split = _split_indices(bm.indices, ngpus)
55
+ print('Indices:', indices_split)
56
+
57
+ # send data to GPUs
58
+ for k in range(1, ngpus):
59
+ sendToChild(comm, bm.indices, indices_split[k], k, bm.data, bm.labels, bm.nbrw,
60
+ bm.sorw, bm.allaxis, bm.platform)
61
+
62
+ # select platform
63
+ if bm.platform == 'cuda':
64
+ import pycuda.driver as cuda
65
+ import pycuda.gpuarray as gpuarray
66
+ from biomedisa_features.random_walk.gpu_kernels import (_build_kernel_uncertainty,
67
+ _build_kernel_max, _build_update_gpu, _build_curvature_gpu)
68
+ cuda.init()
69
+ dev = cuda.Device(rank)
70
+ ctx, queue = dev.make_context(), None
71
+ if bm.allaxis:
72
+ from biomedisa_features.random_walk.pycuda_small_allx import walk
73
+ else:
74
+ from biomedisa_features.random_walk.pycuda_small import walk
75
+ else:
76
+ ctx, queue = _get_device(bm.platform, rank)
77
+ from biomedisa_features.random_walk.pyopencl_small import walk
78
+
79
+ # run random walks
80
+ tic = time.time()
81
+ walkmap = walk(bm.data, bm.labels, bm.indices, indices_split[0], bm.nbrw, bm.sorw, name, ctx, queue)
82
+ tac = time.time()
83
+ print('Walktime_%s: ' %(name) + str(int(tac - tic)) + ' ' + 'seconds')
84
+
85
+ # gather data
86
+ zsh_tmp = bm.argmax_z - bm.argmin_z
87
+ ysh_tmp = bm.argmax_y - bm.argmin_y
88
+ xsh_tmp = bm.argmax_x - bm.argmin_x
89
+ if ngpus > 1:
90
+ final_zero = np.empty((bm.nol, zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
91
+ for k in range(bm.nol):
92
+ sendbuf = np.copy(walkmap[k], order='C')
93
+ recvbuf = np.empty((zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
94
+ comm.Barrier()
95
+ comm.Reduce([sendbuf, MPI.FLOAT], [recvbuf, MPI.FLOAT], root=0, op=MPI.SUM)
96
+ final_zero[k] = recvbuf
97
+ else:
98
+ final_zero = walkmap
99
+
100
+ # block and grid size
101
+ block = (32, 32, 1)
102
+ x_grid = (xsh_tmp // 32) + 1
103
+ y_grid = (ysh_tmp // 32) + 1
104
+ grid = (int(x_grid), int(y_grid), int(zsh_tmp))
105
+ xsh_gpu = np.int32(xsh_tmp)
106
+ ysh_gpu = np.int32(ysh_tmp)
107
+
108
+ if bm.django_env:
109
+ from biomedisa_app.views import unique_file_path
110
+
111
+ # smooth
112
+ if bm.smooth:
113
+ try:
114
+ update_gpu = _build_update_gpu()
115
+ curvature_gpu = _build_curvature_gpu()
116
+ a_gpu = gpuarray.empty((zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
117
+ b_gpu = gpuarray.zeros((zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
118
+ final_smooth = np.copy(final_zero, order='C')
119
+ for k in range(bm.nol):
120
+ a_gpu = gpuarray.to_gpu(final_smooth[k])
121
+ for l in range(bm.smooth):
122
+ curvature_gpu(a_gpu, b_gpu, xsh_gpu, ysh_gpu, block=block, grid=grid)
123
+ update_gpu(a_gpu, b_gpu, xsh_gpu, ysh_gpu, block=block, grid=grid)
124
+ final_smooth[k] = a_gpu.get()
125
+ final_smooth = np.argmax(final_smooth, axis=0).astype(np.uint8)
126
+ final_smooth = get_labels(final_smooth, bm.allLabels)
127
+ smooth_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
128
+ smooth_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_smooth
129
+ smooth_result = smooth_result[1:-1, 1:-1, 1:-1]
130
+ results['smooth'] = smooth_result
131
+ if bm.django_env and not bm.remote:
132
+ bm.path_to_smooth = unique_file_path(bm.path_to_smooth)
133
+ if bm.path_to_data:
134
+ save_data(bm.path_to_smooth, smooth_result, bm.header, bm.final_image_type, bm.compression)
135
+ except Exception as e:
136
+ print('Warning: GPU out of memory to allocate smooth array. Process starts without smoothing.')
137
+ bm.smooth = 0
138
+
139
+ # uncertainty
140
+ if bm.uncertainty:
141
+ try:
142
+ max_gpu = gpuarray.zeros((3, zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
143
+ a_gpu = gpuarray.zeros((zsh_tmp, ysh_tmp, xsh_tmp), dtype=np.float32)
144
+ kernel_uncertainty = _build_kernel_uncertainty()
145
+ kernel_max = _build_kernel_max()
146
+ for k in range(bm.nol):
147
+ a_gpu = gpuarray.to_gpu(final_zero[k])
148
+ kernel_max(max_gpu, a_gpu, xsh_gpu, ysh_gpu, block=block, grid=grid)
149
+ kernel_uncertainty(max_gpu, a_gpu, xsh_gpu, ysh_gpu, block=block, grid=grid)
150
+ uq = a_gpu.get()
151
+ uq *= 255
152
+ uq = uq.astype(np.uint8)
153
+ uncertainty_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
154
+ uncertainty_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = uq
155
+ uncertainty_result = uncertainty_result[1:-1, 1:-1, 1:-1]
156
+ results['uncertainty'] = uncertainty_result
157
+ if bm.django_env and not bm.remote:
158
+ bm.path_to_uq = unique_file_path(bm.path_to_uq)
159
+ if bm.path_to_data:
160
+ save_data(bm.path_to_uq, uncertainty_result, compress=bm.compression)
161
+ except Exception as e:
162
+ print('Warning: GPU out of memory to allocate uncertainty array. Process starts without uncertainty.')
163
+ bm.uncertainty = False
164
+
165
+ # free device
166
+ if bm.platform == 'cuda':
167
+ ctx.pop()
168
+ del ctx
169
+
170
+ # return hits
171
+ if bm.return_hits:
172
+ hits = np.zeros((bm.nol, bm.zsh, bm.ysh, bm.xsh), dtype=np.float32)
173
+ hits[:, bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_zero
174
+ hits = hits[:,1:-1,1:-1,1:-1]
175
+ results['hits'] = hits
176
+
177
+ # get original labels
178
+ final_zero = np.argmax(final_zero, axis=0).astype(np.uint8)
179
+ final_zero = get_labels(final_zero, bm.allLabels)
180
+
181
+ # validate result and check for allaxis
182
+ mask = bm.labelData>0
183
+ dice = Dice_score(bm.labelData, final_zero*mask)
184
+ if dice < 0.3:
185
+ print('Warning: Bad result! Use "--allaxis" if you labeled axes other than the xy-plane.')
186
+
187
+ # regular result
188
+ final_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
189
+ final_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_zero
190
+ final_result = final_result[1:-1,1:-1,1:-1]
191
+ results['regular'] = final_result
192
+ if bm.django_env and not bm.remote:
193
+ bm.path_to_final = unique_file_path(bm.path_to_final)
194
+ if bm.path_to_data:
195
+ save_data(bm.path_to_final, final_result, bm.header, bm.final_image_type, bm.compression)
196
+
197
+ # remove outliers
198
+ if bm.clean:
199
+ cleaned_result = clean(final_result, bm.clean)
200
+ results['cleaned'] = cleaned_result
201
+ if bm.path_to_data:
202
+ save_data(bm.path_to_cleaned, cleaned_result, bm.header, bm.final_image_type, bm.compression)
203
+ if bm.smooth:
204
+ smooth_cleaned = clean(smooth_result, bm.clean)
205
+ results['smooth_cleaned'] = smooth_cleaned
206
+ if bm.path_to_data:
207
+ save_data(bm.path_to_smooth_cleaned, smooth_cleaned, bm.header, bm.final_image_type, bm.compression)
208
+ if bm.fill:
209
+ filled_result = fill(final_result, bm.fill)
210
+ results['filled'] = filled_result
211
+ if bm.path_to_data:
212
+ save_data(bm.path_to_filled, filled_result, bm.header, bm.final_image_type, bm.compression)
213
+ if bm.clean and bm.fill:
214
+ cleaned_filled_result = cleaned_result + (filled_result - final_result)
215
+ results['cleaned_filled'] = cleaned_filled_result
216
+ if bm.path_to_data:
217
+ save_data(bm.path_to_cleaned_filled, cleaned_filled_result, bm.header, bm.final_image_type, bm.compression)
218
+
219
+ # post-processing with active contour
220
+ if bm.acwe:
221
+ data = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=bm.data.dtype)
222
+ data[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = bm.data
223
+ acwe_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, bm.acwe_alpha, bm.acwe_smooth, bm.acwe_steps)
224
+ refined_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, simple=True)
225
+ results['acwe'] = acwe_result
226
+ results['refined'] = refined_result
227
+ if bm.path_to_data:
228
+ save_data(bm.path_to_acwe, acwe_result, bm.header, bm.final_image_type, bm.compression)
229
+ save_data(bm.path_to_refined, refined_result, bm.header, bm.final_image_type, bm.compression)
230
+
231
+ # computation time
232
+ t = int(time.time() - bm.TIC)
233
+ if t < 60:
234
+ time_str = str(t) + ' sec'
235
+ elif 60 <= t < 3600:
236
+ time_str = str(t // 60) + ' min ' + str(t % 60) + ' sec'
237
+ elif 3600 < t:
238
+ time_str = str(t // 3600) + ' h ' + str((t % 3600) // 60) + ' min ' + str(t % 60) + ' sec'
239
+ print('Computation time:', time_str)
240
+
241
+ # post processing
242
+ if bm.django_env:
243
+ from biomedisa_app.config import config
244
+ from biomedisa_features.django_env import post_processing
245
+ post_processing(bm.path_to_final, time_str, config['SERVER_ALIAS'], bm.remote, bm.queue,
246
+ dice=dice, uncertainty=bm.uncertainty, smooth=bm.smooth,
247
+ path_to_uq=bm.path_to_uq, path_to_smooth=bm.path_to_smooth,
248
+ img_id=bm.img_id, label_id=bm.label_id)
249
+
250
+ # write in logfile
251
+ with open(bm.path_to_time, 'a') as timefile:
252
+ print('%s %s %s %s MB %s on %s' %(time.ctime(), bm.username, bm.shortfilename, bm.imageSize, time_str, config['SERVER_ALIAS']), file=timefile)
253
+
254
+ # return results
255
+ return results
256
+
257
+ else:
258
+
259
+ data_z, data_y, data_x, data_dtype = comm.recv(source=0, tag=0)
260
+ data = np.empty((data_z, data_y, data_x), dtype=data_dtype)
261
+ if data_dtype == 'uint8':
262
+ comm.Recv([data, MPI.BYTE], source=0, tag=1)
263
+ else:
264
+ comm.Recv([data, MPI.FLOAT], source=0, tag=1)
265
+ allx, nbrw, sorw, platform = comm.recv(source=0, tag=2)
266
+ if allx:
267
+ labels = []
268
+ for k in range(3):
269
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=k+3)
270
+ labels_tmp = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
271
+ comm.Recv([labels_tmp, MPI.INT], source=0, tag=k+6)
272
+ labels.append(labels_tmp)
273
+ else:
274
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=3)
275
+ labels = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
276
+ comm.Recv([labels, MPI.INT], source=0, tag=6)
277
+ indices = comm.recv(source=0, tag=9)
278
+ indices_child = comm.recv(source=0, tag=10)
279
+
280
+ # select platform
281
+ if platform == 'cuda':
282
+ import pycuda.driver as cuda
283
+ cuda.init()
284
+ dev = cuda.Device(rank % cuda.Device.count())
285
+ ctx, queue = dev.make_context(), None
286
+ if allx:
287
+ from biomedisa_features.random_walk.pycuda_small_allx import walk
288
+ else:
289
+ from biomedisa_features.random_walk.pycuda_small import walk
290
+ else:
291
+ ctx, queue = _get_device(platform, rank)
292
+ from biomedisa_features.random_walk.pyopencl_small import walk
293
+
294
+ # run random walks
295
+ tic = time.time()
296
+ walkmap = walk(data, labels, indices, indices_child, nbrw, sorw, name, ctx, queue)
297
+ tac = time.time()
298
+ print('Walktime_%s: ' %(name) + str(int(tac - tic)) + ' ' + 'seconds')
299
+
300
+ # free device
301
+ if platform == 'cuda':
302
+ ctx.pop()
303
+ del ctx
304
+
305
+ # send data
306
+ for k in range(walkmap.shape[0]):
307
+ datatemporaer = np.copy(walkmap[k], order='C')
308
+ comm.Barrier()
309
+ comm.Reduce([datatemporaer, MPI.FLOAT], None, root=0, op=MPI.SUM)
310
+