Mercurial > repos > rv43 > tomo
comparison tomo.py @ 61:75dd6e15f628 draft
"planemo upload for repository https://github.com/rolfverberg/galaxytools commit 47b7bc203de6eac4d3e081b1fae8acb352f54b55"
| author | rv43 |
|---|---|
| date | Wed, 17 Aug 2022 12:11:20 +0000 |
| parents | 26f99fdd8d61 |
| children | 98a83f03d91b |
comparison
equal
deleted
inserted
replaced
| 60:52db7707ff48 | 61:75dd6e15f628 |
|---|---|
| 43 from fit import Fit | 43 from fit import Fit |
| 44 #from msnctools.general import illegal_value, is_int, is_num, is_index_range, get_trailing_int, \ | 44 #from msnctools.general import illegal_value, is_int, is_num, is_index_range, get_trailing_int, \ |
| 45 from general import illegal_value, is_int, is_num, is_index_range, get_trailing_int, \ | 45 from general import illegal_value, is_int, is_num, is_index_range, get_trailing_int, \ |
| 46 input_int, input_num, input_yesno, input_menu, findImageFiles, loadImageStack, clearPlot, \ | 46 input_int, input_num, input_yesno, input_menu, findImageFiles, loadImageStack, clearPlot, \ |
| 47 draw_mask_1d, quickPlot, clearImshow, quickImshow, combine_tiffs_in_h5, Config | 47 draw_mask_1d, quickPlot, clearImshow, quickImshow, combine_tiffs_in_h5, Config |
| 48 from general import selectArrayBounds,selectImageRange, selectImageBounds | 48 from general import selectImageRange, selectImageBounds |
| 49 | 49 |
| 50 # the following tomopy routines don't run with more than 24 cores on Galaxy-Dev | 50 # the following tomopy routines don't run with more than 24 cores on Galaxy-Dev |
| 51 # - tomopy.find_center_vo | 51 # - tomopy.find_center_vo |
| 52 # - tomopy.prep.stripe.remove_stripe_fw | 52 # - tomopy.prep.stripe.remove_stripe_fw |
| 53 num_core_tomopy_limit = 24 | 53 num_core_tomopy_limit = 24 |
| 427 # Validate input parameters | 427 # Validate input parameters |
| 428 if config_file is not None and not os.path.isfile(config_file): | 428 if config_file is not None and not os.path.isfile(config_file): |
| 429 raise OSError(f'Invalid config_file input {config_file} {type(config_file)}') | 429 raise OSError(f'Invalid config_file input {config_file} {type(config_file)}') |
| 430 if config_dict is not None and not isinstance(config_dict, dict): | 430 if config_dict is not None and not isinstance(config_dict, dict): |
| 431 raise ValueError(f'Invalid config_dict input {config_dict} {type(config_dict)}') | 431 raise ValueError(f'Invalid config_dict input {config_dict} {type(config_dict)}') |
| 432 if config_out is not None: | 432 if self.config_out is not None and not isinstance(self.config_out, str): |
| 433 if isinstance(config_out, str): | 433 raise OSError(f'Invalid config_out input {self.config_out} {type(self.config_out)}') |
| 434 if isinstance(log_stream, str): | |
| 435 path = os.path.split(log_stream)[0] | |
| 436 if path and not os.path.isdir(path): | |
| 437 raise OSError(f'Invalid log_stream path') | |
| 438 else: | |
| 439 raise OSError(f'Invalid config_out input {config_out} {type(config_out)}') | |
| 440 if not os.path.isdir(output_folder): | 434 if not os.path.isdir(output_folder): |
| 441 os.mkdir(os.path.abspath(output_folder)) | 435 os.mkdir(os.path.abspath(output_folder)) |
| 442 if isinstance(log_stream, str): | 436 if isinstance(log_stream, str): |
| 443 path = os.path.split(log_stream)[0] | 437 path = os.path.split(log_stream)[0] |
| 444 if path and not os.path.isdir(path): | 438 if path and not os.path.isdir(path): |
| 445 raise OSError(f'Invalid log_stream path') | 439 raise OSError(f'Invalid log_stream path') |
| 446 if not os.path.isabs(path): | 440 if not os.path.isabs(path): |
| 447 log_stream = f'{output_folder}/{log_stream}' | 441 log_stream = f'{output_folder}/{log_stream}' |
| 448 if not isinstance(galaxy_flag, bool): | 442 if not isinstance(galaxy_flag, bool): |
| 449 raise ValueError(f'Invalid galaxy_flag input {galaxy_flag} {type(galaxy_flag)}') | 443 raise ValueError(f'Invalid galaxy_flag input {galaxy_flag} {type(galaxy_flag)}') |
| 450 if not isinstance(test_mode, bool): | 444 if not isinstance(self.test_mode, bool): |
| 451 raise ValueError(f'Invalid test_mode input {test_mode} {type(test_mode)}') | 445 raise ValueError(f'Invalid test_mode input {self.test_mode} {type(self.test_mode)}') |
| 452 if not isinstance(num_core, int) or num_core < -1 or num_core == 0: | 446 if not isinstance(num_core, int) or num_core < -1 or num_core == 0: |
| 453 raise ValueError(f'Invalid num_core input {num_core} {type(num_core)}') | 447 raise ValueError(f'Invalid num_core input {num_core} {type(num_core)}') |
| 454 if num_core == -1: | 448 if num_core == -1: |
| 455 self.num_core = mp.cpu_count() | 449 self.num_core = mp.cpu_count() |
| 456 else: | 450 else: |
| 663 | 657 |
| 664 # Take median | 658 # Take median |
| 665 self.tdf = np.median(tdf_stack, axis=0) | 659 self.tdf = np.median(tdf_stack, axis=0) |
| 666 del tdf_stack | 660 del tdf_stack |
| 667 | 661 |
| 668 # RV make input of some kind (not always needed) | 662 # Remove dark field intensities above the cutoff |
| 669 tdf_cutoff = 21 | 663 tdf_cutoff = dark_field.get('cutoff') |
| 670 self.tdf[self.tdf > tdf_cutoff] = np.nan | 664 if tdf_cutoff is not None: |
| 665 if not is_num(tdf_cutoff, 0): | |
| 666 logging.warning(f'Ignoring illegal value of tdf_cutoff {tdf_cutoff}') | |
| 667 else: | |
| 668 self.tdf[self.tdf > tdf_cutoff] = np.nan | |
| 669 logging.debug(f'tdf_cutoff = {tdf_cutoff}') | |
| 670 | |
| 671 tdf_mean = np.nanmean(self.tdf) | 671 tdf_mean = np.nanmean(self.tdf) |
| 672 logging.debug(f'tdf_cutoff = {tdf_cutoff}') | |
| 673 logging.debug(f'tdf_mean = {tdf_mean}') | 672 logging.debug(f'tdf_mean = {tdf_mean}') |
| 674 np.nan_to_num(self.tdf, copy=False, nan=tdf_mean, posinf=tdf_mean, neginf=0.) | 673 np.nan_to_num(self.tdf, copy=False, nan=tdf_mean, posinf=tdf_mean, neginf=0.) |
| 675 if self.galaxy_flag: | 674 if self.galaxy_flag: |
| 676 quickImshow(self.tdf, title='dark field', path='setup_pngs', | 675 quickImshow(self.tdf, title='dark field', path='setup_pngs', |
| 677 save_fig=True, save_only=True) | 676 save_fig=True, save_only=True) |
| 1240 t0 = time() | 1239 t0 = time() |
| 1241 recon_sinogram = iradon(sinogram, theta=thetas_deg, circle=True) | 1240 recon_sinogram = iradon(sinogram, theta=thetas_deg, circle=True) |
| 1242 logging.debug(f'inverting sinogram took {time()-t0:.2f} seconds!') | 1241 logging.debug(f'inverting sinogram took {time()-t0:.2f} seconds!') |
| 1243 del sinogram | 1242 del sinogram |
| 1244 | 1243 |
| 1245 # Removing ring artifacts | 1244 # Performing Gaussian filtering and removing ring artifacts |
| 1246 # RV parameters for the denoise, gaussian, and ring removal will be different for different feature sizes | 1245 recon_parameters = self.config.get('recon_parameters') |
| 1246 if recon_parameters is None: | |
| 1247 sigma = 1.0 | |
| 1248 ring_width = 15 | |
| 1249 else: | |
| 1250 sigma = recon_parameters.get('gaussian_sigma', 1.0) | |
| 1251 if not is_num(sigma, 0.0): | |
| 1252 logging.warning(f'Illegal gaussian_sigma ({sigma}) in _reconstructOnePlane, '+ | |
| 1253 'set to a default value of 1.0') | |
| 1254 sigma = 1.0 | |
| 1255 ring_width = recon_parameters.get('ring_width', 15) | |
| 1256 if not is_int(ring_width, 0): | |
| 1257 logging.warning(f'Illegal ring_width ({ring_width}) in _reconstructOnePlane, '+ | |
| 1258 'set to a default value of 15') | |
| 1259 ring_width = 15 | |
| 1247 t0 = time() | 1260 t0 = time() |
| 1248 # recon_sinogram = filters.gaussian(recon_sinogram, 3.0) | 1261 recon_sinogram = spi.gaussian_filter(recon_sinogram, sigma, mode='nearest') |
| 1249 recon_sinogram = spi.gaussian_filter(recon_sinogram, 0.5) | |
| 1250 recon_clean = np.expand_dims(recon_sinogram, axis=0) | 1262 recon_clean = np.expand_dims(recon_sinogram, axis=0) |
| 1251 del recon_sinogram | 1263 del recon_sinogram |
| 1252 t1 = time() | 1264 t1 = time() |
| 1253 logging.debug(f'running remove_ring on {num_core} cores ...') | 1265 logging.debug(f'running remove_ring on {num_core} cores ...') |
| 1254 recon_clean = tomopy.misc.corr.remove_ring(recon_clean, rwidth=17, ncore=num_core) | 1266 recon_clean = tomopy.misc.corr.remove_ring(recon_clean, rwidth=ring_width, ncore=num_core) |
| 1255 logging.debug(f'... remove_ring took {time()-t1:.2f} seconds!') | 1267 logging.debug(f'... remove_ring took {time()-t1:.2f} seconds!') |
| 1256 logging.debug(f'filtering and removing ring artifact took {time()-t0:.2f} seconds!') | 1268 logging.debug(f'filtering and removing ring artifact took {time()-t0:.2f} seconds!') |
| 1257 return recon_clean | 1269 return recon_clean |
| 1258 | 1270 |
| 1259 def _plotEdgesOnePlane(self, recon_plane, title, path=None, weight=0.001): | 1271 def _plotEdgesOnePlane(self, recon_plane, title, path=None): |
| 1260 # RV parameters for the denoise, gaussian, and ring removal will be different for different feature sizes | 1272 vis_parameters = self.config.get('vis_parameters') |
| 1261 edges = denoise_tv_chambolle(recon_plane, weight = weight) | 1273 if vis_parameters is None: |
| 1274 weight = 0.1 | |
| 1275 else: | |
| 1276 weight = vis_parameters.get('denoise_weight', 0.1) | |
| 1277 if not is_num(weight, 0.0): | |
| 1278 logging.warning(f'Illegal weight ({weight}) in _plotEdgesOnePlane, '+ | |
| 1279 'set to a default value of 0.1') | |
| 1280 weight = 0.1 | |
| 1281 edges = denoise_tv_chambolle(recon_plane, weight=weight) | |
| 1262 vmax = np.max(edges[0,:,:]) | 1282 vmax = np.max(edges[0,:,:]) |
| 1263 vmin = -vmax | 1283 vmin = -vmax |
| 1264 if self.galaxy_flag: | 1284 if self.galaxy_flag: |
| 1265 quickImshow(edges[0,:,:], title, path=path, save_fig=True, save_only=True, | 1285 quickImshow(edges[0,:,:], title, path=path, save_fig=True, save_only=True, |
| 1266 cmap='gray', vmin=vmin, vmax=vmax) | 1286 cmap='gray', vmin=vmin, vmax=vmax) |
| 1393 center_offset = center_offset_vo | 1413 center_offset = center_offset_vo |
| 1394 else: | 1414 else: |
| 1395 center_offset = input_num(' Enter chosen center offset', -center, center) | 1415 center_offset = input_num(' Enter chosen center offset', -center, center) |
| 1396 return float(center_offset) | 1416 return float(center_offset) |
| 1397 | 1417 |
| 1398 def _reconstructOneTomoStack(self, tomo_stack, thetas, row_bounds=None, | 1418 def _reconstructOneTomoStack(self, tomo_stack, thetas, row_bounds=None, center_offsets=[], |
| 1399 center_offsets=[], sigma=0.1, rwidth=30, num_core=1, algorithm='gridrec', | 1419 num_core=1, algorithm='gridrec'): |
| 1400 run_secondary_sirt=False, secondary_iter=100): | |
| 1401 """reconstruct a single tomography stack. | 1420 """reconstruct a single tomography stack. |
| 1402 """ | 1421 """ |
| 1403 # stack order: row,theta,column | 1422 # stack order: row,theta,column |
| 1404 # thetas must be in radians | 1423 # thetas must be in radians |
| 1405 # centers_offset: tomography axis shift in pixels relative to column center | 1424 # centers_offset: tomography axis shift in pixels relative to column center |
| 1423 else: | 1442 else: |
| 1424 if center_offsets.size != row_bounds[1]-row_bounds[0]: | 1443 if center_offsets.size != row_bounds[1]-row_bounds[0]: |
| 1425 raise ValueError('center_offsets dimension mismatch in reconstructOneTomoStack') | 1444 raise ValueError('center_offsets dimension mismatch in reconstructOneTomoStack') |
| 1426 centers = center_offsets | 1445 centers = center_offsets |
| 1427 centers += tomo_stack.shape[2]/2 | 1446 centers += tomo_stack.shape[2]/2 |
| 1447 | |
| 1448 # Removing horizontal stripe and ring artifacts and perform secondary iterations | |
| 1449 recon_parameters = self.config.get('recon_parameters') | |
| 1450 if recon_parameters is None: | |
| 1451 sigma = 2.0 | |
| 1452 secondary_iters = 0 | |
| 1453 ring_width = 15 | |
| 1454 else: | |
| 1455 sigma = recon_parameters.get('stripe_fw_sigma', 2.0) | |
| 1456 if not is_num(sigma, 0): | |
| 1457 logging.warning(f'Illegal stripe_fw_sigma ({sigma}) in '+ | |
| 1458 '_reconstructOneTomoStack, set to a default value of 2.0') | |
| 1459 ring_width = 15 | |
| 1460 secondary_iters = recon_parameters.get('secondary_iters', 0) | |
| 1461 if not is_int(secondary_iters, 0): | |
| 1462 logging.warning(f'Illegal secondary_iters ({secondary_iters}) in '+ | |
| 1463 '_reconstructOneTomoStack, set to a default value of 0 (skip them)') | |
| 1464 ring_width = 0 | |
| 1465 ring_width = recon_parameters.get('ring_width', 15) | |
| 1466 if not is_int(ring_width, 0): | |
| 1467 logging.warning(f'Illegal ring_width ({ring_width}) in _reconstructOnePlane, '+ | |
| 1468 'set to a default value of 15') | |
| 1469 ring_width = 15 | |
| 1428 if True: | 1470 if True: |
| 1429 t0 = time() | 1471 t0 = time() |
| 1430 if num_core > num_core_tomopy_limit: | 1472 if num_core > num_core_tomopy_limit: |
| 1431 logging.debug('running remove_stripe_fw on {num_core_tomopy_limit} cores ...') | 1473 logging.debug('running remove_stripe_fw on {num_core_tomopy_limit} cores ...') |
| 1432 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( | 1474 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( |
| 1443 t0 = time() | 1485 t0 = time() |
| 1444 logging.debug(f'running recon on {num_core} cores ...') | 1486 logging.debug(f'running recon on {num_core} cores ...') |
| 1445 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, sinogram_order=True, | 1487 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, sinogram_order=True, |
| 1446 algorithm=algorithm, ncore=num_core) | 1488 algorithm=algorithm, ncore=num_core) |
| 1447 logging.debug(f'... recon took {time()-t0:.2f} seconds!') | 1489 logging.debug(f'... recon took {time()-t0:.2f} seconds!') |
| 1448 if run_secondary_sirt and secondary_iter > 0: | 1490 if secondary_iters > 0: |
| 1449 logging.debug(f'running {secondary_iter} secondary iterations') | 1491 logging.debug(f'running {secondary_iters} secondary iterations') |
| 1450 #options = {'method':'SIRT_CUDA', 'proj_type':'cuda', 'num_iter':secondary_iter} | 1492 #options = {'method':'SIRT_CUDA', 'proj_type':'cuda', 'num_iter':secondary_iters} |
| 1451 #RV: doesn't work for me: "Error: CUDA error 803: system has unsupported display driver / | 1493 #RV: doesn't work for me: "Error: CUDA error 803: system has unsupported display driver / |
| 1452 # cuda driver combination." | 1494 # cuda driver combination." |
| 1453 #options = {'method':'SIRT', 'proj_type':'linear', 'MinConstraint': 0, 'num_iter':secondary_iter} | 1495 #options = {'method':'SIRT', 'proj_type':'linear', 'MinConstraint': 0, 'num_iter':secondary_iters} |
| 1454 #SIRT did not finish while running overnight | 1496 #SIRT did not finish while running overnight |
| 1455 #options = {'method':'SART', 'proj_type':'linear', 'num_iter':secondary_iter} | 1497 #options = {'method':'SART', 'proj_type':'linear', 'num_iter':secondary_iters} |
| 1456 options = {'method':'SART', 'proj_type':'linear', 'MinConstraint': 0, | 1498 options = {'method':'SART', 'proj_type':'linear', 'MinConstraint': 0, |
| 1457 'num_iter':secondary_iter} | 1499 'num_iter':secondary_iters} |
| 1458 t0 = time() | 1500 t0 = time() |
| 1459 logging.debug(f'running recon on {num_core} cores ...') | 1501 logging.debug(f'running recon on {num_core} cores ...') |
| 1460 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, | 1502 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, |
| 1461 init_recon=tomo_recon_stack, options=options, sinogram_order=True, | 1503 init_recon=tomo_recon_stack, options=options, sinogram_order=True, |
| 1462 algorithm=tomopy.astra, ncore=num_core) | 1504 algorithm=tomopy.astra, ncore=num_core) |
| 1463 logging.debug(f'... recon took {time()-t0:.2f} seconds!') | 1505 logging.debug(f'... recon took {time()-t0:.2f} seconds!') |
| 1464 if True: | 1506 if True: |
| 1465 t0 = time() | 1507 t0 = time() |
| 1466 logging.debug(f'running remove_ring on {num_core} cores ...') | 1508 logging.debug(f'running remove_ring on {num_core} cores ...') |
| 1467 tomopy.misc.corr.remove_ring(tomo_recon_stack, rwidth=rwidth, out=tomo_recon_stack, | 1509 tomopy.misc.corr.remove_ring(tomo_recon_stack, rwidth=ring_width, out=tomo_recon_stack, |
| 1468 ncore=num_core) | 1510 ncore=num_core) |
| 1469 logging.debug(f'... remove_ring took {time()-t0:.2f} seconds!') | 1511 logging.debug(f'... remove_ring took {time()-t0:.2f} seconds!') |
| 1470 return tomo_recon_stack | 1512 return tomo_recon_stack |
| 1471 | 1513 |
| 1472 def findImageFiles(self, tiff_to_h5_flag = False): | 1514 def findImageFiles(self, tiff_to_h5_flag = False): |
| 1621 logging.warning('Ignoring galaxy_param in genTomoStacks (only for Galaxy)') | 1663 logging.warning('Ignoring galaxy_param in genTomoStacks (only for Galaxy)') |
| 1622 galaxy_param = None | 1664 galaxy_param = None |
| 1623 tdf_files, tbf_files, tomo_stack_files = self.findImageFiles() | 1665 tdf_files, tbf_files, tomo_stack_files = self.findImageFiles() |
| 1624 if not self.is_valid: | 1666 if not self.is_valid: |
| 1625 return | 1667 return |
| 1668 if self.test_mode: | |
| 1669 required = True | |
| 1670 else: | |
| 1671 required = False | |
| 1626 for i,stack in enumerate(stacks): | 1672 for i,stack in enumerate(stacks): |
| 1627 if not self.tomo_stacks[i].size and stack.get('preprocessed', False): | 1673 if not self.tomo_stacks[i].size and stack.get('preprocessed', False): |
| 1628 self.tomo_stacks[i], available_stacks[i] = \ | 1674 self.tomo_stacks[i], available_stacks[i] = \ |
| 1629 self._loadTomo('red stack', stack['index']) | 1675 self._loadTomo('red stack', stack['index'], required=required) |
| 1630 | 1676 |
| 1631 # Preprocess any unloaded stacks | 1677 # Preprocess any unloaded stacks |
| 1632 if False in available_stacks: | 1678 if False in available_stacks: |
| 1633 logging.debug('Preprocessing tomography images') | 1679 logging.debug('Preprocessing tomography images') |
| 1634 | 1680 |
| 1926 if self.save_plots_only: | 1972 if self.save_plots_only: |
| 1927 clearImshow(f'theta={theta_start}') | 1973 clearImshow(f'theta={theta_start}') |
| 1928 if use_row: | 1974 if use_row: |
| 1929 center_offset = find_center.get('upper_center_offset') | 1975 center_offset = find_center.get('upper_center_offset') |
| 1930 if is_num(center_offset): | 1976 if is_num(center_offset): |
| 1931 use_center = input_yesrnNo('Current upper center offset = '+ | 1977 use_center = input_yesno('Current upper center offset = '+ |
| 1932 f'{center_offset}, use this value (y/n)?', 'y') | 1978 f'{center_offset}, use this value (y/n)?', 'y') |
| 1933 if not use_center: | 1979 if not use_center: |
| 1934 if not use_row: | 1980 if not use_row: |
| 1935 if not self.test_mode: | 1981 if not self.test_mode: |
| 1936 quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', | 1982 quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', |
| 2126 center_offsets = [lower_center_offset-lower_row*center_slope, | 2172 center_offsets = [lower_center_offset-lower_row*center_slope, |
| 2127 upper_center_offset+(self.tomo_stacks[i].shape[0]-1-upper_row)*center_slope] | 2173 upper_center_offset+(self.tomo_stacks[i].shape[0]-1-upper_row)*center_slope] |
| 2128 t0 = time() | 2174 t0 = time() |
| 2129 logging.debug(f'running _reconstructOneTomoStack on {num_core} cores ...') | 2175 logging.debug(f'running _reconstructOneTomoStack on {num_core} cores ...') |
| 2130 self.tomo_recon_stacks[i]= self._reconstructOneTomoStack(self.tomo_stacks[i], | 2176 self.tomo_recon_stacks[i]= self._reconstructOneTomoStack(self.tomo_stacks[i], |
| 2131 thetas, center_offsets=center_offsets, sigma=0.1, num_core=num_core, | 2177 thetas, center_offsets=center_offsets, num_core=num_core, |
| 2132 algorithm='gridrec', run_secondary_sirt=True, secondary_iter=25) | 2178 algorithm='gridrec') |
| 2133 logging.debug(f'... _reconstructOneTomoStack took {time()-t0:.2f} seconds!') | 2179 logging.debug(f'... _reconstructOneTomoStack took {time()-t0:.2f} seconds!') |
| 2134 logging.info(f'Reconstruction of stack {index} took {time()-t0:.2f} seconds!') | 2180 logging.info(f'Reconstruction of stack {index} took {time()-t0:.2f} seconds!') |
| 2135 if self.galaxy_flag: | 2181 if self.galaxy_flag: |
| 2136 x_slice = int(self.tomo_stacks[i].shape[0]/2) | 2182 x_slice = int(self.tomo_recon_stacks[i].shape[0]/2) |
| 2137 title = f'{basetitle} {index} xslice{x_slice}' | 2183 title = f'{basetitle} {index} xslice{x_slice}' |
| 2138 quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, | 2184 quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, |
| 2139 path='center_slice_pngs', save_fig=True, save_only=True) | 2185 path='center_slice_pngs', save_fig=True, save_only=True) |
| 2140 y_slice = int(self.tomo_stacks[i].shape[0]/2) | 2186 y_slice = int(self.tomo_recon_stacks[i].shape[1]/2) |
| 2141 title = f'{basetitle} {index} yslice{y_slice}' | 2187 title = f'{basetitle} {index} yslice{y_slice}' |
| 2142 quickImshow(self.tomo_recon_stacks[i][:,y_slice,:], title=title, | 2188 quickImshow(self.tomo_recon_stacks[i][:,y_slice,:], title=title, |
| 2143 path='center_slice_pngs', save_fig=True, save_only=True) | 2189 path='center_slice_pngs', save_fig=True, save_only=True) |
| 2144 z_slice = int(self.tomo_stacks[i].shape[0]/2) | 2190 z_slice = int(self.tomo_recon_stacks[i].shape[2]/2) |
| 2145 title = f'{basetitle} {index} zslice{z_slice}' | 2191 title = f'{basetitle} {index} zslice{z_slice}' |
| 2146 quickImshow(self.tomo_recon_stacks[i][:,:,z_slice], title=title, | 2192 quickImshow(self.tomo_recon_stacks[i][:,:,z_slice], title=title, |
| 2147 path='center_slice_pngs', save_fig=True, save_only=True) | 2193 path='center_slice_pngs', save_fig=True, save_only=True) |
| 2148 elif not self.test_mode: | 2194 else: |
| 2149 x_slice = int(self.tomo_stacks[i].shape[0]/2) | 2195 x_slice = int(self.tomo_recon_stacks[i].shape[0]/2) |
| 2150 title = f'{basetitle} {index} xslice{x_slice}' | 2196 title = f'{basetitle} {index} xslice{x_slice}' |
| 2151 quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, | 2197 quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, |
| 2152 path=self.output_folder, save_fig=self.save_plots, | 2198 path=self.output_folder, save_fig=self.save_plots, |
| 2153 save_only=self.save_plots_only) | 2199 save_only=self.save_plots_only) |
| 2154 quickPlot(self.tomo_recon_stacks[i] | 2200 y_slice = int(self.tomo_recon_stacks[i].shape[1]/2) |
| 2155 [x_slice,int(self.tomo_recon_stacks[i].shape[2]/2),:], | 2201 title = f'{basetitle} {index} yslice{y_slice}' |
| 2156 title=f'{title} cut{int(self.tomo_recon_stacks[i].shape[2]/2)}', | 2202 quickImshow(self.tomo_recon_stacks[i][:,y_slice,:], title=title, |
| 2157 path=self.output_folder, save_fig=self.save_plots, | 2203 path=self.output_folder, save_fig=self.save_plots, |
| 2158 save_only=self.save_plots_only) | 2204 save_only=self.save_plots_only) |
| 2159 self._saveTomo('recon stack', self.tomo_recon_stacks[i], index) | 2205 z_slice = int(self.tomo_recon_stacks[i].shape[2]/2) |
| 2206 title = f'{basetitle} {index} zslice{z_slice}' | |
| 2207 quickImshow(self.tomo_recon_stacks[i][:,:,z_slice], title=title, | |
| 2208 path=self.output_folder, save_fig=self.save_plots, | |
| 2209 save_only=self.save_plots_only) | |
| 2210 # quickPlot(self.tomo_recon_stacks[i] | |
| 2211 # [x_slice,int(self.tomo_recon_stacks[i].shape[1]/2),:], | |
| 2212 # title=f'{title} cut{int(self.tomo_recon_stacks[i].shape[1]/2)}', | |
| 2213 # path=self.output_folder, save_fig=self.save_plots, | |
| 2214 # save_only=self.save_plots_only) | |
| 2215 if not self.test_mode: | |
| 2216 self._saveTomo('recon stack', self.tomo_recon_stacks[i], index) | |
| 2160 self.tomo_stacks[i] = np.array([]) | 2217 self.tomo_stacks[i] = np.array([]) |
| 2161 | 2218 |
| 2162 # Update config and save to file | 2219 # Update config and save to file |
| 2163 stack['reconstructed'] = True | 2220 stack['reconstructed'] = True |
| 2164 combine_stacks = self.config.get('combine_stacks') | 2221 combine_stacks = self.config.get('combine_stacks') |
| 2279 quickPlot((range(tomosum.size), tomosum), | 2336 quickPlot((range(tomosum.size), tomosum), |
| 2280 ([x_bounds[0], x_bounds[0]], [tomosum_min, tomosum_max], 'r-'), | 2337 ([x_bounds[0], x_bounds[0]], [tomosum_min, tomosum_max], 'r-'), |
| 2281 ([x_bounds[1]-1, x_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), | 2338 ([x_bounds[1]-1, x_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), |
| 2282 title=f'recon stack sum yz', path='combine_pngs', save_fig=True, save_only=True) | 2339 title=f'recon stack sum yz', path='combine_pngs', save_fig=True, save_only=True) |
| 2283 else: | 2340 else: |
| 2341 x_bounds = None | |
| 2342 change_x_bounds = 'y' | |
| 2284 if combine_stacks and 'x_bounds' in combine_stacks: | 2343 if combine_stacks and 'x_bounds' in combine_stacks: |
| 2285 x_bounds = combine_stacks['x_bounds'] | 2344 x_bounds = combine_stacks['x_bounds'] |
| 2286 if not is_index_range(x_bounds, 0, tomosum.size): | 2345 if is_index_range(x_bounds, 0, tomosum.size): |
| 2346 if not self.test_mode: | |
| 2347 quickPlot(tomosum, vlines=x_bounds, title='recon stack sum yz') | |
| 2348 print(f'x_bounds = {x_bounds} (lower bound inclusive, upper bound '+ | |
| 2349 'exclusive)') | |
| 2350 change_x_bounds = 'n' | |
| 2351 else: | |
| 2287 illegal_value(x_bounds, 'combine_stacks:x_bounds', 'config file') | 2352 illegal_value(x_bounds, 'combine_stacks:x_bounds', 'config file') |
| 2288 elif not self.test_mode: | 2353 x_bounds = None |
| 2354 if self.test_mode: | |
| 2355 if x_bounds is None: | |
| 2356 x_bounds = [0, tomosum.size] | |
| 2357 else: | |
| 2358 if not input_yesno('\nDo you want to change the image x-bounds (y/n)?', | |
| 2359 change_x_bounds): | |
| 2360 if x_bounds is None: | |
| 2361 x_bounds = [0, tomosum.size] | |
| 2362 else: | |
| 2289 accept = False | 2363 accept = False |
| 2364 if x_bounds is None: | |
| 2365 index_ranges = None | |
| 2366 else: | |
| 2367 index_ranges = [x_bounds] | |
| 2290 while not accept: | 2368 while not accept: |
| 2291 mask, x_bounds = draw_mask_1d(tomosum, current_index_ranges=x_bounds, | 2369 mask, x_bounds = draw_mask_1d(tomosum, current_index_ranges=index_ranges, |
| 2292 title='select x data range', legend='recon stack sum yz') | 2370 title='select x data range', legend='recon stack sum yz') |
| 2293 while len(x_bounds) != 1: | 2371 while len(x_bounds) != 1: |
| 2294 print('Please select exactly one continuous range') | 2372 print('Please select exactly one continuous range') |
| 2295 mask, x_bounds = draw_mask_1d(tomosum, title='select x data range', | 2373 mask, x_bounds = draw_mask_1d(tomosum, title='select x data range', |
| 2296 legend='recon stack sum yz') | 2374 legend='recon stack sum yz') |
| 2297 x_bounds = list(x_bounds[0]) | 2375 x_bounds = list(x_bounds[0]) |
| 2298 quickPlot(tomosum, vlines=x_bounds, title='recon stack sum yz') | 2376 quickPlot(tomosum, vlines=x_bounds, title='recon stack sum yz') |
| 2299 print(f'x_bounds = {x_bounds} (lower bound inclusive, upper bound '+ | 2377 print(f'x_bounds = {x_bounds} (lower bound inclusive, upper bound '+ |
| 2300 'exclusive)') | 2378 'exclusive)') |
| 2301 accept = input_yesno('Accept these bounds (y/n)?', 'y') | 2379 accept = input_yesno('Accept these bounds (y/n)?', 'y') |
| 2302 if not accept: | |
| 2303 x_bounds = None | |
| 2304 else: | |
| 2305 if not input_yesno('\nDo you want to change the image x-bounds (y/n)?', 'n'): | |
| 2306 x_bounds = [0, tomosum.size] | |
| 2307 else: | |
| 2308 accept = False | |
| 2309 while not accept: | |
| 2310 mask, x_bounds = draw_mask_1d(tomosum, title='select x data range', | |
| 2311 legend='recon stack sum yz') | |
| 2312 while len(x_bounds) != 1: | |
| 2313 print('Please select exactly one continuous range') | |
| 2314 mask, x_bounds = draw_mask_1d(tomosum, title='select x data range', | |
| 2315 legend='recon stack sum yz') | |
| 2316 x_bounds = list(x_bounds[0]) | |
| 2317 quickPlot(tomosum, vlines=x_bounds, title='recon stack sum yz') | |
| 2318 print(f'x_bounds = {x_bounds} (lower bound inclusive, upper bound '+ | |
| 2319 'exclusive)') | |
| 2320 accept = input_yesno('Accept these bounds (y/n)?', 'y') | |
| 2321 if False and self.test_mode: | |
| 2322 np.savetxt(f'{self.output_folder}/recon_stack_sum_yz.txt', | |
| 2323 tomosum[x_bounds[0]:x_bounds[1]], fmt='%.6e') | |
| 2324 if self.save_plots_only: | 2380 if self.save_plots_only: |
| 2325 clearPlot('recon stack sum yz') | 2381 clearPlot('recon stack sum yz') |
| 2382 logging.info(f'x_bounds = {x_bounds}') | |
| 2326 | 2383 |
| 2327 # Selecting y bounds (in xz-plane) | 2384 # Selecting y bounds (in xz-plane) |
| 2328 tomosum = 0 | 2385 tomosum = 0 |
| 2329 #RV FIX := | 2386 #RV FIX := |
| 2330 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,1)) for tomo_recon_stack in | 2387 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,1)) for tomo_recon_stack in |
| 2341 quickPlot((range(tomosum.size), tomosum), | 2398 quickPlot((range(tomosum.size), tomosum), |
| 2342 ([y_bounds[0], y_bounds[0]], [tomosum_min, tomosum_max], 'r-'), | 2399 ([y_bounds[0], y_bounds[0]], [tomosum_min, tomosum_max], 'r-'), |
| 2343 ([y_bounds[1]-1, y_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), | 2400 ([y_bounds[1]-1, y_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), |
| 2344 title=f'recon stack sum xz', path='combine_pngs', save_fig=True, save_only=True) | 2401 title=f'recon stack sum xz', path='combine_pngs', save_fig=True, save_only=True) |
| 2345 else: | 2402 else: |
| 2403 y_bounds = None | |
| 2404 change_y_bounds = 'y' | |
| 2346 if combine_stacks and 'y_bounds' in combine_stacks: | 2405 if combine_stacks and 'y_bounds' in combine_stacks: |
| 2347 y_bounds = combine_stacks['y_bounds'] | 2406 y_bounds = combine_stacks['y_bounds'] |
| 2348 if not is_index_range(y_bounds, 0, tomosum.size): | 2407 if is_index_range(y_bounds, 0, tomosum.size): |
| 2408 if not self.test_mode: | |
| 2409 quickPlot(tomosum, vlines=y_bounds, title='recon stack sum xz') | |
| 2410 print(f'y_bounds = {y_bounds} (lower bound inclusive, upper bound '+ | |
| 2411 'exclusive)') | |
| 2412 change_y_bounds = 'n' | |
| 2413 else: | |
| 2349 illegal_value(y_bounds, 'combine_stacks:y_bounds', 'config file') | 2414 illegal_value(y_bounds, 'combine_stacks:y_bounds', 'config file') |
| 2350 elif not self.test_mode: | 2415 y_bounds = None |
| 2416 if self.test_mode: | |
| 2417 if y_bounds is None: | |
| 2418 y_bounds = [0, tomosum.size] | |
| 2419 else: | |
| 2420 if not input_yesno('\nDo you want to change the image y-bounds (y/n)?', | |
| 2421 change_y_bounds): | |
| 2422 if y_bounds is None: | |
| 2423 y_bounds = [0, tomosum.size] | |
| 2424 else: | |
| 2351 accept = False | 2425 accept = False |
| 2426 if y_bounds is None: | |
| 2427 index_ranges = None | |
| 2428 else: | |
| 2429 index_ranges = [y_bounds] | |
| 2352 while not accept: | 2430 while not accept: |
| 2353 mask, y_bounds = draw_mask_1d(tomosum, current_index_ranges=y_bounds, | 2431 mask, y_bounds = draw_mask_1d(tomosum, current_index_ranges=index_ranges, |
| 2354 title='select y data range', legend='recon stack sum xz') | 2432 title='select x data range', legend='recon stack sum xz') |
| 2355 while len(y_bounds) != 1: | 2433 while len(y_bounds) != 1: |
| 2356 print('Please select exactly one continuous range') | 2434 print('Please select exactly one continuous range') |
| 2357 mask, y_bounds = draw_mask_1d(tomosum, title='select y data range', | 2435 mask, y_bounds = draw_mask_1d(tomosum, title='select x data range', |
| 2358 legend='recon stack sum xz') | 2436 legend='recon stack sum xz') |
| 2359 y_bounds = list(y_bounds[0]) | 2437 y_bounds = list(y_bounds[0]) |
| 2360 quickPlot(tomosum, vlines=y_bounds, title='recon stack sum xz') | 2438 quickPlot(tomosum, vlines=y_bounds, title='recon stack sum xz') |
| 2361 print(f'y_bounds = {y_bounds} (lower bound inclusive, upper bound '+ | 2439 print(f'y_bounds = {y_bounds} (lower bound inclusive, upper bound '+ |
| 2362 'exclusive)') | 2440 'exclusive)') |
| 2363 accept = input_yesno('Accept these bounds (y/n)?', 'y') | 2441 accept = input_yesno('Accept these bounds (y/n)?', 'y') |
| 2364 if not accept: | |
| 2365 y_bounds = None | |
| 2366 else: | |
| 2367 if not input_yesno('\nDo you want to change the image y-bounds (y/n)?', 'n'): | |
| 2368 y_bounds = [0, tomosum.size] | |
| 2369 else: | |
| 2370 accept = False | |
| 2371 while not accept: | |
| 2372 mask, y_bounds = draw_mask_1d(tomosum, title='select y data range', | |
| 2373 legend='recon stack sum xz') | |
| 2374 while len(y_bounds) != 1: | |
| 2375 print('Please select exactly one continuous range') | |
| 2376 mask, y_bounds = draw_mask_1d(tomosum, title='select y data range', | |
| 2377 legend='recon stack sum xz') | |
| 2378 y_bounds = list(y_bounds[0]) | |
| 2379 quickPlot(tomosum, vlines=y_bounds, title='recon stack sum xz') | |
| 2380 print(f'y_bounds = {y_bounds} (lower bound inclusive, upper bound '+ | |
| 2381 'exclusive)') | |
| 2382 accept = input_yesno('Accept these bounds (y/n)?', 'y') | |
| 2383 if False and self.test_mode: | |
| 2384 np.savetxt(f'{self.output_folder}/recon_stack_sum_xz.txt', | |
| 2385 tomosum[y_bounds[0]:y_bounds[1]], fmt='%.6e') | |
| 2386 if self.save_plots_only: | 2442 if self.save_plots_only: |
| 2387 clearPlot('recon stack sum xz') | 2443 clearPlot('recon stack sum xz') |
| 2444 logging.info(f'y_bounds = {y_bounds}') | |
| 2388 | 2445 |
| 2389 # Combine reconstructed tomography stacks | 2446 # Combine reconstructed tomography stacks |
| 2390 logging.info(f'Combining reconstructed stacks ...') | 2447 logging.info(f'Combining reconstructed stacks ...') |
| 2391 t0 = time() | 2448 t0 = time() |
| 2392 num_tomo_stacks = len(stacks) | 2449 num_tomo_stacks = len(stacks) |
| 2406 [self.tomo_recon_stacks[num_tomo_stacks-1][row_bounds[0]:, | 2463 [self.tomo_recon_stacks[num_tomo_stacks-1][row_bounds[0]:, |
| 2407 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]]]) | 2464 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]]]) |
| 2408 logging.info(f'... done in {time()-t0:.2f} seconds!') | 2465 logging.info(f'... done in {time()-t0:.2f} seconds!') |
| 2409 combined_stacks = [stack['index'] for stack in stacks] | 2466 combined_stacks = [stack['index'] for stack in stacks] |
| 2410 | 2467 |
| 2411 # Wrap up if in test_mode | 2468 # Selecting z bounds (in xy-plane) |
| 2412 tomosum = np.sum(tomo_recon_combined, axis=(1,2)) | 2469 tomosum = np.sum(tomo_recon_combined, axis=(1,2)) |
| 2413 if self.test_mode: | |
| 2414 zoom_perc = self.config['preprocess'].get('zoom_perc', 100) | |
| 2415 filename = 'recon combined sum xy' | |
| 2416 if zoom_perc is None or zoom_perc == 100: | |
| 2417 filename += ' fullres.dat' | |
| 2418 else: | |
| 2419 filename += f' {zoom_perc}p.dat' | |
| 2420 quickPlot(tomosum, title='recon combined sum xy', | |
| 2421 path=self.output_folder, save_fig=self.save_plots, | |
| 2422 save_only=self.save_plots_only) | |
| 2423 if False: | |
| 2424 np.savetxt(f'{self.output_folder}/recon_combined_sum_xy.txt', | |
| 2425 tomosum, fmt='%.6e') | |
| 2426 np.savetxt(f'{self.output_folder}/recon_combined.txt', | |
| 2427 tomo_recon_combined[int(tomosum.size/2),:,:], fmt='%.6e') | |
| 2428 | |
| 2429 # Update config and save to file | |
| 2430 if combine_stacks: | |
| 2431 combine_stacks['x_bounds'] = x_bounds | |
| 2432 combine_stacks['y_bounds'] = y_bounds | |
| 2433 combine_stacks['stacks'] = combined_stacks | |
| 2434 else: | |
| 2435 self.config['combine_stacks'] = {'x_bounds' : x_bounds, 'y_bounds' : y_bounds, | |
| 2436 'stacks' : combined_stacks} | |
| 2437 self.cf.saveFile(self.config_out) | |
| 2438 return | |
| 2439 | |
| 2440 # Selecting z bounds (in xy-plane) | |
| 2441 if self.galaxy_flag: | 2470 if self.galaxy_flag: |
| 2442 if z_bounds[0] == -1: | 2471 if z_bounds[0] == -1: |
| 2443 z_bounds[0] = 0 | 2472 z_bounds[0] = 0 |
| 2444 if z_bounds[1] == -1: | 2473 if z_bounds[1] == -1: |
| 2445 z_bounds[1] = tomosum.size | 2474 z_bounds[1] = tomosum.size |
| 2450 quickPlot((range(tomosum.size), tomosum), | 2479 quickPlot((range(tomosum.size), tomosum), |
| 2451 ([z_bounds[0], z_bounds[0]], [tomosum_min, tomosum_max], 'r-'), | 2480 ([z_bounds[0], z_bounds[0]], [tomosum_min, tomosum_max], 'r-'), |
| 2452 ([z_bounds[1]-1, z_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), | 2481 ([z_bounds[1]-1, z_bounds[1]-1], [tomosum_min, tomosum_max], 'r-'), |
| 2453 title=f'recon stack sum xy', path='combine_pngs', save_fig=True, save_only=True) | 2482 title=f'recon stack sum xy', path='combine_pngs', save_fig=True, save_only=True) |
| 2454 else: | 2483 else: |
| 2455 if not input_yesno('\nDo you want to change the image z-bounds (y/n)?', 'n'): | 2484 z_bounds = None |
| 2456 z_bounds = [0, tomosum.size] | 2485 if combine_stacks and 'z_bounds' in combine_stacks: |
| 2457 else: | 2486 z_bounds = combine_stacks['z_bounds'] |
| 2458 accept = False | 2487 if is_index_range(z_bounds, 0, tomosum.size): |
| 2459 while not accept: | 2488 if not self.test_mode: |
| 2460 mask, z_bounds = draw_mask_1d(tomosum, title='select z data range', | 2489 quickPlot(tomosum, vlines=z_bounds, title='recon stack sum xy') |
| 2461 legend='recon stack sum xy') | 2490 print(f'z_bounds = {z_bounds} (lower bound inclusive, upper bound '+ |
| 2462 while len(z_bounds) != 1: | 2491 'exclusive)') |
| 2463 print('Please select exactly one continuous range') | 2492 else: |
| 2464 mask, z_bounds = draw_mask_1d(tomosum, title='select z data range', | 2493 illegal_value(z_bounds, 'combine_stacks:z_bounds', 'config file') |
| 2465 legend='recon stack sum xy') | 2494 z_bounds = None |
| 2466 z_bounds = list(z_bounds[0]) | 2495 if self.test_mode: |
| 2467 quickPlot(tomosum, vlines=z_bounds, title='recon stack sum xy') | 2496 if z_bounds is None: |
| 2468 print(f'z_bounds = {z_bounds} (lower bound inclusive, upper bound exclusive)') | 2497 z_bounds = [0, tomosum.size] |
| 2469 accept = input_yesno('Accept these bounds (y/n)?', 'y') | 2498 else: |
| 2499 if not input_yesno('\nDo you want to change the image z-bounds (y/n)?', 'n'): | |
| 2500 if z_bounds is None: | |
| 2501 z_bounds = [0, tomosum.size] | |
| 2502 else: | |
| 2503 accept = False | |
| 2504 if z_bounds is None: | |
| 2505 index_ranges = None | |
| 2506 else: | |
| 2507 index_ranges = [z_bounds] | |
| 2508 while not accept: | |
| 2509 mask, z_bounds = draw_mask_1d(tomosum, current_index_ranges=index_ranges, | |
| 2510 title='select x data range', legend='recon stack sum xy') | |
| 2511 while len(z_bounds) != 1: | |
| 2512 print('Please select exactly one continuous range') | |
| 2513 mask, z_bounds = draw_mask_1d(tomosum, title='select x data range', | |
| 2514 legend='recon stack sum xy') | |
| 2515 z_bounds = list(z_bounds[0]) | |
| 2516 quickPlot(tomosum, vlines=z_bounds, title='recon stack sum xy') | |
| 2517 print(f'z_bounds = {z_bounds} (lower bound inclusive, upper bound '+ | |
| 2518 'exclusive)') | |
| 2519 accept = input_yesno('Accept these bounds (y/n)?', 'y') | |
| 2470 if self.save_plots_only: | 2520 if self.save_plots_only: |
| 2471 clearPlot('recon combined sum xy') | 2521 clearPlot('recon stack sum xy') |
| 2472 if z_bounds[0] != 0 or z_bounds[1] != tomosum.size: | 2522 logging.info(f'z_bounds = {z_bounds}') |
| 2473 tomo_recon_combined = tomo_recon_combined[z_bounds[0]:z_bounds[1],:,:] | |
| 2474 | 2523 |
| 2475 # Plot center slices | 2524 # Plot center slices |
| 2476 if self.galaxy_flag: | 2525 if self.galaxy_flag: |
| 2477 path = 'combine_pngs' | 2526 path = 'combine_pngs' |
| 2478 save_fig = True | 2527 save_fig = True |
| 2489 path=path, save_fig=save_fig, save_only=save_only) | 2538 path=path, save_fig=save_fig, save_only=save_only) |
| 2490 quickImshow(tomo_recon_combined[:,:,int(tomo_recon_combined.shape[2]/2)], | 2539 quickImshow(tomo_recon_combined[:,:,int(tomo_recon_combined.shape[2]/2)], |
| 2491 title=f'recon combined zslice{int(tomo_recon_combined.shape[2]/2)}', | 2540 title=f'recon combined zslice{int(tomo_recon_combined.shape[2]/2)}', |
| 2492 path=path, save_fig=save_fig, save_only=save_only) | 2541 path=path, save_fig=save_fig, save_only=save_only) |
| 2493 | 2542 |
| 2494 # Save combined reconstructed tomography stack to file | 2543 # Save combined reconstructed tomography stack or test mode data to file |
| 2495 if self.galaxy_flag: | 2544 if self.galaxy_flag: |
| 2496 t0 = time() | 2545 t0 = time() |
| 2497 output_name = galaxy_param['output_name'] | 2546 output_name = galaxy_param['output_name'] |
| 2498 logging.info(f'Saving combined reconstructed tomography stack to {output_name} ...') | 2547 logging.info(f'Saving combined reconstructed tomography stack to {output_name} ...') |
| 2499 np.save(output_name, tomo_recon_combined) | 2548 np.save(output_name, tomo_recon_combined) |
| 2500 logging.info(f'... done in {time()-t0:.2f} seconds!') | 2549 logging.info(f'... done in {time()-t0:.2f} seconds!') |
| 2550 elif self.test_mode: | |
| 2551 zoom_perc = self.config['preprocess'].get('zoom_perc', 100) | |
| 2552 filename = 'recon combined sum xy' | |
| 2553 if zoom_perc is None or zoom_perc == 100: | |
| 2554 filename += ' fullres.dat' | |
| 2555 else: | |
| 2556 filename += f' {zoom_perc}p.dat' | |
| 2557 quickPlot(tomosum, title='recon combined sum xy', | |
| 2558 path=self.output_folder, save_fig=self.save_plots, | |
| 2559 save_only=self.save_plots_only) | |
| 2560 np.savetxt(f'{self.output_folder}/recon_combined.txt', | |
| 2561 tomo_recon_combined[int(tomosum.size/2),:,:], fmt='%.6e') | |
| 2501 else: | 2562 else: |
| 2502 base_name = 'recon combined' | 2563 base_name = 'recon combined' |
| 2503 for stack in stacks: | 2564 for stack in stacks: |
| 2504 base_name += f' {stack["index"]}' | 2565 base_name += f' {stack["index"]}' |
| 2505 self._saveTomo(base_name, tomo_recon_combined) | 2566 self._saveTomo(base_name, tomo_recon_combined) |
