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.
- biomedisa/__init__.py +53 -0
- biomedisa/__main__.py +18 -0
- biomedisa/biomedisa_features/DataGenerator.py +299 -0
- biomedisa/biomedisa_features/DataGeneratorCrop.py +121 -0
- biomedisa/biomedisa_features/PredictDataGenerator.py +87 -0
- biomedisa/biomedisa_features/PredictDataGeneratorCrop.py +74 -0
- biomedisa/biomedisa_features/__init__.py +0 -0
- biomedisa/biomedisa_features/active_contour.py +434 -0
- biomedisa/biomedisa_features/amira_to_np/__init__.py +0 -0
- biomedisa/biomedisa_features/amira_to_np/amira_data_stream.py +980 -0
- biomedisa/biomedisa_features/amira_to_np/amira_grammar.py +369 -0
- biomedisa/biomedisa_features/amira_to_np/amira_header.py +290 -0
- biomedisa/biomedisa_features/amira_to_np/amira_helper.py +72 -0
- biomedisa/biomedisa_features/assd.py +167 -0
- biomedisa/biomedisa_features/biomedisa_helper.py +801 -0
- biomedisa/biomedisa_features/create_slices.py +286 -0
- biomedisa/biomedisa_features/crop_helper.py +586 -0
- biomedisa/biomedisa_features/curvop_numba.py +149 -0
- biomedisa/biomedisa_features/django_env.py +172 -0
- biomedisa/biomedisa_features/keras_helper.py +1219 -0
- biomedisa/biomedisa_features/nc_reader.py +179 -0
- biomedisa/biomedisa_features/pid.py +52 -0
- biomedisa/biomedisa_features/process_image.py +253 -0
- biomedisa/biomedisa_features/pycuda_test.py +84 -0
- biomedisa/biomedisa_features/random_walk/__init__.py +0 -0
- biomedisa/biomedisa_features/random_walk/gpu_kernels.py +183 -0
- biomedisa/biomedisa_features/random_walk/pycuda_large.py +826 -0
- biomedisa/biomedisa_features/random_walk/pycuda_large_allx.py +806 -0
- biomedisa/biomedisa_features/random_walk/pycuda_small.py +414 -0
- biomedisa/biomedisa_features/random_walk/pycuda_small_allx.py +493 -0
- biomedisa/biomedisa_features/random_walk/pyopencl_large.py +760 -0
- biomedisa/biomedisa_features/random_walk/pyopencl_small.py +441 -0
- biomedisa/biomedisa_features/random_walk/rw_large.py +390 -0
- biomedisa/biomedisa_features/random_walk/rw_small.py +310 -0
- biomedisa/biomedisa_features/remove_outlier.py +399 -0
- biomedisa/biomedisa_features/split_volume.py +274 -0
- biomedisa/deeplearning.py +519 -0
- biomedisa/interpolation.py +371 -0
- biomedisa/mesh.py +406 -0
- biomedisa-2024.5.14.dist-info/LICENSE +191 -0
- biomedisa-2024.5.14.dist-info/METADATA +306 -0
- biomedisa-2024.5.14.dist-info/RECORD +44 -0
- biomedisa-2024.5.14.dist-info/WHEEL +5 -0
- 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
|
+
|