Esempio n. 1
0
def main():
    normalized = i3.normalize(ct_series,
                              dfs,
                              obs,
                              workdir=os.path.join(workdir, 'normalization'))
    tilt_corrected = i3.correct_tilt(normalized,
                                     workdir=os.path.join(
                                         workdir, 'tilt-correction'))
    if_corrected = i3.correct_intensity_fluctuation(
        tilt_corrected,
        workdir=os.path.join(workdir, 'intensity-fluctuation-correction'))
    angles, sinograms = i3.build_sinograms(if_corrected,
                                           workdir=os.path.join(
                                               workdir, 'sinogram'))
    # take the middle part to calculate the center of rotation
    sino = [s.data for s in sinograms[900:1100]]
    sino = np.array(sino)
    proj = np.swapaxes(sino, 0, 1)
    rot_center = tomopy.find_center(proj,
                                    theta,
                                    emission=False,
                                    init=1024,
                                    tol=0.5)
    rot_center = rot_center[0]
    # reconstruct
    recon = i3.reconstruct(angles,
                           sinograms,
                           workdir=outdir,
                           center=rot_center)
    return
Esempio n. 2
0
 def evaluate(self):
     self.center.value = tomopy.find_center(
         self.tomo.value,
         self.theta.value,
         ind=self.ind.value,
         init=self.init.value,
         tol=self.tol.value,
         mask=self.mask.value,
         ratio=self.ratio.value,
         sinogram_order=self.sinogram_order.value)
def main():
    normalized = i3.normalize(ct_series, dfs, obs, workdir=os.path.join(workdir, 'normalization'))
    tilt_corrected = i3.correct_tilt(normalized, workdir=os.path.join(workdir, 'tilt-correction'))
    if_corrected = i3.correct_intensity_fluctuation(tilt_corrected, workdir=os.path.join(workdir, 'intensity-fluctuation-correction'))
    angles, sinograms = i3.build_sinograms(if_corrected, workdir=os.path.join(workdir, 'sinogram'))
    # take the middle part to calculate the center of rotation
    sino = [s.data for s in sinograms[900:1100]]
    sino= np.array(sino)
    proj = np.swapaxes(sino, 0, 1)
    rot_center = tomopy.find_center(proj, theta, emission=False, init=1024, tol=0.5)
    rot_center = rot_center[0]
    # reconstruct
    recon = i3.reconstruct(angles, sinograms, workdir=outdir, center=rot_center)
    return
Esempio n. 4
0
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
Esempio n. 5
0
def tomo_reconstruction(sino,
                        refine_center=False,
                        center_range=None,
                        center=None,
                        method=None,
                        algorithm_A=None,
                        algorithm_B=None,
                        omega=None,
                        sinogram_order=False,
                        **args):
    '''
    INPUT ->  sino : slice, 2th, x OR 2th, slice, x (with flag sinogram_order=True)
    OUTPUT -> tomo : slice, x, y
    '''

    check = check_parameters(sino, method, center, omega, algorithm_A,
                             algorithm_B, sinogram_order)
    sino, method, center, omega, algorithm_A, algorithm_B, sinogram_order = check

    if method is None:
        print('No tomographic reconstruction packages available')
        return center, np.zeros((1, sino.shape[-1], sino.shape[-1]))

    if method.lower().startswith('scikit') and HAS_scikit:

        npts = sino.shape[2]
        cntr = int(
            npts -
            center)  # flip axis for compatibility with tomopy convention
        if not sinogram_order: sino = np.einsum('jik->ijk', sino)

        args.update({
            'theta': omega,
            'filter': algorithm_A,
            'interpolation': algorithm_B,
            'circle': True
        })

        if refine_center:
            print(' Refining center; start value: %i' % center)
            if center_range is None: center_range = 12
            rng = int(
                center_range) if center_range > 0 and center_range < 21 else 12

            center_list, negentropy = [], []

            for cen in np.arange(cntr - rng, cntr + rng, 1, dtype=int):
                xslice = slice(npts -
                               2 * cen, -1) if cen <= npts / 2. else slice(
                                   0, npts - 2 * cen)
                if sinogram_order:
                    recon = iradon(sino[0, :, xslice].T, **args)
                else:
                    recon = iradon(sino[0, xslice], **args)
                recon = recon - recon.min() + 0.005 * (recon.max() -
                                                       recon.min())
                negentropy += [(recon * np.log(recon)).sum()]
                center_list += [cen]
            cntr = center_list[np.array(negentropy).argmin()]
            center = float(
                npts -
                cntr)  # flip axis for compatibility with tomopy convention
            print('   Best center: %i' % center)

        tomo = []
        xslice = slice(npts - 2 * cntr, -1) if cntr <= npts / 2. else slice(
            0, npts - 2 * cntr)
        for sino0 in sino:
            tomo += [iradon(sino0[:, xslice].T, **args)]
        tomo = np.array(tomo)

    elif method.lower().startswith('tomopy') and HAS_tomopy:

        if refine_center:
            center = tomopy.find_center(sino,
                                        np.radians(omega),
                                        init=center,
                                        ind=0,
                                        tol=0.5,
                                        sinogram_order=sinogram_order)

        args.update({
            'center': center,
            'algorithm': algorithm_A,
            'sinogram_order': sinogram_order
        })

        tomo = tomopy.recon(sino, np.radians(omega), **args)

    return center, tomo


# def registerLarchPlugin():
#     return ('_tomo', {'create_tomogrp': create_tomogrp})
#
#
# def registerLarchGroups():
#     return (tomogrp)
Esempio n. 6
0
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!")
Esempio n. 7
0
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)
Esempio n. 8
0
if __name__ == '__main__':

    # Set path to the micro-CT data to reconstruct.
    fname = 'data_dir/sample_name_prefix'

    # Select the sinogram range to reconstruct.
    start = 0
    end = 16

    # Read the APS 1-ID raw data.
    proj, flat, dark = tomopy.read_aps_1id(fname, 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')
Esempio n. 9
0
def transform_scalars(dataset, rot_center=0, tune_rot_center=True):
    """Reconstruct sinograms using the tomopy gridrec algorithm

    Typically, a data exchange file would be loaded for this
    reconstruction. This operation will attempt to perform
    flat-field correction of the raw data using the dark and
    white background data found in the data exchange file.

    This operator also requires either the tomviz/tomopy-pipeline
    docker image, or a python environment with tomopy installed.
    """

    from tomviz import utils
    import numpy as np
    import tomopy

    # Get the current volume as a numpy array.
    array = utils.get_array(dataset)

    dark = dataset.dark
    white = dataset.white
    angles = utils.get_tilt_angles(dataset)
    tilt_axis = dataset.tilt_axis

    # TomoPy wants the tilt axis to be zero, so ensure that is true
    if tilt_axis == 2:
        order = [2, 1, 0]
        array = np.transpose(array, order)
        if dark is not None and white is not None:
            dark = np.transpose(dark, order)
            white = np.transpose(white, order)

    if angles is not None:
        # tomopy wants radians
        theta = np.radians(angles)
    else:
        # Assume it is equally spaced between 0 and 180 degrees
        theta = tomopy.angles(array.shape[0])

    # Perform flat-field correction of raw data
    if white is not None and dark is not None:
        array = tomopy.normalize(array, white, dark, cutoff=1.4)

    if rot_center == 0:
        # Try to find it automatically
        init = array.shape[2] / 2.0
        rot_center = tomopy.find_center(array,
                                        theta,
                                        init=init,
                                        ind=0,
                                        tol=0.5)
    elif tune_rot_center:
        # Tune the center
        rot_center = tomopy.find_center(array,
                                        theta,
                                        init=rot_center,
                                        ind=0,
                                        tol=0.5)

    # Calculate -log(array)
    array = tomopy.minus_log(array)

    # Remove nan, neg, and inf values
    array = tomopy.remove_nan(array, val=0.0)
    array = tomopy.remove_neg(array, val=0.00)
    array[np.where(array == np.inf)] = 0.00

    # Perform the reconstruction
    array = tomopy.recon(array, theta, center=rot_center, algorithm='gridrec')

    # Mask each reconstructed slice with a circle.
    array = tomopy.circ_mask(array, axis=0, ratio=0.95)

    # Set the transformed array
    child = utils.make_child_dataset(dataset)
    utils.mark_as_volume(child)
    utils.set_array(child, array)

    return_values = {}
    return_values['reconstruction'] = child
    return return_values
Esempio n. 10
0
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
Esempio n. 11
0
# -*- coding: utf-8 -*-
"""
TomoPy example script to reconstruct the tomography data as
with gridrec.
"""
from __future__ import print_function
import tomopy
import dxchange

if __name__ == '__main__':

    # 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 = 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)

    tomopy.minus_log(proj)
Esempio n. 12
0
def cleaning(
    filename,
    bffilename=None,
    inputPath='/',  #input path, location of the data set to reconstruct
    outputPath=None,  # define an output path (default is inputPath), a sub-folder will be created based on file name
    outputFilename=None,  #file name for output tif files (a number and .tiff will be added). default is based on input filename
    fulloutputPath=None,  # definte the full output path, no automatic sub-folder will be created
    doFWringremoval=True,  # Fourier-wavelet ring removal
    ringSigma=3,  # damping parameter in Fourier space (Fourier-wavelet ring removal)
    ringLevel=8,  # number of wavelet transform levels (Fourier-wavelet ring removal)
    ringWavelet='db5',  # type of wavelet filter (Fourier-wavelet ring removal)
    ringNBlock=0,  # used in Titarenko ring removal (doTIringremoval)
    ringAlpha=1.5,  # used in Titarenko ring removal (doTIringremoval)
    ringSize=5,  # used in smoothing filter ring removal (doSFringremoval)
    butterworth_cutoff=0.25,  #0.1 would be very smooth, 0.4 would be very grainy (reconstruction)
    butterworth_order=2,  # for reconstruction
    npad=None,  # amount to pad data before reconstruction
    projused=None,  # should be slicing in projection dimension (start,end,step) Be sure to add one to the end as stop in python means the last value is omitted 
    sinoused=None,  # should be sliceing in sinogram dimension (start,end,step). If first value is negative, it takes the number of slices from the second value in the middle of the stack.
    angle_offset=0,  # this is the angle offset from our default (270) so that tomopy yields output in the same orientation as previous software (Octopus)
    anglelist=None,  # if not set, will assume evenly spaced angles which will be calculated by the angular range and number of angles found in the file. if set to -1, will read individual angles from each image. alternatively, a list of angles can be passed.
    cor=None,  # center of rotation (float). If not used then cor will be detected automatically
    corFunction='pc',  # center of rotation function to use - can be 'pc', 'vo', or 'nm'
    voInd=None,  # index of slice to use for cor search (vo)
    voSMin=-40,  # min radius for searching in sinogram (vo)
    voSMax=40,  # max radius for searching in sinogram (vo)
    voSRad=10,  # search radius (vo)
    voStep=0.5,  # search step (vo)
    voRatio=2.0,  # ratio of field-of-view and object size (vo)
    voDrop=20,  # drop lines around vertical center of mask (vo)
    nmInd=None,  # index of slice to use for cor search (nm)
    nmInit=None,  # initial guess for center (nm)
    nmTol=0.5,  # desired sub-pixel accuracy (nm)
    nmMask=True,  # if True, limits analysis to circular region (nm)
    nmRatio=1.0,  # ratio of radius of circular mask to edge of reconstructed image (nm)
    nmSinoOrder=False,  # if True, analyzes in sinogram space. If False, analyzes in radiograph space
    useNormalize_nf=False,  # normalize based on background intensity (nf)
    bfexposureratio=1  #ratio of exposure time of bf to exposure time of sample
):

    start_time = time.time()
    print("Start {} at:".format(filename) +
          time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))

    outputFilename = os.path.splitext(
        filename)[0] if outputFilename is None else outputFilename
    outputPath = inputPath + 'rec' + os.path.splitext(
        filename
    )[0] + '/' if outputPath is None else outputPath + 'rec' + os.path.splitext(
        filename)[0] + '/'
    fulloutputPath = outputPath if fulloutputPath is None else fulloutputPath
    tempfilenames = [fulloutputPath + 'tmp0.h5', fulloutputPath + 'tmp1.h5']
    filenametowrite = fulloutputPath + outputFilename
    print(filenametowrite)

    print("cleaning up previous temp files", end="")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass

    print(", reading metadata")

    datafile = h5py.File(inputPath + filename, 'r')
    gdata = dict(dxchange.reader._find_dataset_group(datafile).attrs)
    numslices = int(gdata['nslices'])
    numangles = int(gdata['nangles'])
    print('There are ' + str(numslices) + ' sinograms and ' + str(numangles) +
          ' projections')
    angularrange = float(gdata['arange'])
    numrays = int(gdata['nrays'])
    npad = int(np.ceil(numrays * np.sqrt(2)) -
               numrays) // 2 if npad is None else npad
    if projused is not None and (
            projused[1] > numangles - 1 or projused[0] < 0
    ):  #allows program to deal with out of range projection values
        if projused[1] > numangles:
            print(
                "End Projection value greater than number of angles. Value has been lowered to the number of angles "
                + str(numangles))
            projused = (projused[0], numangles, projused[2])
        if projused[0] < 0:
            print("Start Projection value less than zero. Value raised to 0")
            projused = (0, projused[1], projused[2])
    if projused is None:
        projused = (0, numangles, 1)
    else:
        #if projused is different than default, need to chnage numangles and angularrange
        #dula attempting to do this with these two lines, we'll see if it works! 11/16/17
        testrange = range(projused[0], projused[1], projused[2])
        #+1 because we need to compensate for the range functions last value always being one less than the second arg
        angularrange = (angularrange /
                        (numangles - 1)) * (projused[1] - projused[0])
        # want angular range to stay constant if we keep the end values consistent
        numangles = len(testrange)


# ndark = int(gdata['num_dark_fields'])
# ind_dark = list(range(0, ndark))
# group_dark = [numangles - 1]
    inter_bright = int(gdata['i0cycle'])
    if inter_bright > 0:
        group_flat = list(range(0, numangles, inter_bright))
        if group_flat[-1] != numangles - 1:
            group_flat.append(numangles - 1)
    elif inter_bright == 0:
        group_flat = [0, numangles - 1]
    else:
        group_flat = None

    # figure out the angle list (a list of angles, one per projection image)
    dtemp = datafile[list(datafile.keys())[0]]
    fltemp = list(dtemp.keys())
    firstangle = float(dtemp[fltemp[0]].attrs.get('rot_angle', 0))
    anglegap = angularrange / (numangles - 1)
    firstangle += anglegap * projused[0]  #accounting for projused argument
    if anglelist is None:
        #the offset angle should offset from the angle of the first image, which is usually 0, but in the case of timbir data may not be.
        #we add the 270 to be inte same orientation as previous software used at bl832
        angle_offset = 270 + angle_offset - firstangle
        anglelist = tomopy.angles(numangles, angle_offset,
                                  angle_offset - angularrange)
    elif anglelist == -1:
        anglelist = np.zeros(shape=numangles)
        for icount in range(0, numangles):
            anglelist[icount] = np.pi / 180 * (270 + angle_offset - float(
                dtemp[fltemp[icount]].attrs['rot_angle']))

    #figure out how user can pass to do central x number of slices, or set of slices dispersed throughout (without knowing a priori the value of numslices)
    if sinoused is None:
        sinoused = (0, numslices, 1)
    elif sinoused[0] < 0:
        sinoused = (
            int(np.floor(numslices / 2.0) - np.ceil(sinoused[1] / 2.0)),
            int(np.floor(numslices / 2.0) + np.floor(sinoused[1] / 2.0)), 1)

    if cor is None:
        print("Detecting center of rotation", end="")
        if angularrange > 300:
            lastcor = int(np.floor(numangles / 2) - 1)
        else:
            lastcor = numangles - 1
        # I don't want to see the warnings about the reader using a deprecated variable in dxchange
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            tomo, flat, dark, floc = dxchange.read_als_832h5(
                inputPath + filename, ind_tomo=(0, lastcor))
            if bffilename is not None:
                tomobf, flatbf, darkbf, flocbf = dxchange.read_als_832h5(
                    inputPath + bffilename)
                flat = tomobf
        tomo = tomo.astype(np.float32)
        if useNormalize_nf:
            tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo)
            if bfexposureratio != 1:
                tomo = tomo * bfexposureratio
        else:
            tomopy.normalize(tomo, flat, dark, out=tomo)
            if bfexposureratio != 1:
                tomo = tomo * bfexposureratio

        if corFunction == 'vo':
            # same reason for catching warnings as above
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                cor = tomopy.find_center_vo(tomo,
                                            ind=voInd,
                                            smin=voSMin,
                                            smax=voSMax,
                                            srad=voSRad,
                                            step=voStep,
                                            ratio=voRatio,
                                            drop=voDrop)
        elif corFunction == 'nm':
            cor = tomopy.find_center(
                tomo,
                tomopy.angles(numangles, angle_offset,
                              angle_offset - angularrange),
                ind=nmInd,
                init=nmInit,
                tol=nmTol,
                mask=nmMask,
                ratio=nmRatio,
                sinogram_order=nmSinoOrder)
        elif corFunction == 'pc':
            cor = tomopy.find_center_pc(tomo[0], tomo[1], tol=0.25)
        else:
            raise ValueError("\'corFunction\' must be one of: [ pc, vo, nm ].")
        print(", {}".format(cor))
    else:
        print("using user input center of {}".format(cor))

    tomo, flat, dark, floc = dxchange.read_als_832h5(
        inputPath + filename,
        ind_tomo=range(projused[0], projused[1], projused[2]),
        sino=(sinoused[0], sinoused[1], sinoused[2]))

    tomo = tomo.astype(np.float32, copy=False)
    tomopy.normalize(tomo, flat, dark, out=tomo)
    mx = np.float32(0.01)
    ne.evaluate('where(tomo>mx, tomo, mx)', out=tomo)
    tomopy.minus_log(tomo, out=tomo)
    tomo = tomopy.remove_stripe_fw(tomo,
                                   sigma=ringSigma,
                                   level=ringLevel,
                                   pad=True,
                                   wname=ringWavelet)
    tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')

    tomo = np.swapaxes(tomo, 0, 1)
    theta = anglelist

    print('It took {:.3f} s to process {}'.format(time.time() - start_time,
                                                  inputPath + filename))

    return tomo, theta, cor
def recon(
    filename,
    inputPath = './',
    outputPath = None,
    outputFilename = None,
    doOutliers1D = False, # outlier removal in 1d (along sinogram columns)
    outlier_diff1D = 750, # difference between good data and outlier data (outlier removal)
    outlier_size1D = 3, # radius around each pixel to look for outliers (outlier removal)
    doOutliers2D = False, # outlier removal, standard 2d on each projection
    outlier_diff2D = 750, # difference between good data and outlier data (outlier removal)
    outlier_size2D = 3, # radius around each pixel to look for outliers (outlier removal)
    doFWringremoval = True,  # Fourier-wavelet ring removal
    doTIringremoval = False, # Titarenko ring removal
    doSFringremoval = False, # Smoothing filter ring removal
    ringSigma = 3, # damping parameter in Fourier space (Fourier-wavelet ring removal)
    ringLevel = 8, # number of wavelet transform levels (Fourier-wavelet ring removal)
    ringWavelet = 'db5', # type of wavelet filter (Fourier-wavelet ring removal)
    ringNBlock = 0, # used in Titarenko ring removal (doTIringremoval)
    ringAlpha = 1.5, # used in Titarenko ring removal (doTIringremoval)
    ringSize = 5, # used in smoothing filter ring removal (doSFringremoval)
    doPhaseRetrieval = False, # phase retrieval
    alphaReg = 0.0002, # smaller = smoother (used for phase retrieval)
    propagation_dist = 75, # sample-to-scintillator distance (phase retrieval)
    kev = 24, # energy level (phase retrieval)
    butterworth_cutoff = 0.25, #0.1 would be very smooth, 0.4 would be very grainy (reconstruction)
    butterworth_order = 2, # for reconstruction
    doTranslationCorrection = False, # correct for linear drift during scan
    xshift = 0, # undesired dx transation correction (from 0 degree to 180 degree proj)
    yshift = 0, # undesired dy transation correction (from 0 degree to 180 degree proj)
    doPolarRing = False, # ring removal
    Rarc=30, # min angle needed to be considered ring artifact (ring removal)
    Rmaxwidth=100, # max width of rings to be filtered (ring removal)
    Rtmax=3000.0, # max portion of image to filter (ring removal)
    Rthr=3000.0, # max value of offset due to ring artifact (ring removal)
    Rtmin=-3000.0, # min value of image to filter (ring removal)
    cor=None, # center of rotation (float). If not used then cor will be detected automatically
    corFunction = 'pc', # center of rotation function to use - can be 'pc', 'vo', or 'nm'
    voInd = None, # index of slice to use for cor search (vo)
    voSMin = -40, # min radius for searching in sinogram (vo)
    voSMax = 40, # max radius for searching in sinogram (vo)
    voSRad = 10, # search radius (vo)
    voStep = 0.5, # search step (vo)
    voRatio = 2.0, # ratio of field-of-view and object size (vo)
    voDrop = 20, # drop lines around vertical center of mask (vo)
    nmInd = None, # index of slice to use for cor search (nm)
    nmInit = None, # initial guess for center (nm)
    nmTol = 0.5, # desired sub-pixel accuracy (nm)
    nmMask = True, # if True, limits analysis to circular region (nm)
    nmRatio = 1.0, # ratio of radius of circular mask to edge of reconstructed image (nm)
    nmSinoOrder = False, # if True, analyzes in sinogram space. If False, analyzes in radiograph space
    use360to180 = False, # use 360 to 180 conversion
    doBilateralFilter = False, # if True, uses bilateral filter on image just before write step # NOTE: image will be converted to 8bit if it is not already
    bilateral_srad = 3, # spatial radius for bilateral filter (image will be converted to 8bit if not already)
    bilateral_rrad = 30, # range radius for bilateral filter (image will be converted to 8bit if not already)
    castTo8bit = False, # convert data to 8bit before writing
    cast8bit_min=-10, # min value if converting to 8bit
    cast8bit_max=30, # max value if converting to 8bit
    useNormalize_nf = False, # normalize based on background intensity (nf)
    chunk_proj = 100, # chunk size in projection direction
    chunk_sino = 100, # chunk size in sinogram direction
    npad = None, # amount to pad data before reconstruction
    projused = None, #should be slicing in projection dimension (start,end,step)
    sinoused = None, #should be sliceing in sinogram dimension (start,end,step). If first value is negative, it takes the number of slices from the second value in the middle of the stack.
    correcttilt = 0, #tilt dataset
    tiltcenter_slice = None, # tilt center (x direction)
    tiltcenter_det = None, # tilt center (y direction)
    angle_offset = 0, #this is the angle offset from our default (270) so that tomopy yields output in the same orientation as previous software (Octopus)
    anglelist = None, #if not set, will assume evenly spaced angles which will be calculated by the angular range and number of angles found in the file. if set to -1, will read individual angles from each image. alternatively, a list of angles can be passed.
    doBeamHardening = False, #turn on beam hardening correction, based on "Correction for beam hardening in computed tomography", Gabor Herman, 1979 Phys. Med. Biol. 24 81
    BeamHardeningCoefficients = None, #6 values, tomo = a0 + a1*tomo + a2*tomo^2 + a3*tomo^3 + a4*tomo^4 + a5*tomo^5
    projIgnoreList = None, #projections to be ignored in the reconstruction (for simplicity in the code, they will not be removed and will be processed as all other projections but will be set to zero absorption right before reconstruction.
    *args, **kwargs):
    
    start_time = time.time()
    print("Start {} at:".format(filename)+time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))
    
    outputPath = inputPath if outputPath is None else outputPath

    outputFilename = filename if outputFilename is None else outputFilename
    outputFilename = outputFilename.replace('.h5','')
    tempfilenames = [outputPath+'tmp0.h5',outputPath+'tmp1.h5']
    filenametowrite = outputPath+'/rec'+filename.strip(".h5")+'/'+outputFilename
    #filenametowrite = outputPath+'/rec'+filename+'/'+outputFilename
    
    print("cleaning up previous temp files", end="")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass
    
    print(", reading metadata")
    
    datafile = h5py.File(inputPath+filename, 'r')
    gdata = dict(dxchange.reader._find_dataset_group(datafile).attrs) 
    pxsize = float(gdata['pxsize'])/10 # /10 to convert units from mm to cm
    numslices = int(gdata['nslices'])
    numangles = int(gdata['nangles'])
    angularrange = float(gdata['arange'])
    numrays = int(gdata['nrays'])
    npad = int(np.ceil(numrays * np.sqrt(2)) - numrays)//2 if npad is None else npad
    projused = (0,numangles-1,1) if projused is None else projused

#    ndark = int(gdata['num_dark_fields'])
#    ind_dark = list(range(0, ndark))
#    group_dark = [numangles - 1]
    inter_bright = int(gdata['i0cycle'])
    nflat = int(gdata['num_bright_field'])
    ind_flat = list(range(0, nflat))
    if inter_bright > 0:
        group_flat = list(range(0, numangles, inter_bright))
        if group_flat[-1] != numangles - 1:
            group_flat.append(numangles - 1)
    elif inter_bright == 0:
        group_flat = [0, numangles - 1]
    else:
        group_flat = None
    ind_tomo = list(range(0, numangles))
    floc_independent = dxchange.reader._map_loc(ind_tomo, group_flat)        

    #figure out the angle list (a list of angles, one per projection image)
    dtemp = datafile[list(datafile.keys())[0]]
    fltemp = list(dtemp.keys())
    firstangle = float(dtemp[fltemp[0]].attrs.get('rot_angle',0))
    if anglelist is None:
        #the offset angle should offset from the angle of the first image, which is usually 0, but in the case of timbir data may not be.
        #we add the 270 to be inte same orientation as previous software used at bl832
        angle_offset = 270 + angle_offset - firstangle
        anglelist = tomopy.angles(numangles, angle_offset, angle_offset-angularrange)
    elif anglelist==-1:
        anglelist = np.zeros(shape=numangles)
        for icount in range(0,numangles):
            anglelist[icount] = np.pi/180*(270 + angle_offset - float(dtemp[fltemp[icount]].attrs['rot_angle']))
            
    #if projused is different than default, need to chnage numangles and angularrange
    
    #can't do useNormalize_nf and doOutliers2D at the same time, or doOutliers2D and doOutliers1D at the same time, b/c of the way we chunk, for now just disable that
    if useNormalize_nf==True and doOutliers2D==True:
        useNormalize_nf = False
        print("we cannot currently do useNormalize_nf and doOutliers2D at the same time, turning off useNormalize_nf")
    if doOutliers2D==True and doOutliers1D==True:
        doOutliers1D = False
        print("we cannot currently do doOutliers1D and doOutliers2D at the same time, turning off doOutliers1D")
    
    #figure out how user can pass to do central x number of slices, or set of slices dispersed throughout (without knowing a priori the value of numslices)
    if sinoused is None:
        sinoused = (0,numslices,1)
    elif sinoused[0]<0:
        sinoused=(int(np.floor(numslices/2.0)-np.ceil(sinoused[1]/2.0)),int(np.floor(numslices/2.0)+np.floor(sinoused[1]/2.0)),1)
    
    num_proj_per_chunk = np.minimum(chunk_proj,projused[1]-projused[0])
    numprojchunks = (projused[1]-projused[0]-1)//num_proj_per_chunk+1
    num_sino_per_chunk = np.minimum(chunk_sino,sinoused[1]-sinoused[0])
    numsinochunks = (sinoused[1]-sinoused[0]-1)//num_sino_per_chunk+1
    numprojused = (projused[1]-projused[0])//projused[2]
    numsinoused = (sinoused[1]-sinoused[0])//sinoused[2]
    
    BeamHardeningCoefficients = (0, 1, 0, 0, 0, .1) if BeamHardeningCoefficients is None else BeamHardeningCoefficients

    if cor is None:
        print("Detecting center of rotation", end="") 
        if angularrange>300:
            lastcor = int(np.floor(numangles/2)-1)
        else:
            lastcor = numangles-1
        #I don't want to see the warnings about the reader using a deprecated variable in dxchange
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            tomo, flat, dark, floc = dxchange.read_als_832h5(inputPath+filename,ind_tomo=(0,lastcor))
        tomo = tomo.astype(np.float32)
        if useNormalize_nf:
            tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo)
        else:
            tomopy.normalize(tomo, flat, dark, out=tomo)

        if corFunction == 'vo':
            # same reason for catching warnings as above
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                cor = tomopy.find_center_vo(tomo, ind=voInd, smin=voSMin, smax=voSMax, srad=voSRad, step=voStep,
                                        ratio=voRatio, drop=voDrop)
        elif corFunction == 'nm':
            cor = tomopy.find_center(tomo, tomopy.angles(numangles, angle_offset, angle_offset-angularrange),
                                     ind=nmInd, init=nmInit, tol=nmTol, mask=nmMask, ratio=nmRatio,
                                     sinogram_order=nmSinoOrder)
        elif corFunction == 'pc':
            cor = tomopy.find_center_pc(tomo[0], tomo[1], tol=0.25)
        else:
            raise ValueError("\'corFunction\' must be one of: [ pc, vo, nm ].")
        print(", {}".format(cor))
    else:
        print("using user input center of {}".format(cor))
        
    
    function_list = []

    if doOutliers1D:
        function_list.append('remove_outlier1d')
    if doOutliers2D:
        function_list.append('remove_outlier2d')
    if useNormalize_nf:
        function_list.append('normalize_nf')
    else:
        function_list.append('normalize')
    function_list.append('minus_log')
    if doBeamHardening:
        function_list.append('beam_hardening')
    if doFWringremoval:
        function_list.append('remove_stripe_fw')
    if doTIringremoval:
        function_list.append('remove_stripe_ti')
    if doSFringremoval:
        function_list.append('remove_stripe_sf')
    if correcttilt:
        function_list.append('correcttilt')
    if use360to180:
        function_list.append('do_360_to_180')
    if doPhaseRetrieval:
        function_list.append('phase_retrieval')
    function_list.append('recon_mask')
    if doPolarRing:
        function_list.append('polar_ring')
    if castTo8bit:
        function_list.append('castTo8bit')
    if doBilateralFilter:
        function_list.append('bilateral_filter')
    function_list.append('write_output')
        
    
    # Figure out first direction to slice
    for func in function_list:
        if slice_dir[func] != 'both':
            axis = slice_dir[func]
            break
    
    done = False
    curfunc = 0
    curtemp = 0
    while True: # Loop over reading data in certain chunking direction
        if axis=='proj':
            niter = numprojchunks
        else:
            niter = numsinochunks
        for y in range(niter): # Loop over chunks
            print("{} chunk {} of {}".format(axis, y+1, niter))
            if curfunc==0:
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore")
                    if axis=='proj':
                        tomo, flat, dark, floc = dxchange.read_als_832h5(inputPath+filename,ind_tomo=range(y*num_proj_per_chunk+projused[0],np.minimum((y + 1)*num_proj_per_chunk+projused[0],numangles)),sino=(sinoused[0],sinoused[1], sinoused[2]) )
                    else:
                        tomo, flat, dark, floc = dxchange.read_als_832h5(inputPath+filename,ind_tomo=range(projused[0],projused[1],projused[2]),sino=(y*num_sino_per_chunk+sinoused[0],np.minimum((y + 1)*num_sino_per_chunk+sinoused[0],numslices),1) )
            else:
                if axis=='proj':
                    start, end = y * num_proj_per_chunk, np.minimum((y + 1) * num_proj_per_chunk,numprojused)
                    tomo = dxchange.reader.read_hdf5(tempfilenames[curtemp],'/tmp/tmp',slc=((start,end,1),(0,numslices,1),(0,numrays,1))) #read in intermediate file
                else:
                    start, end = y * num_sino_per_chunk, np.minimum((y + 1) * num_sino_per_chunk,numsinoused)
                    tomo = dxchange.reader.read_hdf5(tempfilenames[curtemp],'/tmp/tmp',slc=((0,numangles,1),(start,end,1),(0,numrays,1)))
            dofunc = curfunc
            keepvalues = None
            while True: # Loop over operations to do in current chunking direction
                func_name = function_list[dofunc]
                newaxis = slice_dir[func_name]
                if newaxis != 'both' and newaxis != axis:
                    # We have to switch axis, so flush to disk
                    if y==0:
                        try:
                            os.remove(tempfilenames[1-curtemp])
                        except OSError:
                            pass
                    appendaxis = 1 if axis=='sino' else 0
                    dxchange.writer.write_hdf5(tomo,fname=tempfilenames[1-curtemp],gname='tmp',dname='tmp',overwrite=False,appendaxis=appendaxis) #writing intermediate file...
                    break
                print(func_name, end=" ")
                curtime = time.time()
                if func_name == 'remove_outlier1d':
                    tomo = tomo.astype(np.float32,copy=False)
                    remove_outlier1d(tomo, outlier_diff1D, size=outlier_size1D, out=tomo)
                if func_name == 'remove_outlier2d':
                    tomo = tomo.astype(np.float32,copy=False)
                    tomopy.remove_outlier(tomo, outlier_diff2D, size=outlier_size2D, axis=0, out=tomo)
                elif func_name == 'normalize_nf':
                    tomo = tomo.astype(np.float32,copy=False)
                    tomopy.normalize_nf(tomo, flat, dark, floc_independent, out=tomo) #use floc_independent b/c when you read file in proj chunks, you don't get the correct floc returned right now to use here.
                elif func_name == 'normalize':
                    tomo = tomo.astype(np.float32,copy=False)
                    tomopy.normalize(tomo, flat, dark, out=tomo)
                elif func_name == 'minus_log':
                    mx = np.float32(0.00000000000000000001)
                    ne.evaluate('where(tomo>mx, tomo, mx)', out=tomo)
                    tomopy.minus_log(tomo, out=tomo)
                elif func_name == 'beam_hardening':
                    loc_dict = {'a{}'.format(i):np.float32(val) for i,val in enumerate(BeamHardeningCoefficients)}
                    tomo = ne.evaluate('a0 + a1*tomo + a2*tomo**2 + a3*tomo**3 + a4*tomo**4 + a5*tomo**5', local_dict=loc_dict, out=tomo)
                elif func_name == 'remove_stripe_fw':
                    tomo = tomopy.remove_stripe_fw(tomo, sigma=ringSigma, level=ringLevel, pad=True, wname=ringWavelet)
                elif func_name == 'remove_stripe_ti':
                    tomo = tomopy.remove_stripe_ti(tomo, nblock=ringNBlock, alpha=ringAlpha)
                elif func_name == 'remove_stripe_sf':
                    tomo = tomopy.remove_stripe_sf(tomo, size=ringSize)
                elif func_name == 'correcttilt':
                    if tiltcenter_slice is None:
                        tiltcenter_slice = numslices/2.
                    if tiltcenter_det is None:
                        tiltcenter_det = tomo.shape[2]/2
                    new_center = tiltcenter_slice - 0.5 - sinoused[0]
                    center_det = tiltcenter_det - 0.5
                    
                    #add padding of 10 pixels, to be unpadded right after tilt correction. This makes the tilted image not have zeros at certain edges, which matters in cases where sample is bigger than the field of view. For the small amounts we are generally tilting the images, 10 pixels is sufficient.
#                    tomo = tomopy.pad(tomo, 2, npad=10, mode='edge')
#                    center_det = center_det + 10
                    
                    cntr = (center_det, new_center)
                    for b in range(tomo.shape[0]):
                        tomo[b] = st.rotate(tomo[b], correcttilt, center=cntr, preserve_range=True, order=1, mode='edge', clip=True) #center=None means image is rotated around its center; order=1 is default, order of spline interpolation
#                    tomo = tomo[:, :, 10:-10]    
                        
                elif func_name == 'do_360_to_180':
                    
                    # Keep values around for processing the next chunk in the list
                    keepvalues = [angularrange, numangles, projused, num_proj_per_chunk, numprojchunks, numprojused, numrays, anglelist]
                    
                    #why -.5 on one and not on the other?
                    if tomo.shape[0]%2>0:
                        tomo = sino_360_to_180(tomo[0:-1,:,:], overlap=int(np.round((tomo.shape[2]-cor-.5))*2), rotation='right')
                        angularrange = angularrange/2 - angularrange/(tomo.shape[0]-1)
                    else:
                        tomo = sino_360_to_180(tomo[:,:,:], overlap=int(np.round((tomo.shape[2]-cor))*2), rotation='right')
                        angularrange = angularrange/2
                    numangles = int(numangles/2)
                    projused = (0,numangles-1,1)
                    num_proj_per_chunk = np.minimum(chunk_proj,projused[1]-projused[0])
                    numprojchunks = (projused[1]-projused[0]-1)//num_proj_per_chunk+1
                    numprojused = (projused[1]-projused[0])//projused[2]
                    numrays = tomo.shape[2]
                    
                    anglelist = anglelist[:numangles]
                
                elif func_name == 'phase_retrieval':
                    tomo = tomopy.retrieve_phase(tomo, pixel_size=pxsize, dist=propagation_dist, energy=kev, alpha=alphaReg, pad=True)
                
                elif func_name == 'translation_correction':
                    tomo = linear_translation_correction(tomo,dx=xshift,dy=yshift,interpolation=False):
                    
                elif func_name == 'recon_mask':
                    tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')

                    if projIgnoreList is not None:
                        for badproj in projIgnoreList:
                            tomo[badproj] = 0

                    rec = tomopy.recon(tomo, anglelist, center=cor+npad, algorithm='gridrec', filter_name='butterworth', filter_par=[butterworth_cutoff, butterworth_order])
                    rec = rec[:, npad:-npad, npad:-npad]
                    rec /= pxsize  # convert reconstructed voxel values from 1/pixel to 1/cm
                    rec = tomopy.circ_mask(rec, 0)
                elif func_name == 'polar_ring':
                    rec = np.ascontiguousarray(rec, dtype=np.float32)
                    rec = tomopy.remove_ring(rec, theta_min=Rarc, rwidth=Rmaxwidth, thresh_max=Rtmax, thresh=Rthr, thresh_min=Rtmin,out=rec)
                elif func_name == 'castTo8bit':
                    rec = convert8bit(rec, cast8bit_min, cast8bit_max)
                elif func_name == 'bilateral_filter':
                    rec = pyF3D.run_BilateralFilter(rec, spatialRadius=bilateral_srad, rangeRadius=bilateral_rrad)
                elif func_name == 'write_output':
                    dxchange.write_tiff_stack(rec, fname=filenametowrite, start=y*num_sino_per_chunk + sinoused[0])
                print('(took {:.2f} seconds)'.format(time.time()-curtime))
                dofunc+=1
                if dofunc==len(function_list):
                    break
            if y<niter-1 and keepvalues: # Reset original values for next chunk
                angularrange, numangles, projused, num_proj_per_chunk, numprojchunks, numprojused, numrays, anglelist = keepvalues
                
        curtemp = 1 - curtemp
        curfunc = dofunc
        if curfunc==len(function_list):
            break
        axis = slice_dir[function_list[curfunc]]
    print("cleaning up temp files")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass
    print("End Time: "+time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))
    print('It took {:.3f} s to process {}'.format(time.time()-start_time,inputPath+filename))
Esempio n. 14
0
# Read the APS 32-ID or 2-BM raw data
prj, flat, dark = tomopy.io.exchange.read_aps_32id(fname, sino=(start, end))

# Set the data collection angles as equally spaced between 0-180 degrees
theta  = tomopy.angles(prj.shape[0], ang1=0, ang2=180)

# Normalize the raw projection data
prj = tomopy.normalize(prj, flat, dark)

# Set the aprox rotation axis location.
# This parameter is the starting angle for auto centering routine
start_center=295 
print "Start Center: ", start_center

# Auto centering
calc_center = tomopy.find_center(prj, theta, emission=False, ind=0, init=start_center, tol=0.3)
print "Calculated Center:", calc_center

# Recon using gridrec
rec = tomopy.recon(prj, theta, center=calc_center, algorithm='gridrec', emission=False)

# Mask each reconstructed slice with a circle
rec = tomopy.circ_mask(rec, axis=0, ratio=0.8)

# to save the reconstructed images uncomment and customize the following line:
rec_name = 'rec/tooth'

# Write data as stack of TIFs.
tomopy.io.writer.write_tiff_stack(rec, fname=rec_name)
print "Done!  reconstructions at: ", rec_name
Esempio n. 15
0
def tomo_reconstruction(sino,
                        refine_cen=False,
                        cen_range=None,
                        center=None,
                        method=None,
                        algorithm_A=None,
                        algorithm_B=None,
                        omega=None):
    '''
    INPUT ->  sino : slice, x, 2th
    OUTPUT -> tomo : slice, x, y
    '''

    method, center, omega, algorithm_A, algorithm_B = check_parameters(
        sino, method, center, omega, algorithm_A, algorithm_B)
    if method is None:
        print('No tomographic reconstruction packages available')
        return

    if method.lower().startswith('scikit') and HAS_scikit:

        tomo = []
        npts = sino.shape[1]
        cntr = int(
            npts -
            center)  # flip axis for compatibility with tomopy convention

        if refine_cen:

            if cen_range is None: cen_range = 12
            rng = int(cen_range) if cen_range > 0 and cen_range < 21 else 12

            npts = sino.shape[1]
            cen_list, negentropy = [], []

            for cen in np.arange(cntr - rng, cntr + rng, 1, dtype=int):
                xslice = slice(npts -
                               2 * cen, -1) if cen < npts / 2. else slice(
                                   0, npts - 2 * cen)
                recon = iradon(sino[0, xslice],
                               theta=omega,
                               filter=algorithm_A,
                               interpolation=algorithm_B,
                               circle=True)
                recon = recon - recon.min() + 0.005 * (recon.max() -
                                                       recon.min())
                negentropy += [(recon * np.log(recon)).sum()]
                cen_list += [cen]
            center = cen_list[np.array(negentropy).argmin()]

        xslice = slice(npts - 2 * cntr, -1) if cntr < npts / 2. else slice(
            0, npts - 2 * cntr)

        for sino0 in sino:
            tomo += [
                iradon(sino0[xslice],
                       theta=omega,
                       filter=algorithm_A,
                       interpolation=algorithm_B,
                       circle=True)
            ]
        tomo = np.flip(tomo, 1)
        center = (npts - cntr
                  ) / 1.  # flip axis for compatibility with tomopy convention

    elif method.lower().startswith('tomopy') and HAS_tomopy:

        ## reorder to: 2th,slice,x for tomopy
        sino = np.einsum('jki->ijk', np.einsum('kji->ijk', sino).T)

        if refine_cen:
            center = tomopy.find_center(sino,
                                        np.radians(omega),
                                        init=center,
                                        ind=0,
                                        tol=0.5)

        tomo = tomopy.recon(sino,
                            np.radians(omega),
                            center=center,
                            algorithm=algorithm_A)  #,
        #                             filter_name=algorithm_B)

        ## reorder to slice, x, y
        tomo = np.flip(tomo, 1)

    return center, tomo


# def registerLarchPlugin():
#     return ('_tomo', {'create_tomogrp': create_tomogrp})
#
#
# def registerLarchGroups():
#     return (tomogrp)
Esempio n. 16
0
def recon(
        filename,
        inputPath='./',
        outputPath=None,
        outputFilename=None,
        doOutliers1D=False,  # outlier removal in 1d (along sinogram columns)
        outlier_diff1D=750,  # difference between good data and outlier data (outlier removal)
        outlier_size1D=3,  # radius around each pixel to look for outliers (outlier removal)
        doOutliers2D=False,  # outlier removal, standard 2d on each projection
        outlier_diff2D=750,  # difference between good data and outlier data (outlier removal)
        outlier_size2D=3,  # radius around each pixel to look for outliers (outlier removal)
        doFWringremoval=True,  # Fourier-wavelet ring removal
        doTIringremoval=False,  # Titarenko ring removal
        doSFringremoval=False,  # Smoothing filter ring removal
        ringSigma=3,  # damping parameter in Fourier space (Fourier-wavelet ring removal)
        ringLevel=8,  # number of wavelet transform levels (Fourier-wavelet ring removal)
        ringWavelet='db5',  # type of wavelet filter (Fourier-wavelet ring removal)
        ringNBlock=0,  # used in Titarenko ring removal (doTIringremoval)
        ringAlpha=1.5,  # used in Titarenko ring removal (doTIringremoval)
        ringSize=5,  # used in smoothing filter ring removal (doSFringremoval)
        doPhaseRetrieval=False,  # phase retrieval
        alphaReg=0.0002,  # smaller = smoother (used for phase retrieval)
        propagation_dist=75,  # sample-to-scintillator distance (phase retrieval)
        kev=24,  # energy level (phase retrieval)
        butterworth_cutoff=0.25,  #0.1 would be very smooth, 0.4 would be very grainy (reconstruction)
        butterworth_order=2,  # for reconstruction
        doPolarRing=False,  # ring removal
        Rarc=30,  # min angle needed to be considered ring artifact (ring removal)
        Rmaxwidth=100,  # max width of rings to be filtered (ring removal)
        Rtmax=3000.0,  # max portion of image to filter (ring removal)
        Rthr=3000.0,  # max value of offset due to ring artifact (ring removal)
        Rtmin=-3000.0,  # min value of image to filter (ring removal)
        cor=None,  # center of rotation (float). If not used then cor will be detected automatically
        corFunction='pc',  # center of rotation function to use - can be 'pc', 'vo', or 'nm'
        voInd=None,  # index of slice to use for cor search (vo)
        voSMin=-40,  # min radius for searching in sinogram (vo)
        voSMax=40,  # max radius for searching in sinogram (vo)
        voSRad=10,  # search radius (vo)
        voStep=0.5,  # search step (vo)
        voRatio=2.0,  # ratio of field-of-view and object size (vo)
        voDrop=20,  # drop lines around vertical center of mask (vo)
        nmInd=None,  # index of slice to use for cor search (nm)
        nmInit=None,  # initial guess for center (nm)
        nmTol=0.5,  # desired sub-pixel accuracy (nm)
        nmMask=True,  # if True, limits analysis to circular region (nm)
        nmRatio=1.0,  # ratio of radius of circular mask to edge of reconstructed image (nm)
        nmSinoOrder=False,  # if True, analyzes in sinogram space. If False, analyzes in radiograph space
        use360to180=False,  # use 360 to 180 conversion
        doBilateralFilter=False,  # if True, uses bilateral filter on image just before write step # NOTE: image will be converted to 8bit if it is not already
        bilateral_srad=3,  # spatial radius for bilateral filter (image will be converted to 8bit if not already)
        bilateral_rrad=30,  # range radius for bilateral filter (image will be converted to 8bit if not already)
        castTo8bit=False,  # convert data to 8bit before writing
        cast8bit_min=-10,  # min value if converting to 8bit
        cast8bit_max=30,  # max value if converting to 8bit
        useNormalize_nf=False,  # normalize based on background intensity (nf)
        chunk_proj=100,  # chunk size in projection direction
        chunk_sino=100,  # chunk size in sinogram direction
        npad=None,  # amount to pad data before reconstruction
        projused=None,  #should be slicing in projection dimension (start,end,step)
        sinoused=None,  #should be sliceing in sinogram dimension (start,end,step). If first value is negative, it takes the number of slices from the second value in the middle of the stack.
        correcttilt=0,  #tilt dataset
        tiltcenter_slice=None,  # tilt center (x direction)
        tiltcenter_det=None,  # tilt center (y direction)
        angle_offset=0,  #this is the angle offset from our default (270) so that tomopy yields output in the same orientation as previous software (Octopus)
        anglelist=None,  #if not set, will assume evenly spaced angles which will be calculated by the angular range and number of angles found in the file. if set to -1, will read individual angles from each image. alternatively, a list of angles can be passed.
        doBeamHardening=False,  #turn on beam hardening correction, based on "Correction for beam hardening in computed tomography", Gabor Herman, 1979 Phys. Med. Biol. 24 81
        BeamHardeningCoefficients=None,  #6 values, tomo = a0 + a1*tomo + a2*tomo^2 + a3*tomo^3 + a4*tomo^4 + a5*tomo^5
        projIgnoreList=None,  #projections to be ignored in the reconstruction (for simplicity in the code, they will not be removed and will be processed as all other projections but will be set to zero absorption right before reconstruction.
        *args,
        **kwargs):

    start_time = time.time()
    print("Start {} at:".format(filename) +
          time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))

    outputPath = inputPath if outputPath is None else outputPath

    outputFilename = filename if outputFilename is None else outputFilename
    tempfilenames = [outputPath + 'tmp0.h5', outputPath + 'tmp1.h5']
    filenametowrite = outputPath + '/rec' + filename.strip(
        ".h5") + '/' + outputFilename
    #filenametowrite = outputPath+'/rec'+filename+'/'+outputFilename

    print("cleaning up previous temp files", end="")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass

    print(", reading metadata")

    datafile = h5py.File(inputPath + filename, 'r')
    gdata = dict(dxchange.reader._find_dataset_group(datafile).attrs)
    pxsize = float(gdata['pxsize']) / 10  # /10 to convert unites from mm to cm
    numslices = int(gdata['nslices'])
    numangles = int(gdata['nangles'])
    angularrange = float(gdata['arange'])
    numrays = int(gdata['nrays'])
    npad = int(np.ceil(numrays * np.sqrt(2)) -
               numrays) // 2 if npad is None else npad
    projused = (0, numangles - 1, 1) if projused is None else projused

    #	ndark = int(gdata['num_dark_fields'])
    #	ind_dark = list(range(0, ndark))
    #	group_dark = [numangles - 1]
    inter_bright = int(gdata['i0cycle'])
    nflat = int(gdata['num_bright_field'])
    ind_flat = list(range(0, nflat))
    if inter_bright > 0:
        group_flat = list(range(0, numangles, inter_bright))
        if group_flat[-1] != numangles - 1:
            group_flat.append(numangles - 1)
    elif inter_bright == 0:
        group_flat = [0, numangles - 1]
    else:
        group_flat = None
    ind_tomo = list(range(0, numangles))
    floc_independent = dxchange.reader._map_loc(ind_tomo, group_flat)

    #figure out the angle list (a list of angles, one per projection image)
    dtemp = datafile[list(datafile.keys())[0]]
    fltemp = list(dtemp.keys())
    firstangle = float(dtemp[fltemp[0]].attrs.get('rot_angle', 0))
    if anglelist is None:
        #the offset angle should offset from the angle of the first image, which is usually 0, but in the case of timbir data may not be.
        #we add the 270 to be inte same orientation as previous software used at bl832
        angle_offset = 270 + angle_offset - firstangle
        anglelist = tomopy.angles(numangles, angle_offset,
                                  angle_offset - angularrange)
    elif anglelist == -1:
        anglelist = np.zeros(shape=numangles)
        for icount in range(0, numangles):
            anglelist[icount] = np.pi / 180 * (270 + angle_offset - float(
                dtemp[fltemp[icount]].attrs['rot_angle']))

    #if projused is different than default, need to chnage numangles and angularrange

    #can't do useNormalize_nf and doOutliers2D at the same time, or doOutliers2D and doOutliers1D at the same time, b/c of the way we chunk, for now just disable that
    if useNormalize_nf == True and doOutliers2D == True:
        useNormalize_nf = False
        print(
            "we cannot currently do useNormalize_nf and doOutliers2D at the same time, turning off useNormalize_nf"
        )
    if doOutliers2D == True and doOutliers1D == True:
        doOutliers1D = False
        print(
            "we cannot currently do doOutliers1D and doOutliers2D at the same time, turning off doOutliers1D"
        )

    #figure out how user can pass to do central x number of slices, or set of slices dispersed throughout (without knowing a priori the value of numslices)
    if sinoused is None:
        sinoused = (0, numslices, 1)
    elif sinoused[0] < 0:
        sinoused = (
            int(np.floor(numslices / 2.0) - np.ceil(sinoused[1] / 2.0)),
            int(np.floor(numslices / 2.0) + np.floor(sinoused[1] / 2.0)), 1)

    num_proj_per_chunk = np.minimum(chunk_proj, projused[1] - projused[0])
    numprojchunks = (projused[1] - projused[0] - 1) // num_proj_per_chunk + 1
    num_sino_per_chunk = np.minimum(chunk_sino, sinoused[1] - sinoused[0])
    numsinochunks = (sinoused[1] - sinoused[0] - 1) // num_sino_per_chunk + 1
    numprojused = (projused[1] - projused[0]) // projused[2]
    numsinoused = (sinoused[1] - sinoused[0]) // sinoused[2]

    BeamHardeningCoefficients = (
        0, 1, 0, 0, 0,
        .1) if BeamHardeningCoefficients is None else BeamHardeningCoefficients

    if cor is None:
        print("Detecting center of rotation", end="")
        if angularrange > 300:
            lastcor = int(np.floor(numangles / 2) - 1)
        else:
            lastcor = numangles - 1
        #I don't want to see the warnings about the reader using a deprecated variable in dxchange
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            tomo, flat, dark, floc = dxchange.read_als_832h5(
                inputPath + filename, ind_tomo=(0, lastcor))
        tomo = tomo.astype(np.float32)
        if useNormalize_nf:
            tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo)
        else:
            tomopy.normalize(tomo, flat, dark, out=tomo)

        if corFunction == 'vo':
            # same reason for catching warnings as above
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                cor = tomopy.find_center_vo(tomo,
                                            ind=voInd,
                                            smin=voSMin,
                                            smax=voSMax,
                                            srad=voSRad,
                                            step=voStep,
                                            ratio=voRatio,
                                            drop=voDrop)
        elif corFunction == 'nm':
            cor = tomopy.find_center(
                tomo,
                tomopy.angles(numangles, angle_offset,
                              angle_offset - angularrange),
                ind=nmInd,
                init=nmInit,
                tol=nmTol,
                mask=nmMask,
                ratio=nmRatio,
                sinogram_order=nmSinoOrder)
        elif corFunction == 'pc':
            cor = tomopy.find_center_pc(tomo[0], tomo[1], tol=0.25)
        else:
            raise ValueError("\'corFunction\' must be one of: [ pc, vo, nm ].")
        print(", {}".format(cor))
    else:
        print("using user input center of {}".format(cor))

    function_list = []

    if doOutliers1D:
        function_list.append('remove_outlier1d')
    if doOutliers2D:
        function_list.append('remove_outlier2d')
    if useNormalize_nf:
        function_list.append('normalize_nf')
    else:
        function_list.append('normalize')
    function_list.append('minus_log')
    if doBeamHardening:
        function_list.append('beam_hardening')
    if doFWringremoval:
        function_list.append('remove_stripe_fw')
    if doTIringremoval:
        function_list.append('remove_stripe_ti')
    if doSFringremoval:
        function_list.append('remove_stripe_sf')
    if correcttilt:
        function_list.append('correcttilt')
    if use360to180:
        function_list.append('do_360_to_180')
    if doPhaseRetrieval:
        function_list.append('phase_retrieval')
    function_list.append('recon_mask')
    if doPolarRing:
        function_list.append('polar_ring')
    if castTo8bit:
        function_list.append('castTo8bit')
    if doBilateralFilter:
        function_list.append('bilateral_filter')
    function_list.append('write_output')

    # Figure out first direction to slice
    for func in function_list:
        if slice_dir[func] != 'both':
            axis = slice_dir[func]
            break

    done = False
    curfunc = 0
    curtemp = 0
    while True:  # Loop over reading data in certain chunking direction
        if axis == 'proj':
            niter = numprojchunks
        else:
            niter = numsinochunks
        for y in range(niter):  # Loop over chunks
            print("{} chunk {} of {}".format(axis, y + 1, niter))
            if curfunc == 0:
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore")
                    if axis == 'proj':
                        tomo, flat, dark, floc = dxchange.read_als_832h5(
                            inputPath + filename,
                            ind_tomo=range(
                                y * num_proj_per_chunk + projused[0],
                                np.minimum(
                                    (y + 1) * num_proj_per_chunk + projused[0],
                                    numangles)),
                            sino=(sinoused[0], sinoused[1], sinoused[2]))
                    else:
                        tomo, flat, dark, floc = dxchange.read_als_832h5(
                            inputPath + filename,
                            ind_tomo=range(projused[0], projused[1],
                                           projused[2]),
                            sino=(y * num_sino_per_chunk + sinoused[0],
                                  np.minimum((y + 1) * num_sino_per_chunk +
                                             sinoused[0], numslices), 1))
            else:
                if axis == 'proj':
                    start, end = y * num_proj_per_chunk, np.minimum(
                        (y + 1) * num_proj_per_chunk, numprojused)
                    tomo = dxchange.reader.read_hdf5(
                        tempfilenames[curtemp],
                        '/tmp/tmp',
                        slc=((start, end, 1), (0, numslices, 1),
                             (0, numrays, 1)))  #read in intermediate file
                else:
                    start, end = y * num_sino_per_chunk, np.minimum(
                        (y + 1) * num_sino_per_chunk, numsinoused)
                    tomo = dxchange.reader.read_hdf5(tempfilenames[curtemp],
                                                     '/tmp/tmp',
                                                     slc=((0, numangles,
                                                           1), (start, end, 1),
                                                          (0, numrays, 1)))
            dofunc = curfunc
            keepvalues = None
            while True:  # Loop over operations to do in current chunking direction
                func_name = function_list[dofunc]
                newaxis = slice_dir[func_name]
                if newaxis != 'both' and newaxis != axis:
                    # We have to switch axis, so flush to disk
                    if y == 0:
                        try:
                            os.remove(tempfilenames[1 - curtemp])
                        except OSError:
                            pass
                    appendaxis = 1 if axis == 'sino' else 0
                    dxchange.writer.write_hdf5(
                        tomo,
                        fname=tempfilenames[1 - curtemp],
                        gname='tmp',
                        dname='tmp',
                        overwrite=False,
                        appendaxis=appendaxis)  #writing intermediate file...
                    break
                print(func_name, end=" ")
                curtime = time.time()
                if func_name == 'remove_outlier1d':
                    tomo = tomo.astype(np.float32, copy=False)
                    remove_outlier1d(tomo,
                                     outlier_diff1D,
                                     size=outlier_size1D,
                                     out=tomo)
                if func_name == 'remove_outlier2d':
                    tomo = tomo.astype(np.float32, copy=False)
                    tomopy.remove_outlier(tomo,
                                          outlier_diff2D,
                                          size=outlier_size2D,
                                          axis=0,
                                          out=tomo)
                elif func_name == 'normalize_nf':
                    tomo = tomo.astype(np.float32, copy=False)
                    tomopy.normalize_nf(
                        tomo, flat, dark, floc_independent, out=tomo
                    )  #use floc_independent b/c when you read file in proj chunks, you don't get the correct floc returned right now to use here.
                elif func_name == 'normalize':
                    tomo = tomo.astype(np.float32, copy=False)
                    tomopy.normalize(tomo, flat, dark, out=tomo)
                elif func_name == 'minus_log':
                    mx = np.float32(0.00000000000000000001)
                    ne.evaluate('where(tomo>mx, tomo, mx)', out=tomo)
                    tomopy.minus_log(tomo, out=tomo)
                elif func_name == 'beam_hardening':
                    loc_dict = {
                        'a{}'.format(i): np.float32(val)
                        for i, val in enumerate(BeamHardeningCoefficients)
                    }
                    tomo = ne.evaluate(
                        'a0 + a1*tomo + a2*tomo**2 + a3*tomo**3 + a4*tomo**4 + a5*tomo**5',
                        local_dict=loc_dict,
                        out=tomo)
                elif func_name == 'remove_stripe_fw':
                    tomo = tomopy.remove_stripe_fw(tomo,
                                                   sigma=ringSigma,
                                                   level=ringLevel,
                                                   pad=True,
                                                   wname=ringWavelet)
                elif func_name == 'remove_stripe_ti':
                    tomo = tomopy.remove_stripe_ti(tomo,
                                                   nblock=ringNBlock,
                                                   alpha=ringAlpha)
                elif func_name == 'remove_stripe_sf':
                    tomo = tomopy.remove_stripe_sf(tomo, size=ringSize)
                elif func_name == 'correcttilt':
                    if tiltcenter_slice is None:
                        tiltcenter_slice = numslices / 2.
                    if tiltcenter_det is None:
                        tiltcenter_det = tomo.shape[2] / 2
                    new_center = tiltcenter_slice - 0.5 - sinoused[0]
                    center_det = tiltcenter_det - 0.5

                    #add padding of 10 pixels, to be unpadded right after tilt correction. This makes the tilted image not have zeros at certain edges, which matters in cases where sample is bigger than the field of view. For the small amounts we are generally tilting the images, 10 pixels is sufficient.
                    #					tomo = tomopy.pad(tomo, 2, npad=10, mode='edge')
                    #					center_det = center_det + 10

                    cntr = (center_det, new_center)
                    for b in range(tomo.shape[0]):
                        tomo[b] = st.rotate(
                            tomo[b],
                            correcttilt,
                            center=cntr,
                            preserve_range=True,
                            order=1,
                            mode='edge',
                            clip=True
                        )  #center=None means image is rotated around its center; order=1 is default, order of spline interpolation


#					tomo = tomo[:, :, 10:-10]

                elif func_name == 'do_360_to_180':

                    # Keep values around for processing the next chunk in the list
                    keepvalues = [
                        angularrange, numangles, projused, num_proj_per_chunk,
                        numprojchunks, numprojused, numrays, anglelist
                    ]

                    #why -.5 on one and not on the other?
                    if tomo.shape[0] % 2 > 0:
                        tomo = sino_360_to_180(
                            tomo[0:-1, :, :],
                            overlap=int(
                                np.round((tomo.shape[2] - cor - .5)) * 2),
                            rotation='right')
                        angularrange = angularrange / 2 - angularrange / (
                            tomo.shape[0] - 1)
                    else:
                        tomo = sino_360_to_180(
                            tomo[:, :, :],
                            overlap=int(np.round((tomo.shape[2] - cor)) * 2),
                            rotation='right')
                        angularrange = angularrange / 2
                    numangles = int(numangles / 2)
                    projused = (0, numangles - 1, 1)
                    num_proj_per_chunk = np.minimum(chunk_proj,
                                                    projused[1] - projused[0])
                    numprojchunks = (projused[1] - projused[0] -
                                     1) // num_proj_per_chunk + 1
                    numprojused = (projused[1] - projused[0]) // projused[2]
                    numrays = tomo.shape[2]

                    anglelist = anglelist[:numangles]

                elif func_name == 'phase_retrieval':
                    tomo = tomopy.retrieve_phase(tomo,
                                                 pixel_size=pxsize,
                                                 dist=propagation_dist,
                                                 energy=kev,
                                                 alpha=alphaReg,
                                                 pad=True)
                elif func_name == 'recon_mask':
                    tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')

                    if projIgnoreList is not None:
                        for badproj in projIgnoreList:
                            tomo[badproj] = 0

                    rec = tomopy.recon(
                        tomo,
                        anglelist,
                        center=cor + npad,
                        algorithm='gridrec',
                        filter_name='butterworth',
                        filter_par=[butterworth_cutoff, butterworth_order])
                    rec = rec[:, npad:-npad, npad:-npad]
                    rec /= pxsize  # convert reconstructed voxel values from 1/pixel to 1/cm
                    rec = tomopy.circ_mask(rec, 0)
                elif func_name == 'polar_ring':
                    rec = np.ascontiguousarray(rec, dtype=np.float32)
                    rec = tomopy.remove_ring(rec,
                                             theta_min=Rarc,
                                             rwidth=Rmaxwidth,
                                             thresh_max=Rtmax,
                                             thresh=Rthr,
                                             thresh_min=Rtmin,
                                             out=rec)
                elif func_name == 'castTo8bit':
                    rec = convert8bit(rec, cast8bit_min, cast8bit_max)
                elif func_name == 'bilateral_filter':
                    rec = pyF3D.run_BilateralFilter(
                        rec,
                        spatialRadius=bilateral_srad,
                        rangeRadius=bilateral_rrad)
                elif func_name == 'write_output':
                    dxchange.write_tiff_stack(rec,
                                              fname=filenametowrite,
                                              start=y * num_sino_per_chunk +
                                              sinoused[0])
                print('(took {:.2f} seconds)'.format(time.time() - curtime))
                dofunc += 1
                if dofunc == len(function_list):
                    break
            if y < niter - 1 and keepvalues:  # Reset original values for next chunk
                angularrange, numangles, projused, num_proj_per_chunk, numprojchunks, numprojused, numrays, anglelist = keepvalues

        curtemp = 1 - curtemp
        curfunc = dofunc
        if curfunc == len(function_list):
            break
        axis = slice_dir[function_list[curfunc]]
    print("cleaning up temp files")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass
    print("End Time: " +
          time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))
    print('It took {:.3f} s to process {}'.format(time.time() - start_time,
                                                  inputPath + filename))
Esempio n. 17
0
plt.figure()
plt.imshow(abs(FBPrec_ideal - FBPrec_error), vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('FBP reconsrtuction differences')
rmse2 = np.linalg.norm(FBPrec_ideal -
                       FBPrec_error) / np.linalg.norm(FBPrec_error)

#%%
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("Reconstructing analytical sinogram using gridrec (TomoPy)...")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
import tomopy

sinoTP = np.zeros((angles_num, 1, P), dtype='float32')
sinoTP[:, 0, :] = sino_an
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')
sinoTP[:, 0, :] = noisy_zing_stripe
reconTomoPy_noisy = tomopy.recon(sinoTP,
                                 angles_rad,
                                 center=rot_center,
                                 algorithm='gridrec')

plt.figure()
plt.subplot(121)
plt.imshow(reconTomoPy_ideal[0, :, :], vmin=0, vmax=1, cmap="gray")
plt.colorbar(ticks=[0, 0.5, 1], orientation='vertical')
plt.title('Ideal reconstruction (TomoPy)')
Esempio n. 18
0
 def find_center(self, tomo, thetas, slice_index, init_center, tol, mask_bool, ratio):
     center = tomopy.find_center(tomo, thetas, slice_index, init_center, tol, mask_bool, ratio)
     return center[0]
if manual_rcen:
    # find rotation center manually by varying the rcen and writing back to file. Exits script when done.
    rcen_range = [754, 764, 0.1]
    tomopy.write_center(proj,
                        theta,
                        dpath=recodir + 'tmp/center',
                        cen_range=rcen_range)
    logger.info(
        'Reconstructed with varying rotation center from %g to %g in %g steps.'
        % (rcen_range[0], rcen_range[1], rcen_range[2]))
    raise SystemExit(0)

if auto_rcen:
    rcen_tol = 0.08
    logger.info('determine rotation center with tolerance: %g' % rcen_tol)
    rcen = tomopy.find_center(proj, theta, tol=rcen_tol)
    logger.info('found rotation center at %g px' % rcen)
    if rcen - proj.shape[2] > 20:
        logger.warning(
            'rotation center more than 20px from projection center.')

################################
# Reduce dataset
#
nslice = 10
slices = [numpy.int(i * proj.shape[1] / nslice) for i in numpy.arange(1, 10)]
proj = proj[:, slices, :]
logger.info('reduced proj stack to {} slices at {}'.format(nslice, slices))
# or use a single slice
# slicenum =750
# proj = proj[:, slicenum, :]
Esempio n. 20
0
    # Read the APS 26-ID raw data.
    proj, flat, metadata = dxchange.read_aps_26id(fname,
                                                  ind_tomo,
                                                  ind_flat,
                                                  sino=(start, end))

    # make the darks
    dark = np.zeros((1, proj.shape[1], proj.shape[2]))

    # 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, init=1024, ind=0, tol=0.5)
    print("Center of rotation: ", rot_center)

    proj = tomopy.minus_log(proj)

    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(proj, 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')
Esempio n. 21
0
#    eng = 31
#    pxl = 0.325e-4
#    rat = 5e-03
#    rat = 1e-03
    #d.phase_retrieval(dist=z, energy=eng, pixel_size=pxl, alpha=rat,padding=True)
    #data = tomopy.retrieve_phase(data, dist=z, energy=eng, pixel_size=pxl, alpha=rat,pad=True)
    
    #if remove_stripe2: d.stripe_removal2()
    if remove_stripe2: data = tomopy.remove_stripe_ti(data)

    #d.downsample2d(level=level) # apply binning on the data
    data = tomopy.downsample(data, level=level) # apply binning on the data
    theta  = tomopy.angles(data.shape[0])
    if 1:
        #if not best_center: d.optimize_center()
        if not best_center: calc_center = tomopy.find_center(data, theta, emission=False, ind=0, tol=0.3)
        else: 
            #d.center=best_center/pow(2,level) # Manage the rotation center
            calc_center = best_center/pow(2,level) # Manage the rotation center
        #d.gridrec(ringWidth=RingW) # Run the reconstruction
        rec = tomopy.recon(data, theta, center=calc_center, algorithm='gridrec', emission=False)
        
        #d.apply_mask(ratio=1)
        rec = tomopy.circ_mask(rec, axis=0)

        # Write data as stack of TIFs.
        #tomopy.xtomo_writer(d.data_recon, output_name, 
        #                    axis=0,
        #                    x_start=slice_first)
        tomopy.io.writer.write_tiff_stack(rec, fname=output_name, axis=0, start=slice_first)
Esempio n. 22
0
def center(io_paras, data_paras, center_start, center_end, center_step, diag_cycle=0, 
            mode='diag', normalize=True, stripe_removal=10, phase_retrieval=False):
    
    # 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')

    # Set start and end of each subcycle
    projections_start = diag_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 center diagnosis (projs %s to %s)" 
        % (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:
        data = tomopy.normalize(data, white, dark, cutoff=None, ncore=_ncore, nchunk=None)

    ## Remove stripes caused by dead pixels in the detector
    if stripe_removal:
        data = tomopy.remove_stripe_fw(data, level=stripe_removal, wname='db5', 
                                        sigma=2, pad=True, ncore=None, 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:
        data = tomopy.retrieve_phase(data,
                    pixel_size=6.5e-5, dist=33, energy=30,
                    alpha=1e-3, pad=True, ncore=_ncore, nchunk=None)
    
    ## Determine and set the center of rotation
    ### Using optimization method to automatically find the center
    # d.optimize_center()
    if 'opti' in mode:
        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)
    ### Output the reconstruction results using a range of centers,
    ### and then manually find the optimal center.
    if 'diag' in mode:
        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!")
Esempio n. 23
0
    end = 16

    # APS 26-ID has an x-radia system collecting raw data as xrm.
    proj, flat, metadata = dxchange.read_aps_26id(fname, ind_tomo, ind_flat,
                                                 sino=(start, end))

    # make the darks
    dark = np.zeros((1, proj.shape[1], proj.shape[2]))    

    # 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, init=1024,
                                    ind=0, tol=0.5)
    print("Center of rotation: ", rot_center)

    proj = tomopy.minus_log(proj)

    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(proj, 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')
Esempio n. 24
0
    proj, flat, dark = tomopy.read_anka_tomotopo(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.
Esempio n. 25
0
"""Capstone Project: Write your own script!

In this file, write your own reconstruction script to do the following:

1. Load a dataset using dxchange.

2. Use the find center function to find the rotation center.
"""

import tomopy
import dxchange

if __name__ == '__main__':
    data, flat, dark, theta = dxchange.read_aps_32id(
        fname='activities/data/data-simulated.h5')
    print(tomopy.find_center(tomo=data, theta=theta, ind=5, tol=0.1))