Mercurial > repos > rv43 > tomo
comparison tomo.py @ 41:ef5c2f7b49ec draft
"planemo upload for repository https://github.com/rolfverberg/galaxytools commit 0d207c80e38a6019595ebe178f5678372b75f3e7"
author | rv43 |
---|---|
date | Thu, 21 Apr 2022 14:21:38 +0000 |
parents | fa94fe25ca46 |
children | 0b9ce9489ecc |
comparison
equal
deleted
inserted
replaced
40:fa94fe25ca46 | 41:ef5c2f7b49ec |
---|---|
18 import pyinputplus as pyip | 18 import pyinputplus as pyip |
19 except: | 19 except: |
20 pass | 20 pass |
21 import argparse | 21 import argparse |
22 import numpy as np | 22 import numpy as np |
23 import numexpr as ne | 23 try: |
24 import numexpr as ne | |
25 except: | |
26 pass | |
24 import multiprocessing as mp | 27 import multiprocessing as mp |
25 import scipy.ndimage as spi | 28 try: |
26 import tomopy | 29 import scipy.ndimage as spi |
30 except: | |
31 pass | |
32 try: | |
33 import tomopy | |
34 except: | |
35 pass | |
27 from time import time | 36 from time import time |
28 from skimage.transform import iradon | 37 try: |
29 from skimage.restoration import denoise_tv_chambolle | 38 from skimage.transform import iradon |
39 except: | |
40 pass | |
41 try: | |
42 from skimage.restoration import denoise_tv_chambolle | |
43 except: | |
44 pass | |
30 | 45 |
31 import msnc_tools as msnc | 46 import msnc_tools as msnc |
47 | |
48 # the following tomopy routines don't run with more than 24 cores on Galaxy-Dev | |
49 # - tomopy.find_center_vo | |
50 # - tomopy.prep.stripe.remove_stripe_fw | |
51 num_core_tomopy_limit = 24 | |
32 | 52 |
33 class set_numexpr_threads: | 53 class set_numexpr_threads: |
34 | 54 |
35 def __init__(self, num_core): | 55 def __init__(self, num_core): |
36 cpu_count = mp.cpu_count() | 56 cpu_count = mp.cpu_count() |
628 if self.is_valid: | 648 if self.is_valid: |
629 self.cf.saveFile(self.config_out) | 649 self.cf.saveFile(self.config_out) |
630 | 650 |
631 return | 651 return |
632 | 652 |
633 def _genDark(self, tdf_files, dark_field_pngname): | 653 def _genDark(self, tdf_files): |
634 """Generate dark field. | 654 """Generate dark field. |
635 """ | 655 """ |
636 # Load the dark field images | 656 # Load the dark field images |
637 logging.debug('Loading dark field...') | 657 logging.debug('Loading dark field...') |
638 dark_field = self.config['dark_field'] | 658 dark_field = self.config['dark_field'] |
649 tdf_mean = np.nanmean(self.tdf) | 669 tdf_mean = np.nanmean(self.tdf) |
650 logging.debug(f'tdf_cutoff = {tdf_cutoff}') | 670 logging.debug(f'tdf_cutoff = {tdf_cutoff}') |
651 logging.debug(f'tdf_mean = {tdf_mean}') | 671 logging.debug(f'tdf_mean = {tdf_mean}') |
652 np.nan_to_num(self.tdf, copy=False, nan=tdf_mean, posinf=tdf_mean, neginf=0.) | 672 np.nan_to_num(self.tdf, copy=False, nan=tdf_mean, posinf=tdf_mean, neginf=0.) |
653 if self.galaxy_flag: | 673 if self.galaxy_flag: |
654 msnc.quickImshow(self.tdf, title='dark field', name=dark_field_pngname, | 674 msnc.quickImshow(self.tdf, title='dark field', path='setup_pngs', |
655 save_fig=True, save_only=True) | 675 save_fig=True, save_only=True) |
656 elif not self.test_mode: | 676 elif not self.test_mode: |
657 msnc.quickImshow(self.tdf, title='dark field', path=self.output_folder, | 677 msnc.quickImshow(self.tdf, title='dark field', path=self.output_folder, |
658 save_fig=self.save_plots, save_only=self.save_plots_only) | 678 save_fig=self.save_plots, save_only=self.save_plots_only) |
659 | 679 |
660 def _genBright(self, tbf_files, bright_field_pngname): | 680 def _genBright(self, tbf_files): |
661 """Generate bright field. | 681 """Generate bright field. |
662 """ | 682 """ |
663 # Load the bright field images | 683 # Load the bright field images |
664 logging.debug('Loading bright field...') | 684 logging.debug('Loading bright field...') |
665 bright_field = self.config['bright_field'] | 685 bright_field = self.config['bright_field'] |
683 if self.tdf.size: | 703 if self.tdf.size: |
684 self.tbf -= self.tdf | 704 self.tbf -= self.tdf |
685 else: | 705 else: |
686 logging.warning('Dark field unavailable') | 706 logging.warning('Dark field unavailable') |
687 if self.galaxy_flag: | 707 if self.galaxy_flag: |
688 msnc.quickImshow(self.tbf, title='bright field', name=bright_field_pngname, | 708 msnc.quickImshow(self.tbf, title='bright field', path='setup_pngs', |
689 save_fig=True, save_only=True) | 709 save_fig=True, save_only=True) |
690 elif not self.test_mode: | 710 elif not self.test_mode: |
691 msnc.quickImshow(self.tbf, title='bright field', path=self.output_folder, | 711 msnc.quickImshow(self.tbf, title='bright field', path=self.output_folder, |
692 save_fig=self.save_plots, save_only=self.save_plots_only) | 712 save_fig=self.save_plots, save_only=self.save_plots_only) |
693 | 713 |
694 def _setDetectorBounds(self, tomo_stack_files, tomo_field_pngname, detectorbounds_pngname): | 714 def _setDetectorBounds(self, tomo_stack_files): |
695 """Set vertical detector bounds for image stack. | 715 """Set vertical detector bounds for image stack. |
696 """ | 716 """ |
697 preprocess = self.config.get('preprocess') | 717 preprocess = self.config.get('preprocess') |
698 if preprocess is None: | 718 if preprocess is None: |
699 img_x_bounds = [None, None] | 719 img_x_bounds = [None, None] |
727 if num_tomo_stacks > 1: | 747 if num_tomo_stacks > 1: |
728 delta_z = stacks[1]['ref_height']-stacks[0]['ref_height'] | 748 delta_z = stacks[1]['ref_height']-stacks[0]['ref_height'] |
729 for i in range(2, num_tomo_stacks): | 749 for i in range(2, num_tomo_stacks): |
730 delta_z = min(delta_z, stacks[i]['ref_height']-stacks[i-1]['ref_height']) | 750 delta_z = min(delta_z, stacks[i]['ref_height']-stacks[i-1]['ref_height']) |
731 logging.debug(f'delta_z = {delta_z}') | 751 logging.debug(f'delta_z = {delta_z}') |
732 num_x_min = int(delta_z/pixel_size)+1 | 752 num_x_min = int((delta_z-0.5*pixel_size)/pixel_size) |
733 logging.debug(f'num_x_min = {num_x_min}') | 753 logging.debug(f'num_x_min = {num_x_min}') |
734 if num_x_min > self.tbf.shape[0]: | 754 if num_x_min > self.tbf.shape[0]: |
735 logging.warning('Image bounds and pixel size prevent seamless stacking') | 755 logging.warning('Image bounds and pixel size prevent seamless stacking') |
736 num_x_min = self.tbf.shape[0] | 756 num_x_min = None |
737 | 757 |
738 # Select image bounds | 758 # Select image bounds |
739 if self.galaxy_flag: | 759 if self.galaxy_flag: |
740 if num_x_min is None or num_x_min >= self.tbf.shape[0]: | 760 x_sum = np.sum(self.tbf, 1) |
741 img_x_bounds = [0, self.tbf.shape[0]] | |
742 else: | |
743 margin = int(num_x_min/10) | |
744 offset = min(0, int((self.tbf.shape[0]-num_x_min)/2-margin)) | |
745 img_x_bounds = [offset, num_x_min+offset+2*margin] | |
746 tomo_stack = msnc.loadImageStack(tomo_stack_files[0], self.config['data_filetype'], | |
747 stacks[0]['img_offset'], 1) | |
748 x_sum = np.sum(tomo_stack[0,:,:], 1) | |
749 x_sum_min = x_sum.min() | 761 x_sum_min = x_sum.min() |
750 x_sum_max = x_sum.max() | 762 x_sum_max = x_sum.max() |
751 title = f'tomography image at theta={self.config["theta_range"]["start"]}' | 763 x_low = 0 |
752 msnc.quickImshow(tomo_stack[0,:,:], title=title, name=tomo_field_pngname, | 764 x_upp = x_sum.size |
753 save_fig=True, save_only=True, show_grid=True) | 765 if num_x_min is not None: |
766 fit = msnc.fitStep(y=x_sum, model='rectangle', form='atan') | |
767 x_low = fit.get('center1', None) | |
768 x_upp = fit.get('center2', None) | |
769 sig_low = fit.get('sigma1', None) | |
770 sig_upp = fit.get('sigma2', None) | |
771 if (x_low is not None and x_upp is not None and sig_low is not None and | |
772 sig_upp is not None and 0 <= x_low < x_upp <= x_sum.size and | |
773 (sig_low+sig_upp)/(x_upp-x_low) < 0.1): | |
774 if num_tomo_stacks == 1 or num_x_min is None: | |
775 x_low = int(x_low-(x_upp-x_low)/10) | |
776 x_upp = int(x_upp+(x_upp-x_low)/10) | |
777 else: | |
778 x_low = int((x_low+x_upp)/2-num_x_min/2) | |
779 x_upp = x_low+num_x_min | |
780 if x_low < 0: | |
781 x_low = 0 | |
782 if x_upp > x_sum.size: | |
783 x_upp = x_sum.size | |
784 else: | |
785 x_low = 0 | |
786 x_upp = x_sum.size | |
754 msnc.quickPlot((range(x_sum.size), x_sum), | 787 msnc.quickPlot((range(x_sum.size), x_sum), |
755 ([img_x_bounds[0], img_x_bounds[0]], [x_sum_min, x_sum_max], 'r-'), | 788 ([x_low, x_low], [x_sum_min, x_sum_max], 'r-'), |
756 ([img_x_bounds[1]-1, img_x_bounds[1]-1], [x_sum_min, x_sum_max], 'r-'), | 789 ([x_upp-1, x_upp-1], [x_sum_min, x_sum_max], 'r-'), |
757 title='sum over theta and y', name=detectorbounds_pngname, | 790 title=f'sum bright field over theta/y (row bounds: [{x_low}, {x_upp}])', |
758 save_fig=True, save_only=True, show_grid=True) | 791 path='setup_pngs', name='detectorbounds.png', save_fig=True, save_only=True, |
792 show_grid=True) | |
793 for i,stack in enumerate(stacks): | |
794 tomo_stack = msnc.loadImageStack(tomo_stack_files[i], self.config['data_filetype'], | |
795 stack['img_offset'], 1) | |
796 tomo_stack = tomo_stack[0,:,:] | |
797 if num_x_min is not None: | |
798 tomo_stack_max = tomo_stack.max() | |
799 tomo_stack[x_low,:] = tomo_stack_max | |
800 tomo_stack[x_upp-1,:] = tomo_stack_max | |
801 title = f'tomography image at theta={self.config["theta_range"]["start"]}' | |
802 msnc.quickImshow(tomo_stack, title=title, path='setup_pngs', | |
803 name=f'tomo_{stack["index"]}.png', save_fig=True, save_only=True, | |
804 show_grid=True) | |
805 del tomo_stack | |
759 | 806 |
760 # Update config and save to file | 807 # Update config and save to file |
808 img_x_bounds = [x_low, x_upp] | |
809 logging.debug(f'img_x_bounds: {img_x_bounds}') | |
761 if preprocess is None: | 810 if preprocess is None: |
762 self.cf.config['preprocess'] = {'img_x_bounds' : img_x_bounds} | 811 self.cf.config['preprocess'] = {'img_x_bounds' : img_x_bounds} |
763 else: | 812 else: |
764 preprocess['img_x_bounds'] = img_x_bounds | 813 preprocess['img_x_bounds'] = img_x_bounds |
765 self.cf.saveFile(self.config_out) | 814 self.cf.saveFile(self.config_out) |
830 title='sum over theta and y') | 879 title='sum over theta and y') |
831 print(f'lower bound = {img_x_bounds[0]} (inclusive)\n'+ | 880 print(f'lower bound = {img_x_bounds[0]} (inclusive)\n'+ |
832 f'upper bound = {img_x_bounds[1]} (exclusive)]') | 881 f'upper bound = {img_x_bounds[1]} (exclusive)]') |
833 use_bounds = pyip.inputYesNo('Accept these bounds ([y]/n)?: ', blank=True) | 882 use_bounds = pyip.inputYesNo('Accept these bounds ([y]/n)?: ', blank=True) |
834 if use_bounds == 'no': | 883 if use_bounds == 'no': |
884 use_fit = 'no' | |
835 fit = msnc.fitStep(y=x_sum, model='rectangle', form='atan') | 885 fit = msnc.fitStep(y=x_sum, model='rectangle', form='atan') |
836 x_low = fit.get('center1', None) | 886 x_low = fit.get('center1', None) |
837 x_upp = fit.get('center2', None) | 887 x_upp = fit.get('center2', None) |
838 if (x_low is not None and x_low >= 0 and x_upp is not None and | 888 sig_low = fit.get('sigma1', None) |
839 x_low < x_upp < x_sum.size): | 889 sig_upp = fit.get('sigma2', None) |
840 x_low = int(x_low-(x_upp-x_low)/10) | 890 if (x_low is not None and x_upp is not None and sig_low is not None and |
891 sig_upp is not None and 0 <= x_low < x_upp <= x_sum.size and | |
892 (sig_low+sig_upp)/(x_upp-x_low) < 0.1): | |
893 if num_tomo_stacks == 1 or num_x_min is None: | |
894 x_low = int(x_low-(x_upp-x_low)/10) | |
895 x_upp = int(x_upp+(x_upp-x_low)/10) | |
896 else: | |
897 x_low = int((x_low+x_upp)/2-num_x_min/2) | |
898 x_upp = x_low+num_x_min | |
841 if x_low < 0: | 899 if x_low < 0: |
842 x_low = 0 | 900 x_low = 0 |
843 x_upp = int(x_upp+(x_upp-x_low)/10) | 901 if x_upp > x_sum.size: |
844 if x_upp >= x_sum.size: | |
845 x_upp = x_sum.size | 902 x_upp = x_sum.size |
846 tmp = np.copy(self.tbf) | 903 tmp = np.copy(self.tbf) |
847 tmp_max = tmp.max() | 904 tmp_max = tmp.max() |
848 tmp[x_low,:] = tmp_max | 905 tmp[x_low,:] = tmp_max |
849 tmp[x_upp-1,:] = tmp_max | 906 tmp[x_upp-1,:] = tmp_max |
852 del tmp | 909 del tmp |
853 msnc.quickPlot((range(x_sum.size), x_sum), | 910 msnc.quickPlot((range(x_sum.size), x_sum), |
854 ([x_low, x_low], [x_sum_min, x_sum_max], 'r-'), | 911 ([x_low, x_low], [x_sum_min, x_sum_max], 'r-'), |
855 ([x_upp, x_upp], [x_sum_min, x_sum_max], 'r-'), | 912 ([x_upp, x_upp], [x_sum_min, x_sum_max], 'r-'), |
856 title='sum over theta and y') | 913 title='sum over theta and y') |
857 print(f'lower bound = {x_low} (inclusive)\nupper bound = {x_upp} (exclusive)]') | 914 print(f'lower bound = {x_low} (inclusive)') |
915 print(f'upper bound = {x_upp} (exclusive)]') | |
858 use_fit = pyip.inputYesNo('Accept these bounds ([y]/n)?: ', blank=True) | 916 use_fit = pyip.inputYesNo('Accept these bounds ([y]/n)?: ', blank=True) |
859 if use_fit == 'no': | 917 if use_fit == 'no': |
860 img_x_bounds = msnc.selectArrayBounds(x_sum, img_x_bounds[0], img_x_bounds[1], | 918 img_x_bounds = msnc.selectArrayBounds(x_sum, img_x_bounds[0], img_x_bounds[1], |
861 num_x_min, 'sum over theta and y') | 919 num_x_min, 'sum over theta and y') |
862 else: | 920 else: |
863 img_x_bounds = [x_low, x_upp] | 921 img_x_bounds = [x_low, x_upp] |
864 if num_x_min is not None and img_x_bounds[1]-img_x_bounds[0]+1 < num_x_min: | 922 if num_x_min is not None and img_x_bounds[1]-img_x_bounds[0]+1 < num_x_min: |
865 logging.warning('Image bounds and pixel size prevent seamless stacking') | 923 logging.warning('Image bounds and pixel size prevent seamless stacking') |
866 msnc.quickPlot(range(img_x_bounds[0], img_x_bounds[1]), | 924 #msnc.quickPlot(range(img_x_bounds[0], img_x_bounds[1]), |
867 x_sum[img_x_bounds[0]:img_x_bounds[1]], | 925 # x_sum[img_x_bounds[0]:img_x_bounds[1]], |
926 # title='sum over theta and y', path=self.output_folder, | |
927 # save_fig=self.save_plots, save_only=True) | |
928 msnc.quickPlot((range(x_sum.size), x_sum), | |
929 ([img_x_bounds[0], img_x_bounds[0]], [x_sum_min, x_sum_max], 'r-'), | |
930 ([img_x_bounds[1], img_x_bounds[1]], [x_sum_min, x_sum_max], 'r-'), | |
868 title='sum over theta and y', path=self.output_folder, | 931 title='sum over theta and y', path=self.output_folder, |
869 save_fig=self.save_plots, save_only=True) | 932 save_fig=self.save_plots, save_only=True) |
870 del x_sum | 933 del x_sum |
934 for i,stack in enumerate(stacks): | |
935 tomo_stack = msnc.loadImageStack(tomo_stack_files[i], self.config['data_filetype'], | |
936 stack['img_offset'], 1) | |
937 tomo_stack = tomo_stack[0,:,:] | |
938 if num_x_min is not None: | |
939 tomo_stack_max = tomo_stack.max() | |
940 tomo_stack[img_x_bounds[0],:] = tomo_stack_max | |
941 tomo_stack[img_x_bounds[1]-1,:] = tomo_stack_max | |
942 title = f'tomography image at theta={self.config["theta_range"]["start"]}' | |
943 msnc.quickImshow(tomo_stack, title=title, path='setup_pngs', | |
944 name=f'tomo_{stack["index"]}.png', save_fig=self.save_plots, save_only=True, | |
945 show_grid=True) | |
946 del tomo_stack | |
871 logging.debug(f'img_x_bounds: {img_x_bounds}') | 947 logging.debug(f'img_x_bounds: {img_x_bounds}') |
872 | 948 |
873 if self.save_plots_only: | 949 if self.save_plots_only: |
874 msnc.clearFig('bright field') | 950 msnc.clearFig('bright field') |
875 msnc.clearFig('sum over theta and y') | 951 msnc.clearFig('sum over theta and y') |
1146 # recon_sinogram = filters.gaussian(recon_sinogram, 3.0) | 1222 # recon_sinogram = filters.gaussian(recon_sinogram, 3.0) |
1147 recon_sinogram = spi.gaussian_filter(recon_sinogram, 0.5) | 1223 recon_sinogram = spi.gaussian_filter(recon_sinogram, 0.5) |
1148 recon_clean = np.expand_dims(recon_sinogram, axis=0) | 1224 recon_clean = np.expand_dims(recon_sinogram, axis=0) |
1149 del recon_sinogram | 1225 del recon_sinogram |
1150 t1 = time() | 1226 t1 = time() |
1151 logging.info(f'running tomopy.misc.corr.remove_ring on {num_core} cores ...') | 1227 logging.debug(f'running remove_ring on {num_core} cores ...') |
1152 recon_clean = tomopy.misc.corr.remove_ring(recon_clean, rwidth=17, ncore=num_core) | 1228 recon_clean = tomopy.misc.corr.remove_ring(recon_clean, rwidth=17, ncore=num_core) |
1153 logging.info(f'... tomopy.misc.corr.remove_ring took {time()-t1:.2f} seconds!') | 1229 logging.debug(f'... remove_ring took {time()-t1:.2f} seconds!') |
1154 logging.debug(f'filtering and removing ring artifact took {time()-t0:.2f} seconds!') | 1230 logging.debug(f'filtering and removing ring artifact took {time()-t0:.2f} seconds!') |
1155 return recon_clean | 1231 return recon_clean |
1156 | 1232 |
1157 def _plotEdgesOnePlane(self, recon_plane, title, path=None, weight=0.001): | 1233 def _plotEdgesOnePlane(self, recon_plane, title, path=None, weight=0.001): |
1158 # RV parameters for the denoise, gaussian, and ring removal will be different for different feature sizes | 1234 # RV parameters for the denoise, gaussian, and ring removal will be different for different feature sizes |
1175 def _findCenterOnePlane(self, sinogram, row, thetas_deg, eff_pixel_size, cross_sectional_dim, | 1251 def _findCenterOnePlane(self, sinogram, row, thetas_deg, eff_pixel_size, cross_sectional_dim, |
1176 tol=0.1, num_core=1, galaxy_param=None): | 1252 tol=0.1, num_core=1, galaxy_param=None): |
1177 """Find center for a single tomography plane. | 1253 """Find center for a single tomography plane. |
1178 """ | 1254 """ |
1179 if self.galaxy_flag: | 1255 if self.galaxy_flag: |
1180 assert(galaxy_param) | 1256 assert(isinstance(galaxy_param, dict)) |
1181 if not os.path.exists('find_center_pngs'): | 1257 if not os.path.exists('find_center_pngs'): |
1182 os.mkdir('find_center_pngs') | 1258 os.mkdir('find_center_pngs') |
1183 # sinogram index order: theta,column | 1259 # sinogram index order: theta,column |
1184 # need index order column,theta for iradon, so take transpose | 1260 # need index order column,theta for iradon, so take transpose |
1185 sinogram_T = sinogram.T | 1261 sinogram_T = sinogram.T |
1186 center = sinogram.shape[1]/2 | 1262 center = sinogram.shape[1]/2 |
1187 | 1263 |
1188 # try automatic center finding routines for initial value | 1264 # try automatic center finding routines for initial value |
1189 t0 = time() | 1265 t0 = time() |
1190 if num_core > 24: | 1266 if num_core > num_core_tomopy_limit: |
1191 logging.info('running tomopy.find_center_vo on 24 cores ...') | 1267 logging.debug(f'running find_center_vo on {num_core_tomopy_limit} cores ...') |
1192 tomo_center = tomopy.find_center_vo(sinogram, ncore=24) | 1268 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core_tomopy_limit) |
1193 else: | 1269 else: |
1194 logging.info(f'running tomopy.find_center_vo on {num_core} cores ...') | 1270 logging.debug(f'running find_center_vo on {num_core} cores ...') |
1195 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core) | 1271 tomo_center = tomopy.find_center_vo(sinogram, ncore=num_core) |
1196 logging.info(f'... tomopy.find_center_vo took {time()-t0:.2f} seconds!') | 1272 logging.debug(f'... find_center_vo took {time()-t0:.2f} seconds!') |
1197 center_offset_vo = tomo_center-center | 1273 center_offset_vo = tomo_center-center |
1198 if self.test_mode: | 1274 if self.test_mode: |
1199 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') | 1275 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') |
1200 del sinogram_T | 1276 del sinogram_T |
1201 return float(center_offset_vo) | 1277 return float(center_offset_vo) |
1202 elif self.galaxy_flag: | 1278 elif self.galaxy_flag: |
1203 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') | 1279 logging.info(f'Center at row {row} using Nghia Vo’s method = {center_offset_vo:.2f}') |
1204 t0 = time() | 1280 t0 = time() |
1205 logging.info(f'running self._reconstructOnePlane on {num_core} cores ...') | 1281 logging.debug(f'running _reconstructOnePlane on {num_core} cores ...') |
1206 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg, | 1282 recon_plane = self._reconstructOnePlane(sinogram_T, tomo_center, thetas_deg, |
1207 eff_pixel_size, cross_sectional_dim, False, num_core) | 1283 eff_pixel_size, cross_sectional_dim, False, num_core) |
1208 logging.info(f'... self._reconstructOnePlane took {time()-t0:.2f} seconds!') | 1284 logging.debug(f'... _reconstructOnePlane took {time()-t0:.2f} seconds!') |
1209 title = f'edges row{row} center offset{center_offset_vo:.2f} Vo' | 1285 title = f'edges row{row} center offset{center_offset_vo:.2f} Vo' |
1210 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs') | 1286 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs') |
1211 del recon_plane | 1287 del recon_plane |
1212 if not galaxy_param['center_type_selector']: | 1288 if not galaxy_param['center_type_selector']: |
1213 del sinogram_T | 1289 del sinogram_T |
1277 num_center_offset = 1+int((center_offset_upp-center_offset_low)/center_offset_step) | 1353 num_center_offset = 1+int((center_offset_upp-center_offset_low)/center_offset_step) |
1278 center_offsets = np.linspace(center_offset_low, center_offset_upp, num_center_offset) | 1354 center_offsets = np.linspace(center_offset_low, center_offset_upp, num_center_offset) |
1279 for center_offset in center_offsets: | 1355 for center_offset in center_offsets: |
1280 if center_offset == center_offset_vo: | 1356 if center_offset == center_offset_vo: |
1281 continue | 1357 continue |
1282 logging.info(f'center_offset = {center_offset:.2f}') | |
1283 t0 = time() | 1358 t0 = time() |
1284 logging.info(f'running self._reconstructOnePlane on {num_core} cores ...') | 1359 logging.debug(f'running _reconstructOnePlane on {num_core} cores ...') |
1285 recon_plane = self._reconstructOnePlane(sinogram_T, center_offset+center, | 1360 recon_plane = self._reconstructOnePlane(sinogram_T, center_offset+center, |
1286 thetas_deg, eff_pixel_size, cross_sectional_dim, False, num_core) | 1361 thetas_deg, eff_pixel_size, cross_sectional_dim, False, num_core) |
1287 logging.info(f'... self._reconstructOnePlane took {time()-t0:.2f} seconds!') | 1362 logging.debug(f'... _reconstructOnePlane took {time()-t0:.2f} seconds!') |
1288 title = f'edges row{row} center_offset{center_offset:.2f}' | 1363 title = f'edges row{row} center_offset{center_offset:.2f}' |
1289 if self.galaxy_flag: | 1364 if self.galaxy_flag: |
1290 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs') | 1365 self._plotEdgesOnePlane(recon_plane, title, path='find_center_pngs') |
1291 else: | 1366 else: |
1292 self._plotEdgesOnePlane(recon_plane, title) | 1367 self._plotEdgesOnePlane(recon_plane, title) |
1333 raise ValueError('center_offsets dimension mismatch in reconstructOneTomoStack') | 1408 raise ValueError('center_offsets dimension mismatch in reconstructOneTomoStack') |
1334 centers = center_offsets | 1409 centers = center_offsets |
1335 centers += tomo_stack.shape[2]/2 | 1410 centers += tomo_stack.shape[2]/2 |
1336 if True: | 1411 if True: |
1337 t0 = time() | 1412 t0 = time() |
1338 if num_core > 24: | 1413 if num_core > num_core_tomopy_limit: |
1339 logging.info(f'running tomopy.prep.stripe.remove_stripe_fw on 24 cores ...') | 1414 logging.debug('running remove_stripe_fw on {num_core_tomopy_limit} cores ...') |
1340 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( | 1415 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( |
1341 tomo_stack[row_bounds[0]:row_bounds[1]], sigma=sigma, ncore=24) | 1416 tomo_stack[row_bounds[0]:row_bounds[1]], sigma=sigma, |
1417 ncore=num_core_tomopy_limit) | |
1342 else: | 1418 else: |
1343 logging.info(f'running tomopy.prep.stripe.remove_stripe_fw on {num_core} cores ...') | 1419 logging.debug(f'running remove_stripe_fw on {num_core} cores ...') |
1344 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( | 1420 tomo_stack = tomopy.prep.stripe.remove_stripe_fw( |
1345 tomo_stack[row_bounds[0]:row_bounds[1]], sigma=sigma, ncore=num_core) | 1421 tomo_stack[row_bounds[0]:row_bounds[1]], sigma=sigma, ncore=num_core) |
1346 logging.info(f'... tomopy.prep.stripe.remove_stripe_fw took {time()-t0:.2f} seconds!') | 1422 logging.debug(f'... tomopy.prep.stripe.remove_stripe_fw took {time()-t0:.2f} seconds!') |
1347 else: | 1423 else: |
1348 tomo_stack = tomo_stack[row_bounds[0]:row_bounds[1]] | 1424 tomo_stack = tomo_stack[row_bounds[0]:row_bounds[1]] |
1349 logging.info('performing initial reconstruction') | 1425 logging.debug('performing initial reconstruction') |
1350 t0 = time() | 1426 t0 = time() |
1351 logging.info(f'running tomopy.recon on {num_core} cores ...') | 1427 logging.debug(f'running recon on {num_core} cores ...') |
1352 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, sinogram_order=True, | 1428 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, sinogram_order=True, |
1353 algorithm=algorithm, ncore=num_core) | 1429 algorithm=algorithm, ncore=num_core) |
1354 logging.info(f'... tomopy.recon took {time()-t0:.2f} seconds!') | 1430 logging.debug(f'... recon took {time()-t0:.2f} seconds!') |
1355 if run_secondary_sirt and secondary_iter > 0: | 1431 if run_secondary_sirt and secondary_iter > 0: |
1356 logging.info(f'running {secondary_iter} secondary iterations') | 1432 logging.debug(f'running {secondary_iter} secondary iterations') |
1357 #options = {'method':'SIRT_CUDA', 'proj_type':'cuda', 'num_iter':secondary_iter} | 1433 #options = {'method':'SIRT_CUDA', 'proj_type':'cuda', 'num_iter':secondary_iter} |
1358 #RV: doesn't work for me: "Error: CUDA error 803: system has unsupported display driver / | 1434 #RV: doesn't work for me: "Error: CUDA error 803: system has unsupported display driver / |
1359 # cuda driver combination." | 1435 # cuda driver combination." |
1360 #options = {'method':'SIRT', 'proj_type':'linear', 'MinConstraint': 0, 'num_iter':secondary_iter} | 1436 #options = {'method':'SIRT', 'proj_type':'linear', 'MinConstraint': 0, 'num_iter':secondary_iter} |
1361 #SIRT did not finish while running overnight | 1437 #SIRT did not finish while running overnight |
1362 #options = {'method':'SART', 'proj_type':'linear', 'num_iter':secondary_iter} | 1438 #options = {'method':'SART', 'proj_type':'linear', 'num_iter':secondary_iter} |
1363 options = {'method':'SART', 'proj_type':'linear', 'MinConstraint': 0, | 1439 options = {'method':'SART', 'proj_type':'linear', 'MinConstraint': 0, |
1364 'num_iter':secondary_iter} | 1440 'num_iter':secondary_iter} |
1365 t0 = time() | 1441 t0 = time() |
1366 logging.info(f'running tomopy.recon on {num_core} cores ...') | 1442 logging.debug(f'running recon on {num_core} cores ...') |
1367 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, | 1443 tomo_recon_stack = tomopy.recon(tomo_stack, thetas, centers, |
1368 init_recon=tomo_recon_stack, options=options, sinogram_order=True, | 1444 init_recon=tomo_recon_stack, options=options, sinogram_order=True, |
1369 algorithm=tomopy.astra, ncore=num_core) | 1445 algorithm=tomopy.astra, ncore=num_core) |
1370 logging.info(f'... tomopy.recon took {time()-t0:.2f} seconds!') | 1446 logging.debug(f'... recon took {time()-t0:.2f} seconds!') |
1371 if True: | 1447 if True: |
1372 t0 = time() | 1448 t0 = time() |
1373 logging.info(f'running tomopy.misc.corr.remove_ring on {num_core} cores ...') | 1449 logging.debug(f'running remove_ring on {num_core} cores ...') |
1374 tomopy.misc.corr.remove_ring(tomo_recon_stack, rwidth=rwidth, out=tomo_recon_stack, | 1450 tomopy.misc.corr.remove_ring(tomo_recon_stack, rwidth=rwidth, out=tomo_recon_stack, |
1375 ncore=num_core) | 1451 ncore=num_core) |
1376 logging.info(f'... tomopy.misc.corr.remove_ring took {time()-t0:.2f} seconds!') | 1452 logging.debug(f'... remove_ring took {time()-t0:.2f} seconds!') |
1377 return tomo_recon_stack | 1453 return tomo_recon_stack |
1378 | 1454 |
1379 def findImageFiles(self): | 1455 def findImageFiles(self, tiff_to_h5_flag = False): |
1380 """Find all available image files. | 1456 """Find all available image files. |
1381 """ | 1457 """ |
1382 self.is_valid = True | 1458 self.is_valid = True |
1383 | 1459 |
1384 # Find dark field images | 1460 # Find dark field images |
1405 logging.error('Inconsistent image start index for dark field images') | 1481 logging.error('Inconsistent image start index for dark field images') |
1406 if dark_field['data_path']: | 1482 if dark_field['data_path']: |
1407 self.is_valid = False | 1483 self.is_valid = False |
1408 logging.info(f'Number of dark field images = {dark_field["num"]}') | 1484 logging.info(f'Number of dark field images = {dark_field["num"]}') |
1409 logging.info(f'Dark field image start index = {dark_field["img_start"]}') | 1485 logging.info(f'Dark field image start index = {dark_field["img_start"]}') |
1486 if num_imgs and tiff_to_h5_flag and self.config['data_filetype'] == 'tif': | |
1487 dark_files = msnc.combine_tiffs_in_h5(dark_files, num_imgs, | |
1488 f'{self.config["work_folder"]}/dark_field.h5') | |
1489 dark_field['data_path'] = dark_files[0] | |
1410 | 1490 |
1411 # Find bright field images | 1491 # Find bright field images |
1412 bright_field = self.config['bright_field'] | 1492 bright_field = self.config['bright_field'] |
1413 img_start, num_imgs, bright_files = msnc.findImageFiles( | 1493 img_start, num_imgs, bright_files = msnc.findImageFiles( |
1414 bright_field['data_path'], self.config['data_filetype'], 'bright field') | 1494 bright_field['data_path'], self.config['data_filetype'], 'bright field') |
1429 if img_start_old < img_start: | 1509 if img_start_old < img_start: |
1430 logging.warning('Inconsistent image start index for bright field images') | 1510 logging.warning('Inconsistent image start index for bright field images') |
1431 self.is_valid = False | 1511 self.is_valid = False |
1432 logging.info(f'Number of bright field images = {bright_field["num"]}') | 1512 logging.info(f'Number of bright field images = {bright_field["num"]}') |
1433 logging.info(f'Bright field image start index = {bright_field["img_start"]}') | 1513 logging.info(f'Bright field image start index = {bright_field["img_start"]}') |
1514 if num_imgs and tiff_to_h5_flag and self.config['data_filetype'] == 'tif': | |
1515 bright_files = msnc.combine_tiffs_in_h5(bright_files, num_imgs, | |
1516 f'{self.config["work_folder"]}/bright_field.h5') | |
1517 bright_field['data_path'] = bright_files[0] | |
1434 | 1518 |
1435 # Find tomography images | 1519 # Find tomography images |
1436 tomo_stack_files = [] | 1520 tomo_stack_files = [] |
1437 for stack in self.config['stack_info']['stacks']: | 1521 for stack in self.config['stack_info']['stacks']: |
1438 index = stack['index'] | 1522 index = stack['index'] |
1455 if img_start_old < img_start: | 1539 if img_start_old < img_start: |
1456 logging.warning('Inconsistent image start index for tomography images') | 1540 logging.warning('Inconsistent image start index for tomography images') |
1457 self.is_valid = False | 1541 self.is_valid = False |
1458 logging.info(f'Number of tomography images for set {index} = {stack["num"]}') | 1542 logging.info(f'Number of tomography images for set {index} = {stack["num"]}') |
1459 logging.info(f'Tomography set {index} image start index = {stack["img_start"]}') | 1543 logging.info(f'Tomography set {index} image start index = {stack["img_start"]}') |
1544 if num_imgs and tiff_to_h5_flag and self.config['data_filetype'] == 'tif': | |
1545 tomo_files = msnc.combine_tiffs_in_h5(tomo_files, num_imgs, | |
1546 f'{self.config["work_folder"]}/tomo_field_{index}.h5') | |
1547 stack['data_path'] = tomo_files[0] | |
1460 tomo_stack_files.append(tomo_files) | 1548 tomo_stack_files.append(tomo_files) |
1461 del tomo_files | 1549 del tomo_files |
1462 | 1550 |
1463 # Safe updated config | 1551 # Safe updated config |
1552 if tiff_to_h5_flag: | |
1553 self.config['data_filetype'] == 'h5' | |
1464 if self.is_valid: | 1554 if self.is_valid: |
1465 self.cf.saveFile(self.config_out) | 1555 self.cf.saveFile(self.config_out) |
1466 | 1556 |
1467 return dark_files, bright_files, tomo_stack_files | 1557 return dark_files, bright_files, tomo_stack_files |
1468 | 1558 |
1499 assert(isinstance(galaxy_param, dict)) | 1589 assert(isinstance(galaxy_param, dict)) |
1500 tdf_files = galaxy_param['tdf_files'] | 1590 tdf_files = galaxy_param['tdf_files'] |
1501 tbf_files = galaxy_param['tbf_files'] | 1591 tbf_files = galaxy_param['tbf_files'] |
1502 tomo_stack_files = galaxy_param['tomo_stack_files'] | 1592 tomo_stack_files = galaxy_param['tomo_stack_files'] |
1503 assert(num_tomo_stacks == len(tomo_stack_files)) | 1593 assert(num_tomo_stacks == len(tomo_stack_files)) |
1594 if not os.path.exists('setup_pngs'): | |
1595 os.mkdir('setup_pngs') | |
1504 else: | 1596 else: |
1505 if galaxy_param: | 1597 if galaxy_param: |
1506 logging.warning('Ignoring galaxy_param in findCenters (only for Galaxy)') | 1598 logging.warning('Ignoring galaxy_param in genTomoStacks (only for Galaxy)') |
1507 galaxy_param = None | 1599 galaxy_param = None |
1508 tdf_files, tbf_files, tomo_stack_files = self.findImageFiles() | 1600 tdf_files, tbf_files, tomo_stack_files = self.findImageFiles() |
1509 if not self.is_valid: | 1601 if not self.is_valid: |
1510 return | 1602 return |
1511 for i,stack in enumerate(stacks): | 1603 for i,stack in enumerate(stacks): |
1523 if not self.is_valid: | 1615 if not self.is_valid: |
1524 return | 1616 return |
1525 | 1617 |
1526 # Generate dark field | 1618 # Generate dark field |
1527 if tdf_files: | 1619 if tdf_files: |
1528 self._genDark(tdf_files, galaxy_param['dark_field_pngname']) | 1620 self._genDark(tdf_files) |
1529 | 1621 |
1530 # Generate bright field | 1622 # Generate bright field |
1531 self._genBright(tbf_files, galaxy_param['bright_field_pngname']) | 1623 self._genBright(tbf_files) |
1532 | 1624 |
1533 # Set vertical detector bounds for image stack | 1625 # Set vertical detector bounds for image stack |
1534 self._setDetectorBounds(tomo_stack_files, galaxy_param['tomo_field_pngname'], | 1626 self._setDetectorBounds(tomo_stack_files) |
1535 galaxy_param['detectorbounds_pngname']) | |
1536 | 1627 |
1537 # Set zoom and/or theta skip to reduce memory the requirement | 1628 # Set zoom and/or theta skip to reduce memory the requirement |
1538 self._setZoomOrSkip() | 1629 self._setZoomOrSkip() |
1539 | 1630 |
1540 # Generate tomography fields | 1631 # Generate tomography fields |
1575 logging.debug('Find centers for tomography stacks') | 1666 logging.debug('Find centers for tomography stacks') |
1576 stacks = self.config['stack_info']['stacks'] | 1667 stacks = self.config['stack_info']['stacks'] |
1577 available_stacks = [stack['index'] for stack in stacks if stack.get('preprocessed', False)] | 1668 available_stacks = [stack['index'] for stack in stacks if stack.get('preprocessed', False)] |
1578 logging.debug('Available stacks: {available_stacks}') | 1669 logging.debug('Available stacks: {available_stacks}') |
1579 if self.galaxy_flag: | 1670 if self.galaxy_flag: |
1580 assert(isinstance(galaxy_param, dict)) | |
1581 row_bounds = galaxy_param['row_bounds'] | 1671 row_bounds = galaxy_param['row_bounds'] |
1582 center_rows = galaxy_param['center_rows'] | 1672 center_rows = galaxy_param['center_rows'] |
1583 if center_rows is None: | |
1584 logging.error('Missing center_rows entry in galaxy_param') | |
1585 return | |
1586 center_type_selector = galaxy_param['center_type_selector'] | 1673 center_type_selector = galaxy_param['center_type_selector'] |
1587 if center_type_selector: | 1674 if center_type_selector: |
1588 if center_type_selector == 'vo': | 1675 if center_type_selector == 'vo': |
1589 set_center = None | 1676 set_center = None |
1590 elif center_type_selector == 'user': | 1677 elif center_type_selector == 'user': |
1636 if not center_stack.size: | 1723 if not center_stack.size: |
1637 stacks[0]['preprocessed'] = False | 1724 stacks[0]['preprocessed'] = False |
1638 raise OSError('Unable to load the required preprocessed tomography stack') | 1725 raise OSError('Unable to load the required preprocessed tomography stack') |
1639 assert(stacks[0].get('preprocessed', False) == True) | 1726 assert(stacks[0].get('preprocessed', False) == True) |
1640 elif self.galaxy_flag: | 1727 elif self.galaxy_flag: |
1641 logging.error('CHECK/FIX FOR GALAXY') | 1728 center_stack_index = stacks[int(num_tomo_stacks/2)]['index'] |
1642 #center_stack_index = stacks[int(num_tomo_stacks/2)]['index'] | 1729 tomo_stack_index = available_stacks.index(center_stack_index) |
1730 center_stack = self.tomo_stacks[tomo_stack_index] | |
1731 if not center_stack.size: | |
1732 stacks[tomo_stack_index]['preprocessed'] = False | |
1733 raise OSError('Unable to load the required preprocessed tomography stack') | |
1734 assert(stacks[tomo_stack_index].get('preprocessed', False) == True) | |
1643 else: | 1735 else: |
1644 while True: | 1736 while True: |
1645 if not center_stack_index: | 1737 if not center_stack_index: |
1646 center_stack_index = pyip.inputInt('\nEnter tomography stack index to get ' | 1738 center_stack_index = pyip.inputInt('\nEnter tomography stack index to get ' |
1647 f'rotation axis centers {available_stacks}: ') | 1739 f'rotation axis centers {available_stacks}: ') |
1673 row_bounds = [0, center_stack.shape[0]] | 1765 row_bounds = [0, center_stack.shape[0]] |
1674 if row_bounds[0] == -1: | 1766 if row_bounds[0] == -1: |
1675 row_bounds[0] = 0 | 1767 row_bounds[0] = 0 |
1676 if row_bounds[1] == -1: | 1768 if row_bounds[1] == -1: |
1677 row_bounds[1] = center_stack.shape[0] | 1769 row_bounds[1] = center_stack.shape[0] |
1770 if center_rows[0] == -1: | |
1771 center_rows[0] = 0 | |
1772 if center_rows[1] == -1: | |
1773 center_rows[1] = center_stack.shape[0]-1 | |
1678 if not msnc.is_index_range(row_bounds, 0, center_stack.shape[0]): | 1774 if not msnc.is_index_range(row_bounds, 0, center_stack.shape[0]): |
1679 msnc.illegal_value('row_bounds', row_bounds) | 1775 msnc.illegal_value('row_bounds', row_bounds) |
1680 return | 1776 return |
1681 | 1777 |
1682 # Set thetas (in degrees) | 1778 # Set thetas (in degrees) |
1716 title=f'center stack theta={theta_start}') | 1812 title=f'center stack theta={theta_start}') |
1717 else: | 1813 else: |
1718 n1 = row_bounds[0] | 1814 n1 = row_bounds[0] |
1719 n2 = row_bounds[1] | 1815 n2 = row_bounds[1] |
1720 else: | 1816 else: |
1721 logging.error('CHECK/FIX FOR GALAXY') | |
1722 tomo_ref_heights = [stack['ref_height'] for stack in stacks] | 1817 tomo_ref_heights = [stack['ref_height'] for stack in stacks] |
1723 n1 = int((1.+(tomo_ref_heights[0]+center_stack.shape[0]*eff_pixel_size- | 1818 n1 = int((1.+(tomo_ref_heights[0]+center_stack.shape[0]*eff_pixel_size- |
1724 tomo_ref_heights[1])/eff_pixel_size)/2) | 1819 tomo_ref_heights[1])/eff_pixel_size)/2) |
1725 n2 = center_stack.shape[0]-n1 | 1820 n2 = center_stack.shape[0]-n1 |
1726 logging.debug(f'n1 = {n1}, n2 = {n2} (n2-n1) = {(n2-n1)*eff_pixel_size:.3f} mm') | 1821 logging.debug(f'n1 = {n1}, n2 = {n2} (n2-n1) = {(n2-n1)*eff_pixel_size:.3f} mm') |
1727 if not center_stack.size: | |
1728 RuntimeError('Center stack not loaded') | |
1729 if not self.test_mode and not self.galaxy_flag: | 1822 if not self.test_mode and not self.galaxy_flag: |
1730 tmp = center_stack[:,0,:] | 1823 tmp = center_stack[:,0,:] |
1731 tmp_max = tmp.max() | 1824 tmp_max = tmp.max() |
1732 tmp[n1,:] = tmp_max | 1825 tmp[n1,:] = tmp_max |
1733 tmp[n2-1,:] = tmp_max | 1826 tmp[n2-1,:] = tmp_max |
1916 def reconstructTomoStacks(self, galaxy_param=None, num_core=None): | 2009 def reconstructTomoStacks(self, galaxy_param=None, num_core=None): |
1917 """Reconstruct tomography stacks. | 2010 """Reconstruct tomography stacks. |
1918 """ | 2011 """ |
1919 if num_core is None: | 2012 if num_core is None: |
1920 num_core = self.num_core | 2013 num_core = self.num_core |
1921 logging.info(f'num_core available = {num_core}') | 2014 logging.info(f'num_core = {num_core}') |
1922 #if num_core > 24: | |
1923 # num_core = 24 | |
1924 logging.info(f'num_core used = {num_core}') | |
1925 if self.galaxy_flag: | 2015 if self.galaxy_flag: |
1926 assert(galaxy_param) | 2016 assert(galaxy_param) |
1927 if not os.path.exists('center_slice_pngs'): | 2017 if not os.path.exists('center_slice_pngs'): |
1928 os.mkdir('center_slice_pngs') | 2018 os.mkdir('center_slice_pngs') |
1929 logging.debug('Reconstruct tomography stacks') | 2019 logging.debug('Reconstruct tomography stacks') |
2014 continue | 2104 continue |
2015 assert(0 <= lower_row < upper_row < self.tomo_stacks[i].shape[0]) | 2105 assert(0 <= lower_row < upper_row < self.tomo_stacks[i].shape[0]) |
2016 center_offsets = [lower_center_offset-lower_row*center_slope, | 2106 center_offsets = [lower_center_offset-lower_row*center_slope, |
2017 upper_center_offset+(self.tomo_stacks[i].shape[0]-1-upper_row)*center_slope] | 2107 upper_center_offset+(self.tomo_stacks[i].shape[0]-1-upper_row)*center_slope] |
2018 t0 = time() | 2108 t0 = time() |
2019 logging.info(f'running self._reconstructOneTomoStack on {num_core} cores ...') | 2109 logging.debug(f'running _reconstructOneTomoStack on {num_core} cores ...') |
2020 self.tomo_recon_stacks[i]= self._reconstructOneTomoStack(self.tomo_stacks[i], | 2110 self.tomo_recon_stacks[i]= self._reconstructOneTomoStack(self.tomo_stacks[i], |
2021 thetas, center_offsets=center_offsets, sigma=0.1, num_core=num_core, | 2111 thetas, center_offsets=center_offsets, sigma=0.1, num_core=num_core, |
2022 algorithm='gridrec', run_secondary_sirt=True, secondary_iter=25) | 2112 algorithm='gridrec', run_secondary_sirt=True, secondary_iter=25) |
2023 logging.info(f'... self._reconstructOneTomoStack took {time()-t0:.2f} seconds!') | 2113 logging.debug(f'... _reconstructOneTomoStack took {time()-t0:.2f} seconds!') |
2024 #logging.info(f'Reconstruction of stack {index} took {time()-t0:.2f} seconds!') | 2114 logging.info(f'Reconstruction of stack {index} took {time()-t0:.2f} seconds!') |
2025 if self.galaxy_flag: | 2115 if self.galaxy_flag: |
2026 x_slice = int(self.tomo_stacks[i].shape[0]/2) | 2116 x_slice = int(self.tomo_stacks[i].shape[0]/2) |
2027 title = f'{basetitle} {index} xslice{x_slice}' | 2117 title = f'{basetitle} {index} xslice{x_slice}' |
2028 msnc.quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, | 2118 msnc.quickImshow(self.tomo_recon_stacks[i][x_slice,:,:], title=title, |
2029 path='center_slice_pngs', save_fig=True, save_only=True) | 2119 path='center_slice_pngs', save_fig=True, save_only=True) |
2219 z_bounds = [0, tomo_recon_combined.shape[0]] | 2309 z_bounds = [0, tomo_recon_combined.shape[0]] |
2220 else: | 2310 else: |
2221 z_bounds = msnc.selectArrayBounds(tomosum, title='recon combined sum xy') | 2311 z_bounds = msnc.selectArrayBounds(tomosum, title='recon combined sum xy') |
2222 if z_bounds[0] != 0 or z_bounds[1] != tomo_recon_combined.shape[0]: | 2312 if z_bounds[0] != 0 or z_bounds[1] != tomo_recon_combined.shape[0]: |
2223 tomo_recon_combined = tomo_recon_combined[z_bounds[0]:z_bounds[1],:,:] | 2313 tomo_recon_combined = tomo_recon_combined[z_bounds[0]:z_bounds[1],:,:] |
2224 logging.info(f'tomo_recon_combined.shape = {tomo_recon_combined.shape}') | |
2225 if self.save_plots_only: | 2314 if self.save_plots_only: |
2226 msnc.clearFig('recon combined sum xy') | 2315 msnc.clearFig('recon combined sum xy') |
2227 | 2316 |
2228 # Plot center slices | 2317 # Plot center slices |
2229 msnc.quickImshow(tomo_recon_combined[int(tomo_recon_combined.shape[0]/2),:,:], | 2318 msnc.quickImshow(tomo_recon_combined[int(tomo_recon_combined.shape[0]/2),:,:], |