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,399 @@
1
+ #!/usr/bin/python3
2
+ ##########################################################################
3
+ ## ##
4
+ ## Copyright (c) 2024 Philipp Lösel. All rights reserved. ##
5
+ ## ##
6
+ ## This file is part of the open source project biomedisa. ##
7
+ ## ##
8
+ ## Licensed under the European Union Public Licence (EUPL) ##
9
+ ## v1.2, or - as soon as they will be approved by the ##
10
+ ## European Commission - subsequent versions of the EUPL; ##
11
+ ## ##
12
+ ## You may redistribute it and/or modify it under the terms ##
13
+ ## of the EUPL v1.2. You may not use this work except in ##
14
+ ## compliance with this Licence. ##
15
+ ## ##
16
+ ## You can obtain a copy of the Licence at: ##
17
+ ## ##
18
+ ## https://joinup.ec.europa.eu/page/eupl-text-11-12 ##
19
+ ## ##
20
+ ## Unless required by applicable law or agreed to in ##
21
+ ## writing, software distributed under the Licence is ##
22
+ ## distributed on an "AS IS" basis, WITHOUT WARRANTIES ##
23
+ ## OR CONDITIONS OF ANY KIND, either express or implied. ##
24
+ ## ##
25
+ ## See the Licence for the specific language governing ##
26
+ ## permissions and limitations under the Licence. ##
27
+ ## ##
28
+ ##########################################################################
29
+
30
+ import sys, os
31
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
32
+ if not BASE_DIR in sys.path:
33
+ sys.path.append(BASE_DIR)
34
+ import biomedisa
35
+ from biomedisa_features.biomedisa_helper import load_data, save_data, silent_remove
36
+ import numpy as np
37
+ from scipy import ndimage
38
+ import argparse
39
+ import traceback
40
+ import subprocess
41
+
42
+ def reduce_blocksize(data):
43
+ zsh, ysh, xsh = data.shape
44
+ argmin_z, argmax_z, argmin_y, argmax_y, argmin_x, argmax_x = zsh, 0, ysh, 0, xsh, 0
45
+ for k in range(zsh):
46
+ y, x = np.nonzero(data[k])
47
+ if x.any():
48
+ argmin_x = min(argmin_x, np.amin(x))
49
+ argmax_x = max(argmax_x, np.amax(x))
50
+ argmin_y = min(argmin_y, np.amin(y))
51
+ argmax_y = max(argmax_y, np.amax(y))
52
+ argmin_z = min(argmin_z, k)
53
+ argmax_z = max(argmax_z, k)
54
+ argmin_x = max(argmin_x - 1, 0)
55
+ argmax_x = min(argmax_x + 1, xsh-1) + 1
56
+ argmin_y = max(argmin_y - 1, 0)
57
+ argmax_y = min(argmax_y + 1, ysh-1) + 1
58
+ argmin_z = max(argmin_z - 1, 0)
59
+ argmax_z = min(argmax_z + 1, zsh-1) + 1
60
+ data = np.copy(data[argmin_z:argmax_z, argmin_y:argmax_y, argmin_x:argmax_x], order='C')
61
+ return data, argmin_z, argmax_z, argmin_y, argmax_y, argmin_x, argmax_x
62
+
63
+ def clean(image, threshold=0.1):
64
+ image_i = np.copy(image, order='C')
65
+ allLabels = np.unique(image_i)
66
+ mask = np.empty_like(image_i)
67
+ s = [[[0,0,0], [0,1,0], [0,0,0]], [[0,1,0], [1,1,1], [0,1,0]], [[0,0,0], [0,1,0], [0,0,0]]]
68
+ for k in allLabels[1:]:
69
+
70
+ # get mask
71
+ label = image_i==k
72
+ mask.fill(0)
73
+ mask[label] = 1
74
+
75
+ # reduce size
76
+ reduced, argmin_z, argmax_z, argmin_y, argmax_y, argmin_x, argmax_x = reduce_blocksize(mask)
77
+
78
+ # get clusters
79
+ labeled_array, _ = ndimage.label(reduced, structure=s)
80
+ size = np.bincount(labeled_array.ravel())
81
+
82
+ # get reference size
83
+ biggest_label = np.argmax(size[1:]) + 1
84
+ label_size = size[biggest_label]
85
+
86
+ # preserve large segments
87
+ reduced.fill(0)
88
+ for l, m in enumerate(size[1:]):
89
+ if m > threshold * label_size:
90
+ reduced[labeled_array==l+1] = 1
91
+
92
+ # get original size
93
+ mask.fill(0)
94
+ mask[argmin_z:argmax_z, argmin_y:argmax_y, argmin_x:argmax_x] = reduced
95
+
96
+ # write cleaned label to array
97
+ image_i[label] = 0
98
+ image_i[mask==1] = k
99
+
100
+ return image_i
101
+
102
+ def fill(image, threshold=0.9):
103
+ image_i = np.copy(image, order='C')
104
+ allLabels = np.unique(image_i)
105
+ mask = np.empty_like(image_i)
106
+ s = [[[0,0,0], [0,1,0], [0,0,0]], [[0,1,0], [1,1,1], [0,1,0]], [[0,0,0], [0,1,0], [0,0,0]]]
107
+ for k in allLabels[1:]:
108
+
109
+ # get mask
110
+ label = image_i==k
111
+ mask.fill(0)
112
+ mask[label] = 1
113
+
114
+ # reduce size
115
+ reduced, argmin_z, argmax_z, argmin_y, argmax_y, argmin_x, argmax_x = reduce_blocksize(mask)
116
+
117
+ # reference size
118
+ label_size = np.sum(reduced)
119
+
120
+ # invert
121
+ reduced = 1 - reduced # background and holes of object
122
+
123
+ # get clusters
124
+ labeled_array, _ = ndimage.label(reduced, structure=s)
125
+ size = np.bincount(labeled_array.ravel())
126
+ biggest_label = np.argmax(size)
127
+
128
+ # get label with all holes filled
129
+ reduced.fill(1)
130
+ reduced[labeled_array==biggest_label] = 0
131
+
132
+ # preserve large holes
133
+ for l, m in enumerate(size[1:]):
134
+ if m > threshold * label_size and l+1 != biggest_label:
135
+ reduced[labeled_array==l+1] = 0
136
+
137
+ # get original size
138
+ mask.fill(0)
139
+ mask[argmin_z:argmax_z, argmin_y:argmax_y, argmin_x:argmax_x] = reduced
140
+
141
+ # write filled label to array
142
+ image_i[label] = 0
143
+ image_i[mask==1] = k
144
+
145
+ return image_i
146
+
147
+ def main_helper(path_to_labels, img_id=None, friend_id=None, fill_holes=True,
148
+ clean_threshold=0.1, fill_threshold=0.9, remote=False, no_compression=False):
149
+
150
+ # django environment
151
+ if img_id is not None:
152
+ django_env = True
153
+ else:
154
+ django_env = False
155
+
156
+ # compression
157
+ if no_compression:
158
+ compression = False
159
+ else:
160
+ compression = True
161
+
162
+ # final filenames
163
+ filename, extension = os.path.splitext(path_to_labels)
164
+ if extension == '.gz':
165
+ extension = '.nii.gz'
166
+ filename = filename[:-4]
167
+ path_to_cleaned = filename + '.cleaned' + extension
168
+ path_to_filled = filename + '.filled' + extension
169
+ path_to_cleaned_filled = filename + '.cleaned.filled' + extension
170
+
171
+ # load data
172
+ final, header = load_data(path_to_labels, 'cleanup')
173
+
174
+ # process data
175
+ final_cleaned = clean(final, clean_threshold)
176
+ if fill_holes:
177
+ final_filled = fill(final, fill_threshold)
178
+ final_cleaned_filled = final_cleaned + (final_filled - final)
179
+
180
+ # unique_file_paths
181
+ if django_env and not remote:
182
+ from biomedisa_app.views import unique_file_path
183
+ path_to_cleaned = unique_file_path(path_to_cleaned)
184
+ path_to_filled = unique_file_path(path_to_filled)
185
+ path_to_cleaned_filled = unique_file_path(path_to_cleaned_filled)
186
+
187
+ # save results
188
+ save_data(path_to_cleaned, final_cleaned, header, extension, compression)
189
+ if fill_holes:
190
+ save_data(path_to_filled, final_filled, header, extension, compression)
191
+ save_data(path_to_cleaned_filled, final_cleaned_filled, header, extension, compression)
192
+
193
+ # post processing
194
+ post_processing(path_to_cleaned, path_to_filled, path_to_cleaned_filled, img_id, friend_id, fill_holes, remote)
195
+
196
+ def post_processing(path_to_cleaned, path_to_filled, path_to_cleaned_filled, img_id=None, friend_id=None, fill_holes=False, remote=False):
197
+ if remote:
198
+ with open(BASE_DIR + '/log/config_6', 'w') as configfile:
199
+ print(path_to_cleaned, path_to_filled, path_to_cleaned_filled, file=configfile)
200
+ else:
201
+ import django
202
+ django.setup()
203
+ from biomedisa_app.models import Upload
204
+ from biomedisa_features.create_slices import create_slices
205
+ from redis import Redis
206
+ from rq import Queue
207
+
208
+ # check if reference data still exists
209
+ image = Upload.objects.filter(pk=img_id)
210
+ friend = Upload.objects.filter(pk=friend_id)
211
+ if len(friend)>0:
212
+ friend = friend[0]
213
+
214
+ # save django object
215
+ shortfilename = os.path.basename(path_to_cleaned)
216
+ pic_path = 'images/' + friend.user.username + '/' + shortfilename
217
+ Upload.objects.create(pic=pic_path, user=friend.user, project=friend.project, final=(2 if fill_holes else 6), imageType=3, shortfilename=shortfilename, friend=friend_id)
218
+
219
+ # create slices for sliceviewer
220
+ if len(image)>0:
221
+ q_slices = Queue('slices', connection=Redis())
222
+ job = q_slices.enqueue_call(create_slices, args=(image[0].pic.path, path_to_cleaned,), timeout=-1)
223
+
224
+ # fill holes
225
+ if fill_holes:
226
+ # save django object
227
+ shortfilename = os.path.basename(path_to_cleaned_filled)
228
+ pic_path = 'images/' + friend.user.username + '/' + shortfilename
229
+ Upload.objects.create(pic=pic_path, user=friend.user, project=friend.project, final=8, imageType=3, shortfilename=shortfilename, friend=friend_id)
230
+ shortfilename = os.path.basename(path_to_filled)
231
+ pic_path = 'images/' + friend.user.username + '/' + shortfilename
232
+ Upload.objects.create(pic=pic_path, user=friend.user, project=friend.project, final=7, imageType=3, shortfilename=shortfilename, friend=friend_id)
233
+
234
+ # create slices for sliceviewer
235
+ if len(image)>0:
236
+ q_slices = Queue('slices', connection=Redis())
237
+ job = q_slices.enqueue_call(create_slices, args=(image[0].pic.path, path_to_filled,), timeout=-1)
238
+ job = q_slices.enqueue_call(create_slices, args=(image[0].pic.path, path_to_cleaned_filled,), timeout=-1)
239
+ else:
240
+ silent_remove(path_to_cleaned)
241
+ silent_remove(path_to_filled)
242
+ silent_remove(path_to_cleaned_filled)
243
+
244
+ def init_remove_outlier(image_id, final_id, label_id, fill_holes=True):
245
+ '''
246
+ Runs clean() and fill() within django environment/webbrowser version
247
+
248
+ Parameters
249
+ ---------
250
+ image_id: int
251
+ Django id of image data used for creating slice preview
252
+ final_id: int
253
+ Django id of result data to be processed
254
+ label_id: int
255
+ Django id of label data used for configuration parameters
256
+ fill_holes: bool
257
+ Fill holes and save as an optional result
258
+
259
+ Returns
260
+ -------
261
+ No returns
262
+ Fails silently
263
+ '''
264
+
265
+ import django
266
+ django.setup()
267
+ from biomedisa_app.models import Upload
268
+ from biomedisa_app.config import config
269
+ from biomedisa_app.views import send_data_to_host, qsub_start, qsub_stop, unique_file_path
270
+
271
+ # get objects
272
+ try:
273
+ image = Upload.objects.get(pk=image_id)
274
+ final = Upload.objects.get(pk=final_id)
275
+ label = Upload.objects.get(pk=label_id)
276
+ success = True
277
+ except Upload.DoesNotExist:
278
+ success = False
279
+
280
+ # get host information
281
+ host = ''
282
+ host_base = BASE_DIR
283
+ subhost, qsub_pid = None, None
284
+ if 'REMOTE_QUEUE_HOST' in config:
285
+ host = config['REMOTE_QUEUE_HOST']
286
+ if host and 'REMOTE_QUEUE_BASE_DIR' in config:
287
+ host_base = config['REMOTE_QUEUE_BASE_DIR']
288
+
289
+ if success:
290
+
291
+ # remote server
292
+ if host:
293
+
294
+ # command
295
+ cmd = ['python3', host_base+'/biomedisa_features/remove_outlier.py', final.pic.path.replace(BASE_DIR,host_base)]
296
+ cmd += [f'-iid={image.id}', f'-fid={final.friend}', '-r']
297
+
298
+ # command (append only on demand)
299
+ if fill_holes:
300
+ cmd += ['-fh']
301
+ if not label.compression:
302
+ cmd += ['-nc']
303
+ if label.delete_outliers != 0.1:
304
+ cmd += [f'-c={label.delete_outliers}']
305
+ if label.fill_holes != 0.9:
306
+ cmd += [f'-f={label.fill_holes}']
307
+
308
+ # create user directory
309
+ subprocess.Popen(['ssh', host, 'mkdir', '-p', host_base+'/private_storage/images/'+image.user.username]).wait()
310
+
311
+ # send data to host
312
+ success = send_data_to_host(final.pic.path, host+':'+final.pic.path.replace(BASE_DIR,host_base))
313
+
314
+ if success==0:
315
+
316
+ # qsub start
317
+ if 'REMOTE_QUEUE_QSUB' in config and config['REMOTE_QUEUE_QSUB']:
318
+ subhost, qsub_pid = qsub_start(host, host_base, 6)
319
+
320
+ # start removing outliers
321
+ if subhost:
322
+ cmd = ['ssh', '-t', host, 'ssh', subhost] + cmd
323
+ else:
324
+ cmd = ['ssh', host] + cmd
325
+ subprocess.Popen(cmd).wait()
326
+
327
+ # config
328
+ success = subprocess.Popen(['scp', host+':'+host_base+'/log/config_6', BASE_DIR+'/log/config_6']).wait()
329
+
330
+ if success==0:
331
+ with open(BASE_DIR + '/log/config_6', 'r') as configfile:
332
+ cleaned_on_host, filled_on_host, cleaned_filled_on_host = configfile.read().split()
333
+
334
+ # local file names
335
+ path_to_cleaned = unique_file_path(cleaned_on_host.replace(host_base,BASE_DIR))
336
+ path_to_filled = unique_file_path(filled_on_host.replace(host_base,BASE_DIR))
337
+ path_to_cleaned_filled = unique_file_path(cleaned_filled_on_host.replace(host_base,BASE_DIR))
338
+
339
+ # get results
340
+ subprocess.Popen(['scp', host+':'+cleaned_on_host, path_to_cleaned]).wait()
341
+ if fill_holes:
342
+ subprocess.Popen(['scp', host+':'+filled_on_host, path_to_filled]).wait()
343
+ subprocess.Popen(['scp', host+':'+cleaned_filled_on_host, path_to_cleaned_filled]).wait()
344
+
345
+ # post processing
346
+ post_processing(path_to_cleaned, path_to_filled, path_to_cleaned_filled, image_id, final.friend, fill_holes)
347
+
348
+ # remove config file
349
+ subprocess.Popen(['ssh', host, 'rm', host_base + '/log/config_6']).wait()
350
+
351
+ # local server
352
+ else:
353
+ try:
354
+ main_helper(final.pic.path, img_id=image_id, friend_id=final.friend,
355
+ fill_holes=fill_holes, clean_threshold=label.delete_outliers, fill_threshold=label.fill_holes, remote=False,
356
+ no_compression=(False if label.compression else True))
357
+ except Exception as e:
358
+ print(traceback.format_exc())
359
+
360
+ # qsub stop
361
+ if 'REMOTE_QUEUE_QSUB' in config and config['REMOTE_QUEUE_QSUB']:
362
+ qsub_stop(host, host_base, 6, 'cleanup', subhost, qsub_pid)
363
+
364
+ if __name__ == '__main__':
365
+
366
+ # initialize arguments
367
+ parser = argparse.ArgumentParser(description='Biomedisa remove outliers.',
368
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
369
+
370
+ # required arguments
371
+ parser.add_argument('path_to_labels', type=str, metavar='PATH_TO_LABELS',
372
+ help='Location of label data')
373
+
374
+ # optional arguments
375
+ parser.add_argument('-v', '--version', action='version', version=f'{biomedisa.__version__}',
376
+ help='Biomedisa version')
377
+ parser.add_argument('-fh','--fill_holes', action='store_true', default=False,
378
+ help='Fill holes and save as an optional result')
379
+ parser.add_argument('-c', '--clean_threshold', type=float, default=0.1,
380
+ help='Remove outliers, e.g. 0.5 means that objects smaller than 50 percent of the size of the largest object will be removed')
381
+ parser.add_argument('-f', '--fill_threshold', type=float, default=0.9,
382
+ help='Fill holes, e.g. 0.5 means that all holes smaller than 50 percent of the entire label will be filled')
383
+ parser.add_argument('-nc', '--no_compression', action='store_true', default=False,
384
+ help='Disable compression of segmentation results')
385
+ parser.add_argument('-iid','--img_id', type=str, default=None,
386
+ help='Image ID within django environment/browser version')
387
+ parser.add_argument('-fid','--friend_id', type=str, default=None,
388
+ help='Label ID within django environment/browser version')
389
+ parser.add_argument('-r','--remote', action='store_true', default=False,
390
+ help='Process is carried out on a remote server. Must be set up in config.py')
391
+
392
+ kwargs = vars(parser.parse_args())
393
+
394
+ # main function
395
+ try:
396
+ main_helper(**kwargs)
397
+ except Exception as e:
398
+ print(traceback.format_exc())
399
+
@@ -0,0 +1,274 @@
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
+ import sys, os
30
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
31
+ sys.path.append(BASE_DIR)
32
+ from biomedisa_features.biomedisa_helper import load_data, save_data
33
+ import numpy as np
34
+ import subprocess
35
+ import platform
36
+ import glob
37
+
38
+ if __name__ == '__main__':
39
+
40
+ # path to data
41
+ path_to_data = sys.argv[1]
42
+ path_to_labels = sys.argv[2]
43
+
44
+ # get arguments
45
+ nump = 1
46
+ smooth = 0
47
+ overlap = 100
48
+ sub_z, sub_y, sub_x = 1, 1, 1
49
+ for i, val in enumerate(sys.argv):
50
+ if val in ['--split_z','-sz']:
51
+ sub_z = max(int(sys.argv[i+1]), 1)
52
+ if val in ['--split_y','-sy']:
53
+ sub_y = max(int(sys.argv[i+1]), 1)
54
+ if val in ['--split_x','-sx']:
55
+ sub_x = max(int(sys.argv[i+1]), 1)
56
+ if val in ['--overlap','-ol']:
57
+ overlap = max(int(sys.argv[i+1]), 0)
58
+ if val in ['-n','-np']:
59
+ nump = max(int(sys.argv[i+1]), 1)
60
+ if val in ['--smooth','-s']:
61
+ smooth = int(sys.argv[i+1])
62
+ uq = True if any(x in sys.argv for x in ['--uncertainty','-uq']) else False
63
+ allx = 1 if '-allx' in sys.argv else 0
64
+
65
+ # base directory
66
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
67
+
68
+ # clean tmp folder
69
+ filelist = glob.glob(BASE_DIR+'/tmp/*.tif')
70
+ for f in filelist:
71
+ os.remove(f)
72
+
73
+ # data shape
74
+ data, _ = load_data(path_to_data, 'split_volume')
75
+ shape = np.copy(np.array(data.shape), order='C')
76
+ zsh, ysh, xsh = shape
77
+ del data
78
+
79
+ # split volume
80
+ sub_size_z = np.ceil(zsh / sub_z)
81
+ sub_size_y = np.ceil(ysh / sub_y)
82
+ sub_size_x = np.ceil(xsh / sub_x)
83
+
84
+ # iterate over subvolumes
85
+ for sub_z_i in range(sub_z):
86
+ for sub_y_i in range(sub_y):
87
+ for sub_x_i in range(sub_x):
88
+ subvolume = sub_z_i*sub_y*sub_x + sub_y_i*sub_x + sub_x_i + 1
89
+ print('Subvolume:', subvolume, '/', sub_z*sub_y*sub_x)
90
+
91
+ # determine z subvolume
92
+ blockmin_z = int(sub_z_i * sub_size_z)
93
+ blockmax_z = int((sub_z_i+1) * sub_size_z)
94
+ datamin_z = max(blockmin_z - overlap, 0)
95
+ datamax_z = min(blockmax_z + overlap, zsh)
96
+
97
+ # determine y subvolume
98
+ blockmin_y = int(sub_y_i * sub_size_y)
99
+ blockmax_y = int((sub_y_i+1) * sub_size_y)
100
+ datamin_y = max(blockmin_y - overlap, 0)
101
+ datamax_y = min(blockmax_y + overlap, ysh)
102
+
103
+ # determine x subvolume
104
+ blockmin_x = int(sub_x_i * sub_size_x)
105
+ blockmax_x = int((sub_x_i+1) * sub_size_x)
106
+ datamin_x = max(blockmin_x - overlap, 0)
107
+ datamax_x = min(blockmax_x + overlap, xsh)
108
+
109
+ # extract image subvolume
110
+ data, _ = load_data(path_to_data, 'split_volume')
111
+ save_data(BASE_DIR+f'/tmp/sub_volume_{subvolume}.tif', data[datamin_z:datamax_z,datamin_y:datamax_y,datamin_x:datamax_x], False)
112
+ del data
113
+
114
+ # extract label subvolume
115
+ labelData, header, final_image_type = load_data(path_to_labels, 'split_volume', True)
116
+ save_data(BASE_DIR+'/tmp/labels.sub_volume.tif', labelData[datamin_z:datamax_z,datamin_y:datamax_y,datamin_x:datamax_x])
117
+ del labelData
118
+
119
+ # configure command
120
+ cmd = ['mpiexec', '-np', f'{nump}', 'python3', 'biomedisa_interpolation.py', BASE_DIR+f'/tmp/sub_volume_{subvolume}.tif', BASE_DIR+'/tmp/labels.sub_volume.tif', '-s', f'{smooth}']
121
+ if uq:
122
+ cmd.append('-uq')
123
+ if allx:
124
+ cmd.append('-allx')
125
+ cwd = BASE_DIR + '/demo/'
126
+
127
+ # run segmentation
128
+ if platform.system() == 'Windows':
129
+ cmd[3] = 'python'
130
+ cmd.insert(4, '-u')
131
+ p = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE)
132
+ for line in iter(p.stdout.readline, b''):
133
+ line = str(line,'utf-8')
134
+ print(line.rstrip())
135
+ p.stdout.close()
136
+ else:
137
+ p = subprocess.Popen(cmd, cwd=cwd)
138
+ p.wait()
139
+
140
+ # remove tmp files
141
+ os.remove(BASE_DIR+f'/tmp/sub_volume_{subvolume}.tif')
142
+ os.remove(BASE_DIR+'/tmp/labels.sub_volume.tif')
143
+
144
+ # create path_to_final
145
+ filename, extension = os.path.splitext(os.path.basename(path_to_data))
146
+ if extension == '.gz':
147
+ filename = filename[:-4]
148
+ filename = 'final.' + filename
149
+ path_to_final = path_to_data.replace(os.path.basename(path_to_data), filename + final_image_type)
150
+
151
+ # path_to_uq and path_to_smooth
152
+ filename, extension = os.path.splitext(path_to_final)
153
+ if extension == '.gz':
154
+ filename = filename[:-4]
155
+ path_to_smooth = filename + '.smooth' + final_image_type
156
+ path_to_uq = filename + '.uncertainty.tif'
157
+
158
+ # iterate over subvolumes
159
+ final = np.zeros((zsh, ysh, xsh), dtype=np.uint8)
160
+ for sub_z_i in range(sub_z):
161
+ for sub_y_i in range(sub_y):
162
+ for sub_x_i in range(sub_x):
163
+ subvolume = sub_z_i*sub_y*sub_x + sub_y_i*sub_x + sub_x_i + 1
164
+ print('Subvolume:', subvolume, '/', sub_z*sub_y*sub_x)
165
+
166
+ # determine z subvolume
167
+ blockmin_z = int(sub_z_i * sub_size_z)
168
+ blockmax_z = int((sub_z_i+1) * sub_size_z)
169
+ datamin_z = max(blockmin_z - overlap, 0)
170
+ datamax_z = min(blockmax_z + overlap, zsh)
171
+
172
+ # determine y subvolume
173
+ blockmin_y = int(sub_y_i * sub_size_y)
174
+ blockmax_y = int((sub_y_i+1) * sub_size_y)
175
+ datamin_y = max(blockmin_y - overlap, 0)
176
+ datamax_y = min(blockmax_y + overlap, ysh)
177
+
178
+ # determine x subvolume
179
+ blockmin_x = int(sub_x_i * sub_size_x)
180
+ blockmax_x = int((sub_x_i+1) * sub_size_x)
181
+ datamin_x = max(blockmin_x - overlap, 0)
182
+ datamax_x = min(blockmax_x + overlap, xsh)
183
+
184
+ # load subvolume
185
+ path_to_subvolume = BASE_DIR+f'/tmp/final.sub_volume_{subvolume}.tif'
186
+ if os.path.isfile(path_to_subvolume):
187
+ tmp, _ = load_data(path_to_subvolume)
188
+ final[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
189
+ = tmp[blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
190
+ os.remove(path_to_subvolume)
191
+
192
+ # save result
193
+ save_data(path_to_final, final, header)
194
+
195
+ # iterate over subvolumes (smooth)
196
+ smooth = 0
197
+ final.fill(0)
198
+ for sub_z_i in range(sub_z):
199
+ for sub_y_i in range(sub_y):
200
+ for sub_x_i in range(sub_x):
201
+ subvolume = sub_z_i*sub_y*sub_x + sub_y_i*sub_x + sub_x_i + 1
202
+ print('Subvolume:', subvolume, '/', sub_z*sub_y*sub_x)
203
+
204
+ # determine z subvolume
205
+ blockmin_z = int(sub_z_i * sub_size_z)
206
+ blockmax_z = int((sub_z_i+1) * sub_size_z)
207
+ datamin_z = max(blockmin_z - overlap, 0)
208
+ datamax_z = min(blockmax_z + overlap, zsh)
209
+
210
+ # determine y subvolume
211
+ blockmin_y = int(sub_y_i * sub_size_y)
212
+ blockmax_y = int((sub_y_i+1) * sub_size_y)
213
+ datamin_y = max(blockmin_y - overlap, 0)
214
+ datamax_y = min(blockmax_y + overlap, ysh)
215
+
216
+ # determine x subvolume
217
+ blockmin_x = int(sub_x_i * sub_size_x)
218
+ blockmax_x = int((sub_x_i+1) * sub_size_x)
219
+ datamin_x = max(blockmin_x - overlap, 0)
220
+ datamax_x = min(blockmax_x + overlap, xsh)
221
+
222
+ # load subvolume
223
+ path_to_subvolume = BASE_DIR+f'/tmp/final.sub_volume_{subvolume}.smooth.tif'
224
+ if os.path.isfile(path_to_subvolume):
225
+ tmp, _ = load_data(path_to_subvolume)
226
+ final[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
227
+ = tmp[blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
228
+ os.remove(path_to_subvolume)
229
+ smooth = 1
230
+
231
+ # save result
232
+ if smooth:
233
+ save_data(path_to_smooth, final, header)
234
+
235
+ # iterate over subvolumes (uncertainty)
236
+ uncertainty = 0
237
+ final.fill(0)
238
+ for sub_z_i in range(sub_z):
239
+ for sub_y_i in range(sub_y):
240
+ for sub_x_i in range(sub_x):
241
+ subvolume = sub_z_i*sub_y*sub_x + sub_y_i*sub_x + sub_x_i + 1
242
+ print('Subvolume:', subvolume, '/', sub_z*sub_y*sub_x)
243
+
244
+ # determine z subvolume
245
+ blockmin_z = int(sub_z_i * sub_size_z)
246
+ blockmax_z = int((sub_z_i+1) * sub_size_z)
247
+ datamin_z = max(blockmin_z - overlap, 0)
248
+ datamax_z = min(blockmax_z + overlap, zsh)
249
+
250
+ # determine y subvolume
251
+ blockmin_y = int(sub_y_i * sub_size_y)
252
+ blockmax_y = int((sub_y_i+1) * sub_size_y)
253
+ datamin_y = max(blockmin_y - overlap, 0)
254
+ datamax_y = min(blockmax_y + overlap, ysh)
255
+
256
+ # determine x subvolume
257
+ blockmin_x = int(sub_x_i * sub_size_x)
258
+ blockmax_x = int((sub_x_i+1) * sub_size_x)
259
+ datamin_x = max(blockmin_x - overlap, 0)
260
+ datamax_x = min(blockmax_x + overlap, xsh)
261
+
262
+ # load subvolume
263
+ path_to_subvolume = BASE_DIR+f'/tmp/final.sub_volume_{subvolume}.uncertainty.tif'
264
+ if os.path.isfile(path_to_subvolume):
265
+ tmp, _ = load_data(path_to_subvolume)
266
+ final[blockmin_z:blockmax_z,blockmin_y:blockmax_y,blockmin_x:blockmax_x] \
267
+ = tmp[blockmin_z-datamin_z:blockmax_z-datamin_z,blockmin_y-datamin_y:blockmax_y-datamin_y,blockmin_x-datamin_x:blockmax_x-datamin_x]
268
+ os.remove(path_to_subvolume)
269
+ uncertainty = 1
270
+
271
+ # save result
272
+ if uncertainty:
273
+ save_data(path_to_uq, final, header)
274
+