comparison tomo.py @ 47:c693117d01e9 draft

"planemo upload for repository https://github.com/rolfverberg/galaxytools commit baa3866a541a552710bec26ae5d37a8c624563ac-dirty"
author rv43
date Mon, 25 Apr 2022 20:02:15 +0000
parents d73e715e975b
children 059819ea1f0e
comparison
equal deleted inserted replaced
46:d73e715e975b 47:c693117d01e9
46 import msnc_tools as msnc 46 import msnc_tools as msnc
47 47
48 # the following tomopy routines don't run with more than 24 cores on Galaxy-Dev 48 # the following tomopy routines don't run with more than 24 cores on Galaxy-Dev
49 # - tomopy.find_center_vo 49 # - tomopy.find_center_vo
50 # - tomopy.prep.stripe.remove_stripe_fw 50 # - tomopy.prep.stripe.remove_stripe_fw
51 #RV the same problem reappeared once I started testing with the tenstom_1304r-1 case
52 # not resolved yet
53 num_core_tomopy_limit = 24 51 num_core_tomopy_limit = 24
54 52
55 class set_numexpr_threads: 53 class set_numexpr_threads:
56 54
57 def __init__(self, num_core): 55 def __init__(self, num_core):
1204 assert(0 <= center < tomo_plane_T.shape[0]) 1202 assert(0 <= center < tomo_plane_T.shape[0])
1205 center_offset = center-tomo_plane_T.shape[0]/2 1203 center_offset = center-tomo_plane_T.shape[0]/2
1206 two_offset = 2*int(np.round(center_offset)) 1204 two_offset = 2*int(np.round(center_offset))
1207 two_offset_abs = np.abs(two_offset) 1205 two_offset_abs = np.abs(two_offset)
1208 max_rad = int(0.5*(cross_sectional_dim/eff_pixel_size)*1.1) # 10% slack to avoid edge effects 1206 max_rad = int(0.5*(cross_sectional_dim/eff_pixel_size)*1.1) # 10% slack to avoid edge effects
1207 if max_rad > 0.5*tomo_plane_T.shape[0]:
1208 max_rad = 0.5*tomo_plane_T.shape[0]
1209 dist_from_edge = max(1, int(np.floor((tomo_plane_T.shape[0]-two_offset_abs)/2.)-max_rad)) 1209 dist_from_edge = max(1, int(np.floor((tomo_plane_T.shape[0]-two_offset_abs)/2.)-max_rad))
1210 if two_offset >= 0: 1210 if two_offset >= 0:
1211 logging.debug(f'sinogram range = [{two_offset+dist_from_edge}, {-dist_from_edge}]') 1211 logging.debug(f'sinogram range = [{two_offset+dist_from_edge}, {-dist_from_edge}]')
1212 sinogram = tomo_plane_T[two_offset+dist_from_edge:-dist_from_edge,:] 1212 sinogram = tomo_plane_T[two_offset+dist_from_edge:-dist_from_edge,:]
1213 else: 1213 else:
1271 1271
1272 # try automatic center finding routines for initial value 1272 # try automatic center finding routines for initial value
1273 t0 = time() 1273 t0 = time()
1274 if num_core > num_core_tomopy_limit: 1274 if num_core > num_core_tomopy_limit:
1275 logging.debug(f'running find_center_vo on {num_core_tomopy_limit} cores ...') 1275 logging.debug(f'running find_center_vo on {num_core_tomopy_limit} cores ...')
1276 print(f'running find_center_vo on {num_core_tomopy_limit} cores ...')
1277 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core_tomopy_limit) 1276 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core_tomopy_limit)
1278 else: 1277 else:
1279 logging.debug(f'running find_center_vo on {num_core} cores ...') 1278 logging.debug(f'running find_center_vo on {num_core} cores ...')
1280 print(f'running find_center_vo on {num_core} cores ...')
1281 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core) 1279 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core)
1282 logging.debug(f'... find_center_vo took {time()-t0:.2f} seconds!') 1280 logging.debug(f'... find_center_vo took {time()-t0:.2f} seconds!')
1283 print(f'... find_center_vo took {time()-t0:.2f} seconds!')
1284 center_offset_vo = tomo_center-center 1281 center_offset_vo = tomo_center-center
1285 if self.test_mode: 1282 if self.test_mode:
1286 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') 1283 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}')
1287 del sinogram_T 1284 del sinogram_T
1288 return float(center_offset_vo) 1285 return float(center_offset_vo)
1289 elif self.galaxy_flag: 1286 elif self.galaxy_flag:
1290 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') 1287 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}')
1291 t0 = time() 1288 t0 = time()
1292 logging.debug(f'running _reconstructOnePlane on {num_core} cores ...') 1289 logging.debug(f'running _reconstructOnePlane on {num_core} cores ...')
1293 print('OK AA')
1294 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg, 1290 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg,
1295 eff_pixel_size, cross_sectional_dim, False, num_core) 1291 eff_pixel_size, cross_sectional_dim, False, num_core)
1296 print('OK BB')
1297 logging.debug(f'... _reconstructOnePlane took {time()-t0:.2f} seconds!') 1292 logging.debug(f'... _reconstructOnePlane took {time()-t0:.2f} seconds!')
1298 title = f'edges row{row} center offset{center_offset_vo:.2f} Vo' 1293 title = f'edges row{row} center offset{center_offset_vo:.2f} Vo'
1299 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs') 1294 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs')
1300 print('OK CC')
1301 del recon_plane 1295 del recon_plane
1302 if not galaxy_param['center_type_selector']: 1296 if not galaxy_param['center_type_selector']:
1303 del sinogram_T 1297 del sinogram_T
1304 return float(center_offset_vo) 1298 return float(center_offset_vo)
1305 else: 1299 else:
1335 del sinogram_T 1329 del sinogram_T
1336 del recon_plane 1330 del recon_plane
1337 return float(center_offset) 1331 return float(center_offset)
1338 1332
1339 # perform center finding search 1333 # perform center finding search
1340 print('OK DD')
1341 while True: 1334 while True:
1342 if self.galaxy_flag and galaxy_param and galaxy_param['center_type_selector']: 1335 if self.galaxy_flag and galaxy_param and galaxy_param['center_type_selector']:
1343 set_center = center_offset_vo 1336 set_center = center_offset_vo
1344 if galaxy_param['center_type_selector'] == 'user': 1337 if galaxy_param['center_type_selector'] == 'user':
1345 set_center = galaxy_param['set_center'] 1338 set_center = galaxy_param['set_center']
1381 else: 1374 else:
1382 self._plotEdgesOnePlane(recon_plane, title) 1375 self._plotEdgesOnePlane(recon_plane, title)
1383 if self.galaxy_flag or pyip.inputInt('\nContinue (0) or end the search (1): ', 1376 if self.galaxy_flag or pyip.inputInt('\nContinue (0) or end the search (1): ',
1384 min=0, max=1): 1377 min=0, max=1):
1385 break 1378 break
1386 print('OK EE')
1387 1379
1388 del sinogram_T 1380 del sinogram_T
1389 del recon_plane 1381 del recon_plane
1390 if self.galaxy_flag: 1382 if self.galaxy_flag:
1391 center_offset = center_offset_vo 1383 center_offset = center_offset_vo
1862 1854
1863 # Lower row center 1855 # Lower row center
1864 use_row = 'no' 1856 use_row = 'no'
1865 use_center = 'no' 1857 use_center = 'no'
1866 row = center_rows[0] 1858 row = center_rows[0]
1867 print('Ok1')
1868 if self.test_mode or self.galaxy_flag: 1859 if self.test_mode or self.galaxy_flag:
1869 assert(msnc.is_int(row, n1, n2-2)) 1860 assert(msnc.is_int(row, n1, n2-2))
1870 print('Ok2')
1871 if msnc.is_int(row, n1, n2-2): 1861 if msnc.is_int(row, n1, n2-2):
1872 if self.test_mode or self.galaxy_flag: 1862 if self.test_mode or self.galaxy_flag:
1873 use_row = 'yes' 1863 use_row = 'yes'
1874 else: 1864 else:
1875 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto') 1865 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', aspect='auto')
1880 if use_row != 'no': 1870 if use_row != 'no':
1881 center_offset = find_center.get('lower_center_offset') 1871 center_offset = find_center.get('lower_center_offset')
1882 if msnc.is_num(center_offset): 1872 if msnc.is_num(center_offset):
1883 use_center = pyip.inputYesNo('Current lower center offset = '+ 1873 use_center = pyip.inputYesNo('Current lower center offset = '+
1884 f'{center_offset}, use this value ([y]/n)? ', blank=True) 1874 f'{center_offset}, use this value ([y]/n)? ', blank=True)
1885 print(f'Ok3 {use_center} {use_row}')
1886 if use_center == 'no': 1875 if use_center == 'no':
1887 if use_row == 'no': 1876 if use_row == 'no':
1888 if not self.test_mode: 1877 if not self.test_mode:
1889 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}', 1878 msnc.quickImshow(center_stack[:,0,:], title=f'theta={theta_start}',
1890 aspect='auto') 1879 aspect='auto')
1893 if row == '': 1882 if row == '':
1894 row = n1 1883 row = n1
1895 if self.save_plots_only: 1884 if self.save_plots_only:
1896 msnc.clearFig(f'theta={theta_start}') 1885 msnc.clearFig(f'theta={theta_start}')
1897 # center_stack order: row,theta,column 1886 # center_stack order: row,theta,column
1898 print('Ok4')
1899 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg, 1887 center_offset = self._findCenterOnePlane(center_stack[row,:,:], row, thetas_deg,
1900 eff_pixel_size, cross_sectional_dim, num_core=num_core, 1888 eff_pixel_size, cross_sectional_dim, num_core=num_core,
1901 galaxy_param=galaxy_param) 1889 galaxy_param=galaxy_param)
1902 print('Ok5')
1903 logging.info(f'lower_center_offset = {center_offset:.2f} {type(center_offset)}') 1890 logging.info(f'lower_center_offset = {center_offset:.2f} {type(center_offset)}')
1904 print('Ok6')
1905 1891
1906 # Update config and save to file 1892 # Update config and save to file
1907 find_center['row_bounds'] = [n1, n2] 1893 find_center['row_bounds'] = [n1, n2]
1908 find_center['lower_row'] = row 1894 find_center['lower_row'] = row
1909 find_center['lower_center_offset'] = center_offset 1895 find_center['lower_center_offset'] = center_offset
2097 if zoom_perc == 100: 2083 if zoom_perc == 100:
2098 basetitle = 'recon stack fullres' 2084 basetitle = 'recon stack fullres'
2099 else: 2085 else:
2100 basetitle = f'recon stack {zoom_perc}p' 2086 basetitle = f'recon stack {zoom_perc}p'
2101 load_error = False 2087 load_error = False
2102 stacks = self.config['stack_info']['stacks']
2103 for i,stack in enumerate(stacks): 2088 for i,stack in enumerate(stacks):
2104 # Check if stack can be loaded 2089 # Check if stack can be loaded
2105 # reconstructed stack order for each one in stack : row/z,x,y 2090 # reconstructed stack order for each one in stack : row/z,x,y
2106 # preprocessed stack order for each one in stack: row,theta,column 2091 # preprocessed stack order for each one in stack: row,theta,column
2107 index = stack['index'] 2092 index = stack['index']
2166 combine_stacks = self.config.get('combine_stacks') 2151 combine_stacks = self.config.get('combine_stacks')
2167 if combine_stacks and index in combine_stacks.get('stacks', []): 2152 if combine_stacks and index in combine_stacks.get('stacks', []):
2168 combine_stacks['stacks'].remove(index) 2153 combine_stacks['stacks'].remove(index)
2169 self.cf.saveFile(self.config_out) 2154 self.cf.saveFile(self.config_out)
2170 2155
2171 # Save reconstructed tomography stack to file
2172 if self.galaxy_flag: 2156 if self.galaxy_flag:
2157 # Save reconstructed tomography stack to file
2173 t0 = time() 2158 t0 = time()
2174 output_name = galaxy_param['output_name'] 2159 output_name = galaxy_param['output_name']
2175 logging.info(f'Saving reconstructed tomography stack to {output_name} ...') 2160 logging.info(f'Saving reconstructed tomography stack to {output_name} ...')
2176 save_stacks = {f'set_{stack["index"]}':tomo_stack 2161 save_stacks = {f'set_{stack["index"]}':tomo_stack
2177 for stack,tomo_stack in zip(stacks,self.tomo_recon_stacks)} 2162 for stack,tomo_stack in zip(stacks,self.tomo_recon_stacks)}
2178 np.savez(output_name, **save_stacks) 2163 np.savez(output_name, **save_stacks)
2179 logging.info(f'... done in {time()-t0:.2f} seconds!') 2164 logging.info(f'... done in {time()-t0:.2f} seconds!')
2165
2166 # Create cross section profile in yz-plane
2167 tomosum = 0
2168 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,2)) for tomo_recon_stack in
2169 self.tomo_recon_stacks]
2170 msnc.quickPlot(tomosum, title='recon stack sum yz', path='center_slice_pngs',
2171 save_fig=True, save_only=True)
2172
2173 # Create cross section profile in xz-plane
2174 tomosum = 0
2175 [tomosum := tomosum+np.sum(tomo_recon_stack, axis=(0,1)) for tomo_recon_stack in
2176 self.tomo_recon_stacks]
2177 msnc.quickPlot(tomosum, title='recon stack sum xz', path='center_slice_pngs',
2178 save_fig=True, save_only=True)
2179
2180 # Create cross section profile in xy-plane
2181 num_tomo_stacks = len(stacks)
2182 row_bounds = self.config['find_center']['row_bounds']
2183 if not msnc.is_index_range(row_bounds, 0, self.tomo_recon_stacks[0].shape[0]):
2184 msnc.illegal_value('row_bounds', row_bounds, 'config file')
2185 return
2186 if num_tomo_stacks == 1:
2187 low_bound = row_bounds[0]
2188 else:
2189 low_bound = 0
2190 tomosum = np.sum(self.tomo_recon_stacks[0][low_bound:row_bounds[1],:,:], axis=(1,2))
2191 if num_tomo_stacks > 2:
2192 tomosum = np.concatenate([tomosum]+
2193 [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)])
2195 print(f'tomosum.shape = {tomosum.shape}')
2196 if num_tomo_stacks > 1:
2197 tomosum = np.concatenate([tomosum,
2198 np.sum(self.tomo_recon_stacks[num_tomo_stacks-1][row_bounds[0]:,:,:],
2199 axis=(1,2))])
2200 print(f'tomosum.shape = {tomosum.shape}')
2201 msnc.quickPlot(tomosum, title='recon stack sum xy', path='center_slice_pngs',
2202 save_fig=True, save_only=True)
2180 2203
2181 def combineTomoStacks(self): 2204 def combineTomoStacks(self):
2182 """Combine the reconstructed tomography stacks. 2205 """Combine the reconstructed tomography stacks.
2183 """ 2206 """
2184 # stack order: stack,row(z),x,y 2207 # stack order: stack,row(z),x,y
2278 num_tomo_stacks = stack_info['num'] 2301 num_tomo_stacks = stack_info['num']
2279 if num_tomo_stacks == 1: 2302 if num_tomo_stacks == 1:
2280 low_bound = row_bounds[0] 2303 low_bound = row_bounds[0]
2281 else: 2304 else:
2282 low_bound = 0 2305 low_bound = 0
2283 tomo_recon_combined = self.tomo_recon_stacks[0][low_bound:row_bounds[1]:, 2306 tomo_recon_combined = self.tomo_recon_stacks[0][low_bound:row_bounds[1],
2284 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]] 2307 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]]
2285 if num_tomo_stacks > 2: 2308 if num_tomo_stacks > 2:
2286 tomo_recon_combined = np.concatenate([tomo_recon_combined]+ 2309 tomo_recon_combined = np.concatenate([tomo_recon_combined]+
2287 [self.tomo_recon_stacks[i][row_bounds[0]:row_bounds[1], 2310 [self.tomo_recon_stacks[i][row_bounds[0]:row_bounds[1],
2288 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]] 2311 x_bounds[0]:x_bounds[1],y_bounds[0]:y_bounds[1]]