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,390 @@
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, _error_,
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
+ from biomedisa_app.views import unique_file_path
188
+ bm.path_to_final = unique_file_path(bm.path_to_final)
189
+ if bm.path_to_data:
190
+ save_data(bm.path_to_final, final_result, bm.header, bm.final_image_type, bm.compression)
191
+
192
+ # uncertainty
193
+ if final_uncertainty is not None:
194
+ final_uncertainty *= 255
195
+ final_uncertainty = final_uncertainty.astype(np.uint8)
196
+ for source in range(1, ngpus):
197
+ lendataListe = comm.recv(source=source, tag=0)
198
+ for l in range(lendataListe):
199
+ data_z, data_y, data_x = comm.recv(source=source, tag=10+(2*l))
200
+ receivedata = np.empty((data_z, data_y, data_x), dtype=np.uint8)
201
+ comm.Recv([receivedata, MPI.BYTE], source=source, tag=10+(2*l+1))
202
+ final_uncertainty = np.append(final_uncertainty, receivedata, axis=0)
203
+ # save finals
204
+ uncertainty_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
205
+ uncertainty_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_uncertainty
206
+ uncertainty_result = uncertainty_result[1:-1, 1:-1, 1:-1]
207
+ results['uncertainty'] = uncertainty_result
208
+ if bm.django_env and not bm.remote:
209
+ bm.path_to_uq = unique_file_path(bm.path_to_uq)
210
+ if bm.path_to_data:
211
+ save_data(bm.path_to_uq, uncertainty_result, compress=bm.compression)
212
+ else:
213
+ bm.uncertainty = False
214
+
215
+ # smooth
216
+ if final_smooth is not None:
217
+ for source in range(1, ngpus):
218
+ lendataListe = comm.recv(source=source, tag=0)
219
+ for l in range(lendataListe):
220
+ data_z, data_y, data_x = comm.recv(source=source, tag=10+(2*l))
221
+ receivedata = np.empty((data_z, data_y, data_x), dtype=np.uint8)
222
+ comm.Recv([receivedata, MPI.BYTE], source=source, tag=10+(2*l+1))
223
+ final_smooth = np.append(final_smooth, receivedata, axis=0)
224
+ # save finals
225
+ smooth_result = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=np.uint8)
226
+ smooth_result[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = final_smooth
227
+ smooth_result = smooth_result[1:-1, 1:-1, 1:-1]
228
+ results['smooth'] = smooth_result
229
+ if bm.django_env and not bm.remote:
230
+ bm.path_to_smooth = unique_file_path(bm.path_to_smooth)
231
+ if bm.path_to_data:
232
+ save_data(bm.path_to_smooth, smooth_result, bm.header, bm.final_image_type, bm.compression)
233
+ else:
234
+ bm.smooth = 0
235
+
236
+ # remove outliers
237
+ if bm.clean:
238
+ cleaned_result = clean(final_result, bm.clean)
239
+ results['cleaned'] = cleaned_result
240
+ if bm.path_to_data:
241
+ save_data(bm.path_to_cleaned, cleaned_result, bm.header, bm.final_image_type, bm.compression)
242
+ if bm.smooth:
243
+ smooth_cleaned = clean(smooth_result, bm.clean)
244
+ results['smooth_cleaned'] = smooth_cleaned
245
+ if bm.path_to_data:
246
+ save_data(bm.path_to_smooth_cleaned, smooth_cleaned, bm.header, bm.final_image_type, bm.compression)
247
+ if bm.fill:
248
+ filled_result = fill(final_result, bm.fill)
249
+ results['filled'] = filled_result
250
+ if bm.path_to_data:
251
+ save_data(bm.path_to_filled, filled_result, bm.header, bm.final_image_type, bm.compression)
252
+ if bm.clean and bm.fill:
253
+ cleaned_filled_result = cleaned_result + (filled_result - final_result)
254
+ results['cleaned_filled'] = cleaned_filled_result
255
+ if bm.path_to_data:
256
+ save_data(bm.path_to_cleaned_filled, cleaned_filled_result, bm.header, bm.final_image_type, bm.compression)
257
+
258
+ # post-processing with active contour
259
+ if bm.acwe:
260
+ data = np.zeros((bm.zsh, bm.ysh, bm.xsh), dtype=bm.data.dtype)
261
+ data[bm.argmin_z:bm.argmax_z, bm.argmin_y:bm.argmax_y, bm.argmin_x:bm.argmax_x] = bm.data
262
+ acwe_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, bm.acwe_alpha, bm.acwe_smooth, bm.acwe_steps)
263
+ refined_result = activeContour(data[1:-1, 1:-1, 1:-1], final_result, simple=True)
264
+ results['acwe'] = acwe_result
265
+ results['refined'] = refined_result
266
+ if bm.path_to_data:
267
+ save_data(bm.path_to_acwe, acwe_result, bm.header, bm.final_image_type, bm.compression)
268
+ save_data(bm.path_to_refined, refined_result, bm.header, bm.final_image_type, bm.compression)
269
+
270
+ # computation time
271
+ t = int(time.time() - bm.TIC)
272
+ if t < 60:
273
+ time_str = str(t) + ' sec'
274
+ elif 60 <= t < 3600:
275
+ time_str = str(t // 60) + ' min ' + str(t % 60) + ' sec'
276
+ elif 3600 < t:
277
+ time_str = str(t // 3600) + ' h ' + str((t % 3600) // 60) + ' min ' + str(t % 60) + ' sec'
278
+ print('Computation time:', time_str)
279
+
280
+ # post processing
281
+ if bm.django_env:
282
+ from biomedisa_app.config import config
283
+ from biomedisa_features.django_env import post_processing
284
+ post_processing(bm.path_to_final, time_str, config['SERVER_ALIAS'], bm.remote, bm.queue,
285
+ dice=dice, uncertainty=bm.uncertainty, smooth=bm.smooth,
286
+ path_to_uq=bm.path_to_uq, path_to_smooth=bm.path_to_smooth,
287
+ img_id=bm.img_id, label_id=bm.label_id)
288
+
289
+ # write in logfile
290
+ with open(bm.path_to_time, 'a') as timefile:
291
+ print('%s %s %s %s MB %s on %s' %(time.ctime(), bm.username, bm.shortfilename, bm.imageSize, time_str, config['SERVER_ALIAS']), file=timefile)
292
+
293
+ # return results
294
+ return results
295
+
296
+ else:
297
+
298
+ lendataListe = comm.recv(source=0, tag=0)
299
+ for k in range(lendataListe):
300
+ data_z, data_y, data_x, data_dtype = comm.recv(source=0, tag=10+(2*k))
301
+ if k==0: data = np.zeros((0, data_y, data_x), dtype=data_dtype)
302
+ data_temp = np.empty((data_z, data_y, data_x), dtype=data_dtype)
303
+ if data_dtype == 'uint8':
304
+ comm.Recv([data_temp, MPI.BYTE], source=0, tag=10+(2*k+1))
305
+ else:
306
+ comm.Recv([data_temp, MPI.FLOAT], source=0, tag=10+(2*k+1))
307
+ data = np.append(data, data_temp, axis=0)
308
+
309
+ nbrw, sorw, allx, smooth, uncertainty, platform = comm.recv(source=0, tag=1)
310
+
311
+ if allx:
312
+ labels = []
313
+ for k in range(3):
314
+ lenlabelsListe = comm.recv(source=0, tag=2+k)
315
+ for l in range(lenlabelsListe):
316
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=100+(2*k))
317
+ if l==0: labels_tmp = np.zeros((0, labels_y, labels_x), dtype=np.int32)
318
+ tmp = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
319
+ comm.Recv([tmp, MPI.INT], source=0, tag=100+(2*k+1))
320
+ labels_tmp = np.append(labels_tmp, tmp, axis=0)
321
+ labels.append(labels_tmp)
322
+ else:
323
+ lenlabelsListe = comm.recv(source=0, tag=2)
324
+ for k in range(lenlabelsListe):
325
+ labels_z, labels_y, labels_x = comm.recv(source=0, tag=100+(2*k))
326
+ if k==0: labels = np.zeros((0, labels_y, labels_x), dtype=np.int32)
327
+ tmp = np.empty((labels_z, labels_y, labels_x), dtype=np.int32)
328
+ comm.Recv([tmp, MPI.INT], source=0, tag=100+(2*k+1))
329
+ labels = np.append(labels, tmp, axis=0)
330
+
331
+ allLabels = comm.recv(source=0, tag=99)
332
+ indices = comm.recv(source=0, tag=8)
333
+ blocks = comm.recv(source=0, tag=9)
334
+
335
+ blockmin = blocks[rank]
336
+ blockmax = blocks[rank+1]
337
+
338
+ # select platform
339
+ if platform == 'cuda':
340
+ import pycuda.driver as cuda
341
+ cuda.init()
342
+ dev = cuda.Device(rank % cuda.Device.count())
343
+ ctx, queue = dev.make_context(), None
344
+ if allx:
345
+ from biomedisa_features.random_walk.pycuda_large_allx import walk
346
+ else:
347
+ from biomedisa_features.random_walk.pycuda_large import walk
348
+ else:
349
+ ctx, queue = _get_device(platform, rank)
350
+ from biomedisa_features.random_walk.pyopencl_large import walk
351
+
352
+ # run random walks
353
+ tic = time.time()
354
+ memory_error, final, final_uncertainty, final_smooth = walk(comm, data, labels, indices, nbrw, sorw,
355
+ blockmin, blockmax, name, allLabels, smooth, uncertainty, ctx, queue, platform)
356
+ tac = time.time()
357
+ print('Walktime_%s: ' %(name) + str(int(tac - tic)) + ' ' + 'seconds')
358
+
359
+ # free device
360
+ if platform == 'cuda':
361
+ ctx.pop()
362
+ del ctx
363
+
364
+ # send finals
365
+ if not memory_error:
366
+ dataListe = splitlargedata(final)
367
+ comm.send(len(dataListe), dest=0, tag=0)
368
+ for k, dataTemp in enumerate(dataListe):
369
+ dataTemp = dataTemp.copy(order='C')
370
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
371
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
372
+
373
+ if final_uncertainty is not None:
374
+ final_uncertainty *= 255
375
+ final_uncertainty = final_uncertainty.astype(np.uint8)
376
+ dataListe = splitlargedata(final_uncertainty)
377
+ comm.send(len(dataListe), dest=0, tag=0)
378
+ for k, dataTemp in enumerate(dataListe):
379
+ dataTemp = dataTemp.copy(order='C')
380
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
381
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
382
+
383
+ if final_smooth is not None:
384
+ dataListe = splitlargedata(final_smooth)
385
+ comm.send(len(dataListe), dest=0, tag=0)
386
+ for k, dataTemp in enumerate(dataListe):
387
+ dataTemp = dataTemp.copy(order='C')
388
+ comm.send([dataTemp.shape[0], dataTemp.shape[1], dataTemp.shape[2]], dest=0, tag=10+(2*k))
389
+ comm.Send([dataTemp, MPI.BYTE], dest=0, tag=10+(2*k+1))
390
+