Mercurial > repos > rv43 > tomo
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]] |