comparison tomo.py @ 7:845270a96464 draft

"planemo upload for repository https://github.com/rolfverberg/galaxytools commit a08ed1264ea7b7c878ba96801e4b27ef621fb6be"
author rv43
date Thu, 07 Apr 2022 21:09:58 +0000
parents f9c52762c32c
children ec7c3e84d611
comparison
equal deleted inserted replaced
6:baf9f5eef128 7:845270a96464
1164 save_fig=self.save_plots, save_only=self.save_plots_only, cmap='gray', 1164 save_fig=self.save_plots, save_only=self.save_plots_only, cmap='gray',
1165 vmin=vmin, vmax=vmax) 1165 vmin=vmin, vmax=vmax)
1166 del edges 1166 del edges
1167 1167
1168 def _findCenterOnePlane(self, sinogram, row, thetas_deg, eff_pixel_size, cross_sectional_dim, 1168 def _findCenterOnePlane(self, sinogram, row, thetas_deg, eff_pixel_size, cross_sectional_dim,
1169 tol=0.1, num_core=1, recon_pngname=None): 1169 tol=0.1, num_core=1, recon_pngname=None, galaxy_param=None):
1170 """Find center for a single tomography plane. 1170 """Find center for a single tomography plane.
1171 """ 1171 """
1172 # sinogram index order: theta,column 1172 # sinogram index order: theta,column
1173 # need index order column,theta for iradon, so take transpose 1173 # need index order column,theta for iradon, so take transpose
1174 sinogram_T = sinogram.T 1174 sinogram_T = sinogram.T
1175 center = sinogram.shape[1]/2 1175 center = sinogram.shape[1]/2
1176 1176
1177 # try automatic center finding routines for initial value 1177 # try automatic center finding routines for initial value
1178 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core) 1178 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core)
1179 center_offset_vo = tomo_center-center 1179 center_offset_vo = tomo_center-center
1180 if self.test_mode or self.galaxy_flag: 1180 if self.test_mode:
1181 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') 1181 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}')
1182 if self.test_mode: 1182 del sinogram_T
1183 return float(center_offset_vo)
1184 elif self.galaxy_flag:
1185 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}')
1186 if recon_pngname:
1187 assert(isinstance(recon_pngname, str))
1188 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg,
1189 eff_pixel_size, cross_sectional_dim, False, num_core)
1190 title = os.path.basename(recon_pngname)
1191 self._plotEdgesOnePlane(recon_plane, title, name=recon_pngname)
1192 del recon_plane
1193 if not galaxy_param or not galaxy_param['center_type_selector']:
1183 del sinogram_T 1194 del sinogram_T
1184 return float(center_offset_vo) 1195 return float(center_offset_vo)
1185 else: 1196 else:
1186 print(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') 1197 print(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}')
1187 if recon_pngname: 1198 if recon_pngname:
1188 logging.warning('Ignoring recon_pngname in _findCenterOnePlane (only for Galaxy)') 1199 logging.warning('Ignoring recon_pngname in _findCenterOnePlane (only for Galaxy)')
1189 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg, 1200 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg,
1190 eff_pixel_size, cross_sectional_dim, False, num_core) 1201 eff_pixel_size, cross_sectional_dim, False, num_core)
1191 if self.galaxy_flag:
1192 assert(isinstance(recon_pngname, str))
1193 title = os.path.basename(recon_pngname)
1194 self._plotEdgesOnePlane(recon_plane, title, name=recon_pngname)
1195 del sinogram_T
1196 del recon_plane
1197 return float(center_offset_vo)
1198 else:
1199 title = f'edges row{row} center_offset_vo{center_offset_vo:.2f}' 1202 title = f'edges row{row} center_offset_vo{center_offset_vo:.2f}'
1200 self._plotEdgesOnePlane(recon_plane, title) 1203 self._plotEdgesOnePlane(recon_plane, title)
1201 if (pyip.inputYesNo('Try finding center using phase correlation '+ 1204 if not self.galaxy_flag:
1202 '(y/[n])? ', blank=True) == 'yes'): 1205 if (pyip.inputYesNo('Try finding center using phase correlation '+
1203 tomo_center = tomopy.find_center_pc(sinogram, sinogram, tol=0.1, 1206 '(y/[n])? ', blank=True) == 'yes'):
1204 rotc_guess=tomo_center) 1207 tomo_center = tomopy.find_center_pc(sinogram, sinogram, tol=0.1,
1205 error = 1.
1206 while error > tol:
1207 prev = tomo_center
1208 tomo_center = tomopy.find_center_pc(sinogram, sinogram, tol=tol,
1209 rotc_guess=tomo_center) 1208 rotc_guess=tomo_center)
1210 error = np.abs(tomo_center-prev) 1209 error = 1.
1211 center_offset = tomo_center-center 1210 while error > tol:
1212 print(f'Center at row {row} using phase correlation = {center_offset:.2f}') 1211 prev = tomo_center
1213 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg, 1212 tomo_center = tomopy.find_center_pc(sinogram, sinogram, tol=tol,
1214 eff_pixel_size, cross_sectional_dim, False, num_core) 1213 rotc_guess=tomo_center)
1215 title = f'edges row{row} center_offset{center_offset:.2f}' 1214 error = np.abs(tomo_center-prev)
1216 self._plotEdgesOnePlane(recon_plane, title) 1215 center_offset = tomo_center-center
1217 if (pyip.inputYesNo('Accept a center location ([y]) or continue '+ 1216 print(f'Center at row {row} using phase correlation = {center_offset:.2f}')
1218 'search (n)? ', blank=True) != 'no'): 1217 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg,
1219 del sinogram_T 1218 eff_pixel_size, cross_sectional_dim, False, num_core)
1220 del recon_plane 1219 title = f'edges row{row} center_offset{center_offset:.2f}'
1221 center_offset = pyip.inputNum( 1220 self._plotEdgesOnePlane(recon_plane, title)
1222 f' Enter chosen center offset [{-int(center)}, {int(center)}] '+ 1221 if (pyip.inputYesNo('Accept a center location ([y]) or continue '+
1223 f'([{center_offset_vo}])): ', blank=True) 1222 'search (n)? ', blank=True) != 'no'):
1224 if center_offset == '': 1223 center_offset = pyip.inputNum(
1225 center_offset = center_offset_vo 1224 f' Enter chosen center offset [{-int(center)}, {int(center)}] '+
1226 return float(center_offset) 1225 f'([{center_offset_vo:.2f}])): ', blank=True)
1227 1226 if center_offset == '':
1227 center_offset = center_offset_vo
1228 del sinogram_T
1229 del recon_plane
1230 return float(center_offset)
1231
1232 # perform center finding search
1228 while True: 1233 while True:
1229 center_offset_low = pyip.inputInt('\nEnter lower bound for center offset '+ 1234 if self.galaxy_flag and galaxy_param and galaxy_param['center_type_selector']:
1230 f'[{-int(center)}, {int(center)}]: ', min=-int(center), max=int(center)) 1235 set_center = center_offset_vo
1231 center_offset_upp = pyip.inputInt('Enter upper bound for center offset '+ 1236 if galaxy_param['center_type_selector'] == 'user':
1232 f'[{center_offset_low}, {int(center)}]: ', 1237 set_center = galaxy_param['set_center']
1233 min=center_offset_low, max=int(center)) 1238 set_range = galaxy_param['set_range']
1234 if center_offset_upp == center_offset_low: 1239 center_offset_step = galaxy_param['set_step']
1235 center_offset_step = 1 1240 if (not msnc.is_num(set_range, 0) or not msnc.is_num(center_offset_step) or
1236 else: 1241 center_offset_step <= 0):
1237 center_offset_step = pyip.inputInt('Enter step size for center offset search '+ 1242 logging.warning('Illegal center finding search parameter, skip search')
1238 f'[1, {center_offset_upp-center_offset_low}]: ', 1243 del sinogram_T
1239 min=1, max=center_offset_upp-center_offset_low) 1244 return float(center_offset_vo)
1240 for center_offset in range(center_offset_low, center_offset_upp+center_offset_step, 1245 set_range = center_offset_step*max(1, int(set_range/center_offset_step))
1241 center_offset_step): 1246 center_offset_low = set_center-set_range
1242 logging.info(f'center_offset = {center_offset}') 1247 center_offset_upp = set_center+set_range
1248 else:
1249 center_offset_low = pyip.inputInt('\nEnter lower bound for center offset '+
1250 f'[{-int(center)}, {int(center)}]: ', min=-int(center), max=int(center))
1251 center_offset_upp = pyip.inputInt('Enter upper bound for center offset '+
1252 f'[{center_offset_low}, {int(center)}]: ',
1253 min=center_offset_low, max=int(center))
1254 if center_offset_upp == center_offset_low:
1255 center_offset_step = 1
1256 else:
1257 center_offset_step = pyip.inputInt('Enter step size for center offset search '+
1258 f'[1, {center_offset_upp-center_offset_low}]: ',
1259 min=1, max=center_offset_upp-center_offset_low)
1260 num_center_offset = 1+int((center_offset_upp-center_offset_low)/center_offset_step)
1261 center_offsets = np.linspace(center_offset_low, center_offset_upp, num_center_offset)
1262 for center_offset in center_offsets:
1263 if center_offset == center_offset_vo:
1264 continue
1265 logging.info(f'center_offset = {center_offset:.2f}')
1243 recon_plane = self._reconstructOnePlane(sinogram_T, center_offset+center, 1266 recon_plane = self._reconstructOnePlane(sinogram_T, center_offset+center,
1244 thetas_deg, eff_pixel_size, cross_sectional_dim, False, num_core) 1267 thetas_deg, eff_pixel_size, cross_sectional_dim, False, num_core)
1245 title = f'edges row{row} center_offset{center_offset}' 1268 title = f'edges row{row} center_offset{center_offset:.2f}'
1246 self._plotEdgesOnePlane(recon_plane, title) 1269 self._plotEdgesOnePlane(recon_plane, title)
1247 if pyip.inputInt('\nContinue (0) or end the search (1): ', min=0, max=1): 1270 if self.galaxy_flag or pyip.inputInt('\nContinue (0) or end the search (1): ',
1271 min=0, max=1):
1248 break 1272 break
1249 1273
1250 del sinogram_T 1274 del sinogram_T
1251 del recon_plane 1275 del recon_plane
1252 center_offset = pyip.inputNum(f' Enter chosen center offset '+ 1276 if self.galaxy_flag:
1277 center_offset = center_offset_vo
1278 else:
1279 center_offset = pyip.inputNum(f' Enter chosen center offset '+
1253 f'[{-int(center)}, {int(center)}]: ', min=-int(center), max=int(center)) 1280 f'[{-int(center)}, {int(center)}]: ', min=-int(center), max=int(center))
1254 return float(center_offset) 1281 return float(center_offset)
1255 1282
1256 def _reconstructOneTomoStack(self, tomo_stack, thetas, row_bounds=None, 1283 def _reconstructOneTomoStack(self, tomo_stack, thetas, row_bounds=None,
1257 center_offsets=[], sigma=0.1, rwidth=30, num_core=1, algorithm='gridrec', 1284 center_offsets=[], sigma=0.1, rwidth=30, num_core=1, algorithm='gridrec',
1511 pixel_size *= img_x_bounds[0] 1538 pixel_size *= img_x_bounds[0]
1512 for stack in stacks: 1539 for stack in stacks:
1513 stack['ref_height'] = stack['ref_height']+pixel_size 1540 stack['ref_height'] = stack['ref_height']+pixel_size
1514 self.cf.saveFile(self.config_out) 1541 self.cf.saveFile(self.config_out)
1515 1542
1516 def findCenters(self, row_bounds=None, center_rows=None, recon_low_pngname=None, 1543 def findCenters(self, galaxy_param=None, num_core=None):
1517 recon_upp_pngname=None, num_core=None):
1518 """Find rotation axis centers for the tomography stacks. 1544 """Find rotation axis centers for the tomography stacks.
1519 """ 1545 """
1520 if num_core is None: 1546 if num_core is None:
1521 num_core = self.num_core 1547 num_core = self.num_core
1522 logging.debug('Find centers for tomography stacks') 1548 logging.debug('Find centers for tomography stacks')
1523 stacks = self.config['stack_info']['stacks'] 1549 stacks = self.config['stack_info']['stacks']
1524 available_stacks = [stack['index'] for stack in stacks if stack.get('preprocessed', False)] 1550 available_stacks = [stack['index'] for stack in stacks if stack.get('preprocessed', False)]
1525 logging.debug('Available stacks: {available_stacks}') 1551 logging.debug('Available stacks: {available_stacks}')
1526 if self.galaxy_flag: 1552 if self.galaxy_flag:
1527 assert(isinstance(row_bounds, list) and len(row_bounds) == 2) 1553 assert(isinstance(galaxy_param, dict))
1528 assert(isinstance(center_rows, list) and len(center_rows) == 2) 1554 row_bounds = galaxy_param['row_bounds']
1529 assert(isinstance(recon_low_pngname, str)) 1555 center_rows = galaxy_param['center_rows']
1530 assert(isinstance(recon_upp_pngname, str)) 1556 if center_rows is None:
1531 else: 1557 logging.error('Missing center_rows entry in galaxy_param')
1532 if row_bounds: 1558 return
1533 logging.warning('Ignoring row_bounds in findCenters (only for Galaxy)') 1559 center_type_selector = galaxy_param['center_type_selector']
1534 row_bounds = None 1560 if center_type_selector:
1535 if center_rows: 1561 if center_type_selector == 'vo':
1536 logging.warning('Ignoring center_rows in findCenters (only for Galaxy)') 1562 set_center = None
1537 center_rows = None 1563 elif center_type_selector == 'user':
1538 if recon_low_pngname: 1564 set_center = galaxy_param['set_center']
1539 logging.warning('Ignoring recon_low_pngname in findCenters (only for Galaxy)') 1565 else:
1540 recon_low_pngname = None 1566 logging.error('Illegal center_type_selector entry in galaxy_param '+
1541 if recon_upp_pngname: 1567 f'({center_type_selector})')
1542 logging.warning('Ignoring recon_upp_pngname in findCenters (only for Galaxy)') 1568 galaxy_param['center_type_selector'] = None
1543 recon_upp_pngname = None 1569 else:
1570 if galaxy_param:
1571 logging.warning('Ignoring galaxy_param in findCenters (only for Galaxy)')
1572 galaxy_param = None
1544 1573
1545 # Check for valid available center stack index 1574 # Check for valid available center stack index
1546 find_center = self.config.get('find_center') 1575 find_center = self.config.get('find_center')
1547 center_stack_index = None 1576 center_stack_index = None
1548 if find_center and 'center_stack_index' in find_center: 1577 if find_center and 'center_stack_index' in find_center:
1608 find_center['center_stack_index'] = center_stack_index 1637 find_center['center_stack_index'] = center_stack_index
1609 if not self.galaxy_flag: 1638 if not self.galaxy_flag:
1610 row_bounds = find_center.get('row_bounds', None) 1639 row_bounds = find_center.get('row_bounds', None)
1611 center_rows = [find_center.get('lower_row', None), 1640 center_rows = [find_center.get('lower_row', None),
1612 find_center.get('upper_row', None)] 1641 find_center.get('upper_row', None)]
1642 if row_bounds is None:
1643 row_bounds = [0, center_stack.shape[0]]
1644 if row_bounds[0] == -1:
1645 row_bounds[0] = 0
1646 if row_bounds[1] == -1:
1647 row_bounds[1] = center_stack.shape[0]
1648 if not msnc.is_index_range(row_bounds, 0, center_stack.shape[0]):
1649 msnc.illegal_value('row_bounds', row_bounds)
1650 return
1613 1651
1614 # Set thetas (in degrees) 1652 # Set thetas (in degrees)
1615 theta_range = self.config['theta_range'] 1653 theta_range = self.config['theta_range']
1616 theta_start = theta_range['start'] 1654 theta_start = theta_range['start']
1617 theta_end = theta_range['end'] 1655 theta_end = theta_range['end']
1685 1723
1686 # Lower row center 1724 # Lower row center
1687 use_row = 'no' 1725 use_row = 'no'
1688 use_center = 'no' 1726 use_center = 'no'
1689 row = center_rows[0] 1727 row = center_rows[0]
1728 if self.test_mode or self.galaxy_flag:
1729 assert(msnc.is_int(row, n1, n2-2))
1690 if msnc.is_int(row, n1, n2-2): 1730 if msnc.is_int(row, n1, n2-2):
1691 if self.test_mode or self.galaxy_flag: 1731 if self.test_mode or self.galaxy_flag:
1692 assert(row is not None)
1693 use_row = 'yes' 1732 use_row = 'yes'
1694 else: 1733 else:
1695 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto') 1734 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto')
1696 use_row = pyip.inputYesNo('\nCurrent row index for lower center = ' 1735 use_row = pyip.inputYesNo('\nCurrent row index for lower center = '
1697 f'{row}, use this value ([y]/n)? ', blank=True) 1736 f'{row}, use this value ([y]/n)? ', blank=True)
1712 if row == '': 1751 if row == '':
1713 row = n1 1752 row = n1
1714 if self.save_plots_only: 1753 if self.save_plots_only:
1715 msnc.clearFig(f'theta={theta_start}') 1754 msnc.clearFig(f'theta={theta_start}')
1716 # center_stack order: row,theta,column 1755 # center_stack order: row,theta,column
1756 if galaxy_param:
1757 recon_pngname = galaxy_param['recon_center_low']
1758 else:
1759 recon_pngname = None
1717 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg, 1760 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg,
1718 eff_pixel_size, cross_sectional_dim, num_core=num_core, 1761 eff_pixel_size, cross_sectional_dim, num_core=num_core,
1719 recon_pngname=recon_low_pngname) 1762 recon_pngname=recon_pngname, galaxy_param=galaxy_param)
1763 logging.info(f'lower_center_offset = {center_offset:.2f} {type(center_offset)}')
1764 print(center_offset)
1720 1765
1721 # Update config and save to file 1766 # Update config and save to file
1722 find_center['row_bounds'] = [n1, n2] 1767 find_center['row_bounds'] = [n1, n2]
1723 find_center['lower_row'] = row 1768 find_center['lower_row'] = row
1724 find_center['lower_center_offset'] = center_offset 1769 find_center['lower_center_offset'] = center_offset
1727 1772
1728 # Upper row center 1773 # Upper row center
1729 use_row = 'no' 1774 use_row = 'no'
1730 use_center = 'no' 1775 use_center = 'no'
1731 row = center_rows[1] 1776 row = center_rows[1]
1777 if self.test_mode or self.galaxy_flag:
1778 assert(msnc.is_int(row, lower_row+1, n2-1))
1732 if msnc.is_int(row, lower_row+1, n2-1): 1779 if msnc.is_int(row, lower_row+1, n2-1):
1733 if self.test_mode or self.galaxy_flag: 1780 if self.test_mode or self.galaxy_flag:
1734 assert(row is not None)
1735 use_row = 'yes' 1781 use_row = 'yes'
1736 else: 1782 else:
1737 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto') 1783 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto')
1738 use_row = pyip.inputYesNo('\nCurrent row index for upper center = ' 1784 use_row = pyip.inputYesNo('\nCurrent row index for upper center = '
1739 f'{row}, use this value ([y]/n)? ', blank=True) 1785 f'{row}, use this value ([y]/n)? ', blank=True)
1754 if row == '': 1800 if row == '':
1755 row = n2-1 1801 row = n2-1
1756 if self.save_plots_only: 1802 if self.save_plots_only:
1757 msnc.clearFig(f'theta={theta_start}') 1803 msnc.clearFig(f'theta={theta_start}')
1758 # center_stack order: row,theta,column 1804 # center_stack order: row,theta,column
1805 if galaxy_param:
1806 recon_pngname = galaxy_param['recon_center_upp']
1807 else:
1808 recon_pngname = None
1759 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg, 1809 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg,
1760 eff_pixel_size, cross_sectional_dim, num_core=num_core, 1810 eff_pixel_size, cross_sectional_dim, num_core=num_core,
1761 recon_pngname=recon_upp_pngname) 1811 recon_pngname=recon_pngname, galaxy_param=galaxy_param)
1762 logging.info(f'upper_center_offset = {center_offset}') 1812 logging.info(f'upper_center_offset = {center_offset:.2f}')
1763 del center_stack 1813 del center_stack
1764 1814
1765 # Update config and save to file 1815 # Update config and save to file
1766 find_center['upper_row'] = row 1816 find_center['upper_row'] = row
1767 find_center['upper_center_offset'] = center_offset 1817 find_center['upper_center_offset'] = center_offset