comparison tomo.py @ 48:059819ea1f0e draft

"planemo upload for repository https://github.com/rolfverberg/galaxytools commit b97c6a8f181dea6d2f9cfa2069b86d30dcc47b4d"
author rv43
date Wed, 27 Apr 2022 17:28:26 +0000
parents c693117d01e9
children 26f99fdd8d61
comparison
equal deleted inserted replaced
47:c693117d01e9 48:059819ea1f0e
1562 if self.is_valid: 1562 if self.is_valid:
1563 self.cf.saveFile(self.config_out) 1563 self.cf.saveFile(self.config_out)
1564 1564
1565 return dark_files, bright_files, tomo_stack_files 1565 return dark_files, bright_files, tomo_stack_files
1566 1566
1567 def loadTomoStacks(self, input_name): 1567 def loadTomoStacks(self, input_name, recon_flag=False):
1568 """Load tomography stacks (only for Galaxy). 1568 """Load tomography stacks (only for Galaxy).
1569 """ 1569 """
1570 assert(self.galaxy_flag) 1570 assert(self.galaxy_flag)
1571 t0 = time() 1571 t0 = time()
1572 logging.info(f'Loading preprocessed tomography stack from {input_name} ...') 1572 logging.info(f'Loading preprocessed tomography stack from {input_name} ...')
1573 stack_info = self.config['stack_info'] 1573 stack_info = self.config['stack_info']
1574 stacks = stack_info.get('stacks') 1574 stacks = stack_info.get('stacks')
1575 assert(len(self.tomo_stacks) == stack_info['num']) 1575 assert(len(self.tomo_stacks) == stack_info['num'])
1576 with np.load(input_name) as f: 1576 with np.load(input_name) as f:
1577 for i,stack in enumerate(stacks): 1577 if recon_flag:
1578 self.tomo_stacks[i] = f[f'set_{stack["index"]}'] 1578 for i,stack in enumerate(stacks):
1579 logging.info(f'loaded stack {i}: index = {stack["index"]}, shape = '+ 1579 self.tomo_recon_stacks[i] = f[f'set_{stack["index"]}']
1580 f'{self.tomo_stacks[i].shape}') 1580 logging.info(f'loaded stack {i}: index = {stack["index"]}, shape = '+
1581 f'{self.tomo_recon_stacks[i].shape}')
1582 else:
1583 for i,stack in enumerate(stacks):
1584 self.tomo_stacks[i] = f[f'set_{stack["index"]}']
1585 logging.info(f'loaded stack {i}: index = {stack["index"]}, shape = '+
1586 f'{self.tomo_stacks[i].shape}')
1581 logging.info(f'... done in {time()-t0:.2f} seconds!') 1587 logging.info(f'... done in {time()-t0:.2f} seconds!')
1582 1588
1583 def genTomoStacks(self, galaxy_param=None, num_core=None): 1589 def genTomoStacks(self, galaxy_param=None, num_core=None):
1584 """Preprocess tomography images. 1590 """Preprocess tomography images.
1585 """ 1591 """
2190 tomosum = np.sum(self.tomo_recon_stacks[0][low_bound:row_bounds[1],:,:], axis=(1,2)) 2196 tomosum = np.sum(self.tomo_recon_stacks[0][low_bound:row_bounds[1],:,:], axis=(1,2))
2191 if num_tomo_stacks > 2: 2197 if num_tomo_stacks > 2:
2192 tomosum = np.concatenate([tomosum]+ 2198 tomosum = np.concatenate([tomosum]+
2193 [np.sum(self.tomo_recon_stacks[i][row_bounds[0]:row_bounds[1],:,:], 2199 [np.sum(self.tomo_recon_stacks[i][row_bounds[0]:row_bounds[1],:,:],
2194 axis=(1,2)) for i in range(1, num_tomo_stacks-1)]) 2200 axis=(1,2)) for i in range(1, num_tomo_stacks-1)])
2195 print(f'tomosum.shape = {tomosum.shape}')
2196 if num_tomo_stacks > 1: 2201 if num_tomo_stacks > 1:
2197 tomosum = np.concatenate([tomosum, 2202 tomosum = np.concatenate([tomosum,
2198 np.sum(self.tomo_recon_stacks[num_tomo_stacks-1][row_bounds[0]:,:,:], 2203 np.sum(self.tomo_recon_stacks[num_tomo_stacks-1][row_bounds[0]:,:,:],
2199 axis=(1,2))]) 2204 axis=(1,2))])
2200 print(f'tomosum.shape = {tomosum.shape}')
2201 msnc.quickPlot(tomosum, title='recon stack sum xy', path='center_slice_pngs', 2205 msnc.quickPlot(tomosum, title='recon stack sum xy', path='center_slice_pngs',
2202 save_fig=True, save_only=True) 2206 save_fig=True, save_only=True)
2203 2207
2204 def combineTomoStacks(self): 2208 def combineTomoStacks(self, galaxy_param=None):
2205 """Combine the reconstructed tomography stacks. 2209 """Combine the reconstructed tomography stacks.
2206 """ 2210 """
2207 # stack order: stack,row(z),x,y 2211 # stack order: stack,row(z),x,y
2212 if self.galaxy_flag:
2213 assert(galaxy_param)
2214 if not os.path.exists('combine_pngs'):
2215 os.mkdir('combine_pngs')
2208 logging.debug('Combine reconstructed tomography stacks') 2216 logging.debug('Combine reconstructed tomography stacks')
2209 # Load any unloaded reconstructed stacks
2210 stack_info = self.config['stack_info'] 2217 stack_info = self.config['stack_info']
2211 stacks = stack_info['stacks'] 2218 stacks = stack_info['stacks']
2219 assert(len(self.tomo_recon_stacks) == stack_info['num'])
2220 assert(len(self.tomo_recon_stacks) == len(stacks))
2221 if self.galaxy_flag:
2222 assert(isinstance(galaxy_param, dict))
2223 # Get image bounds
2224 x_bounds = galaxy_param['x_bounds']
2225 assert(isinstance(x_bounds, list) and len(x_bounds) == 2)
2226 y_bounds = galaxy_param['y_bounds']
2227 assert(isinstance(y_bounds, list) and len(y_bounds) == 2)
2228 z_bounds = galaxy_param['z_bounds']
2229 assert(isinstance(z_bounds, list) and len(z_bounds) == 2)
2230 else:
2231 if galaxy_param:
2232 logging.warning('Ignoring galaxy_param in reconstructTomoStacks (only for Galaxy)')
2233 galaxy_param = None
2234
2235 # Load any unloaded reconstructed stacks
2212 for i,stack in enumerate(stacks): 2236 for i,stack in enumerate(stacks):
2213 available = False 2237 available = False
2214 if not self.tomo_recon_stacks[i].size and stack.get('reconstructed', False): 2238 if not self.tomo_recon_stacks[i].size and stack.get('reconstructed', False):
2215 self.tomo_recon_stacks[i], available = self._loadTomo('recon stack', 2239 self.tomo_recon_stacks[i], available = self._loadTomo('recon stack',
2216 stack['index'], required=True) 2240 stack['index'], required=True)
2234 tomosum = 0 2258 tomosum = 0
2235 #RV FIX := 2259 #RV FIX :=
2236 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,2)) for tomo_recon_stack in 2260 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,2)) for tomo_recon_stack in
2237 self.tomo_recon_stacks] 2261 self.tomo_recon_stacks]
2238 combine_stacks = self.config.get('combine_stacks') 2262 combine_stacks = self.config.get('combine_stacks')
2239 if combine_stacks and 'x_bounds' in combine_stacks: 2263 if self.galaxy_flag:
2240 x_bounds = combine_stacks['x_bounds'] 2264 if x_bounds[0] == -1:
2241 if not msnc.is_index_range(x_bounds, 0, self.tomo_recon_stacks[0].shape[1]): 2265 x_bounds[0] = 0
2242 msnc.illegal_value('x_bounds', x_bounds, 'config file') 2266 if x_bounds[1] == -1:
2243 elif not self.test_mode: 2267 x_bounds[1] = tomosum.size
2268 if not msnc.is_index_range(x_bounds, 0, tomosum.size):
2269 msnc.illegal_value('x_bounds', x_bounds, 'galaxy input')
2270 tomosum_min = tomosum.min()
2271 tomosum_max = tomosum.max()
2272 msnc.quickPlot((range(tomosum.size), tomosum),
2273 ([x_bounds[0], x_bounds[0]], [tomosum_min, tomosum_max], 'r-'),
2274 ([x_bounds[1]-1, x_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'),
2275 title=f'recon stack sum yz', path='combine_pngs', save_fig=True, save_only=True)
2276 else:
2277 if combine_stacks and 'x_bounds' in combine_stacks:
2278 x_bounds = combine_stacks['x_bounds']
2279 if not msnc.is_index_range(x_bounds, 0, tomosum.size):
2280 msnc.illegal_value('x_bounds', x_bounds, 'config file')
2281 elif not self.test_mode:
2282 msnc.quickPlot(tomosum, title='recon stack sum yz')
2283 if pyip.inputYesNo('\nCurrent image x-bounds: '+
2284 f'[{x_bounds[0]}, {x_bounds[1]}], use these values ([y]/n)? ',
2285 blank=True) == 'no':
2286 if pyip.inputYesNo(
2287 'Do you want to change the image x-bounds ([y]/n)? ',
2288 blank=True) == 'no':
2289 x_bounds = [0, tomosum.size]
2290 else:
2291 x_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz')
2292 else:
2244 msnc.quickPlot(tomosum, title='recon stack sum yz') 2293 msnc.quickPlot(tomosum, title='recon stack sum yz')
2245 if pyip.inputYesNo('\nCurrent image x-bounds: '+ 2294 if pyip.inputYesNo('\nDo you want to change the image x-bounds (y/n)? ') == 'no':
2246 f'[{x_bounds[0]}, {x_bounds[1]}], use these values ([y]/n)? ', 2295 x_bounds = [0, tomosum.size]
2247 blank=True) == 'no': 2296 else:
2248 if pyip.inputYesNo( 2297 x_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz')
2249 'Do you want to change the image x-bounds ([y]/n)? ', 2298 if False and self.test_mode:
2250 blank=True) == 'no': 2299 np.savetxt(f'{self.output_folder}/recon_stack_sum_yz.txt',
2251 x_bounds = [0, self.tomo_recon_stacks[0].shape[1]] 2300 tomosum[x_bounds[0]:x_bounds[1]], fmt='%.6e')
2252 else: 2301 if self.save_plots_only:
2253 x_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz') 2302 msnc.clearFig('recon stack sum yz')
2254 else:
2255 msnc.quickPlot(tomosum, title='recon stack sum yz')
2256 if pyip.inputYesNo('\nDo you want to change the image x-bounds (y/n)? ') == 'no':
2257 x_bounds = [0, self.tomo_recon_stacks[0].shape[1]]
2258 else:
2259 x_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz')
2260 if False and self.test_mode:
2261 np.savetxt(f'{self.output_folder}/recon_stack_sum_yz.txt',
2262 tomosum[x_bounds[0]:x_bounds[1]], fmt='%.6e')
2263 if self.save_plots_only:
2264 msnc.clearFig('recon stack sum yz')
2265 2303
2266 # Selecting y bounds (in xz-plane) 2304 # Selecting y bounds (in xz-plane)
2267 tomosum = 0 2305 tomosum = 0
2268 #RV FIX := 2306 #RV FIX :=
2269 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,1)) for tomo_recon_stack in 2307 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,1)) for tomo_recon_stack in
2270 self.tomo_recon_stacks] 2308 self.tomo_recon_stacks]
2271 if combine_stacks and 'y_bounds' in combine_stacks: 2309 if self.galaxy_flag:
2272 y_bounds = combine_stacks['y_bounds'] 2310 if y_bounds[0] == -1:
2273 if not msnc.is_index_range(y_bounds, 0, self.tomo_recon_stacks[0].shape[1]): 2311 y_bounds[0] = 0
2274 msnc.illegal_value('y_bounds', y_bounds, 'config file') 2312 if y_bounds[1] == -1:
2275 elif not self.test_mode: 2313 y_bounds[1] = tomosum.size
2314 if not msnc.is_index_range(y_bounds, 0, tomosum.size):
2315 msnc.illegal_value('y_bounds', y_bounds, 'galaxy input')
2316 tomosum_min = tomosum.min()
2317 tomosum_max = tomosum.max()
2318 msnc.quickPlot((range(tomosum.size), tomosum),
2319 ([y_bounds[0], y_bounds[0]], [tomosum_min, tomosum_max], 'r-'),
2320 ([y_bounds[1]-1, y_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'),
2321 title=f'recon stack sum xz', path='combine_pngs', save_fig=True, save_only=True)
2322 else:
2323 if combine_stacks and 'y_bounds' in combine_stacks:
2324 y_bounds = combine_stacks['y_bounds']
2325 if not msnc.is_index_range(y_bounds, 0, tomosum.size):
2326 msnc.illegal_value('y_bounds', y_bounds, 'config file')
2327 elif not self.test_mode:
2328 msnc.quickPlot(tomosum, title='recon stack sum xz')
2329 if pyip.inputYesNo('\nCurrent image y-bounds: '+
2330 f'[{y_bounds[0]}, {y_bounds[1]}], use these values ([y]/n)? ',
2331 blank=True) == 'no':
2332 if pyip.inputYesNo(
2333 'Do you want to change the image y-bounds ([y]/n)? ',
2334 blank=True) == 'no':
2335 y_bounds = [0, tomosum.size]
2336 else:
2337 y_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz')
2338 else:
2276 msnc.quickPlot(tomosum, title='recon stack sum xz') 2339 msnc.quickPlot(tomosum, title='recon stack sum xz')
2277 if pyip.inputYesNo('\nCurrent image y-bounds: '+ 2340 if pyip.inputYesNo('\nDo you want to change the image y-bounds (y/n)? ') == 'no':
2278 f'[{y_bounds[0]}, {y_bounds[1]}], use these values ([y]/n)? ', 2341 y_bounds = [0, tomosum.size]
2279 blank=True) == 'no': 2342 else:
2280 if pyip.inputYesNo( 2343 y_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum xz')
2281 'Do you want to change the image y-bounds ([y]/n)? ', 2344 if False and self.test_mode:
2282 blank=True) == 'no': 2345 np.savetxt(f'{self.output_folder}/recon_stack_sum_xz.txt',
2283 y_bounds = [0, self.tomo_recon_stacks[0].shape[1]] 2346 tomosum[y_bounds[0]:y_bounds[1]], fmt='%.6e')
2284 else: 2347 if self.save_plots_only:
2285 y_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum yz') 2348 msnc.clearFig('recon stack sum xz')
2286 else:
2287 msnc.quickPlot(tomosum, title='recon stack sum xz')
2288 if pyip.inputYesNo('\nDo you want to change the image y-bounds (y/n)? ') == 'no':
2289 y_bounds = [0, self.tomo_recon_stacks[0].shape[1]]
2290 else:
2291 y_bounds = msnc.selectArrayBounds(tomosum, title='recon stack sum xz')
2292 if False and self.test_mode:
2293 np.savetxt(f'{self.output_folder}/recon_stack_sum_xz.txt',
2294 tomosum[y_bounds[0]:y_bounds[1]], fmt='%.6e')
2295 if self.save_plots_only:
2296 msnc.clearFig('recon stack sum xz')
2297 2349
2298 # Combine reconstructed tomography stacks 2350 # Combine reconstructed tomography stacks
2299 logging.info(f'Combining reconstructed stacks ...') 2351 logging.info(f'Combining reconstructed stacks ...')
2300 t0 = time() 2352 t0 = time()
2301 num_tomo_stacks = stack_info['num'] 2353 num_tomo_stacks = len(stacks)
2302 if num_tomo_stacks == 1: 2354 if num_tomo_stacks == 1:
2303 low_bound = row_bounds[0] 2355 low_bound = row_bounds[0]
2304 else: 2356 else:
2305 low_bound = 0 2357 low_bound = 0
2306 tomo_recon_combined = self.tomo_recon_stacks[0][low_bound:row_bounds[1], 2358 tomo_recon_combined = self.tomo_recon_stacks[0][low_bound:row_bounds[1],
2331 save_only=self.save_plots_only) 2383 save_only=self.save_plots_only)
2332 if False: 2384 if False:
2333 np.savetxt(f'{self.output_folder}/recon_combined_sum_xy.txt', 2385 np.savetxt(f'{self.output_folder}/recon_combined_sum_xy.txt',
2334 tomosum, fmt='%.6e') 2386 tomosum, fmt='%.6e')
2335 np.savetxt(f'{self.output_folder}/recon_combined.txt', 2387 np.savetxt(f'{self.output_folder}/recon_combined.txt',
2336 tomo_recon_combined[int(tomo_recon_combined.shape[0]/2),:,:], fmt='%.6e') 2388 tomo_recon_combined[int(tomosum.size/2),:,:], fmt='%.6e')
2337 2389
2338 # Update config and save to file 2390 # Update config and save to file
2339 if combine_stacks: 2391 if combine_stacks:
2340 combine_stacks['x_bounds'] = x_bounds 2392 combine_stacks['x_bounds'] = x_bounds
2341 combine_stacks['y_bounds'] = y_bounds 2393 combine_stacks['y_bounds'] = y_bounds
2345 'stacks' : combined_stacks} 2397 'stacks' : combined_stacks}
2346 self.cf.saveFile(self.config_out) 2398 self.cf.saveFile(self.config_out)
2347 return 2399 return
2348 2400
2349 # Selecting z bounds (in xy-plane) 2401 # Selecting z bounds (in xy-plane)
2350 msnc.quickPlot(tomosum, title='recon combined sum xy') 2402 if self.galaxy_flag:
2351 if pyip.inputYesNo( 2403 if z_bounds[0] == -1:
2352 '\nDo you want to change the image z-bounds (y/[n])? ', 2404 z_bounds[0] = 0
2353 blank=True) != 'yes': 2405 if z_bounds[1] == -1:
2354 z_bounds = [0, tomo_recon_combined.shape[0]] 2406 z_bounds[1] = tomosum.size
2355 else: 2407 if not msnc.is_index_range(z_bounds, 0, tomosum.size):
2356 z_bounds = msnc.selectArrayBounds(tomosum, title='recon combined sum xy') 2408 msnc.illegal_value('z_bounds', z_bounds, 'galaxy input')
2357 if z_bounds[0] != 0 or z_bounds[1] != tomo_recon_combined.shape[0]: 2409 tomosum_min = tomosum.min()
2410 tomosum_max = tomosum.max()
2411 msnc.quickPlot((range(tomosum.size), tomosum),
2412 ([z_bounds[0], z_bounds[0]], [tomosum_min, tomosum_max], 'r-'),
2413 ([z_bounds[1]-1, z_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'),
2414 title=f'recon stack sum xy', path='combine_pngs', save_fig=True, save_only=True)
2415 else:
2416 msnc.quickPlot(tomosum, title='recon combined sum xy')
2417 if pyip.inputYesNo(
2418 '\nDo you want to change the image z-bounds (y/[n])? ',
2419 blank=True) != 'yes':
2420 z_bounds = [0, tomosum.size]
2421 else:
2422 z_bounds = msnc.selectArrayBounds(tomosum, title='recon combined sum xy')
2423 if self.save_plots_only:
2424 msnc.clearFig('recon combined sum xy')
2425 if z_bounds[0] != 0 or z_bounds[1] != tomosum.size:
2358 tomo_recon_combined = tomo_recon_combined[z_bounds[0]:z_bounds[1],:,:] 2426 tomo_recon_combined = tomo_recon_combined[z_bounds[0]:z_bounds[1],:,:]
2359 if self.save_plots_only:
2360 msnc.clearFig('recon combined sum xy')
2361 2427
2362 # Plot center slices 2428 # Plot center slices
2429 if self.galaxy_flag:
2430 path = 'combine_pngs'
2431 save_fig = True
2432 save_only = True
2433 else:
2434 path = self.output_folder
2435 save_fig = self.save_plots
2436 save_only = self.save_plots_only
2363 msnc.quickImshow(tomo_recon_combined[int(tomo_recon_combined.shape[0]/2),:,:], 2437 msnc.quickImshow(tomo_recon_combined[int(tomo_recon_combined.shape[0]/2),:,:],
2364 title=f'recon combined xslice{int(tomo_recon_combined.shape[0]/2)}', 2438 title=f'recon combined xslice{int(tomo_recon_combined.shape[0]/2)}',
2365 path=self.output_folder, save_fig=self.save_plots, 2439 path=path, save_fig=save_fig, save_only=save_only)
2366 save_only=self.save_plots_only)
2367 msnc.quickImshow(tomo_recon_combined[:,int(tomo_recon_combined.shape[1]/2),:], 2440 msnc.quickImshow(tomo_recon_combined[:,int(tomo_recon_combined.shape[1]/2),:],
2368 title=f'recon combined yslice{int(tomo_recon_combined.shape[1]/2)}', 2441 title=f'recon combined yslice{int(tomo_recon_combined.shape[1]/2)}',
2369 path=self.output_folder, save_fig=self.save_plots, 2442 path=path, save_fig=save_fig, save_only=save_only)
2370 save_only=self.save_plots_only)
2371 msnc.quickImshow(tomo_recon_combined[:,:,int(tomo_recon_combined.shape[2]/2)], 2443 msnc.quickImshow(tomo_recon_combined[:,:,int(tomo_recon_combined.shape[2]/2)],
2372 title=f'recon combined zslice{int(tomo_recon_combined.shape[2]/2)}', 2444 title=f'recon combined zslice{int(tomo_recon_combined.shape[2]/2)}',
2373 path=self.output_folder, save_fig=self.save_plots, 2445 path=path, save_fig=save_fig, save_only=save_only)
2374 save_only=self.save_plots_only) 2446
2375 2447 # Save combined reconstructed tomography stack to file
2376 # Save combined reconstructed tomo stacks 2448 if self.galaxy_flag:
2377 base_name = 'recon combined' 2449 t0 = time()
2378 for stack in stacks: 2450 output_name = galaxy_param['output_name']
2379 base_name += f' {stack["index"]}' 2451 logging.info(f'Saving combined reconstructed tomography stack to {output_name} ...')
2380 self._saveTomo(base_name, tomo_recon_combined) 2452 np.save(output_name, tomo_recon_combined)
2453 logging.info(f'... done in {time()-t0:.2f} seconds!')
2454 else:
2455 base_name = 'recon combined'
2456 for stack in stacks:
2457 base_name += f' {stack["index"]}'
2458 self._saveTomo(base_name, tomo_recon_combined)
2381 2459
2382 # Update config and save to file 2460 # Update config and save to file
2383 if combine_stacks: 2461 if combine_stacks:
2384 combine_stacks['x_bounds'] = x_bounds 2462 combine_stacks['x_bounds'] = x_bounds
2385 combine_stacks['y_bounds'] = y_bounds 2463 combine_stacks['y_bounds'] = y_bounds