def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 8 # Propagation distance of the wavefront in cm detector_pixel_size_x = 2.247e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 24.9 # Energy of incident wave in keV alpha = 1e-02 # Phase retrieval coeff. zinger_level = 800 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) # zinger_removal # proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) # flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. ##data = tomopy.normalize(proj, flat, dark, cutoff=0.8) data = tomopy.normalize(proj, flat, dark) # remove stripes data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) # data = tomopy.remove_stripe_ti(data, alpha=1.5) # data = tomopy.remove_stripe_sf(data, size=150) # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center/np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) elif algorithm == 'astrasirt': extra_options ={'MinConstraint':0} options = {'proj_type':'cuda', 'method':'SIRT_CUDA', 'num_iter':200, 'extra_options':extra_options} rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options) else: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def main(argv): try: opts, args = getopt.getopt(argv,"hc:s:",["core=","sino="]) except getopt.GetoptError: print 'test.py -c <ncore> -s <nsino>' sys.exit(2) for opt, arg in opts: if opt == '-h': print 'test.py -c <ncore> -s <nsino>' sys.exit() elif opt in ("-c", "--core"): ncore = int(arg) elif opt in ("-s", "--sino"): nsino = int(arg) file_name = '/local/decarlo/data/proj_10.hdf' output_name = './recon/proj10_rec' sino_start = 200 # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_start, sino_start+nsino)) # Fix flats because sample did not move flat = np.full((flat.shape[0], flat.shape[1], flat.shape[2]), 1000) # Set angles theta = tomopy.angles(prj.shape[0])
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 30 # Propagation distance of the wavefront in cm detector_pixel_size_x = 1.17e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 25.74 # Energy of incident wave in keV alpha = 1e-02 # Phase retrieval coeff. zinger_level = 1000 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white miss_angles = [141,226] # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) print (theta) # Manage the missing angles: #proj_size = np.shape(proj) #theta = np.linspace(0,180,proj_size[0]) proj = np.concatenate((proj[0:miss_angles[0],:,:], proj[miss_angles[1]+1:-1,:,:]), axis=0) theta = np.concatenate((theta[0:miss_angles[0]], theta[miss_angles[1]+1:-1])) # zinger_removal #proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) #flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=0.8) # remove stripes data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) # phase retrieval # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center/np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) else: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. ##rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm, binning): zinger_level = 800 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white data_shape = get_dx_dims(h5fname, 'data') print(data_shape) ssino = int(data_shape[1] * nsino) center_range = (rot_center-center_search_width, rot_center+center_search_width, 0.5) #print(sino,ssino, center_range) #print(center_range[0], center_range[1], center_range[2]) # Select sinogram range to reconstruct sino = None start = ssino end = start + 1 sino = (start, end) # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) # zinger_removal proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=1.4) # remove stripes data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) stack = np.empty((len(np.arange(*center_range)), data_shape[0], data_shape[2])) index = 0 for axis in np.arange(*center_range): stack[index] = data[:, 0, :] index = index + 1 # Reconstruct the same slice with a range of centers. rec = tomopy.recon(stack, theta, center=np.arange(*center_range), sinogram_order=True, algorithm='gridrec', filter_name='parzen', nchunk=1) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) index = 0 # Save images to a temporary folder. fname = os.path.dirname(h5fname) + '/' + 'try_rec/' + 'recon_' + os.path.splitext(os.path.basename(h5fname))[0] for axis in np.arange(*center_range): rfname = fname + '_' + str('{0:.2f}'.format(axis) + '.tiff') dxchange.write_tiff(rec[index], fname=rfname, overwrite=True) index = index + 1 print("Reconstructions: ", fname)
def recon_batch_singlenode( sinograms, theta, recon_series, center=None, algorithm=None): """reconstruct from a bunch of sinograms. This is intended to be run on just one node. theta: sample rotation angle in radian """ import tomopy, imars3d.io proj = [img.data for img in sinograms] proj = np.array(proj) proj = np.swapaxes(proj, 0, 1) Y,X = proj[0].shape if center is None: center = X/2. # reconstruct algorithm = algorithm or 'gridrec' # algorithm='fbp', # lgorithm='pml_hybrid', rec = tomopy.recon( proj, theta=theta, center=center, algorithm=algorithm, emission=False, ncore = 1, ) # output for i, img in enumerate(recon_series): img.data = rec[i] img.save() continue return
def rec_test(file_name, sino_start, sino_end, astra_method, extra_options, num_iter=1): print '\n#### Processing '+ file_name sino_start = sino_start + 200 sino_end = sino_start + 2 print "Test reconstruction of slice [%d]" % sino_start # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_start, sino_end)) # Manage the missing angles: theta = tomopy.angles(prj.shape[0]) prj = np.concatenate((prj[0:miss_angles[0],:,:], prj[miss_angles[1]+1:-1,:,:]), axis=0) theta = np.concatenate((theta[0:miss_angles[0]], theta[miss_angles[1]+1:-1])) # normalize the prj prj = tomopy.normalize(prj, flat, dark) # remove ring artefacts prjn = tomopy.remove_stripe_fw(prj) # reconstruct rec = tomopy.recon(prj[:,::reduce_amount,::reduce_amount], theta, center=float(best_center)/reduce_amount, algorithm=tomopy.astra, options={'proj_type':proj_type,'method':astra_method,'extra_options':extra_options,'num_iter':num_iter}, emission=False) # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname=output_name) print "Slice saved as [%s_00000.tiff]" % output_name
def main(): #**************************************************************************** file_name = '/local/dataraid/databank/dataExchange/tmp/Australian_rank3.h5' output_name = '/local/dataraid/databank/dataExchange/tmp/rec/Australian_rank3' sino_start = 290 sino_end = 294 # Read HDF5 file. exchange_rank = 3; prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, exchange_rank, sino=(sino_start, sino_end)) theta = tomopy.angles(prj.shape[0]) # normalize the data prj = tomopy.normalize(prj, flat, dark) best_center=1184 print "Best Center: ", best_center calc_center = best_center #calc_center = tomopy.find_center(prj, theta, emission=False, ind=0, init=best_center, tol=0.8) print "Calculated Center:", calc_center # reconstruct rec = tomopy.recon(prj, theta, center=calc_center, algorithm='gridrec', emission=False) #rec = tomopy.circ_mask(rec, axis=0) # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname=output_name) plt.gray() plt.axis('off') plt.imshow(rec[0])
def recon(sinogram, theta, outpath, center=None): """Use tomopy to reconstruct from one sinogram theta: sample rotation angle in radian """ import tomopy, imars3d.io proj = [sinogram.data] proj = np.array(proj) # tomopy.recon needs the shape to be # angles, Y, X proj = np.swapaxes(proj, 0, 1) Y,X = proj[0].shape if center is None: center = X/2. # reconstruct rec = tomopy.recon( proj, theta=theta, center=center, algorithm='gridrec', emission=False, ncore = 1, ) rec = rec[0] # there is only one layer # output img = imars3d.io.ImageFile(path=outpath) img.data = rec img.save() return
def reconstruct(proj_fn_template, layers, theta, console_out, outdir="recon"): """proj_fn_template: projection filename tempate layers: list of integers for layers to be reconstructed theta: sample rotation angle in radian """ import tomopy proj = tomopy.read_tiff_stack(proj_fn_template % layers[0], layers, digit=5) proj = np.swapaxes(proj, 0,1) Y,X = proj[0].shape # reconstruct console_out.write("tomopy.reconstruct..."); console_out.flush() rec = tomopy.recon( proj, theta=theta, center=X/2., algorithm='gridrec', emission=False, ncore = 1, ) console_out.write("done\n"); console_out.flush() # output if not os.path.exists(outdir): os.makedirs(outdir) console_out.write("tomopy.write_tiff_stack..."); console_out.flush() tomopy.write_tiff_stack( rec, fname=os.path.join(outdir, 'recon'), axis=0, overwrite=True) console_out.write("done\n"); console_out.flush() return
def rec_test(file_name, sino_start, sino_end): print "\n#### Processing " + file_name sino_start = sino_start + 200 sino_end = sino_start + 2 print "Test reconstruction of slice [%d]" % sino_start # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_start, sino_end)) # Manage the missing angles: theta = tomopy.angles(prj.shape[0]) prj = np.concatenate((prj[0 : miss_angles[0], :, :], prj[miss_angles[1] + 1 : -1, :, :]), axis=0) theta = np.concatenate((theta[0 : miss_angles[0]], theta[miss_angles[1] + 1 : -1])) # normalize the prj prj = tomopy.normalize(prj, flat, dark) # reconstruct rec = tomopy.recon(prj, theta, center=best_center, algorithm="gridrec", emission=False) # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname=output_name) print "Slice saved as [%s_00000.tiff]" % output_name # show the reconstructed slice pl.gray() pl.axis("off") pl.imshow(rec[0])
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 8 # Propagation distance of the wavefront in cm detector_pixel_size_x = 2.247e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 24.9 # Energy of incident wave in keV alpha = 1e-02 # Phase retrieval coeff. zinger_level = 800 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white # h5fname_norm = '/local/data/2019-02/Burke/C47M_0015.h5' h5fname_norm = '/local/data/2019-02/Burke/kc78_Menardii_0003.h5' proj1, flat, dark, theta1 = dxchange.read_aps_32id(h5fname_norm, sino=sino) proj, dummy, dummy1, theta = dxchange.read_aps_32id(h5fname, sino=sino) # zinger_removal proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. ##data = tomopy.normalize(proj, flat, dark, cutoff=0.8) data = tomopy.normalize(proj, flat, dark) # remove stripes data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) #data = tomopy.remove_stripe_ti(data, alpha=1.5) data = tomopy.remove_stripe_sf(data, size=20) # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center/np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) else: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def main(arg): parser = argparse.ArgumentParser() parser.add_argument("top", help="top directory where the tiff images are located: /data/") parser.add_argument("start", nargs='?', const=1, type=int, default=1, help="index of the first image: 1000 (default 1)") args = parser.parse_args() top = args.top index_start = int(args.start) template = os.listdir(top)[0] nfile = len(fnmatch.filter(os.listdir(top), '*.tif')) index_end = index_start + nfile ind_tomo = range(index_start, index_end) fname = top + template print (nfile, index_start, index_end, fname) # Select the sinogram range to reconstruct. start = 0 end = 512 sino=(start, end) # Read the tiff raw data. ndata = dxchange.read_tiff_stack(fname, ind=ind_tomo, slc=(sino, None)) print(ndata.shape) binning = 8 ndata = tomopy.downsample(ndata, level=binning, axis=1) print(ndata.shape) # Normalize to 1 using the air counts ndata = tomopy.normalize_bg(ndata, air=5) ## slider(ndata) # Set data collection angles as equally spaced between 0-180 degrees. theta = tomopy.angles(ndata.shape[0]) rot_center = 960 print("Center of rotation: ", rot_center) ndata = tomopy.minus_log(ndata) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(ndata, theta, center=rot_center, algorithm='gridrec') # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. dxchange.write_tiff_stack(rec, fname='/local/dataraid/mark/rec/recon')
def process_frames(self, data): self.sino = data[0] self.cors, angles, vol_shape, init = self.get_frame_params() if init: self.kwargs['init_recon'] = init recon = tomopy.recon(self.sino, np.deg2rad(angles), center=self.cors[0], ncore=1, algorithm=self.alg, **self.kwargs) return self._finalise_data(recon)
def run(phantom, algorithm, args, get_recon=False): global image_quality imgs = [] bname = get_basepath(args, algorithm, phantom) oname = os.path.join(bname, "orig_{}_".format(algorithm)) fname = os.path.join(bname, "stack_{}_".format(algorithm)) dname = os.path.join(bname, "diff_{}_".format(algorithm)) prj, ang, obj = generate(phantom, args.size, args.angles) # always add algorithm _kwargs = {"algorithm": algorithm} # assign number of cores _kwargs["ncore"] = ncores # don't assign "num_iter" if gridrec or fbp if algorithm not in ["fbp", "gridrec"]: _kwargs["num_iter"] = args.num_iter print("kwargs: {}".format(_kwargs)) with timemory.util.auto_timer("[tomopy.recon(algorithm='{}')]".format( algorithm)): rec = tomopy.recon(prj, ang, **_kwargs) obj = normalize(obj) rec = normalize(rec) rec = trim_border(rec, rec.shape[0], rec[0].shape[0] - obj[0].shape[0], rec[0].shape[1] - obj[0].shape[1]) label = "{} @ {}".format(algorithm.upper(), phantom.upper()) quantify_difference(label, obj, rec) if "orig" not in image_quality: image_quality["orig"] = obj dif = obj - rec image_quality[algorithm] = dif if get_recon is True: return rec print("oname = {}, fname = {}, dname = {}".format(oname, fname, dname)) imgs.extend(output_images(obj, oname, args.format, args.scale, args.ncol)) imgs.extend(output_images(rec, fname, args.format, args.scale, args.ncol)) imgs.extend(output_images(dif, dname, args.format, args.scale, args.ncol)) return imgs
def reconstruct(h5fname, sino, rot_center, args, blocked_views=None): # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) # Manage the missing angles: if blocked_views is not None: print("Blocked Views: ", blocked_views) proj = np.concatenate((proj[0:blocked_views[0], :, :], proj[blocked_views[1]+1:-1, :, :]), axis=0) theta = np.concatenate((theta[0:blocked_views[0]], theta[blocked_views[1]+1: -1])) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=1.4) # remove stripes data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1, pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 algorithm = args.algorithm ncores = args.ncores nitr = args.num_iter # always add algorithm _kwargs = {"algorithm": algorithm} # assign number of cores _kwargs["ncore"] = ncores # don't assign "num_iter" if gridrec or fbp if algorithm not in ["fbp", "gridrec"]: _kwargs["num_iter"] = nitr # Reconstruct object. with timemory.util.auto_timer( "[tomopy.recon(algorithm='{}')]".format(algorithm)): rec = tomopy.recon(proj, theta, **_kwargs) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def recon_slice(row_sino, center_pos, sinogram_order=False, algorithm=None, init_recon=None, ncore=None, nchunk=None, **kwargs): t = time.time() ang = tomopy.angles(row_sino.shape[0]) print(row_sino.shape) row_sino = row_sino.astype('float32') # row_sino = tomopy.normalize_bg(row_sino) # WARNING: normalize_bg can unpredicatably give bad results for some slices row_sino = tomopy.remove_stripe_ti(row_sino, alpha=4) rec = tomopy.recon(row_sino, ang, center=center_pos, sinogram_order=sinogram_order, algorithm=algorithm, init_recon=init_recon, ncore=ncore, nchunk=nchunk, **kwargs) print('recon: ' + str(time.time() - t)) return rec
def main(argv): try: opts, args = getopt.getopt(argv,"hc:s:",["core=","sino="]) except getopt.GetoptError: print 'test.py -c <ncore> -s <nsino>' sys.exit(2) for opt, arg in opts: if opt == '-h': print 'test.py -c <ncore> -s <nsino>' sys.exit() elif opt in ("-c", "--core"): ncore = int(arg) elif opt in ("-s", "--sino"): nsino = int(arg) # ********************************************** #file_name = '/local/decarlo/data/proj_10.hdf' #output_name = './recon/proj10_rec' #sino_start = 0 #sino_end = 2048 # ********************************************** file_name = '/local/decarlo/data/Hornby_APS_2011.h5' output_name = './recon/Hornby_APS_2011_' best_center=1024 sino_start = 0 sino_end = 1792 # ********************************************** step_00 = time.time() step_02_delta_total = 0 count = 0 while (sino_start <= (sino_end - nsino)): # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_start, sino_start+nsino)) # Fix flats because sample did not move flat = np.full((flat.shape[0], flat.shape[1], flat.shape[2]), 1000) # Set angles theta = tomopy.angles(prj.shape[0]) # normalize the prj prj = tomopy.normalize(prj, flat, dark) best_center = 1298 step_01 = time.time() # reconstruct rec = tomopy.recon(prj, theta, center=best_center, algorithm='gridrec', emission=False, ncore = ncore)
def rec_sirtfbp(data, theta, rot_center, start=0, test_sirtfbp_iter = True): # Use test_sirtfbp_iter = True to test which number of iterations is suitable for your dataset # Filters are saved in .mat files in "./¨ if test_sirtfbp_iter: nCol = data.shape[2] output_name = './test_iter/' num_iter = [50,100,150] filter_dict = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') for its in num_iter: tomopy_filter = sirtfilter.convert_to_tomopy_filter(filter_dict[its], nCol) rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) output_name_2 = output_name + 'sirt_fbp_%iiter_slice_' % its dxchange.write_tiff_stack(data, fname=output_name_2, start=start, dtype='float32') # Reconstruct object using sirt-fbp algorithm: num_iter = 100 nCol = data.shape[2] sirtfbp_filter = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') tomopy_filter = sirtfilter.convert_to_tomopy_filter(sirtfbp_filter, nCol) rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) return rec
def recon_hdf5_mpi(src_fanme, dest_folder, sino_range, sino_step, center_vec, shift_grid, dtype='float32', algorithm='gridrec', tolerance=1, save_sino=False, sino_blur=None, **kwargs): """ Reconstruct a single tile, or fused HDF5 created using util/total_fusion. MPI supported. """ raise DeprecationWarning if rank == 0: if not os.path.exists(dest_folder): os.mkdir(dest_folder) sino_ini = int(sino_range[0]) sino_end = int(sino_range[1]) f = h5py.File(src_fanme) dset = f['exchange/data'] full_shape = dset.shape theta = tomopy.angles(full_shape[0]) center_vec = np.asarray(center_vec) sino_ls = np.arange(sino_ini, sino_end, sino_step, dtype='int') grid_bins = np.ceil(shift_grid[:, 0, 0]) t0 = time.time() alloc_set = allocate_mpi_subsets(sino_ls.size, size, task_list=sino_ls) for slice in alloc_set[rank]: print(' Rank {:d}: reconstructing {:d}'.format(rank, slice)) grid_line = np.digitize(slice, grid_bins) grid_line = grid_line - 1 center = center_vec[grid_line] data = dset[:, slice, :] if sino_blur is not None: data = gaussian_filter(data, sino_blur) data = data.reshape([full_shape[0], 1, full_shape[2]]) data[np.isnan(data)] = 0 data = data.astype('float32') if save_sino: dxchange.write_tiff(data[:, slice, :], fname=os.path.join(dest_folder, 'sino/recon_{:05d}_{:d}.tiff').format(slice, center)) # data = tomopy.remove_stripe_ti(data) rec = tomopy.recon(data, theta, center=center, algorithm=algorithm, **kwargs) # rec = tomopy.remove_ring(rec) rec = tomopy.remove_outlier(rec, tolerance) rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) dxchange.write_tiff(rec, fname='{:s}/recon/recon_{:05d}_{:d}'.format(dest_folder, slice, center), dtype=dtype) print('Rank {:d} finished in {:.2f} s.'.format(rank, time.time()-t0)) return
def rec_full(file_name, sino_start, sino_end): print "\n#### Processing " + file_name chunks = 10 # number of data chunks for the reconstruction nSino_per_chunk = (sino_end - sino_start) / chunks print "Reconstructing [%d] slices from slice [%d] to [%d] in [%d] chunks of [%d] slices each" % ( (sino_end - sino_start), sino_start, sino_end, chunks, nSino_per_chunk, ) for iChunk in range(0, chunks): print "\n -- chunk # %i" % (iChunk + 1) sino_chunk_start = sino_start + nSino_per_chunk * iChunk sino_chunk_end = sino_start + nSino_per_chunk * (iChunk + 1) print "\n --------> [%i, %i]" % (sino_chunk_start, sino_chunk_end) if sino_chunk_end > sino_end: break # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_chunk_start, sino_chunk_end)) # Manage the missing angles: theta = tomopy.angles(prj.shape[0]) prj = np.concatenate((prj[0 : miss_angles[0], :, :], prj[miss_angles[1] + 1 : -1, :, :]), axis=0) theta = np.concatenate((theta[0 : miss_angles[0]], theta[miss_angles[1] + 1 : -1])) # normalize the prj prj = tomopy.normalize(prj, flat, dark) # reconstruct rec = tomopy.recon(prj, theta, center=best_center, algorithm="gridrec", emission=False) print output_name # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname=output_name, start=sino_chunk_start)
def rec_full(file_name, sino_start, sino_end, astra_method, extra_options, num_iter=1): print '\n#### Processing '+ file_name chunks = 10 # number of data chunks for the reconstruction nSino_per_chunk = (sino_end - sino_start)/chunks print "Reconstructing [%d] slices from slice [%d] to [%d] in [%d] chunks of [%d] slices each" % ((sino_end - sino_start), sino_start, sino_end, chunks, nSino_per_chunk) strt = 0 for iChunk in range(0,chunks): print '\n -- chunk # %i' % (iChunk+1) sino_chunk_start = sino_start + nSino_per_chunk*iChunk sino_chunk_end = sino_start + nSino_per_chunk*(iChunk+1) print '\n --------> [%i, %i]' % (sino_chunk_start, sino_chunk_end) if sino_chunk_end > sino_end: break # Read HDF5 file. prj, flat, dark = tomopy.io.exchange.read_aps_32id(file_name, sino=(sino_chunk_start, sino_chunk_end)) # Manage the missing angles: theta = tomopy.angles(prj.shape[0]) prj = np.concatenate((prj[0:miss_angles[0],:,:], prj[miss_angles[1]+1:-1,:,:]), axis=0) theta = np.concatenate((theta[0:miss_angles[0]], theta[miss_angles[1]+1:-1])) # normalize the prj prj = tomopy.normalize(prj, flat, dark) # remove ring artefacts prj = tomopy.remove_stripe_fw(prj) # reconstruct rec = tomopy.recon(prj[:,::reduce_amount,::reduce_amount], theta, center=float(best_center)/reduce_amount, algorithm=tomopy.astra, options={'proj_type':proj_type,'method':astra_method,'extra_options':extra_options,'num_iter':num_iter}, emission=False) print output_name # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname=output_name, start=strt) strt += prj[:,::reduce_amount,:].shape[1]
def main(arg): fname = '/local/dataraid/elettra/Oak_16bit_slice343_all_repack.h5' # Read the hdf raw data. sino, sflat, sdark, th = dxchange.read_aps_32id(fname) slider(sino) proj = np.swapaxes(sino,0,1) flat = np.swapaxes(sflat,0,1) dark = np.swapaxes(sdark,0,1) # Set data collection angles as equally spaced between 0-180 degrees. theta = tomopy.angles(proj.shape[0], ang1=0.0, ang2=180.0) print(proj.shape, dark.shape, flat.shape, theta.shape) # Flat-field correction of raw data. ndata = tomopy.normalize(proj, flat, dark) #slider(ndata) # Find rotation center. rot_center = 962 binning = 1 ndata = tomopy.downsample(ndata, level=int(binning)) rot_center = rot_center/np.power(2, float(binning)) ndata = tomopy.minus_log(ndata) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(ndata, theta, center=rot_center, algorithm='gridrec') # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. dxchange.write_tiff_stack(rec, fname='recon_dir/recon')
def reconstruct(sname, rot_center, ovlpfind, s_start, s_end): fname = dfolder + sname + '.h5' print (fname) start = s_start end = s_end chunks = 24 num_sino = (end - start) // chunks for m in range(chunks): sino_start = start + num_sino * m sino_end = start + num_sino * (m + 1) start_read_time = time.time() proj, flat, dark, thetat = dxchange.read_aps_2bm(fname, sino=(sino_start, sino_end)) print(' done read in %0.1f min' % ((time.time() - start_read_time)/60)) dark = proj[9001:9002] flat = proj[0:1] proj = proj[1:9000] theta = tomopy.angles(proj.shape[0], 0., 360.) proj = tomopy.sino_360_to_180(proj, overlap=ovlpfind, rotation='right') proj = tomopy.remove_outlier(proj, dif=0.4) proj = tomopy.normalize_bg(proj, air=10) proj = tomopy.minus_log(proj) center = rot_center start_ring_time = time.time() proj = tomopy.remove_stripe_fw(proj, wname='sym5', sigma=4, pad=False) proj = tomopy.remove_stripe_sf(proj, size=3) print(' done pre-process in %0.1f min' % ((time.time() - start_ring_time)/60)) start_phase_time = time.time() proj = tomopy.retrieve_phase(proj, pixel_size=detector_pixel_size_x, dist=sample_detector_distance, energy=energy, alpha=alpha, pad=True, ncore=None, nchunk=None) print(' done phase retrieval in %0.1f min' % ((time.time() - start_phase_time)/60)) start_recon_time = time.time() rec = tomopy.recon(proj, theta, center=center, algorithm='gridrec', filter_name='ramalk') tomopy.circ_mask(rec, axis=0, ratio=0.95) print ("Reconstructed", rec.shape) dxchange.write_tiff_stack(rec, fname = dfolder + '/' + sname + '/' + sname, overwrite=True, start=sino_start) print(' Chunk reconstruction done in %0.1f min' % ((time.time() - start_recon_time)/60)) print ("Done!")
def tomo_reconstruction(sino, omega, algorithm='gridrec', filter_name='shepp', num_iter=1, center=None, refine_center=False, sinogram_order=True): ''' INPUT -> sino : slice, 2th, x OR 2th, slice, x (with flag sinogram_order=True/False) OUTPUT -> tomo : slice, x, y ''' if center is None: center = sino.shape[1]/2. refine_center = True if refine_center: center = tomopy.find_center(sino, np.radians(omega), init=center, ind=0, tol=0.5, sinogram_order=sinogram_order) algorithm = algorithm.lower() recon_kws = {} if algorithm.startswith('gridr'): recon_kws['filter_name'] = filter_name else: recon_kws['num_iter'] = num_iter tomo = tomopy.recon(sino, np.radians(omega), algorithm=algorithm, center=center, sinogram_order=sinogram_order, **recon_kws) return center, tomo
# image along the y-axis. return f.reshape((N, N))[::-1].transpose() if __name__ == "__main__": t_Image = imread("Kayu_Edited_350_pixel.png", as_grey=True) A = 18 N = 3 # t_Sino = np.zeros((A,N)) # t_Sino[int(t_Sino.shape[0]/2)] = 1 # t_Sino[:,2] = 1 t_Angle = np.linspace(0, 180, A, endpoint=False) t_Angle2 = np.linspace(0, 180, A, endpoint=False) t_Sino = radontea.radon_parallel(t_Image, t_Angle) t_Sino2 = radon(t_Image, t_Angle2, circle=True) # t_Reconstruction = art(t_Sino, t_Angle) # t_Reconstruction2 = iradon_sart(t_Sino2, t_Angle2) t_Reconstruction = tomopy.recon(t_Sino, t_Angle) # print(np.abs(t_Sino)) fig, (ax1, ax2) = plt.subplots(1, 2) # ax1.imshow(t_Sino) # ax2.imshow(t_Sino2) # ax1.imshow(np.abs(t_Reconstruction2)) ax2.imshow(np.abs(t_Reconstruction)) plt.show()
trunc_ratio_tomosaic_ls = [] trunc_ratio_local_ls = [] mean_count_tomosaic_ls = [] mean_count_local_ls = [] # create reference recon if os.path.exists(os.path.join('data', 'ref_recon.tiff')): ref_recon = dxchange.read_tiff(os.path.join('data', 'ref_recon.tiff')) else: sino = dxchange.read_tiff( os.path.join('data', 'shirley_full_sino.tiff')) sino = -np.log(sino) sino = sino[:, np.newaxis, :] theta = tomopy.angles(sino.shape[0]) ref_recon = tomopy.recon(sino, theta, center=pad_length + true_center, algorithm='gridrec') dxchange.write_tiff(ref_recon, 'data/ref_recon', overwrite=True) ref_recon = np.squeeze(ref_recon) try: raise Exception mean_count_tomosaic_ls = np.load( os.path.join('data', 'shirley_local', 'mean_count_tomosaic_ls.npy')) mean_count_local_ls = np.load( os.path.join('data', 'shirley_local', 'mean_count_local_ls.npy')) trunc_ratio_tomosaic_ls = np.load( os.path.join('data', 'shirley_local', 'trunc_ratio_tomosaic_ls.npy')) trunc_ratio_local_ls = np.load(
print('loading flat images') for y in range(0, len(floc)): inputPath = '{}{}_{:d}{}'.format(fn, flatextension, floc[y], fileextension) flat[y] = dxchange.reader.read_tiff(inputPath, slc=(sinoused, raysused)) print('loading dark images') for y in range(0, numdrk): inputPath = '{}{}_{:d}{}'.format(fn, darkextension, y, fileextension) dark[y] = dxchange.reader.read_tiff(inputPath, slc=(sinoused, raysused)) print('normalizing') tomo = tomo.astype(np.float32) tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo) tomopy.minus_log(tomo, out=tomo) tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge') rec = tomopy.recon(tomo, tomopy.angles(numangles, angle_offset, angle_offset - angularrange), center=cor + npad, algorithm='gridrec', filter_name='butterworth', filter_par=[.25, 2]) rec = rec[:, npad:-npad, npad:-npad] rec /= pxsize # convert reconstructed voxel values from 1/pixel to 1/cm rec = tomopy.circ_mask(rec, 0) print('writing recon') dxchange.write_tiff_stack(rec, fname='rec/' + fn, start=sinoused[0])
data = tomopy.normalize(proj, flat, dark) # remove stripes data = tomopy.prep.stripe.remove_stripe_fw(data, level=5, wname='sym16', sigma=1, pad=True) # phase retrieval data = tomopy.prep.phase.retrieve_phase(data, pixel_size=detector_pixel_size_x, dist=sample_detector_distance, energy=monochromator_energy, alpha=8e-3, pad=True) # Set rotation center. rot_center = rot_center data = tomopy.minus_log(data) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec') # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. dxchange.write_tiff_stack(rec, fname='recon_dir/tomo_00072')
def recon_hdf5(src_fanme, dest_folder, sino_range, sino_step, shift_grid, center_vec=None, center_eq=None, dtype='float32', algorithm='gridrec', tolerance=1, chunk_size=20, save_sino=False, sino_blur=None, flattened_radius=120, mode='180', test_mode=False, phase_retrieval=None, ring_removal=True, **kwargs): """ center_eq: a and b parameters in fitted center position equation center = a*slice + b. """ if not os.path.exists(dest_folder): try: os.mkdir(dest_folder) except: pass sino_ini = int(sino_range[0]) sino_end = int(sino_range[1]) sino_ls_all = np.arange(sino_ini, sino_end, sino_step, dtype='int') alloc_set = allocate_mpi_subsets(sino_ls_all.size, size, task_list=sino_ls_all) sino_ls = alloc_set[rank] # prepare metadata f = h5py.File(src_fanme) dset = f['exchange/data'] full_shape = dset.shape theta = tomopy.angles(full_shape[0]) if center_eq is not None: a, b = center_eq center_ls = sino_ls * a + b center_ls = np.round(center_ls) for iblock in range(int(sino_ls.size/chunk_size)+1): print('Beginning block {:d}.'.format(iblock)) t0 = time.time() istart = iblock*chunk_size iend = np.min([(iblock+1)*chunk_size, sino_ls.size]) fstart = sino_ls[istart] fend = sino_ls[iend] center = center_ls[istart:iend] data = dset[:, fstart:fend:sino_step, :] data[np.isnan(data)] = 0 data = data.astype('float32') data = tomopy.remove_stripe_ti(data, alpha=4) if sino_blur is not None: for i in range(data.shape[1]): data[:, i, :] = gaussian_filter(data[:, i, :], sino_blur) rec = tomopy.recon(data, theta, center=center, algorithm=algorithm, **kwargs) rec = tomopy.remove_ring(rec) rec = tomopy.remove_outlier(rec, tolerance) rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) for i in range(rec.shape[0]): slice = fstart + i*sino_step dxchange.write_tiff(rec[i, :, :], fname=os.path.join(dest_folder, 'recon/recon_{:05d}_{:05d}.tiff').format(slice, sino_ini)) if save_sino: dxchange.write_tiff(data[:, i, :], fname=os.path.join(dest_folder, 'sino/recon_{:05d}_{:d}.tiff').format(slice, int(center[i]))) iblock += 1 print('Block {:d} finished in {:.2f} s.'.format(iblock, time.time()-t0)) else: # divide chunks grid_bins = np.append(np.ceil(shift_grid[:, 0, 0]), full_shape[1]) chunks = [] center_ls = [] istart = 0 counter = 0 # irow should be 0 for slice 0 irow = np.searchsorted(grid_bins, sino_ls[0], side='right')-1 for i in range(sino_ls.size): counter += 1 sino_next = i+1 if i != sino_ls.size-1 else i if counter >= chunk_size or sino_ls[sino_next] >= grid_bins[irow+1] or sino_next == i: iend = i+1 chunks.append((istart, iend)) istart = iend center_ls.append(center_vec[irow]) if sino_ls[sino_next] >= grid_bins[irow+1]: irow += 1 counter = 0 # reconstruct chunks iblock = 1 for (istart, iend), center in izip(chunks, center_ls): print('Beginning block {:d}.'.format(iblock)) t0 = time.time() fstart = sino_ls[istart] fend = sino_ls[iend-1] print('Reading data...') data = dset[:, fstart:fend+1:sino_step, :] if mode == '360': overlap = 2 * (dset.shape[2] - center) data = tomosaic.morph.sino_360_to_180(data, overlap=overlap, rotation='right') theta = tomopy.angles(data.shape[0]) data[np.isnan(data)] = 0 data = data.astype('float32') if sino_blur is not None: for i in range(data.shape[1]): data[:, i, :] = gaussian_filter(data[:, i, :], sino_blur) if ring_removal: data = tomopy.remove_stripe_ti(data, alpha=4) if phase_retrieval: data = tomopy.retrieve_phase(data, kwargs['pixel_size'], kwargs['dist'], kwargs['energy'], kwargs['alpha']) rec0 = tomopy.recon(data, theta, center=center, algorithm=algorithm, **kwargs) rec = tomopy.remove_ring(np.copy(rec0)) cent = int((rec.shape[1]-1) / 2) xx, yy = np.meshgrid(np.arange(rec.shape[2]), np.arange(rec.shape[1])) mask0 = ((xx-cent)**2+(yy-cent)**2 <= flattened_radius**2) mask = np.zeros(rec.shape, dtype='bool') for i in range(mask.shape[0]): mask[i, :, :] = mask0 rec[mask] = (rec[mask] + rec0[mask])/2 else: rec = tomopy.recon(data, theta, center=center, algorithm=algorithm, **kwargs) rec = tomopy.remove_outlier(rec, tolerance) rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) for i in range(rec.shape[0]): slice = fstart + i*sino_step if test_mode: dxchange.write_tiff(rec[i, :, :], fname=os.path.join(dest_folder, 'recon/recon_{:05d}_{:d}.tiff').format(slice, center), dtype=dtype) else: dxchange.write_tiff(rec[i, :, :], fname=os.path.join(dest_folder, 'recon/recon_{:05d}.tiff').format(slice), dtype=dtype) if save_sino: dxchange.write_tiff(data[:, i, :], fname=os.path.join(dest_folder, 'sino/recon_{:05d}_{:d}.tiff').format(slice, center), dtype=dtype) print('Block {:d} finished in {:.2f} s.'.format(iblock, time.time()-t0)) iblock += 1 return
proj = np.zeros((sino.shape[0], 1, sino.shape[1])) proj[:, 0, :] = sino print proj.shape # 4. views initionalize theta = tomopy.angles(sino.shape[0], 0, 180) # 5. find center # center = tomopy.find_center(proj, theta, ind=0, init=1042, tol=0.5) # print center # 6. using tomopy's FBP API reconstruction # rec = tomopy.recon(proj, theta, center=1046.47734375, algorithm='fbp', filter_name='')#, num_gridx=256, num_gridy=256) # print rec.shape # 7. using tomopy plus astra options = {'proj_type': 'line', 'method': 'FBP_CUDA'} rec = tomopy.recon(proj, theta, center=1046.47734375, algorithm=tomopy.astra, options=options) # 8. convert data structure rec = rec[0, :, :] # 9. show reconstruction result plt.figure(), plt.imshow(rec, cmap='gray'), plt.axis('off') plt.figure(), plt.plot(sino[344, :], 'b') plt.show()
def rotaxis_precise(projections, rotaxis_scan_interval, rot_step=10, crop_ratio=2, downscale=0.25): """ This function calculates tomo-reconstructions and tells you which tomo-slice is the sharpest one it works like auto-focus in a smartphone Check this post for the idea (I use FFT) https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/ Parameters __________ projections: 3D array 0 direction is different images rotaxis_scan_interval: array range of integers for potential rotation axis values rot_step: int number of radiographic projections per 1 degree (typically 1 or 10) crop_ratio: int which portion of the original image will be considered by this function Example: if 2, then the new ROI will be from 1/4 to 3/4 of the original ROI downscale: int number<1, corresponds to the downscale factor of the image for resolution estimation elements: 2D array 0dim: rotaxis coordinate for the most sharpest image 1dim: standard deviation (contrast) of the tomo-image at this rotaxis higher std means better sharpness """ # calculate angles n = projections.shape[0] angle = np.pi * np.arange(n) / (rot_step * 180) # counter for best std elements = [] # 0 direction to store rotaxis elements.append([]) # 1 direction to store contrast values elements.append([]) # body for i in rotaxis_scan_interval: # make the reconsturction image = tomopy.recon(projections, angle, center=i, algorithm='gridrec', filter_name='shepp')[0] # crop squared tomo-reconstructio so you use only the ROI with a sample. a = int(image.shape[0] * (crop_ratio - 1) / (2 * crop_ratio)) b = int(image.shape[0] * (crop_ratio + 1) / (2 * crop_ratio)) # downscale the image image = rescale(image[a:b, a:b], downscale, anti_aliasing=True, multichannel=False) # calculate standard deviation and save results image = np.std(np.log(abs(fftshift(fft2(image))))) elements[1].append(image) elements[0].append(i) return np.asarray(elements)
def reconstruct( data, params, dynamic_range, max_iter, phantom, output_dir, max_time=3600, ): """Reconstruct data using given params. Resume from previous reconstruction if exact files already exist. Save files to file named by as: output_dir/algorithm/algorithm.filter_name.device.INTERPOLATION.[npz png] Parameters ---------- data : dictionary Contains three keys: original : the original image sinogram : the projections angles : the angles of each of the projections params : dictionary Contains parameters to use for recostructing the data using tomopy.recon(). dynamic_range : float The expected dynamic range of the reconstructed image. This param is used to scale a png image of the reconstruction max_iter : int The maximum number iterations if the algorithm is iterative max_time : float The maximum wall time per slice before stopping (seconds). phantom : string The name of the phantom """ logger.info('{}'.format(params)) # padding was added to keep square image in the field of view pad = (data['sinogram'].shape[2] - data['original'].shape[2]) // 2 # Determine the algorithm name in the filesystem if params['algorithm'] is tomopy.astra: algorithm = 'astra-' + params['options']['method'].lower() elif params['algorithm'] is tomopy.lprec: algorithm = 'lprec-' + params['lpmethod'].lower() else: algorithm = params['algorithm'].lower() base_path = os.path.join(output_dir, phantom, algorithm) if 'device' in params and params['device'] == 'gpu': base_path = base_path + '_cuda' # initial reconstruction guess; use defaults unique to each algorithm recon = None peak_quality = 0 total_time = 0 # Create evenly spaced samples across a log plot if 'gridrec' in algorithm or 'fbp' in algorithm: iters, steps = [1], [1] else: iters = np.unique(np.logspace(0, np.log10(max_iter), num=16, dtype=int)) steps = [iters[0]] + np.diff(iters).tolist() np.testing.assert_array_equal(np.cumsum(steps), iters) for i in range(len(iters)): # name the output file by combining the algorithm name with some # important (key) input parameters filename = algorithm for key_param in ['filter_name', 'device', 'interpolation']: if key_param in params: filename = ".".join([filename, str(params[key_param])]) filename = os.path.join(base_path, "{}.{:03d}".format(filename, iters[i])) # look for the ouput; only reconstruct if it doesn't exist if os.path.isfile(filename + '.npz'): logger.info("{} exists!".format(filename)) existing_data = np.load(filename + '.npz') recon = existing_data['recon'] wall_time = existing_data['time'] total_time += wall_time else: if 'gridrec' in algorithm or 'fbp' in algorithm: pass elif params['algorithm'] is tomopy.astra: params['options']['num_iter'] = steps[i] else: params['num_iter'] = steps[i] try: start = time.perf_counter() # Do reconstruction in chunks because GPU memory is small # FIXME: It's not fair to include all of this GPU memory # allocation and destruction in the wall_time. In practice, # you wouldn't check the answer every few iterations? chunk_size = 8 shape = data['sinogram'].shape if (shape[1] > chunk_size and 'device' in params and params['device'] == 'gpu'): if recon is None: recon = np.empty((shape[1], shape[2], shape[2])) for j in range(0, 32, chunk_size): recon[j:j + chunk_size] = tomopy.recon( init_recon=None, tomo=data['sinogram'][:, j:j + chunk_size, :], theta=data['angles'], **params, ) else: for j in range(0, 32, chunk_size): recon[j:j + chunk_size] = tomopy.recon( init_recon=recon[j:j + chunk_size], tomo=data['sinogram'][:, j:j + chunk_size, :], theta=data['angles'], **params, ) elif params['algorithm'] is tomopy.lprec: recon = tomopy.recon( init_recon=recon, tomo=data['sinogram'] / np.sqrt(1500 * 2048), theta=data['angles'], **params, ) else: recon = tomopy.recon( init_recon=recon, tomo=data['sinogram'], theta=data['angles'], **params, ) stop = time.perf_counter() wall_time = stop - start total_time += wall_time except Exception as e: logger.warning(e) return os.makedirs(base_path, exist_ok=True) # save all information np.savez_compressed( filename + '.npz', recon=recon, time=wall_time, total_time=total_time, ) plt.imsave( filename + '.png', recon[0, pad:recon.shape[1] - pad, pad:recon.shape[2] - pad], format='png', cmap=plt.cm.cividis, vmin=0, vmax=1.1 * dynamic_range, ) logger.info("{} : time = {:05.3f}s, total time = {:05.3f}s".format( filename, wall_time, total_time)) if total_time > max_time * recon.shape[0]: logger.info(f"Terminate early due to {max_time}s time limit.") break
# Set path to the micro-CT data to reconstruct. fname = '/tomobank/phantoms/' + tomobank_id + '/' + tomobank_id + '.h5' # Select the sinogram range to reconstruct. start = 0 end = 1 # Read the APS 2-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(fname, sino=(start, end)) # Flat-field correction of raw data. proj = tomopy.normalize(proj, flat, dark) # Set rotation center. rot_center = (proj.shape[2] - 1) / 2. print(rot_center) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(proj, theta, center=rot_center, algorithm='gridrec', nchunk=1) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. fname = '/tomobank/phantoms/' + tomobank_id + '/' + tomobank_id dxchange.write_tiff_stack(rec, fname=fname)
recon = recon_algos[0] # select ART algorithm else: # We only select algortihms which held to differences in the reconstruction: # ,'ospml_hybrid', 'pml_hybrid', 'bart', 'mlem', 'osem'} algorithms = {'art', 'fbp', 'sirt', 'ospml_quad', 'pml_quad'} print('Let\'s reconstruct with: ' + format(algorithms) + ' algorithms') # Display a progressbar bar = progressbar.ProgressBar(redirect_stdout=True, term_width=2, max_value=len( algorithms) * 15) # widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()] bar.start() start = time.time() recon_algos = [] i = 0 for algo in algorithms: # , center=rot_center,) recon = tomopy.recon(mat_360, theta, algorithm=algo) i = i + 10 bar.update(i) # Plotting reconstructed projections by angles sample_stack_proj_Angles(recon, theta, algo=algo) i = i + 4 bar.update(i) # Plotting reconstructed Z slices by Y height sample_stack_Z(recon, algo=algo) recon_algos.append(recon) i = i + 1 bar.update(i) bar.finish() joblib.dump(recon_algos, '360_recon_all_algo_noCentering.pkl') # 20 Mo end = time.time() print("Done in " + str(end - start) + "ms")
end = 804 # Read the APS 1-ID raw data. proj, flat, dark = tomopy.io.exchange.read_anka_topotomo(fname, ind_tomo, ind_flat, ind_dark, sino=(start, end)) # Set data collection angles as equally spaced between 0-180 degrees. theta = tomopy.angles(proj.shape[0], 0, 180) print proj.shape print flat.shape print dark.shape # Flat-field correction of raw data. proj = tomopy.normalize(proj, flat, dark) # Set rotation axis location manually. best_center = 993.825; rot_center = best_center # Find rotation center. #rot_center = tomopy.find_center(proj, theta, emission=False, init=best_center, ind=0, tol=0.3) print "Center of rotation:", rot_center # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(proj, theta, center=rot_center, algorithm='gridrec', emission=False) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. tomopy.io.writer.write_tiff_stack(rec, fname='recon_dir/recon')
def recon(io_paras, data_paras, rot_center=None, normalize=True, stripe_removal=10, phase_retrieval=False, opt_center=False, diag_center=False, output="tiff"): # Input and output datafile = io_paras.get('datafile') path2white = io_paras.get('path2white', datafile) path2dark = io_paras.get('path2dark', path2white) out_dir = io_paras.get('out_dir') diag_cent_dir = io_paras.get('diag_cent_dir', out_dir+"/center_diagnose/") recon_dir = io_paras.get('recon_dir', out_dir+"/recon/") out_prefix = io_paras.get('out_prefix', "recon_") # Parameters of dataset NumCycles = data_paras.get('NumCycles', 1) # Number of cycles used for recon ProjPerCycle = data_paras.get('ProjPerCycle') # Number of projections per cycle, N_theta cycle_offset = data_paras.get('cycle_offset', 0) # Offset in output cycle number proj_start = data_paras.get('proj_start', 0) # Starting projection of reconstruction proj_step = data_paras.get('proj_step') z_start = data_paras.get('z_start', 0) z_end = data_paras.get('z_end', z_start+1) z_step = data_paras.get('z_step') x_start = data_paras.get('x_start') x_end = data_paras.get('x_end', x_start+1) x_step = data_paras.get('x_step') white_start = data_paras.get('white_start') white_end = data_paras.get('white_end') dark_start = data_paras.get('dark_start') dark_end = data_paras.get('dark_end') rot_center_copy = rot_center for cycle in xrange(NumCycles): # Set start and end of each cycle projections_start = cycle * ProjPerCycle + proj_start projections_end = projections_start + ProjPerCycle slice1 = slice(projections_start, projections_end, proj_step) slice2 = slice(z_start, z_end, z_step) slice3 = slice(x_start, x_end, x_step) slices = (slice1, slice2, slice3) white_slices = (slice(white_start, white_end), slice2, slice3) dark_slices = (slice(dark_start, dark_end), slice2, slice3) print("Running cycle #%s (projs %s to %s)" % (cycle, projections_start, projections_end)) # Read HDF5 file. print("Reading datafile %s..." % datafile, end="") sys.stdout.flush() data, white, dark = reader.read_aps_2bm(datafile, slices, white_slices, dark_slices, path2white=path2white, path2dark=path2dark) theta = gen_theta(data.shape[0]) print("Done!") print("Data shape = %s;\nwhite shape = %s;\ndark shape = %s." % (data.shape, white.shape, dark.shape)) ## Normalize dataset using data_white and data_dark if normalize: print("Normalizing data ...") # white = white.mean(axis=0).reshape(-1, *data.shape[1:]) # dark = dark.mean(axis=0).reshape(-1, *data.shape[1:]) # data = (data - dark) / (white - dark) data = tomopy.normalize(data, white, dark, cutoff=None, ncore=_ncore, nchunk=None)[...] ## Remove stripes caused by dead pixels in the detector if stripe_removal: print("Removing stripes ...") data = tomopy.remove_stripe_fw(data, level=stripe_removal, wname='db5', sigma=2, pad=True, ncore=_ncore, nchunk=None) # data = tomopy.remove_stripe_ti(data, nblock=0, alpha=1.5, # ncore=None, nchunk=None) # # Show preprocessed projection # plt.figure("%s-prep" % projections_start) # plt.imshow(d.data[0,:,:], cmap=cm.Greys_r) # plt.savefig(out_dir+"/preprocess/%s-prep.jpg" # % projections_start) # # plt.show() # continue ## Phase retrieval if phase_retrieval: print("Retrieving phase ...") data = tomopy.retrieve_phase(data, pixel_size=1e-4, dist=50, energy=20, alpha=1e-3, pad=True, ncore=_ncore, nchunk=None) ## Determine and set the center of rotation if opt_center or (rot_center == None): ### Using optimization method to automatically find the center # d.optimize_center() print("Optimizing center ...", end="") sys.stdout.flush() rot_center = tomopy.find_center(data, theta, ind=None, emission=True, init=None, tol=0.5, mask=True, ratio=1.) print("Done!") print("center = %s" % rot_center) if diag_center: ### Output the reconstruction results using a range of centers, ### and then manually find the optimal center. # d.diagnose_center() if not os.path.exists(diag_cent_dir): os.makedirs(diag_cent_dir) print("Testing centers ...", end="") sys.stdout.flush() tomopy.write_center(data, theta, dpath=diag_cent_dir, cen_range=[center_start, center_end, center_step], ind=None, emission=False, mask=False, ratio=1.) print("Done!") ## Flip odd frames if (cycle % 2): data[...] = data[...,::-1] rot_center = data.shape[-1] - rot_center_copy else: rot_center = rot_center_copy ## Reconstruction using FBP print("Running gridrec ...", end="") sys.stdout.flush() recon = tomopy.recon(data, theta, center=rot_center, emission=False, algorithm='gridrec', # num_gridx=None, num_gridy=None, filter_name='shepp', ncore=_ncore, nchunk=_nchunk) print("Done!") ## Collect background # if cycle == 0: # bg = recon # elif cycle < 4: # bg += recon # else: # recon -= bg/4. # Write to stack of TIFFs. if not os.path.exists(recon_dir): os.makedirs(recon_dir) out_fname = recon_dir+"/"+out_prefix+"t_%d" % (cycle + cycle_offset) if "hdf" in output: hdf_fname = out_fname + ".hdf5" print("Writing reconstruction output file %s..." % hdf_fname, end="") sys.stdout.flush() tomopy.write_hdf5(recon, fname=hdf_fname, gname='exchange', overwrite=False) print("Done!") if "tif" in output: tiff_fname = out_fname + ".tiff" print("Writing reconstruction tiff files %s ..." % tiff_fname, end="") sys.stdout.flush() tomopy.write_tiff_stack(recon, fname=tiff_fname, axis=0, digit=5, start=0, overwrite=False) print("Done!") if "bin" in output: bin_fname = out_fname + ".bin" print("Writing reconstruction to binary files %s..." % bin_fname, end="") sys.stdout.flush() recon.tofile(bin_fname)
def reconstruct(self): self.pushLoad.setEnabled(False) self.pushReconstruct.setEnabled(False) self.pushReconstruct_all.setEnabled(False) self.slice_number.setEnabled(False) self.COR.setEnabled(False) self.brightness.setEnabled(False) self.Offset_Angle.setEnabled(False) self.speed_W.setEnabled(False) QtWidgets.QApplication.processEvents() print('def reconstruct') self.full_size = self.A.shape[2] self.number_of_projections = self.A.shape[0] self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05 # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!) print('extend_FOV ', self.extend_FOV) if self.number_of_projections * self.speed_W.value() >= 270: self.number_of_used_projections = round(360 / self.speed_W.value()) else: print('smaller than 3/2 Pi') self.number_of_used_projections = round(180 / self.speed_W.value()) print('number of used projections', self.number_of_used_projections) new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180 print(new_list.shape) center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections) print(len(center_list)) transposed_sinos = numpy.zeros((min(self.number_of_used_projections, self.A.shape[0]), 1, self.full_size), dtype=float) transposed_sinos[:,0,:] = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:] print('transposed_sinos_shape', transposed_sinos.shape) extended_sinos = tomopy.misc.morph.pad(transposed_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge') extended_sinos = tomopy.minus_log(extended_sinos) extended_sinos = (extended_sinos + 9.68) * 1000 # conversion factor to uint extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0) if self.checkBox_phase_2.isChecked() == True: extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None) if self.algorithm_list.currentText() == 'FBP_CUDA': options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'} slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra, options=options) else: slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=self.algorithm_list.currentText(), filter_name=self.filter_list.currentText()) slices = slices[:,round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2) , round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2)] slices = tomopy.circ_mask(slices, axis=0, ratio=1.0) original_reconstruction = slices[0, :, :] print(numpy.amin(original_reconstruction)) print(numpy.amax(original_reconstruction)) self.min.setText(str(numpy.amin(original_reconstruction))) self.max.setText(str(numpy.amax(original_reconstruction))) print('reconstructions done') myarray = (original_reconstruction - numpy.amin(original_reconstruction)) * self.brightness.value() / (numpy.amax(original_reconstruction) - numpy.amin(original_reconstruction)) myarray = myarray.repeat(2, axis=0).repeat(2, axis=1) yourQImage = qimage2ndarray.array2qimage(myarray) self.test_reco.setPixmap(QPixmap(yourQImage)) self.pushLoad.setEnabled(True) self.pushReconstruct.setEnabled(True) self.pushReconstruct_all.setEnabled(True) self.slice_number.setEnabled(True) self.COR.setEnabled(True) self.Offset_Angle.setEnabled(True) self.brightness.setEnabled(True) self.speed_W.setEnabled(True) print('Done!')
ind_tomo = range(proj_start, proj_end) ind_flat = range(flat_start, flat_end) ind_dark = range(dark_start, dark_end) # Select the sinogram range to reconstruct. start = 0 end = 16 # Read the Anka tiff raw data. proj, flat, dark = tomopy.read_anka_topotomo(fname, ind_tomo, ind_flat, ind_dark, sino=(start, end)) # Set data collection angles as equally spaced between 0-180 degrees. theta = tomopy.angles(proj.shape[0]) # Flat-field correction of raw data. proj = tomopy.normalize(proj, flat, dark) # Find rotation center. rot_center = tomopy.find_center(proj, theta, emission=False, init=1024, ind=0, tol=0.5) print("Center of rotation: ", rot_center) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(proj, theta, center=rot_center, algorithm='gridrec', emission=False) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. tomopy.write_tiff_stack(rec, fname='recon_dir/recon')
for r in range(proj.shape[0]): r_offset = r - proj.shape[0] // 2 x_shift = -r_offset * np.tan(phi_deg * np.pi / 180) * np.sin(theta) shift(proj[r], x_shift, proj[r], mode='nearest') write_stack("phi_corrected", shifted_projs) # re-create sinos sinos = tomopy.init_tomo(shifted_projs, sinogram_order=False, sharedmem=False) tomopy.minus_log(sinos, out=sinos) del shifted_projs alg = "gridrec" options = {} logger.info(f"Reconstruct using {alg}") rec = tomopy.recon(sinos, thetas, center, sinogram_order=True, algorithm=alg, **options) write_stack(alg, rec) del rec alg = "SART" #rec = load_stack(alg) rec = None iterations = 0 iter_per_loop = 10 while(True): logger.info(f"iterations: {iterations}") iterations += iter_per_loop options = {"PixelWidth": pixel_size, "PixelHeight": pixel_size, "windowFOV": False, #circular crop disabled }
# Set path to the micro-CT data to reconstruct. fname = '../../../tomopy/data/tooth.h5' # Select the sinogram range to reconstruct. start = 0 end = 2 # Read the APS 2-BM 0r 32-ID raw data. proj, flat, dark, theta = dxchange.read_aps_32id(fname, sino=(start, end)) # Set data collection angles as equally spaced between 0-180 degrees. theta = tomopy.angles(proj.shape[0]) # Set data collection angles as equally spaced between 0-180 degrees. proj = tomopy.normalize(proj, flat, dark) # Set data collection angles as equally spaced between 0-180 degrees. rot_center = tomopy.find_center(proj, theta, init=290, ind=0, tol=0.5) proj = tomopy.minus_log(proj) # Reconstruct object using Gridrec algorithm. recon = tomopy.recon(proj, theta, center=rot_center, algorithm='gridrec') # Mask each reconstructed slice with a circle. recon = tomopy.circ_mask(recon, axis=0, ratio=0.95) # Write data as stack of TIFs. dxchange.write_tiff_stack(recon, fname='recon_dir/recon')
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec', options=None, num_iter=100, dark_file=None): sample_detector_distance = 10 # Propagation distance of the wavefront in cm detector_pixel_size_x = 2.247e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 35 # Energy of incident wave in keV alpha = 1e-01 # Phase retrieval coeff. zinger_level = 500 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) if dark_file is not None: proj_, flat, dark, theta_ = dxchange.read_aps_32id(dark_file, sino=sino) del proj_, theta_ # zinger_removal proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) # flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. ##data = tomopy.normalize(proj, flat, dark, cutoff=0.8) data = tomopy.normalize(proj, flat, dark) # remove stripes data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) data = tomopy.remove_stripe_ti(data, alpha=1.5) data = tomopy.remove_stripe_sf(data, size=150) # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center/np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) print(algorithm) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) elif algorithm == "astra_fbp": if options == 'linear': options = {'proj_type':'linear', 'method':'FBP'} else: options = {'proj_type':'cuda', 'method':'FBP_CUDA'} rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options, ncore=1) elif algorithm == "astra_sirt": extra_options = {'MinConstraint':0} options = {'proj_type':'cuda', 'method':'SIRT_CUDA', 'num_iter':num_iter, 'extra_options':extra_options} rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options) elif algorithm == tomopy.astra: rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options) else: try: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') except: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm) print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def reconstruct_all(self): self.pushLoad.setEnabled(False) self.pushReconstruct.setEnabled(False) self.slice_number.setEnabled(False) self.COR.setEnabled(False) self.brightness.setEnabled(False) self.Offset_Angle.setEnabled(False) self.speed_W.setEnabled(False) QtWidgets.QApplication.processEvents() print('def reconstruct complete volume') self.path_out_reconstructed_ask = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select folder for reconstructions.', self.path_klick) self.path_out_reconstructed_full = self.path_out_reconstructed_ask + '/'+ self.folder_name os.mkdir(self.path_out_reconstructed_full) self.full_size = self.A.shape[2] self.number_of_projections = self.A.shape[0] print('X-size', self.A.shape[2]) print('Nr of projections', self.A.shape[0]) print('Nr of slices', self.A.shape[1]) self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05 # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!) print('extend_FOV ', self.extend_FOV) if self.number_of_projections * self.speed_W.value() >= 270: self.number_of_used_projections = round(360 / self.speed_W.value()) else: print('smaller than 3/2 Pi') self.number_of_used_projections = round(180 / self.speed_W.value()) print('number of used projections', self.number_of_used_projections) new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180 print(new_list.shape) center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections) print(len(center_list)) file_name_parameter = self.path_out_reconstructed_full + '/parameter.csv' with open(file_name_parameter, mode = 'w', newline='') as parameter_file: csv_writer = csv.writer(parameter_file, delimiter = ' ', quotechar=' ') csv_writer.writerow(['Path input ', self.path_in,' ']) csv_writer.writerow(['Path output ', self.path_out_reconstructed_full,' ']) csv_writer.writerow(['Number of used projections ', str(self.number_of_used_projections),' ']) csv_writer.writerow(['Center of rotation ', str(self.COR.value()), ' ']) csv_writer.writerow(['Dark field value ', str(self.spinBox_DF.value()),' ']) csv_writer.writerow(['Ring handling radius ', str(self.spinBox_ringradius.value()),' ']) csv_writer.writerow(['Rotation offset ', str(self.Offset_Angle.value()), ' ']) csv_writer.writerow(['Rotation speed [°/image] ', str(self.speed_W.value()), ' ']) csv_writer.writerow(['Phase retrieval ', str(self.checkBox_phase_2.isChecked()), ' ']) csv_writer.writerow(['Phase retrieval distance ', str(self.doubleSpinBox_distance_2.value()), ' ']) csv_writer.writerow(['Phase retrieval energy ', str(self.doubleSpinBox_Energy_2.value()), ' ']) csv_writer.writerow(['Phase retrieval alpha ', str(self.doubleSpinBox_alpha_2.value()), ' ']) csv_writer.writerow(['16-bit ', str(self.radioButton_16bit_integer.isChecked()), ' ']) csv_writer.writerow(['16-bit integer low ', str(self.int_low.value()), ' ']) csv_writer.writerow(['16-bit integer high ', str(self.int_high.value()), ' ']) csv_writer.writerow(['Reconstruction algorithm ', self.algorithm_list.currentText(), ' ']) csv_writer.writerow(['Reconstruction filter ', self.filter_list.currentText(), ' ']) csv_writer.writerow(['Software Version ', version, ' ']) csv_writer.writerow(['binning ', '1x1x1', ' ']) i = 0 while (i < math.ceil(self.A.shape[1] / self.block_size)): print('Reconstructing block', i + 1, 'of', math.ceil(self.A.shape[1] / self.block_size)) extended_sinos = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :] extended_sinos = tomopy.misc.morph.pad(extended_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge') extended_sinos = tomopy.minus_log(extended_sinos) extended_sinos = (extended_sinos + 9.68) * 1000 # conversion factor to uint extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0) if self.checkBox_phase_2.isChecked() == True: extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None) if self.algorithm_list.currentText() == 'FBP_CUDA': options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'} slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra, options=options) else: slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=self.algorithm_list.currentText(), filter_name=self.filter_list.currentText()) slices = slices[:, round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2), round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2)] slices = tomopy.circ_mask(slices, axis=0, ratio=1.0) if self.radioButton_16bit_integer.isChecked() == True: ima3 = 65535 * (slices - self.int_low.value()) / (self.int_high.value() - self.int_low.value()) ima3 = numpy.clip(ima3, 1, 65534) slices_save = ima3.astype(numpy.uint16) if self.radioButton_32bit_float.isChecked() == True: slices_save = slices print('Reconstructed Volume is', slices_save.shape) a = 1 while (a < self.block_size + 1) and (a < slices_save.shape[0] + 1): self.progressBar.setValue((a + (i * self.block_size)) * 100 / self.A.shape[1]) filename2 = self.path_out_reconstructed_full + self.namepart + str(a + self.crop_offset + i * self.block_size).zfill(4) + self.filetype print('Writing Reconstructed Slices:', filename2) slice_save = slices_save[a - 1, :, :] img = Image.fromarray(slice_save) img.save(filename2) QtCore.QCoreApplication.processEvents() time.sleep(0.02) a = a + 1 i = i + 1 self.pushLoad.setEnabled(True) self.pushReconstruct.setEnabled(True) self.slice_number.setEnabled(True) self.COR.setEnabled(True) self.brightness.setEnabled(True) self.Offset_Angle.setEnabled(True) self.speed_W.setEnabled(True) print('Done!')
# ============================================================================= # tomo reconstruction and save # ============================================================================= #find rotation center from phase-retrieved images cent = rotaxis(proj, N_steps) cent = np.median(cent) #print('done with rotation axis, X coordinate = ', cent) n = proj.shape[0] angle = np.pi * np.arange(n) / (N_steps * 180) time1 = time.time() recon = tomopy.recon(proj, angle, center=cent, algorithm='gridrec', filter_name='shepp') print('time for tomo_recon ', time.time() - time1) #np.save(folder_result + data_name + 'save_tomo_result.npy', recon) outs = var.imrescale( recon[:, Pro.Npad:recon.shape[1] - Pro.Npad, Pro.Npad:recon.shape[2] - Pro.Npad], 16) #crop additionally outs = outs[:, 500:1500, 150:1900] folder_tiff = folder_result + 'plane_tiff/' dxchange.write_tiff_stack(outs, fname=folder_tiff + data_name + '_tomo/tomo') #np.save(folder_result + 'tomo.npy', outs)
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 31 # Propagation distance of the wavefront in cm detector_pixel_size_x = 1.17e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 65 # Energy of incident wave in keV # used pink beam alpha = 4 * 1e-4 # Phase retrieval coeff. zinger_level = 800 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white # Read APS 2-BM raw data. # DIMAX saves 3 files: proj, flat, dark # when loading the data set select the proj file (larger size) fname = os.path.splitext(h5fname)[0] fbase = fname.rsplit('_', 1)[0] fnum = fname.rsplit('_', 1)[1] fext = os.path.splitext(h5fname)[1] fnum_flat = str("%4.4d" % (int(fnum) + 1)) fnum_dark = str("%4.4d" % (int(fnum) + 2)) fnproj = fbase + '_' + fnum + fext fnflat = fbase + '_' + fnum_flat + fext fndark = fbase + '_' + fnum_dark + fext print('proj', fnproj) print('flat', fnflat) print('dark', fndark) # Read APS 2-BM DIMAX raw data. proj, dum, dum2, theta = dxchange.read_aps_32id(fnproj, sino=sino) dum3, flat, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino) #flat, dum3, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino) dum6, dum7, dark, dum8 = dxchange.read_aps_32id(fndark, sino=sino) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=1.4) # remove stripes data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1, pad=True) # zinger_removal proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. ##data = tomopy.normalize(proj, flat, dark, cutoff=0.8) data = tomopy.normalize(proj, flat, dark) # remove stripes #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) #data = tomopy.remove_stripe_ti(data, alpha=1.5) data = tomopy.remove_stripe_sf(data, size=150) # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center / np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # padding N = data.shape[2] data_pad = np.zeros([data.shape[0], data.shape[1], 3 * N // 2], dtype="float32") data_pad[:, :, N // 4:5 * N // 4] = data data_pad[:, :, 0:N // 4] = np.tile( np.reshape(data[:, :, 0], [data.shape[0], data.shape[1], 1]), (1, 1, N // 4)) data_pad[:, :, 5 * N // 4:] = np.tile( np.reshape(data[:, :, -1], [data.shape[0], data.shape[1], 1]), (1, 1, N // 4)) data = data_pad rot_center = rot_center + N // 4 nframes = 8 nproj = 1500 theta = np.linspace(0, np.pi * nframes, nproj * nframes, endpoint=False) rec = np.zeros((nframes, data.shape[1], data.shape[2], data.shape[2]), dtype='float32') for time_frame in range(0, nframes): rec0 = tomopy.recon(data[time_frame * nproj:(time_frame + 1) * nproj], theta[time_frame * nproj:(time_frame + 1) * nproj], center=rot_center, algorithm='gridrec') # Mask each reconstructed slice with a circle. rec[time_frame] = tomopy.circ_mask(rec0, axis=0, ratio=0.95) rec = rec[:, :, N // 4:5 * N // 4, N // 4:5 * N // 4] print("Algorithm: ", algorithm) return rec
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 8 # Propagation distance of the wavefront in cm detector_pixel_size_x = 2.247e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 24.9 # Energy of incident wave in keV alpha = 1e-02 # Phase retrieval coeff. zinger_level = 800 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white # Read APS 32-BM raw data. h5fname_norm = '/local/data/2019-02/Dunand/In-situ_100_2/In-situ_100_2_0277.h5' proj1, flat, dark, theta1 = dxchange.read_aps_32id(h5fname_norm, sino=sino) proj, dummy, dummy1, theta = dxchange.read_aps_32id(h5fname, sino=sino) # zinger_removal proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. ##data = tomopy.normalize(proj, flat, dark, cutoff=0.8) data = tomopy.normalize(proj, flat, dark) # remove stripes #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) #data = tomopy.remove_stripe_ti(data, alpha=1.5) #data = tomopy.remove_stripe_sf(data, size=150) # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center / np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) else: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
def tomo(params): fname = str(params.input_file_path) start = params.slice_start end = params.slice_end # Read raw data. if (params.full_reconstruction == False): end = start + 1 # LOG.info('Slice start/end: %s', end) proj, flat, dark, theta = dxchange.read_aps_32id(fname, sino=(start, end)) LOG.info('Slice start/end: %s, %s', start, end) LOG.info('Data successfully imported: %s', fname) LOG.info('Projections: %s', proj.shape) LOG.info('Flat: %s', flat.shape) LOG.info('Dark: %s', dark.shape) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark) LOG.info('Normalization completed') data = tomopy.downsample(data, level=int(params.binning)) LOG.info('Binning: %s', params.binning) # remove stripes data = tomopy.remove_stripe_fw(data, level=5, wname='sym16', sigma=1, pad=True) LOG.info('Ring removal completed') # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-3,pad=True) # Find rotation center #rot_center = tomopy.find_center(proj, theta, init=290, ind=0, tol=0.5) # Set rotation center. rot_center = params.center / np.power(2, float(params.binning)) LOG.info('Rotation center: %s', rot_center) data = tomopy.minus_log(data) LOG.info('Minus log compled') # Reconstruct object using Gridrec algorithm. LOG.info('Reconstruction started using %s', params.reconstruction_algorithm) if (str(params.reconstruction_algorithm) == 'sirt'): LOG.info('Iteration: %s', params.iteration_count) rec = tomopy.recon(data, theta, center=rot_center, algorithm='sirt', num_iter=params.iteration_count) else: LOG.info('Filter: %s', params.filter) rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name=params.filter) LOG.info('Reconstrion of %s completed', rec.shape) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) if (params.dry_run == False): # Write data as stack of TIFs. fname = str(params.output_path) + 'reco' dxchange.write_tiff_stack(rec, fname=fname, overwrite=True) LOG.info('Reconstrcution saved: %s', fname) if (params.full_reconstruction == False): return rec
# Reduce dataset # # skip = 770 # proj = proj[:, ::skip, :] # theta = theta[::skip] # slicenum =750 # proj = proj[:, slicenum, :] # proj = proj[:,numpy.newaxis,:] ################################ # Absorption contrast Reconstruction # reco_algorithm = 'gridrec' reco = tomopy.recon(proj, theta, center=rcen, algorithm=reco_algorithm, ncore=ncore, nchunk=nchunk) logger.info('reconstructed absorption data proj with algorithm: %s' % reco_algorithm) ################################ # Post processing circ_mask_ratio = 1.0 reco = tomopy.circ_mask(reco, axis=0, ratio=circ_mask_ratio) logger.info('applied circular mask with ratio: %s' % circ_mask_ratio) reco = tomopy.remove_ring(reco, ncore=ncore, nchunk=nchunk) logger.info('removed rings from reco with standard settings.')
shifts.dtype) np.save(folder_proj + data_name + '_rotate.npy', proj) np.save(folder_proj + data_name + '_shifts.npy', shifts_2_save) # ============================================================================= # ============================================================================= # tomo reconstruction # ============================================================================= # 1st reconstruction - all files n = proj.shape[0] angle = np.pi * np.arange(n) / (N_steps * 180) time1 = time.time() outs = tomopy.recon(proj, angle, center=cent, algorithm='gridrec', filter_name='shepp', ncore=cp_count) #print('time for tomo_recon ', time.time()-time1) #crop outs = outs[:, Pro.Npad:outs.shape[1] - Pro.Npad, Pro.Npad:outs.shape[2] - Pro.Npad] #crop additionally #outs = outs[:,270:840, 125:1020] np.save(folder_proj + data_name + '_rec.npy', outs) print('reconstruction done')
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'): sample_detector_distance = 30 # Propagation distance of the wavefront in cm detector_pixel_size_x = 1.17e-4 # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4) monochromator_energy = 25.74 # Energy of incident wave in keV alpha = 1e-02 # Phase retrieval coeff. zinger_level = 1000 # Zinger level for projections zinger_level_w = 1000 # Zinger level for white miss_angles = [500, 1050] # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) print(theta) # Manage the missing angles: #proj_size = np.shape(proj) #theta = np.linspace(0,180,proj_size[0]) print(proj.shape, theta.shape) proj = np.concatenate( (proj[0:miss_angles[0], :, :], proj[miss_angles[1] + 1:-1, :, :]), axis=0) theta = np.concatenate( (theta[0:miss_angles[0]], theta[miss_angles[1] + 1:-1])) print(proj.shape, theta.shape) # zinger_removal #proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0) #flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=0.8) # remove stripes # data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True) data = tomopy.remove_stripe_ti(data, 2) # phase retrieval # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) data = tomopy.remove_nan(data, val=0.0) data = tomopy.remove_neg(data, val=0.00) data[np.where(data == np.inf)] = 0.00 rot_center = rot_center / np.power(2, float(binning)) data = tomopy.downsample(data, level=binning) data = tomopy.downsample(data, level=binning, axis=1) # Reconstruct object. if algorithm == 'sirtfbp': rec = rec_sirtfbp(data, theta, rot_center) else: rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen') print("Algorithm: ", algorithm) # Mask each reconstructed slice with a circle. ##rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) return rec
from tomophantom.supp.artifacts import _Artifacts_ # forming dictionaries with artifact types _noise_ = {'noise_type' : 'Poisson', 'noise_sigma' : 10000, # noise amplitude 'noise_seed' : 0} noisy_sino = _Artifacts_(sino_an, **_noise_) plt.figure() plt.rcParams.update({'font.size': 21}) plt.imshow(noisy_sino,cmap="gray") plt.colorbar(ticks=[0, 150, 250], orientation='vertical') plt.title('{}''{}'.format('Analytical noisy sinogram.',model)) #%% print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") print ("Reconstructing analytical sinogram using gridrec (TomoPy)...") print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") import tomopy sinoTP = np.zeros((angles_num,1,P),dtype='float32') sinoTP[:,0,:] = noisy_sino rot_center = tomopy.find_center(sinoTP, angles_rad, init=290, ind=0, tol=0.5) reconTomoPy_ideal = tomopy.recon(sinoTP, angles_rad, center=rot_center, algorithm='gridrec') plt.figure() plt.imshow(reconTomoPy_ideal[0,:,:], vmin=0, vmax=1, cmap="gray") plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical') plt.title('GridRec reconstruction (TomoPy)') plt.show() #%%
end = 1025 proj = proj[:, [start,end], :] flat = flat[:, [start,end], :] dark = dark[:, [start,end], :] # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark) # remove stripes data = tomopy.prep.stripe.remove_stripe_fw(data,level=5,wname='sym16',sigma=1,pad=True) # # phase retrieval #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-3,pad=True) # Set rotation center. rot_center = 1552 print(rot_center) data = tomopy.minus_log(data) # Reconstruct object using Gridrec algorithm. rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name = 'parzen', nchunk=1) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) # Write data as stack of TIFs. fname='/local/decarlo/data/hzg/microtomography/fabian_wilde/recon_dir/recon' dxchange.write_tiff_stack(rec, fname=fname)
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm, binning): data_shape = get_dx_dims(h5fname, 'data') print(data_shape) ssino = int(data_shape[1] * nsino) center_range = (rot_center - center_search_width, rot_center + center_search_width, 0.5) #print(sino,ssino, center_range) #print(center_range[0], center_range[1], center_range[2]) # Select sinogram range to reconstruct sino = None start = ssino end = start + 1 sino = (start, end) # Read APS 32-BM raw data. proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino) # Flat-field correction of raw data. data = tomopy.normalize(proj, flat, dark, cutoff=1.4) # remove stripes data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1, pad=True) print("Raw data: ", h5fname) print("Center: ", rot_center) data = tomopy.minus_log(data) stack = np.empty( (len(np.arange(*center_range)), data_shape[0], data_shape[2])) index = 0 for axis in np.arange(*center_range): stack[index] = data[:, 0, :] index = index + 1 # Reconstruct the same slice with a range of centers. rec = tomopy.recon(stack, theta, center=np.arange(*center_range), sinogram_order=True, algorithm='gridrec', filter_name='parzen', nchunk=1) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95) index = 0 # Save images to a temporary folder. fname = os.path.dirname( h5fname) + '/' + 'try_rec/' + 'recon_' + os.path.splitext( os.path.basename(h5fname))[0] for axis in np.arange(*center_range): rfname = fname + '_' + str('{0:.2f}'.format(axis) + '.tiff') dxchange.write_tiff(rec[index], fname=rfname, overwrite=True) index = index + 1 print("Reconstructions: ", fname)
# reconstruct ########################################## print('\n*** Reconstructing...') start_recon_time = time.time() nCol = prj.shape[2] if (recon_algo == 'gridrec' and rec_filter == 'sirtfbp'): if test_sirtfbp_iter: num_iter = [1, 2, 3] # filter_dict = sirtfilter.getfilterfile(nCol, theta, num_iter, filter_dir='./') filter_dict = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') for its in num_iter: output_name_2 = output_name + '_test_iter/' tomopy_filter = sirtfilter.convert_to_tomopy_filter(filter_dict[its], nCol) rec = tomopy.recon(prj, theta, center=best_center/pow(2,binning), algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) output_name_2 = output_name_2 + 'sirt_fbp_%iiter_slice_' % its dxchange.write_tiff_stack(rec, fname=output_name_2, start=sino_start, dtype='float32') else: # filter_file = sirtfilter.getfilterfile(nCol, theta, num_iter, filter_dir='./') sirtfbp_filter = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') tomopy_filter = sirtfilter.convert_to_tomopy_filter(sirtfbp_filter, nCol) rec = tomopy.recon(prj, theta, center=best_center/pow(2,binning), algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) else: rec = tomopy.recon(prj, theta, center=best_center/pow(2,binning), algorithm=recon_algo, filter_name=rec_filter) print(' Slice reconstruction done in %0.3f min' % ((time.time() - start_recon_time)/60)) print(output_name_2) # Postprocessing reconstruction:
def recon3(io_paras, data_paras, rot_center=None, normalize=True, stripe_removal=10, stripe_sigma=2, phase_retrieval=False, opt_center=False, diag_center=False, output="tiff", z_recon_size=None): # Input and output datafile = io_paras.get('datafile') path2white = io_paras.get('path2white', datafile) path2dark = io_paras.get('path2dark', path2white) out_dir = io_paras.get('out_dir') diag_cent_dir = io_paras.get('diag_cent_dir', out_dir + "/center_diagnose/") recon_dir = io_paras.get('recon_dir', out_dir + "/recon/") out_prefix = io_paras.get('out_prefix', "recon_") # Parameters of dataset NumCycles = data_paras.get('NumCycles', 1) # Number of cycles used for recon ProjPerCycle = data_paras.get( 'ProjPerCycle') # Number of projections per cycle, N_theta cycle_offset = data_paras.get('cycle_offset', 0) # Offset in output cycle number proj_start = data_paras.get('proj_start', 0) # Starting projection of reconstruction proj_step = data_paras.get('proj_step') z_start = data_paras.get('z_start', 0) z_end = data_paras.get('z_end', z_start + 1) z_step = data_paras.get('z_step') x_start = data_paras.get('x_start') x_end = data_paras.get('x_end', x_start + 1) x_step = data_paras.get('x_step') white_start = data_paras.get('white_start') white_end = data_paras.get('white_end') dark_start = data_paras.get('dark_start') dark_end = data_paras.get('dark_end') # TIMBIR parameters NumSubCycles = data_paras.get('NumSubCycles', 1) # Number of subcycles in one cycle, K SlewSpeed = data_paras.get('SlewSpeed', 0) # In deg/s MinAcqTime = data_paras.get('MinAcqTime', 0) # In s TotalNumCycles = data_paras.get( 'TotalNumCycles', 1) # Total number of cycles in the full scan data ProjPerRecon = data_paras.get( 'ProjPerRecon', ProjPerCycle) # Number of projections per reconstruction # Calculate thetas for interlaced scan theta = gen_theta_timbir(NumSubCycles, ProjPerCycle, SlewSpeed, MinAcqTime, TotalNumCycles) if ProjPerRecon is None: ProjPerCycle = theta.size // TotalNumCycles else: ProjPerCycle = ProjPerRecon print("Will use %s projections per reconstruction." % ProjPerCycle) # Distribute z slices to processes if z_step is None: z_step = 1 z_pool = get_pool(z_start, z_end, z_step, z_chunk_size=z_recon_size, fmt='slice') slice3 = slice(x_start, x_end, x_step) rot_center_copy = rot_center for cycle in xrange(NumCycles): # Set start and end of each cycle projections_start = cycle * ProjPerCycle + proj_start projections_end = projections_start + ProjPerCycle slice1 = slice(projections_start, projections_end, proj_step) # Setup continuous output if "cont" in output: if not os.path.exists(recon_dir): os.makedirs(recon_dir) cont_fname = recon_dir+"/"+out_prefix+"t_%d_z_%d_%d.bin" \ % (cycle + cycle_offset, z_start, z_end) cont_file = file(cont_fname, 'wb') # Distribute z slices to processes for i in range(_rank, len(z_pool), _nprocs): slice2 = z_pool[i] slices = (slice1, slice2, slice3) white_slices = (slice(white_start, white_end), slice2, slice3) dark_slices = (slice(dark_start, dark_end), slice2, slice3) print( "Running cycle #%s (projs %s to %s, z = %s - %s) on process %s of %s" % (cycle, projections_start, projections_end, slice2.start, slice2.stop, _rank, _nprocs)) # Read HDF5 file. print("Reading datafile %s..." % datafile, end="") sys.stdout.flush() data, white, dark = reader.read_aps_2bm(datafile, slices, white_slices, dark_slices, path2white=path2white, path2dark=path2dark) # data += 1 # theta = gen_theta(data.shape[0]) print("Done!") print("Data shape = %s;\nwhite shape = %s;\ndark shape = %s." % (data.shape, white.shape, dark.shape)) # data = tomopy.focus_region(data, dia=1560, xcoord=1150, ycoord=1080, # center=rot_center, pad=False, corr=True) # rot_center = None # print("Data shape = %s;\nwhite shape = %s;\ndark shape = %s." # % (data.shape, white.shape, dark.shape)) ## Normalize dataset using data_white and data_dark if normalize: print("Normalizing data ...") # white = white.mean(axis=0).reshape(-1, *data.shape[1:]) # dark = dark.mean(axis=0).reshape(-1, *data.shape[1:]) # data = (data - dark) / (white - dark) data = tomopy.normalize(data, white, dark, cutoff=None, ncore=_ncore, nchunk=_nchunk)[...] ## Remove stripes caused by dead pixels in the detector if stripe_removal: print("Removing stripes ...") data = tomopy.remove_stripe_fw(data, level=stripe_removal, wname='db5', sigma=stripe_sigma, pad=True, ncore=_ncore, nchunk=_nchunk) # data = tomopy.remove_stripe_ti(data, nblock=0, alpha=1.5, # ncore=None, nchunk=None) # # Show preprocessed projection # plt.figure("%s-prep" % projections_start) # plt.imshow(d.data[0,:,:], cmap=cm.Greys_r) # plt.savefig(out_dir+"/preprocess/%s-prep.jpg" # % projections_start) # # plt.show() # continue ## Phase retrieval if phase_retrieval: print("Retrieving phase ...") data = tomopy.retrieve_phase(data, pixel_size=1.1e-4, dist=6, energy=25.7, alpha=1e-2, pad=True, ncore=_ncore, nchunk=_nchunk) ## Determine and set the center of rotation if opt_center: # or (rot_center == None): ### Using optimization method to automatically find the center # d.optimize_center() print("Optimizing center ...", end="") sys.stdout.flush() rot_center = tomopy.find_center(data, theta, ind=None, emission=True, init=None, tol=0.5, mask=True, ratio=1.) print("Done!") print("center = %s" % rot_center) if diag_center: ### Output the reconstruction results using a range of centers, ### and then manually find the optimal center. # d.diagnose_center() if not os.path.exists(diag_cent_dir): os.makedirs(diag_cent_dir) print("Testing centers ...", end="") sys.stdout.flush() tomopy.write_center( data, theta, dpath=diag_cent_dir, cen_range=[center_start, center_end, center_step], ind=None, emission=False, mask=False, ratio=1.) print("Done!") ## Flip odd frames # if (cycle % 2): # data[...] = data[...,::-1] # rot_center = data.shape[-1] - rot_center_copy # else: # rot_center = rot_center_copy ## Reconstruction using FBP print("Running gridrec ...", end="") sys.stdout.flush() recon = tomopy.recon( data, theta[slice1], center=rot_center, emission=False, algorithm='gridrec', # num_gridx=None, num_gridy=None, filter_name='shepp', ncore=_ncore, nchunk=_nchunk) print("Done!") ## Collect background # if cycle == 0: # bg = recon # elif cycle < 4: # bg += recon # else: # recon -= bg/4. # Write to stack of TIFFs. if not os.path.exists(recon_dir): os.makedirs(recon_dir) out_fname = recon_dir + "/" + out_prefix + "t_%d_z_" % ( cycle + cycle_offset) if "hdf" in output: hdf_fname = out_fname + "%d_%d.hdf5" % (slice2.start, slice2.stop) print("Writing reconstruction output file %s..." % hdf_fname, end="") sys.stdout.flush() tomopy.write_hdf5(recon, fname=hdf_fname, gname='exchange', overwrite=False) print("Done!") if "tif" in output: if "stack" in output: # single stacked file for multiple z tiff_fname = out_fname + "%d_%d.tiff" % (slice2.start, slice2.stop) print("Writing reconstruction tiff files %s ..." % tiff_fname, end="") sys.stdout.flush() tomopy.write_tiff(recon, fname=tiff_fname, overwrite=False) print("Done!") else: # separate files for different z for iz, z in enumerate( range(slice2.start, slice2.stop, slice2.step)): tiff_fname = out_fname + "%d.tiff" % z print("Writing reconstruction tiff files %s ..." % tiff_fname, end="") sys.stdout.flush() tomopy.write_tiff(recon[iz], fname=tiff_fname, overwrite=False) print("Done!") if "bin" in output: bin_fname = out_fname + "%d_%d.bin" % (slice2.start, slice2.stop) print("Writing reconstruction to binary files %s..." % bin_fname, end="") sys.stdout.flush() recon.tofile(bin_fname) if "cont" in output: print("Writing reconstruction to binary files %s..." % cont_fname, end="") sys.stdout.flush() recon.tofile(cont_file) print("Done!") if "cont" in output: cont_file.close() if _usempi: comm.Barrier() if _rank == 0: print("All done!")
rot_center = 1552 print(rot_center) data = tomopy.minus_log(data) # Use test_sirtfbp_iter = True to test which number of iterations is suitable for your dataset # Filters are saved in .mat files in "./¨ test_sirtfbp_iter = True if test_sirtfbp_iter: nCol = data.shape[2] output_name = './test_iter/' num_iter = [50,100,150] filter_dict = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') for its in num_iter: tomopy_filter = sirtfilter.convert_to_tomopy_filter(filter_dict[its], nCol) rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) output_name_2 = output_name + 'sirt_fbp_%iiter_slice_' % its dxchange.write_tiff_stack(data, fname=output_name_2, start=start, dtype='float32') # Reconstruct object using sirt-fbp algorithm: num_iter = 100 nCol = data.shape[2] sirtfbp_filter = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./') tomopy_filter = sirtfilter.convert_to_tomopy_filter(sirtfbp_filter, nCol) rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter) # Reconstruct object using Gridrec algorithm. # rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', nchunk=1) # Mask each reconstructed slice with a circle. rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
def recon(io_paras, data_paras, rot_center=None, normalize=True, stripe_removal=10, phase_retrieval=False, opt_center=False, diag_center=False, output="tiff"): # Input and output datafile = io_paras.get('datafile') path2white = io_paras.get('path2white', datafile) path2dark = io_paras.get('path2dark', path2white) out_dir = io_paras.get('out_dir') diag_cent_dir = io_paras.get('diag_cent_dir', out_dir + "/center_diagnose/") recon_dir = io_paras.get('recon_dir', out_dir + "/recon/") out_prefix = io_paras.get('out_prefix', "recon_") # Parameters of dataset NumCycles = data_paras.get('NumCycles', 1) # Number of cycles used for recon ProjPerCycle = data_paras.get( 'ProjPerCycle') # Number of projections per cycle, N_theta cycle_offset = data_paras.get('cycle_offset', 0) # Offset in output cycle number proj_start = data_paras.get('proj_start', 0) # Starting projection of reconstruction proj_step = data_paras.get('proj_step') z_start = data_paras.get('z_start', 0) z_end = data_paras.get('z_end', z_start + 1) z_step = data_paras.get('z_step') x_start = data_paras.get('x_start') x_end = data_paras.get('x_end', x_start + 1) x_step = data_paras.get('x_step') white_start = data_paras.get('white_start') white_end = data_paras.get('white_end') dark_start = data_paras.get('dark_start') dark_end = data_paras.get('dark_end') rot_center_copy = rot_center for cycle in xrange(NumCycles): # Set start and end of each cycle projections_start = cycle * ProjPerCycle + proj_start projections_end = projections_start + ProjPerCycle slice1 = slice(projections_start, projections_end, proj_step) slice2 = slice(z_start, z_end, z_step) slice3 = slice(x_start, x_end, x_step) slices = (slice1, slice2, slice3) white_slices = (slice(white_start, white_end), slice2, slice3) dark_slices = (slice(dark_start, dark_end), slice2, slice3) print("Running cycle #%s (projs %s to %s)" % (cycle, projections_start, projections_end)) # Read HDF5 file. print("Reading datafile %s..." % datafile, end="") sys.stdout.flush() data, white, dark = reader.read_aps_2bm(datafile, slices, white_slices, dark_slices, path2white=path2white, path2dark=path2dark) theta = gen_theta(data.shape[0]) print("Done!") print("Data shape = %s;\nwhite shape = %s;\ndark shape = %s." % (data.shape, white.shape, dark.shape)) ## Normalize dataset using data_white and data_dark if normalize: print("Normalizing data ...") # white = white.mean(axis=0).reshape(-1, *data.shape[1:]) # dark = dark.mean(axis=0).reshape(-1, *data.shape[1:]) # data = (data - dark) / (white - dark) data = tomopy.normalize(data, white, dark, cutoff=None, ncore=_ncore, nchunk=None)[...] ## Remove stripes caused by dead pixels in the detector if stripe_removal: print("Removing stripes ...") data = tomopy.remove_stripe_fw(data, level=stripe_removal, wname='db5', sigma=2, pad=True, ncore=_ncore, nchunk=None) # data = tomopy.remove_stripe_ti(data, nblock=0, alpha=1.5, # ncore=None, nchunk=None) # # Show preprocessed projection # plt.figure("%s-prep" % projections_start) # plt.imshow(d.data[0,:,:], cmap=cm.Greys_r) # plt.savefig(out_dir+"/preprocess/%s-prep.jpg" # % projections_start) # # plt.show() # continue ## Phase retrieval if phase_retrieval: print("Retrieving phase ...") data = tomopy.retrieve_phase(data, pixel_size=1e-4, dist=50, energy=20, alpha=1e-3, pad=True, ncore=_ncore, nchunk=None) ## Determine and set the center of rotation if opt_center or (rot_center == None): ### Using optimization method to automatically find the center # d.optimize_center() print("Optimizing center ...", end="") sys.stdout.flush() rot_center = tomopy.find_center(data, theta, ind=None, emission=True, init=None, tol=0.5, mask=True, ratio=1.) print("Done!") print("center = %s" % rot_center) if diag_center: ### Output the reconstruction results using a range of centers, ### and then manually find the optimal center. # d.diagnose_center() if not os.path.exists(diag_cent_dir): os.makedirs(diag_cent_dir) print("Testing centers ...", end="") sys.stdout.flush() tomopy.write_center( data, theta, dpath=diag_cent_dir, cen_range=[center_start, center_end, center_step], ind=None, emission=False, mask=False, ratio=1.) print("Done!") ## Flip odd frames if (cycle % 2): data[...] = data[..., ::-1] rot_center = data.shape[-1] - rot_center_copy else: rot_center = rot_center_copy ## Reconstruction using FBP print("Running gridrec ...", end="") sys.stdout.flush() recon = tomopy.recon( data, theta, center=rot_center, emission=False, algorithm='gridrec', # num_gridx=None, num_gridy=None, filter_name='shepp', ncore=_ncore, nchunk=_nchunk) print("Done!") ## Collect background # if cycle == 0: # bg = recon # elif cycle < 4: # bg += recon # else: # recon -= bg/4. # Write to stack of TIFFs. if not os.path.exists(recon_dir): os.makedirs(recon_dir) out_fname = recon_dir + "/" + out_prefix + "t_%d" % (cycle + cycle_offset) if "hdf" in output: hdf_fname = out_fname + ".hdf5" print("Writing reconstruction output file %s..." % hdf_fname, end="") sys.stdout.flush() tomopy.write_hdf5(recon, fname=hdf_fname, gname='exchange', overwrite=False) print("Done!") if "tif" in output: tiff_fname = out_fname + ".tiff" print("Writing reconstruction tiff files %s ..." % tiff_fname, end="") sys.stdout.flush() tomopy.write_tiff_stack(recon, fname=tiff_fname, axis=0, digit=5, start=0, overwrite=False) print("Done!") if "bin" in output: bin_fname = out_fname + ".bin" print("Writing reconstruction to binary files %s..." % bin_fname, end="") sys.stdout.flush() recon.tofile(bin_fname)