def srxfftomo_findcenter(corrected_proj_tiff=None,
                         proj=None,
                         save_find_center=True,
                         autocheck=False,
                         check_cen_range_step=[390, 410, 1],
                         auto_selecslice=True,
                         cen_slice=400,
                         outpath=None,
                         samplename=None,
                         starting_angle=0,
                         last_angle=180):
    '''
    input needs to be either 
    1) corrected_proj_tiff, provided as a file path and name, 
    e.g. '/home/xf05id1/localdata/TomoCommissioning/testsample_01/testsample_01_corrected.tiff'
    it is a stack of tiff generated by srxfftomo_correction, where background and stage round out have been corrected
    2) projection numpy array, returned from srxfftomo_correction
    
    The 'proj' array assignment has priority. If it is None, proj was be read from corrected_proj_tiff 
    
    input example:
        check_cen_range_step = [390, 410, 1]
        cen_slice = 400    
    
    return: 
    proj (numpy array, float), with negative natural log has been taken
    
    '''
    if proj is None:
        print('proj is not asigned, load corrected projection from:',
              corrected_proj_tiff)
        proj = tifffile.imread(corrected_proj_tiff)
    else:
        print('proj array is not None, use it as is')

    if save_find_center is True:
        center_check_path = outpath + '/' + samplename + '/center_check/'
        print('saving find center value into ' + center_check_path)

        theta = tomopy.angles(proj.shape[0],
                              ang1=starting_angle,
                              ang2=last_angle)

        if autocheck is True:
            check_cen_range_step = [
                int(proj.shape[2] / 2) - 50,
                int(proj.shape[2]) / 2 + 50, 5
            ]

        if auto_selecslice is True:
            cen_slice = int(proj.shape[1] / 2)

        tomopy.write_center(proj,
                            theta,
                            center_check_path,
                            cen_range=check_cen_range_step,
                            ind=cen_slice,
                            mask=True)

    return proj
Esempio n. 2
0
 def reconstruct(
         self, 
         ct_series, workdir=None, outdir=None,
         rot_center=None, explore_rot_center=True):
     workdir = workdir or self.workdir;  
     outdir = outdir or self.outdir
     theta = self.theta
     # preprocess
     angles, sinograms = i3.build_sinograms(
         ct_series, workdir=os.path.join(workdir, 'sinogram'),
         parallel = self.parallel_preprocessing,
         parallel_nodes = self.parallel_nodes)
     # take the middle part to calculate the center of rotation
     NSINO = len(sinograms)
     sino = [s.data for s in sinograms[NSINO//3: NSINO*2//3]]
     # sino = [s.data for s in sinograms]
     sino= np.array(sino)
     proj = np.swapaxes(sino, 0, 1)
     import tomopy
     X = proj.shape[-1]
     DEVIATION = 40 # max deviation of rot center from center of image
     if explore_rot_center:
         print("* Exploring rotation center using tomopy...")
         tomopy.write_center(
             proj.copy(), theta,
             cen_range=[X//2-DEVIATION, X//2+DEVIATION, 1.],
             dpath=os.path.join(workdir, 'tomopy-findcenter'),
             emission=False)
     if rot_center is None:
         print("* Computing rotation center using 180deg pairs...")
         from .tilt import find_rot_center
         rot_center = find_rot_center.find(
             ct_series, workdir=os.path.join(workdir, 'find-rot-center'))
     print('* Rotation center: %s' % rot_center)
     open(os.path.join(workdir, 'rot_center'), 'wt').write(str(rot_center))
     # reconstruct 
     if self.vertical_range:
         sinograms = sinograms[self.vertical_range]
     recon = i3.reconstruct(
         angles, sinograms, 
         workdir=outdir, center=rot_center,
         nodes=self.parallel_nodes)
     return
Esempio n. 3
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. 4
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. 5
0
print proj.shape
theta = np.arange(0.0, 181.9 + step, step)
print(theta)
theta *= np.pi / 180.
# calculate rotation center
print "* finding center ..."
rot_center = tomopy.find_center(proj,
                                theta,
                                emission=False,
                                init=1024,
                                tol=0.5)
print "  done."
print("Center of rotation: ", rot_center)
# checking
print proj.shape
tomopy.write_center(proj.copy(), theta, dpath='center', emission=False)
# rot_center = tomopy.find_center_vo(proj.copy())
# print("Center of rotation: ", rot_center)
# plot data
# print "* normalizing bg ..."
# proj = tomopy.normalize_bg(data)
# print "  done."

# plot an image
fig, ax = plt.subplots()
im = plt.imshow(data[0], cmap='gray')  #, vmin=0.2, vmax=1.2
fig.colorbar(im)
# plot a projection
fig, ax = plt.subplots()
im = plt.imshow(proj[:, 1000, :], cmap='gray')
fig.colorbar(im)
Esempio n. 6
0
            # Select sinogram range to reconstruct.
            sino = None
            
            start = 1000
            end = 1001
            sino = (start, end)

            # Read APS 2-BM raw data.
            if (int(key) > 6):            
                proj, flat, dark, theta = read_aps_2bm_custom(fname, sino=sino)
            else:
                proj, flat, dark, theta = dxchange.read_aps_2bm(fname, sino=sino)
            
            # zinger_removal
            proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
            flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

            # Flat-field correction of raw data.
            data = tomopy.normalize(proj, flat, dark, cutoff=1.4)

            print(h5name, rot_center)

            data = tomopy.minus_log(data)

            # find center
            fname = top + 'try_center/' + prefix + h5name + '/recon'
            center_shift_w = 10
            cen_range = (rot_center-center_shift_w, rot_center+center_shift_w, 0.5)
            tomopy.write_center(data, theta, fname, cen_range)

print "* normalizing ..."
proj = tomopy.normalize(data, ob_data, df_data)
print "  done."
# checking
print proj.shape
theta = np.arange(0.0, 181.9+step, step)
print(theta)
theta *= np.pi/180.
# calculate rotation center
print "* finding center ..."
rot_center = tomopy.find_center(proj, theta, emission=False, init=1024, tol=0.5)
print "  done."
print("Center of rotation: ", rot_center)
# checking
print proj.shape
tomopy.write_center(proj.copy(), theta, dpath='center', emission=False)
# rot_center = tomopy.find_center_vo(proj.copy())
# print("Center of rotation: ", rot_center)
# plot data
# print "* normalizing bg ..."
# proj = tomopy.normalize_bg(data)
# print "  done."

# plot an image
fig, ax = plt.subplots()
im = plt.imshow(data[0], cmap='gray') #, vmin=0.2, vmax=1.2
fig.colorbar(im)
# plot a projection
fig, ax = plt.subplots()
im = plt.imshow(proj[:, 1000, :], cmap='gray')
fig.colorbar(im)
proj = tomopy.minus_log(proj)
logger.info('logarithmized proj')

################################
# Rotation center

rcen = False
auto_rcen = True
manual_rcen = False

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.')
Esempio n. 9
0
# phase retrieval
#data = tomopy.prep.phase.retrieve_phase(prj,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)


prj = tomopy.median_filter(prj,size=medfilt_size)
print('\n** Median filter done!')
if debug:
    print('## Debug: after nedian filter:')
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))


if level>0:
    prj = tomopy.downsample(prj, level=level)
    print('\n** Down sampling done!\n')
if debug:
    print('## Debug: after down sampling:')
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))

if auto_center == False:

    tomopy.write_center(prj,theta,dpath=output_path,cen_range=[Center_st/pow(2,level),Center_end/pow(2,level),((Center_end - Center_st)/float(N_recon))/pow(2,level)])

else:
    rot_axis = tomopy.find_center_vo(prj)
    rot_axis = rot_axis * pow(2,level)
    print('*** Rotation center: %0.2f' % rot_axis)
    rec = tomopy.recon(prj, theta, center=rot_axis/pow(2,level), algorithm='gridrec', filter_name='parzen')
    rec=np.squeeze(rec)
    plt.figure()
    plt.imshow(rec, cmap='gray', aspect="auto", interpolation='none')
    plt.colorbar(), plt.title('Rotation center: %0.2f' % rot_axis), plt.show()
Esempio n. 10
0
def do_work(out_path, scan_id, center_offset, mpi_projs, flats, darks,
            mpi_thetas):

    logger.info("Flat Field Correction")
    mpi_projs = normalize_mpi(mpi_projs, flats, darks)
    #utils_mpi.write_stack_mpi(out_path/"flat", mpi_projs)
    del flats
    del darks

    logger.info("Outlier Removal")
    # TODO: base parameters on clean simulation data! - might need fill
    projs = mpi_projs.scatter(0)
    # TODO: put back in, I think it is causing issues right now...
    tomopy.remove_outlier(projs, 0.1, 5, ncore=ncore, out=projs)
    #tomopy.remove_outlier_cuda(projs, 0.1, 5, ncore, out=projs)
    np.clip(projs, 1E-6, 1 - 1E-6, projs)

    # TODO: distortion correction factor?

    # TODO: ring removal?

    # # flat field change correction
    # remove_low_frequency_mpi(mpi_projs)
    # utils_mpi.write_stack_mpi(out_path/"low_frequency_removed", mpi_projs)

    # bulk Si intensity correction
    # removes constant absorption contribution from bulk Si, and mounting material
    # TODO: base parameters on clean simulation data! - will need fill
    # TODO: alternatively, refine result after good recon - with theta offset
    target_transmission = 0.80
    logger.info(f"Setting target transmission to {target_transmission}")
    set_target_transmission_mpi(mpi_projs, mpi_thetas, target_transmission)
    projs = mpi_projs.scatter(0)
    np.clip(projs, 1E-6, 1 - 1E-6, projs)
    utils_mpi.write_stack_mpi(out_path / "constant_transmission", mpi_projs)

    # center finding - manual for now?
    if center_offset is None:
        logger.info("Finding center")
        # algorithm = "SART"
        # pixel_size = 2 * 0.000016 #16nm bin 1
        # options = {"PixelWidth": pixel_size,
        #            "PixelHeight": pixel_size,
        #            "windowFOV": False,
        #            "archDir": out_path,
        #            "_mpi_rank": mpi_rank,
        #            }
        # alg_params = {"N_iter": 1,
        #               "N_subsets": 20,
        #               "nonnegativityConstraint": True,
        #               "useFBPasSeedImage": False,
        #               # "Preconditioner": "RAMP",
        #               # "beta": 2e-7,
        #               # "p": 1,
        #               # "delta": 1/20, # delta sets edge strength (difference between regions divide by ten)
        #               # "inverseVarianceExponent": 1.0, # set to 1 to include noise model
        #               # "other": 3, #convergence of low frequencies
        #               }
        # # load data into LTT, then find the center before recon
        # ltt_tomopy.initialize_recon(sinos, thetas, xcenter, True, algorithm, options, ncore=ncore)
        # center = align_tomo.find_center_ltt(lambda c: ltt_tomopy.preview(center=c, algorithm=algorithm, sinogram_order=True, close=False, options=options, alg_params=alg_params, ncore=ncore), xcenter, 0.1, ratio=0.8)
        # ltt_tomopy.recon_close()
        logger.info("Padding sinos for center finding")
        mpi_sinos = utils_mpi.create_sinos_mpi(mpi_projs, ncore)
        sinos = mpi_sinos.scatter(0)
        sinos = pad_sinos(sinos)
        mpi_sinos = MpiArray(sinos)
        gthetas = mpi_thetas.allgather()
        xcenter = sinos.shape[2] // 2
        cen_range = (xcenter - 20, xcenter + 20, 0.5)
        if mpi_rank == mpi_size // 2:
            tomopy.write_center(sinos,
                                gthetas,
                                out_path / ("center"),
                                cen_range,
                                sinogram_order=True)
        del mpi_sinos, sinos
        import sys
        comm.Barrier()
        sys.exit()
        # center_offset = mpi_projs.shape[2]//2-center
        # mpi_projs.comm.Barrier() #for printing
        # print(f"{mpi_projs.mpi_rank}: center={center} offset={center_offset}")
    #center = xcenter + center_offset

    # Shift correction?
    # use MPI and binning for speed
    # use LTT for all recon
    # define recon extent with extra X and less Z

    # Quick recon - LTT with SART or other? (can't use FBP)
    algorithm = "gridrec"
    options = {
        "filter_name": "parzen",
    }
    logger.info(f"Finding layer alignment within volume using {algorithm}")
    mpi_rec = tomopy_recon_mpi(mpi_projs,
                               mpi_thetas,
                               center_offset,
                               algorithm,
                               ncore=ncore,
                               **options)
    utils_mpi.write_stack_mpi(out_path / ("quick_" + algorithm), mpi_rec)
    theta_deg, start_z1, end_z1 = align_layers.find_angle_mpi(mpi_rec, 0)
    logger.info(f"Theta offset angle {theta_deg:0.2} deg")
    # find phi angle (axis 2)
    phi_deg, start_z2, end_z2 = align_layers.find_angle_mpi(mpi_rec, 2)
    logger.info(f"Phi offset angle {phi_deg:0.2} deg")
    start_z = min(start_z1, start_z2)
    end_z = max(end_z1, end_z2)
    # add buffer for start and end
    start_z = max(start_z - 20, 0)
    end_z = min(end_z + 20, mpi_rec.shape[1] - 1)
    #FIXME: override start and end
    start_z = 0
    end_z = mpi_rec.shape[1] - 1
    logger.info(f"Layer extent: {start_z} - {end_z}")

    # change theta with correction for next reconstruction
    thetas = mpi_thetas.scatter(0)
    thetas += np.deg2rad(theta_deg)
    # modify projections to remove phi angle
    # TODO: combine with stage shift code
    projs = mpi_projs.scatter(0)
    align_layers.apply_phi_correction(projs, thetas, phi_deg, projs)

    # Quick aligned recon
    algorithm = "gridrec"
    options = {
        "filter_name": "parzen",
    }
    logger.info("Quick Tomopy Recon")
    mpi_rec = tomopy_recon_mpi(mpi_projs,
                               mpi_thetas,
                               center_offset,
                               algorithm,
                               ncore=ncore,
                               **options)
    rec = mpi_rec.scatter(0)
    rec = rec[:, start_z:end_z, :]
    mpi_rec = MpiArray(rec)
    utils_mpi.write_stack_mpi(out_path / algorithm, mpi_rec)
    del mpi_rec, rec

    # Aligned recon
    # iterative recon with extra recon space in X and a restricted Z axis
    algorithm = "SART"  #"RDLS"#"DFM"#"ASD-POCS"#"SART"#"FBP"
    logger.info(f"Reconstructing aligned layers using {algorithm}")
    mpi_sinos = utils_mpi.create_sinos_mpi(mpi_projs, ncore)
    #utils_mpi.write_stack_mpi(out_path/"sinos", mpi_sinos)
    sinos = mpi_sinos.scatter(0)
    # add padding to recon - fixes cupping effect
    xrecpadding = sinos.shape[2] // 2
    pixel_size = 2 * 0.000016  # 16nm bin 1
    options = {
        "PixelWidth": pixel_size,
        "PixelHeight": pixel_size,
        "ryoffset": start_z,
        "ryelements": end_z - start_z,
        "windowFOV": False,
        "rxelements": sinos.shape[2] + 2 * xrecpadding,
        "rxoffset": -xrecpadding,
        "_mpi_rank": mpi_rank,
    }
    alg_params = {
        "N_iter": 50,
        "nonnegativityConstraint": False,
        "useFBPasSeedImage": False,
        #"Preconditioner": "RAMP",
        #"descentType": "CG",#"GD",
        #"beta": 2e-7,
        #"p": 1,
        #"delta": 20/20, # delta sets edge strength (difference between regions divide by ten)
        #"inverseVarianceExponent": 1.0, # set to 1 to include noise model
        #"other": 3, #convergence of low frequencies
    }
    #TODO: add support to add overlap in future with updates between iterations (see xray_trust6.py)
    gthetas = mpi_thetas.allgather()  #global thetas
    center = sinos.shape[2] // 2 + center_offset
    if gthetas[1] < gthetas[0]:
        # decreasing angle, LTT doesn't support, switch data around
        # TODO: load in reversed order?
        gthetas = gthetas[::-1]
        sinos[:] = sinos[:, ::-1, :]
    rec = ltt_tomopy.recon(sinos,
                           gthetas,
                           center,
                           True,
                           algorithm,
                           alg_params,
                           options,
                           ncore=ncore)
    rec = rec[:, :, xrecpadding:xrecpadding + sinos.shape[2]]
    mpi_rec = MpiArray(rec, distribution=mpi_sinos.distribution)
    utils_mpi.write_stack_mpi(out_path / algorithm, mpi_rec)

    # Neural network processing?

    # Extract layers
    # Use template if available
    logger.info("Extracting Layers")
    mpi_layers = align_layers.extract_layers_mpi(mpi_rec)
    align_layers.write_layers_to_file_mpi(mpi_layers, "layers")

    logger.info(f"Finished {scan_id}")
Esempio n. 11
0
            # Read APS 2-BM raw data.
            if (int(key) > 6):
                proj, flat, dark, theta = read_aps_2bm_custom(fname, sino=sino)
            else:
                proj, flat, dark, theta = dxchange.read_aps_2bm(fname,
                                                                sino=sino)

            # zinger_removal
            proj = tomopy.misc.corr.remove_outlier(proj,
                                                   zinger_level,
                                                   size=15,
                                                   axis=0)
            flat = tomopy.misc.corr.remove_outlier(flat,
                                                   zinger_level_w,
                                                   size=15,
                                                   axis=0)

            # Flat-field correction of raw data.
            data = tomopy.normalize(proj, flat, dark, cutoff=1.4)

            print(h5name, rot_center)

            data = tomopy.minus_log(data)

            # find center
            fname = top + 'try_center/' + prefix + h5name + '/recon'
            center_shift_w = 10
            cen_range = (rot_center - center_shift_w,
                         rot_center + center_shift_w, 0.5)
            tomopy.write_center(data, theta, fname, cen_range)
Esempio n. 12
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!")
# # recon
apply_shifts(projs, shifts, out=projs)
shifted_projs = projs #change name after shifts
del projs
write_stack("shifted_projs", shifted_projs)
sinos = tomopy.init_tomo(shifted_projs, sinogram_order=False, sharedmem=False)
tomopy.minus_log(sinos, out=sinos)

# logger.info("Finding center of rotation")
xcenter = sinos.shape[2] // 2
center = xcenter
if center_offset is not None:
    center = xcenter + center_offset
else:
    tomopy.write_center(sinos, thetas, "xcenter", (xcenter - 50, xcenter + 50, 1), sinogram_order=True)
    #center = tomopy.find_center(sinos, thetas, tol=0.1, mask=True, ratio=0.8, sinogram_order=True, algorithm="sirt", num_iter=10)
    #tomopy.write_center(sinos, thetas, "center", (center - 20, center + 20, 0.5), sinogram_order=True, algorithm="sirt", num_iter=10)
logger.info(f"center: {center:0.2f}")


# for flat samples, align recon to surface
if align_flat_sample:
    # Theta angle correction, do another recon to get better data afterwards!
    alg = "FBP"
    logger.info(f"Correcting theta using recon with {alg}")
    options = {"PixelWidth": pixel_size,
               "PixelHeight": pixel_size,
               "loggingLevel": "logDEBUG",
               }
    alg_params = {"extrapolate": True,
Esempio n. 14
0
def calib(cal_indir,
          cal_infn,
          center_check_path=None,
          use_cal_indir_as_center_check_path=True,
          hist_threshold=1.5,
          max_threshold=10):
    '''
    max_threshold: larger then this value, set img(x,y) = 0.001 to avoid numerical errors
    '''

    plt.ion()
    #cal_indir = '/nfs/xf05id1/data/beamlineData/fullfield_comissioning/pintest_run1_361proj/'
    #cal_indir = '/home/xf05id1/localdata/TomoCommissioning/pintest_run1_361proj/'
    #cal_infn = 'pintest_run1_361proj_norm.tif'
    #cal_infn = 'pintest_run3_1441proj_norm.tif'

    cal_infile = cal_indir + cal_infn
    img = imread(cal_infile)
    img = (-1) * np.log(img)

    #
    #plt.figure()
    #plt.plot(cen[:,1])

    sino = img[:, 400, :]
    #plt.plot(range(sino.shape[1]), sino[0, :])
    plt.figure()
    plt.imshow(sino)
    plt.show()

    img = tomopy.misc.corr.remove_nan(img, val=0.001)
    img[img > max_threshold] = 0.001

    #plot histogram
    hist, bin_edges = np.histogram(img, bins=120, range=(-2.0, 4.0))
    bin_centers = 0.5 * (bin_edges[:-1] + bin_edges[1:])
    plt.figure()
    plt.plot(bin_centers, hist)

    #segment the image by threshold = hist_threshold
    binary_img = img > hist_threshold
    plt.figure()
    plt.imshow(img[0, :, :])
    plt.figure()
    plt.imshow(binary_img[0, :, :])

    cen = np.array([
        ndimage.measurements.center_of_mass(binary_img[i, :, :])
        for i in range(binary_img.shape[0])
    ])

    if use_cal_indir_as_center_check_path is True:
        center_check_path = cal_indir

    if center_check_path is not None:
        print('shifting images....')
        img_shift_xonlyseg = np.array([
            shift(img[i, :, :], [0, cen[:, 1].mean() - cen[i, 1]])
            for i in range(img.shape[0])
        ])
        sino_shift_xonlyseg = img_shift_xonlyseg[:, 400, :]
        plt.figure()
        plt.imshow(sino_shift_xonlyseg)
        plt.show()

        theta = tomopy.angles(binary_img.shape[0])
        tomopy.write_center(img_shift_xonlyseg,
                            theta,
                            center_check_path,
                            cen_range=[390, 410, 1],
                            ind=400,
                            mask=True)

    f = open('cen_seg_x.txt', 'w')
    for i in cen:
        f.write(str(i[1]) + '\n')
    f.close()

    return img, cen, img_shift_xonlyseg
Esempio n. 15
0
 def reconstruct(
         self, 
         ct_series, workdir=None, outdir=None,
         rot_center=None, explore_rot_center=True,
         outfilename_template=None,
         remove_rings_at_sinograms=False,
         mirror=True,
         **kwds):
     workdir = workdir or self.workdir;  
     outdir = outdir or self.outdir
     theta = self.theta
     # preprocess
     angles, sinograms = i3.build_sinograms(
         ct_series, workdir=os.path.join(workdir, 'sinogram'),
         parallel = self.parallel_preprocessing,
         parallel_nodes = self.parallel_nodes)
     # take the middle part to calculate the center of rotation
     NSINO = len(sinograms)
     sino = [s.data for s in sinograms[NSINO//3: NSINO*2//3]]
     # sino = [s.data for s in sinograms]
     sino= np.array(sino)
     proj = np.swapaxes(sino, 0, 1)
     import tomopy
     X = proj.shape[-1]
     DEVIATION = 40 # max deviation of rot center from center of image
     if explore_rot_center:
         print("* Exploring rotation center using tomopy...")
         dpath=os.path.join(workdir, 'tomopy-findcenter')
         if not os.path.exists(dpath): # skip if already done
             tomopy.write_center(
                 proj.copy(), theta,
                 cen_range=[X//2-DEVIATION, X//2+DEVIATION, 1.],
                 dpath=dpath,
                 emission=False)
     if rot_center is None:
         print("* Computing rotation center using 180deg pairs...")
         from .tilt import find_rot_center
         rot_center = find_rot_center.find(
             ct_series, workdir=os.path.join(workdir, 'find-rot-center'))
     print('* Rotation center: %s' % rot_center)
     self.rot_center = rot_center
     open(os.path.join(workdir, 'rot_center'), 'wt').write(str(rot_center))
     # reconstruct 
     if self.vertical_range:
         sinograms = sinograms[self.vertical_range]
     self.r.sinograms = sinograms
     # sometimes the rotation angles and the stacking sequence coulb be not in the right convention
     if mirror:
         angles = -np.array(angles)
     # reconstruct using original sinograms
     recon = i3.reconstruct(
         angles, sinograms, 
         workdir=outdir, filename_template=outfilename_template,
         center=rot_center,
         nodes=self.parallel_nodes,
         **kwds)
     self.r.reconstructed = recon
     # reconstruct using rar filtered sinograms
     if remove_rings_at_sinograms:
         if remove_rings_at_sinograms is True:
             remove_rings_at_sinograms = {}
         self.r.rar_sino = sinograms = i3.ring_artifact_removal_Ketcham(
             sinograms, workdir=os.path.join(workdir, 'rar_sinograms'),
             parallel = self.parallel_preprocessing,
             **remove_rings_at_sinograms)
         recon = i3.reconstruct(
             angles, sinograms, 
             workdir=os.path.join(outdir, 'rar_sinograms'),
             filename_template=outfilename_template,
             center=rot_center,
             nodes=self.parallel_nodes,
             **kwds)
         self.r.reconstructed_using_rar_sinograms = recon
     return recon