def forward(obj=None, obj_corner=None, probe=None, theta=None, v=None, h=None, **kwargs): """Compute line integrals over an obj; i.e. simulate data acquisition.""" Lr = tomopy.project(obj=obj.real, theta=theta, pad=False) Li = tomopy.project(obj=obj.imag, theta=theta, pad=False) line_integrals = np.empty(Lr.shape, dtype=complex) line_integrals.real = Lr line_integrals.imag = Li return line_integrals
def generate(phantom, args): """Return the simulated data for the given phantom.""" with timemory.util.auto_timer("[tomopy.misc.phantom.{}]".format(phantom)): obj = getattr(tomopy.misc.phantom, phantom)(size=args.size) obj = tomopy.misc.morph.pad(obj, axis=1, mode='constant') obj = tomopy.misc.morph.pad(obj, axis=2, mode='constant') if args.partial: data_size = obj.shape[0] subset = list(args.subset) subset.sort() nbeg, nend = subset[0], subset[1] if nbeg == nend: nend += 1 if not args.no_center: ndiv = (nend - nbeg) // 2 offset = data_size // 2 nbeg = (offset - ndiv) nend = (offset + ndiv) print("[partial]> slices = {} ({}, {}) of {}".format( nend - nbeg, nbeg, nend, data_size)) obj = obj[nbeg:nend, :, :] with timemory.util.auto_timer("[tomopy.angles]"): ang = tomopy.angles(args.angles) with timemory.util.auto_timer("[tomopy.project]"): prj = tomopy.project(obj, ang) print("[dims]> projection = {}, angles = {}, object = {}".format( prj.shape, ang.shape, obj.shape)) return [prj, ang, obj]
def generate(phantom, args): """Return the simulated data for the given phantom.""" with timemory.util.auto_timer("[tomopy.misc.phantom.{}]".format(phantom)): obj = getattr(tomopy.misc.phantom, phantom)(size=args.size) obj = tomopy.misc.morph.pad(obj, axis=1, mode='constant') obj = tomopy.misc.morph.pad(obj, axis=2, mode='constant') if args.partial: data_size = obj.shape[0] subset = list(args.subset) subset.sort() nbeg, nend = subset[0], subset[1] if nbeg == nend: nend += 1 if not args.no_center: ndiv = (nend - nbeg) // 2 offset = data_size // 2 nbeg = (offset - ndiv) nend = (offset + ndiv) print("[partial]> slices = {} ({}, {}) of {}".format( nend - nbeg, nbeg, nend, data_size)) obj = obj[nbeg:nend,:,:] with timemory.util.auto_timer("[tomopy.angles]"): ang = tomopy.angles(args.angles) with timemory.util.auto_timer("[tomopy.project]"): prj = tomopy.project(obj, ang) print("[dims]> projection = {}, angles = {}, object = {}".format( prj.shape, ang.shape, obj.shape)) return [prj, ang, obj]
def generate(phantom="shepp3d", nsize=512, nangles=360): with timemory.util.auto_timer("[tomopy.misc.phantom.{}]".format(phantom)): obj = getattr(tomopy.misc.phantom, phantom)(size=nsize) with timemory.util.auto_timer("[tomopy.angles]"): ang = tomopy.angles(nangles) with timemory.util.auto_timer("[tomopy.project]"): prj = tomopy.project(obj, ang) return [prj, ang, obj]
def _project_at_theta(theta_val, vol=None, n_energies=None, beam=None, noise=None): proj = np.asarray([project(vol[ie], \ np.radians([theta_val]), \ pad = False, \ emission = False)[0] for ie in range(n_energies)]) proj = proj * beam + np.random.normal(0, noise / n_energies, beam.shape) proj = simps(proj, x=energy_pts, axis=0) return proj
def sample_stack_proj_Angles(obj, angles, rows=5, cols=5, start_with=0, show_every=16, algo='defaut'): sim = tomopy.project(obj, angles) # Calculate projections fig, ax = plt.subplots(rows, cols, figsize=[12, 12]) for i in range(rows * cols): ind = start_with + i * show_every ax[int(i / rows), int(i % rows)].set_title('Angle %g°' % (ind * 0.9)) ax[int(i / rows), int(i % rows) ].imshow(sim[ind, :, :], cmap=plt.cm.Greys_r) ax[int(i / rows), int(i % rows)].axis('off') #plt.suptitle('%s images' % algo, fontsize=20) plt.tight_layout() plt.savefig('%s_proj_360_angles.png' % algo, dpi=300) plt.close()
def recon(path='NUS 3D/sample2', save_path='./model/'): save_path = os.path.join(save_path, path.split('/')[-1] + '_recon') os.makedirs(save_path, exist_ok=True) paths = os.listdir(path) paths = sorted(paths) for file_name in paths[:5]: ph = os.path.join(path, file_name) sh = os.path.join(save_path, file_name) obj = dxchange.reader.read_tiff(fname=ph, slc=None) # Generate an object ang = tomopy.angles(180) # Generate uniformly spaced tilt angles obj = obj.astype(np.float32) sim = tomopy.project(obj, ang) # Calculate projections rec = tomopy.recon(sim, ang, algorithm='art') # Reconstruct object tifffile.imwrite(sh, rec)
def choix_fichier(self): # L'utilisateur choisi le dossier dans lequel se trouve les fichiers path = QtWidgets.QFileDialog.getExistingDirectory( self, "Open a folder", os.sep.join( (os.path.expanduser('~'), 'Desktop' )), #Permet d'afficher le bureau à l'ouverture de la fenêtre options=QtWidgets.QFileDialog.ShowDirsOnly) #Gestion de l'exception dans le cas où l'utilisateur choisit un mauvais dossier #Si aucun dossier n'est sélectionné path = 0 et il ne se passe rien if path: try: MatrixGeneration(path + '/*.tif') except IndexError: return tomopy.project(tomopy.shepp3d(), tomopy.angles(180))
def test_tomogram_360(self): # Prepare mocked config parameters params = mock.MagicMock() params.rotation_axis_flip = 10 flip_axis = 82 # Prepare simulated flipped data original = misc.phantom.shepp2d((128, 128), dtype='float32') theta360 = np.linspace(0, np.pi * 2, num=362) fullsino = project(original, theta=theta360) sino360 = fullsino[:, :, flip_axis:] # Flip and stitch to simulated data sino180, flat180, dark180 = file_io.flip_and_stitch(params, img360=sino360, flat360=sino360, dark360=sino360) # Test the result self.assertEqual(sino180.shape, (181, 1, 183))
def choix_fichier(self): factor = float(str(self.selectFactor.currentText())) # L'utilisateur choisi le dossier dans lequel se trouve les fichiers path = QtWidgets.QFileDialog.getExistingDirectory( self, "Open a folder", os.sep.join((os.path.expanduser('~'), 'Desktop')), #Permet d'afficher le bureau à l'ouverture de la fenêtre options = QtWidgets.QFileDialog.ShowDirsOnly ) #Gestion de l'exception dans le cas où l'utilisateur choisit un mauvais dossier #Dans ce cas on envoie des projections générées virtuellement par tomopy #Si aucun dossier n'est sélectionné path = 0 et il ne se passe rien if path: try: MatrixGeneration(self, path, factor) except IndexError: return tomopy.project(tomopy.shepp3d(), tomopy.angles(180))
def main(): obj = dxchange.reader.read_tiff( fname= './NUS 3D/sample1/sample1 zscan 1xzoom 50um fiber 70um 1um step.tif', slc=None) # Generate an object ang = tomopy.angles(180) # Generate uniformly spaced tilt angles obj = obj.astype(np.float32) sim = tomopy.project(obj, ang) # Calculate projections rec = tomopy.recon(sim, ang, algorithm='art') # Reconstruct object print(rec.shape) # show 64th slice of the reconstructed object. # mlab.imshow(rec[64], colormap='gray') # mlab.show() mlab.contour3d(rec, contours=1, colormap='gist_gray', transparent=True) # transparent: 该对象可以透明表示,可以查看内部 mlab.show() return
ang = tomopy.angles(num_angles) # Generate uniformly spaced tilt angles. obj_recv = np.zeros(blk_size * num_col * num_col, dtype=np.float32) if (comm.rank == 0): # obj = np.random.rand(num_slice,num_col,num_col).astype(np.float32) obj = np.float32(tomopy.shepp3d( (num_slice, num_col, num_col))) # Generate an object. vol = np.zeros((num_slice, num_col, num_col), dtype=np.float32) else: obj = None chunks = None vol = np.empty(num_slice * num_col * num_col) comm.Scatter(obj, obj_recv, root=0) #proj_data = np.random.rand(ang.size,num_slice,num_col) # Calculate projections for the relevant chunk proj_data = tomopy.project(obj_recv.reshape(blk_size, num_col, num_col), ang) # Calculate projections for the relevant chunk theta, rows, cols = proj_data.shape proj_data = proj_data[:, :, cols / 2 - num_col / 2:cols / 2 + num_col / 2] t_start = MPI.Wtime() rec = np.float32(reconMBIR_tomocam(proj_data, ang, comm.rank)) t_diff = MPI.Wtime() - t_start print('Time taken by process %d : %f s' % (comm.rank, t_diff)) # gather reconstructed volumes comm.Gather(rec, vol, root=0) if (comm.rank == 0): vol = vol.reshape(num_slice, num_col, num_col) pg.image(vol) pg.QtGui.QApplication.exec_()
import tomopy import pylab obj = tomopy.shepp3d() # Generate an object. ang = tomopy.angles(180) # Generate uniformly spaced tilt angles. sim = tomopy.project(obj, ang) # Calculate projections. # rec = tomopy.recon_accelerated(sim, ang, algorithm='ospml_quad', hardware='Xeon_Phi', implementation='tomoperi') # Reconstruct object. rec = tomopy.recon_accelerated(sim, ang, algorithm="ospml_hybrid") # Show 64th slice of the reconstructed object. pylab.imshow(rec[64], cmap="gray") pylab.show()
def align(prj, ang, iters=10, pad=(0, 0), save=False, debug=True): """Aligns the projection image stack using the conventional re-projection algorithm. Parameters ---------- prj : ndarray 3D stack of projection images. The first dimension is projection axis, second and third dimensions are the x- and y-axes of the projection image, respectively. ang : ndarray Projection angles in radians as an array. iters : scalar, optional Number of iterations of the algorithm. pad : list-like, optional Padding for projection images in x and y-axes. save : bool, optional Saves projections and corresponding reconstruction for each algorithm iteration. debug : book, optional Provides debugging info such as iterations and error. Returns ------- ndarray 3D stack of projection images with jitter. ndarray Error array for each iteration. """ from xcor.utils import scale from skimage import transform as tf from skimage.feature import register_translation import tomopy import dxchange import numpy as np # Needs scaling for skimage float operations. prj, scl = scale(prj) # Pad images. npad = ((0, 0), (pad[1], pad[1]), (pad[0], pad[0])) prj = np.pad(prj, npad, mode='constant', constant_values=0) # Register each image frame-by-frame. for n in range(iters): # Reconstruct image. rec = tomopy.recon(prj, ang, algorithm='mlem') # Re-project data and obtain simulated data. sim = tomopy.project(rec, ang, pad=False) # Initialize error matrix per iteration. err = np.zeros((iters, prj.shape[0])) # For each projection for m in range(prj.shape[0]): # Register current projection in sub-pixel precision shift, error, diffphase = register_translation(prj[m], sim[m], 100) err[n, m] = np.sqrt(shift[0] * shift[0] + shift[1] * shift[1]) # Register current image with the simulated one tform = tf.SimilarityTransform(translation=(shift[1], shift[0])) prj[m] = tf.warp(prj[m], tform, order=5) if debug: print('iter=' + str(n) + ', err=' + str(np.linalg.norm(err))) if save: dxchange.write_tiff(prj, 'tmp/iters/prj/prj') dxchange.write_tiff(rec[int(rec.shape[0] / 2)], 'tmp/iters/rec/rec') # Re-normalize data prj *= scl return prj, np.linalg.norm(err)
import tomopy import pylab obj = tomopy.shepp3d() # Generate an object. ang = tomopy.angles(180) # Generate uniformly spaced tilt angles. sim = tomopy.project(obj, ang) # Calculate projections. #rec = tomopy.recon_accelerated(sim, ang, algorithm='ospml_quad', hardware='Xeon_Phi', implementation='tomoperi') # Reconstruct object. rec = tomopy.recon_accelerated(sim, ang, algorithm='ospml_hybrid') # Show 64th slice of the reconstructed object. pylab.imshow(rec[64], cmap='gray') pylab.show()
obj_path = 'foam_obj.tiff' if not os.path.exists(obj_path): print('Building...') np.random.seed(0) # random seed for repeatability p1 = Foam(size_range=[0.05, 0.002]) d1 = discrete_phantom(p1, SIZE) plt.imshow(d1, cmap='viridis') dxchange.write_tiff(d1, obj_path, dtype='float32', overwrite=True) print('Phantom built.\n') else: print('Reading existing...') d1 = dxchange.read_tiff(obj_path) d1 = d1[np.newaxis, :, :] theta = tomopy.angles(4096) print('Radon') sino = tomopy.project(d1.astype('float32'), theta, center=1024, ncore=10, nchunk=50) sino = sino / sino.max() sino = np.exp(-sino) dxchange.write_tiff(np.squeeze(sino), 'foam_sino') # p1 = Phantom(shape='circle') # p1.sprinkle(300, [0.1, 0.03], gap=10, mass_atten=1) # d1 = discrete_phantom(p1, SIZE) # plt.imshow(d1, cmap='viridis') # plt.show()
def project(obj, ang, energy): pb = tomopy.project(obj.beta, ang, pad=False) * obj.voxelsize pd = tomopy.project(obj.delta, ang, pad=False) * obj.voxelsize psi = np.exp(1j * wavenumber(energy) * (pd + 1j * pb)) return psi
#!/usr/bin/env python import tomopy import numpy import time print "Hey!" obj = numpy.ones((512, 512, 512), dtype='float32') ang = tomopy.angles(512) t = time.time() prj = tomopy.project(obj, ang) print time.time() - t t = time.time() rec = tomopy.recon(prj, ang, algorithm='gridrec', num_gridx=1024, num_gridy=1024) print time.time() - t tomopy.write_tiff_stack(rec, overwrite=True)
def trigger(self): super().trigger() self.image.put(tomopy.project(obj, angle.read()['angle']['value'])) return NullStatus()
def radon(obj, ang): pb = tomopy.project(obj.beta, ang, pad=False) * obj.voxelsize pd = tomopy.project(obj.delta, ang, pad=False) * obj.voxelsize return np.exp(1j * (2 * PI) / wavelength(obj.energy) * (pd + 1j * pb))
import tomopy from PIL import Image import numpy as np def load_image(infilename): pil_imgray = Image.open(infilename).convert('LA') img = np.array(list(pil_imgray.getdata(band=0)), float) img.shape = (pil_imgray.size[1], pil_imgray.size[0]) return img obj = tomopy.misc.phantom.baboon(size=256, dtype=u'float32') ang = tomopy.angles(25) prj = tomopy.project(obj, ang) rec = tomopy.recon(prj, ang, algorithm='gridrec', num_gridx=1024, num_gridy=1024)
def get_projections(self, theta=(0, 180, 180), beam=None, noise=0.01, blur_size=5, detector_dist=0.0): ''' Acquire projections on the phantom. Returns ------- np.array output shape is a stack of radiographs (nthetas, nrows, ncols) Parameters ---------- theta : tuple The tuple must be defined as (starting_theta, ending_theta, number_projections). The angle is intepreted as degrees. beam : np.array The flat-field (beam array) must be provided with shape (1, nrows, ncols) or (n_energies, nrows, ncols). noise : float The noise parameter is interpreted as a fraction (0,1). The noise transforms the pixel map I(y,x) in the projection space as I(y,x) --> I(y,x)*(1 + N(mu=0, sigma=noise)). ''' # make theta array in radians theta = np.linspace(*theta, endpoint=True) theta = np.radians(theta) # make beam array (if not passed) if beam is None: beam = np.ones(self.proj_shape, dtype=np.float32) beam = beam * (2**self.bits - 1) # if monochromatic beam if self.n_energies == 1: projs = project(self.vol, theta, pad=False, emission=False) projs = projs * beam # scintillator / detector blurring if blur_size > 0: projs = [proj for proj in projs] projs = Parallelize(projs, gaussian_filter, \ procs = 12, \ sigma = 0.3*(0.5*(blur_size - 1) - 1) + 0.8, \ order = 0) projs = np.asarray(projs) # in-line phase contrast based on detector-sample distance (cm) if detector_dist > 0.0: pad_h = int(projs.shape[1] * 0.4) projs = np.pad(projs, ((0, 0), (pad_h, pad_h), (0, 0)), mode='reflect') projs = add_phase_contrast(projs, \ pixel_size = self.res*1e-04, \ energy = float(self.energy_pts), \ dist = detector_dist) projs = projs[:, pad_h:-pad_h, :] # Poisson noise model (approximated as normal distribution) projs = np.random.normal(projs, noise * np.sqrt(projs)) # projs = np.random.poisson(projs) # This actually worked fine # projs = projs*beam*(1 + np.random.normal(0, noise, projs.shape)) # if polychromatic beam else: projs = Parallelize(theta.tolist(), \ _project_at_theta, \ vol = self.vol, \ n_energies = self.n_energies, \ beam = beam, \ noise = noise, procs = 12) projs = np.asarray(projs) # saturated pixels projs = np.clip(projs, 0, 2**self.bits - 1) return projs.astype(np.uint16)
#!/usr/bin/env python # -*- coding: utf-8 -*- """ TomoPy example script to reconstruct the Anka topo-tomo tomography data as original tiff. """ from __future__ import print_function import tomopy if __name__ == '__main__': obj = tomopy.baboon() theta = tomopy.angles(180) proj = tomopy.project(obj, theta) import pdb; pdb.set_trace() # 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')
import matplotlib.pyplot as plt from bluesky import RunEngine from bluesky.examples import Reader, Mover from bluesky.plans import scan from bluesky.callbacks import LiveTable, CallbackBase from bluesky.utils import install_qt_kicker import tomopy import numpy as np L = 64 obj = tomopy.lena(L) det = Reader('det', {'image': lambda: tomopy.project(obj, angle.read()['angle']['value'])}) angle = Mover('angle', {'angle': lambda x: x}, {'x': 0}) angle._fake_sleep = 0.01 RE = RunEngine({}) install_qt_kicker() t = LiveTable([angle]) class LiveRecon(CallbackBase): SMALL = 1e-6 def __init__(self, name, x, y, ax=None, **recon_kwargs): if ax is None: import matplotlib.pyplot as plt ax = plt.gca() ax.set_title('Reconstruction using Tomopy') ax.set_xlabel('x')
from XT_ForwardModel import forward_project, init_nufft_params, back_project from XT_Common import padmat from normalize import normalize_bo num_slice = 50 im_size = 512 #A n X n X n volume sino_center = im_size / 2 num_angles = 256 slice_idx = num_slice / 2 obj = tomopy.shepp3d((num_slice, im_size, im_size)) # Generate an object. #obj = tomopy.shepp3d(im_size) # Generate an object. ang = tomopy.angles(num_angles) # Generate uniformly spaced tilt angles. ### Comparing to tomopy sim = tomopy.project(obj, ang) sino = {} geom = {} sino['Ns'] = 768 #3624#im_size*2 #Sinogram size after padding sino['Ns_orig'] = im_size #size of original sinogram sino['center'] = sino_center + (sino['Ns'] / 2 - sino['Ns_orig'] / 2 ) #for padded sinogram sino['angles'] = ang params = init_nufft_params(sino, geom) ##Create a simulated object to test forward and back-projection routines x = afnp.array(padmat(obj[slice_idx], np.array([sino['Ns'], sino['Ns']]), 0), dtype=afnp.complex64)
def align_seq(prj, ang, fdir='.', iters=10, pad=(0, 0), blur=True, save=False, debug=True): """Aligns the projection image stack using the errorentional re-projection algorithm. Parameters ---------- prj : ndarray 3D stack of projection images. The first dimension is projection axis, second and third dimensions are the x- and y-axes of the projection image, respectively. ang : ndarray Projection angles in radians as an array. iters : scalar, optional Number of iterations of the algorithm. pad : list-like, optional Padding for projection images in x and y-axes. blur : bool, optional Blurs the edge of the image before registration. save : bool, optional Saves projections and corresponding reconstruction for each algorithm iteration. debug : book, optional Provides debugging info such as iterations and error. Returns ------- ndarray 3D stack of projection images with jitter. ndarray Error array for each iteration. """ from skimage import transform as tf from skimage.feature import register_translation import tomopy import dxchange import numpy as np # Needs scaling for skimage float operations. prj, scl = scale(prj) # Shift arrays sx = np.zeros((prj.shape[0])) sy = np.zeros((prj.shape[0])) conv = np.zeros((iters)) # Pad images. npad = ((0, 0), (pad[1], pad[1]), (pad[0], pad[0])) prj = np.pad(prj, npad, mode='constant', constant_values=0) #prj = np.pad(prj, npad, mode='edge') # Register each image frame-by-frame. for n in range(iters): # Reconstruct image. rec = tomopy.recon(prj, ang, algorithm='sirt') ##rec = tomopy.recon(prj, ang, algorithm='sirt', num_iter=2) #rec = tomopy.recon(prj, ang, algorithm='gridrec') # Re-project data and obtain simulated data. sim = tomopy.project(rec, ang, pad=False) # Blur edges. if blur: _prj = blur_edges(prj, 0.6, 0.9) _sim = blur_edges(sim, 0.6, 0.9) else: _prj = prj _sim = sim # Initialize error matrix per iteration. err = np.zeros((prj.shape[0])) # For each projection for m in range(prj.shape[0]): # Register current projection in sub-pixel precision shift, error, diffphase = register_translation(_prj[m], _sim[m], 2) err[m] = np.sqrt(shift[0] * shift[0] + shift[1] * shift[1]) sx[m] += shift[0] sy[m] += shift[1] # Register current image with the simulated one tform = tf.SimilarityTransform(translation=(shift[1], shift[0])) prj[m] = tf.warp(prj[m], tform, order=5) ##prj[m] = tf.warp(prj[m], tform, order=0, mode='edge') if debug: print('iter=' + str(n) + ', err=' + str(np.linalg.norm(err))) conv[n] = np.linalg.norm(err) if save: dxchange.write_tiff(prj, fdir + '/tmp/iters/prj/prj') dxchange.write_tiff(sim, fdir + '/tmp/iters/sim/sim') dxchange.write_tiff(rec, fdir + '/tmp/iters/rec/rec') # Re-normalize data prj *= scl return prj, sx, sy, conv
def tomopyfp(im, ang): fp = tomopy.project(np.expand_dims(im, 0), ang).flatten() fps = len(fp) return fp[fps // 2 - im.shape[0] // 2 : fps // 2 - im.shape[0] // 2 + im.shape[0]]
#!/usr/bin/env python # -*- coding: utf-8 -*- """ TomoPy example script to reconstruct the Anka topo-tomo tomography data as original tiff. """ from __future__ import print_function import tomopy if __name__ == '__main__': obj = tomopy.baboon() theta = tomopy.angles(180) proj = tomopy.project(obj, theta) import pdb pdb.set_trace() # 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',
def shift_correction(projs, thetas, center=None, init_shifts=None, scale=1, alg="gridrec", init_recon=None, **kwargs): # initial shift values if init_shifts is None: shifts = np.zeros((projs.shape[0], 2)) else: shifts = np.copy(init_shifts) # scaled projections used after recon/reproject if scale != 1: scaled_projs = zoom_array(projs, 1.0 / scale) else: scaled_projs = projs if center is None: center = projs.shape[2] / 2. center /= scale # perform initial shifts shifted_projs = apply_shifts(projs, shifts) # scale shifted if necessary if scale != 1: shifted_projs = zoom_array(shifted_projs, 1.0 / scale) np.clip(shifted_projs, 0, 1.0, shifted_projs) tomopy.minus_log(shifted_projs, out=shifted_projs) # find center of rotation logger.info("finding center...") center = tomopy.find_center(shifted_projs, thetas, tol=0.01, init=center, algorithm=alg, **kwargs) logger.info("Updated center to be %0.3f", center * scale) # recon logger.info("Shift reconstruct using %s" % alg) rec = init_recon rec = tomopy.recon(shifted_projs, thetas, center, sinogram_order=False, algorithm=alg, init_recon=rec, **kwargs) del shifted_projs np.clip(rec, 0.0, 1.0, rec) #TODO: needed? # simulate projections sim_projs = tomopy.project(rec, thetas, center, pad=False, emission=False) write_stack("test_rec", rec) write_stack("sim_projs", sim_projs) # calculate shift for each translation_sum = np.zeros((2, )) logger.info("Projecting and aligning slices") for t in range(sim_projs.shape[0]): translation = register_translation(sim_projs[t], scaled_projs[t], 100)[0] translation_sum += np.abs(shifts[t] - translation * scale) shifts[t] = translation * scale logger.info("translation sum is y:%0.2f, x:%0.2f" % (translation_sum[0], translation_sum[1])) del scaled_projs del sim_projs return shifts, rec, center * scale