Ejemplo n.º 1
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 30       # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 1.17e-4     # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 25.74        # Energy of incident wave in keV
    alpha = 1e-02                       # Phase retrieval coeff.
    zinger_level = 1000                 # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    miss_angles = [141,226]

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)
        

    print (theta)
    # Manage the missing angles:
    #proj_size = np.shape(proj)
    #theta = np.linspace(0,180,proj_size[0])
    proj = np.concatenate((proj[0:miss_angles[0],:,:], proj[miss_angles[1]+1:-1,:,:]), axis=0)
    theta = np.concatenate((theta[0:miss_angles[0]], theta[miss_angles[1]+1:-1]))

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

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    # phase retrieval
    # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
    ##rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    
    return rec
Ejemplo n.º 2
0
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm, binning):
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white
    
    data_shape = get_dx_dims(h5fname, 'data')
    print(data_shape)
    ssino = int(data_shape[1] * nsino)

    center_range = (rot_center-center_search_width, rot_center+center_search_width, 0.5)
    #print(sino,ssino, center_range)
    #print(center_range[0], center_range[1], center_range[2])

    # Select sinogram range to reconstruct
    sino = None
        
    start = ssino
    end = start + 1
    sino = (start, end)

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)
        
    # Flat-field correction of raw data.
    data = tomopy.normalize(proj, flat, dark, cutoff=1.4)

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)


    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    stack = np.empty((len(np.arange(*center_range)), data_shape[0], data_shape[2]))

    index = 0
    for axis in np.arange(*center_range):
        stack[index] = data[:, 0, :]
        index = index + 1

    # Reconstruct the same slice with a range of centers.
    rec = tomopy.recon(stack, theta, center=np.arange(*center_range), sinogram_order=True, algorithm='gridrec', filter_name='parzen', nchunk=1)

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

    index = 0
    # Save images to a temporary folder.
    fname = os.path.dirname(h5fname) + '/' + 'try_rec/' + 'recon_' + os.path.splitext(os.path.basename(h5fname))[0]    
    for axis in np.arange(*center_range):
        rfname = fname + '_' + str('{0:.2f}'.format(axis) + '.tiff')
        dxchange.write_tiff(rec[index], fname=rfname, overwrite=True)
        index = index + 1

    print("Reconstructions: ", fname)
Ejemplo n.º 3
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 8        # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.247e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 24.9         # Energy of incident wave in keV
    alpha = 1e-02                       # Phase retrieval coeff.
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)
        
    # zinger_removal
    # proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    # flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    # data = tomopy.remove_stripe_ti(data, alpha=1.5)
    # data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    elif algorithm == 'astrasirt':
        extra_options ={'MinConstraint':0}
        options = {'proj_type':'cuda', 'method':'SIRT_CUDA', 'num_iter':200, 'extra_options':extra_options}
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
    rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    
    return rec
Ejemplo n.º 4
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument("top", help="top directory where the tiff images are located: /data/")
    parser.add_argument("start", nargs='?', const=1, type=int, default=1, help="index of the first image: 1000 (default 1)")

    args = parser.parse_args()

    top = args.top
    index_start = int(args.start)

    template = os.listdir(top)[0]

    nfile = len(fnmatch.filter(os.listdir(top), '*.tif'))
    index_end = index_start + nfile
    ind_tomo = range(index_start, index_end)
    
    fname = top + template

    print (nfile, index_start, index_end, fname)


    # Select the sinogram range to reconstruct.
    start = 0
    end = 512
    sino=(start, end)

    # Read the tiff raw data.
    ndata = dxchange.read_tiff_stack(fname, ind=ind_tomo, slc=(sino, None))
 
    # Normalize to 1 using the air counts
    ndata = tomopy.normalize_bg(ndata, air=5)

    # Set data collection angles as equally spaced between 0-180 degrees.
    theta = tomopy.angles(ndata.shape[0])

    ndata = tomopy.minus_log(ndata)

    # Set binning and number of iterations
    binning = 8
    iters = 21

    print("Original", ndata.shape)
    ndata = tomopy.downsample(ndata, level=binning, axis=1)
#    ndata = tomopy.downsample(ndata, level=binning, axis=2)
    print("Processing:", ndata.shape)

    fdir = 'aligned' + '/noblur_iter_' + str(iters) + '_bin_' + str(binning) 

    print(fdir)
    cprj, sx, sy, conv = alignment.align_seq(ndata, theta, fdir=fdir, iters=iters, pad=(10, 10), blur=False, save=True, debug=True)

    np.save(fdir + '/shift_x', sx)
    np.save(fdir + '/shift_y', sy)

    # Write aligned projections as stack of TIFs.
    dxchange.write_tiff_stack(cprj, fname=fdir + '/radios/image')
Ejemplo n.º 5
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 8        # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.247e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 24.9         # Energy of incident wave in keV
    alpha = 1e-02                       # Phase retrieval coeff.
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # h5fname_norm = '/local/data/2019-02/Burke/C47M_0015.h5'
    h5fname_norm = '/local/data/2019-02/Burke/kc78_Menardii_0003.h5'
    proj1, flat, dark, theta1 = dxchange.read_aps_32id(h5fname_norm, sino=sino)
    proj, dummy, dummy1, theta = dxchange.read_aps_32id(h5fname, sino=sino)
        
    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=20)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
    rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    
    return rec
Ejemplo n.º 6
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument("top", help="top directory where the tiff images are located: /data/")
    parser.add_argument("start", nargs='?', const=1, type=int, default=1, help="index of the first image: 1000 (default 1)")

    args = parser.parse_args()

    top = args.top
    index_start = int(args.start)

    template = os.listdir(top)[0]

    nfile = len(fnmatch.filter(os.listdir(top), '*.tif'))
    index_end = index_start + nfile
    ind_tomo = range(index_start, index_end)
    
    fname = top + template

    print (nfile, index_start, index_end, fname)


    # Select the sinogram range to reconstruct.
    start = 0
    end = 512
    sino=(start, end)

    # Read the tiff raw data.
    ndata = dxchange.read_tiff_stack(fname, ind=ind_tomo, slc=(sino, None))

    print(ndata.shape)
    binning = 8
    ndata = tomopy.downsample(ndata, level=binning, axis=1)
    print(ndata.shape)
    
    # Normalize to 1 using the air counts
    ndata = tomopy.normalize_bg(ndata, air=5)

    ## slider(ndata)

    # Set data collection angles as equally spaced between 0-180 degrees.
    theta = tomopy.angles(ndata.shape[0])
   
    rot_center = 960
    print("Center of rotation: ", rot_center)

    ndata = tomopy.minus_log(ndata)

    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(ndata, theta, center=rot_center, algorithm='gridrec')

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

    # Write data as stack of TIFs.
    dxchange.write_tiff_stack(rec, fname='/local/dataraid/mark/rec/recon')
Ejemplo n.º 7
0
def reconstruct(h5fname, sino, rot_center, args, blocked_views=None):

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    # Manage the missing angles:
    if blocked_views is not None:
        print("Blocked Views: ", blocked_views)
        proj = np.concatenate((proj[0:blocked_views[0], :, :],
                               proj[blocked_views[1]+1:-1, :, :]), axis=0)
        theta = np.concatenate((theta[0:blocked_views[0]],
                                theta[blocked_views[1]+1: -1]))

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1,
                                   pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    algorithm = args.algorithm
    ncores = args.ncores
    nitr = args.num_iter

    # always add algorithm
    _kwargs = {"algorithm": algorithm}

    # assign number of cores
    _kwargs["ncore"] = ncores

    # don't assign "num_iter" if gridrec or fbp
    if algorithm not in ["fbp", "gridrec"]:
        _kwargs["num_iter"] = nitr

    # Reconstruct object.
    with timemory.util.auto_timer(
        "[tomopy.recon(algorithm='{}')]".format(algorithm)):
        rec = tomopy.recon(proj, theta, **_kwargs)

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

    return rec
Ejemplo n.º 8
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument("top", help="top directory where the tiff images are located: /data/")
    parser.add_argument("start", nargs='?', const=1, type=int, default=1, help="index of the first image: 10001 (default 1)")

    args = parser.parse_args()

    top = args.top
    index_start = int(args.start)

    template = os.listdir(top)[1]

    nfile = len(fnmatch.filter(os.listdir(top), '*.tif'))
    index_end = index_start + nfile
    ind_tomo = range(index_start, index_end)

    fname = top + template

    # Read the tiff raw data.
    rdata = dxchange.read_tiff_stack(fname, ind=ind_tomo)
    particle_bed_reference = particle_bed_location(rdata[0], plot=False)
    print("Particle bed location: ", particle_bed_reference)
    
    # Cut the images to remove the particle bed
    cdata = rdata[:, 0:particle_bed_reference, :]

    # Find the image when the shutter starts to close
    dark_index = shutter_off(rdata)
    print("shutter closes on image: ", dark_index)
    # Set the [start, end] index of the blocked images, flat and dark.
    flat_range = [0, 1]
    data_range = [48, dark_index]
    dark_range = [dark_index, nfile]

    # # for fast testing
    # data_range = [48, dark_index]

    flat = cdata[flat_range[0]:flat_range[1], :, :]
    proj = cdata[data_range[0]:data_range[1], :, :]
    dark = np.zeros((dark_range[1]-dark_range[0], proj.shape[1], proj.shape[2]))  

    # if you want to use the shutter closed images as dark uncomment this:
    #dark = cdata[dark_range[0]:dark_range[1], :, :]  

    ndata = tomopy.normalize(proj, flat, dark)
    ndata = tomopy.normalize_bg(ndata, air=ndata.shape[2]/2.5)
    ndata = tomopy.minus_log(ndata)
    sharpening(ndata)
    slider(ndata)
Ejemplo n.º 9
0
def main(arg):

    fname = '/local/dataraid/elettra/Oak_16bit_slice343_all_repack.h5'
    
    # Read the hdf raw data.
    sino, sflat, sdark, th = dxchange.read_aps_32id(fname)

    slider(sino)
    proj = np.swapaxes(sino,0,1)
    flat = np.swapaxes(sflat,0,1)
    dark = np.swapaxes(sdark,0,1)

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

    print(proj.shape, dark.shape, flat.shape, theta.shape)

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

    # Find rotation center.
    rot_center = 962

    binning = 1
    ndata = tomopy.downsample(ndata, level=int(binning))
    rot_center = rot_center/np.power(2, float(binning))    

    ndata = tomopy.minus_log(ndata)
    
    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(ndata, theta, center=rot_center, algorithm='gridrec')

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

    # Write data as stack of TIFs.
    dxchange.write_tiff_stack(rec, fname='recon_dir/recon')
Ejemplo n.º 10
0
def reconstruct(sname, rot_center, ovlpfind, s_start, s_end):
    fname = dfolder + sname + '.h5'
    print (fname)
    start = s_start  
    end =   s_end
    chunks = 24 
    num_sino = (end - start) // chunks
    for m in range(chunks):
        sino_start = start + num_sino * m
        sino_end = start + num_sino * (m + 1)
        start_read_time = time.time()
        proj, flat, dark, thetat = dxchange.read_aps_2bm(fname, sino=(sino_start, sino_end))
        print('   done read in %0.1f min' % ((time.time() - start_read_time)/60))
        dark = proj[9001:9002]
        flat = proj[0:1]
        proj = proj[1:9000]
        theta = tomopy.angles(proj.shape[0], 0., 360.)
        proj = tomopy.sino_360_to_180(proj, overlap=ovlpfind, rotation='right')
        proj = tomopy.remove_outlier(proj, dif=0.4)
        proj = tomopy.normalize_bg(proj, air=10)
        proj = tomopy.minus_log(proj)
        center = rot_center
        start_ring_time = time.time()
        proj = tomopy.remove_stripe_fw(proj, wname='sym5', sigma=4, pad=False)
        proj = tomopy.remove_stripe_sf(proj, size=3)
        print('   done pre-process in %0.1f min' % ((time.time() - start_ring_time)/60))
        start_phase_time = time.time()
        proj = tomopy.retrieve_phase(proj, pixel_size=detector_pixel_size_x, dist=sample_detector_distance, energy=energy, alpha=alpha, pad=True, ncore=None, nchunk=None)
        print('   done phase retrieval in %0.1f min' % ((time.time() - start_phase_time)/60))
        start_recon_time = time.time()
        rec = tomopy.recon(proj, theta, center=center, algorithm='gridrec', filter_name='ramalk')
        tomopy.circ_mask(rec, axis=0, ratio=0.95)
        print ("Reconstructed", rec.shape)
        dxchange.write_tiff_stack(rec, fname = dfolder + '/' + sname + '/' + sname, overwrite=True, start=sino_start)
        print('   Chunk reconstruction done in %0.1f min' % ((time.time() - start_recon_time)/60))
    print ("Done!")
Ejemplo n.º 11
0
def srxfftomo_correction(datapath,
                         sample1_df_path,
                         sample1_wf1_path,
                         sample1_wf2_path,
                         sample1_proj_path,
                         dfprefix,
                         wf1prefix,
                         wf2prefix,
                         projprefix,
                         save_corrected_tiff=True,
                         save_find_center=True,
                         outpath=None,
                         samplename=None,
                         output_tiff_prefix='',
                         reduce_data=True,
                         datareduction_datatype='float32',
                         datareduction_downsample_factor=1,
                         datareduction_downsample_order=None,
                         correct_stage=True,
                         take_neg_log=True):

    print('getting data')
    df, wf, proj = srxfftomo_getdata(datapath,
                                     sample1_df_path,
                                     sample1_wf1_path,
                                     sample1_wf2_path,
                                     sample1_proj_path,
                                     dfprefix,
                                     wf1prefix,
                                     wf2prefix,
                                     projprefix,
                                     showimg=False)

    print('correcting background')
    proj = srxfftomo_bkg_correction(df, wf, proj)

    if reduce_data is True:
        print('reducing data')
        proj = srxfftomo_data_reduction(
            proj,
            datatype_set=datareduction_datatype,
            downsample_factor=datareduction_downsample_factor,
            downsample_order=datareduction_downsample_order)
        output_tiff_prefix = '_resam_' + str(
            datareduction_downsample_factor) + '_dtypef32'
#                             tomopy.remove_outlier(proj, 400, size=6)
    if correct_stage is True:
        print('correcting stage round out')
        proj = srxfftomo_stage_correction(proj)
        output_tiff_prefix = output_tiff_prefix + '_stgcorr'

    if take_neg_log is True:
        print('taking negative natural log')
        proj = tomopy.minus_log(proj)

        print('    handling special values: negatives, Nan, infinite')
        proj = tomopy.misc.corr.remove_neg(proj, val=0.001)
        proj = tomopy.misc.corr.remove_nan(proj, val=0.001)
        proj[np.where(proj == np.inf)] = 0.001
        output_tiff_prefix = output_tiff_prefix + '_neglog'

    if save_corrected_tiff is True:
        outputfile_tiff = outpath + samplename + '/' + samplename + output_tiff_prefix + '.tiff'
        print('saving corrected data into: ' + outputfile_tiff)
        outdir = os.path.dirname(outputfile_tiff)
        if not os.path.exists(outdir):
            os.makedirs(outdir)
        tifffile.imsave(outputfile_tiff, proj)

    return proj
Ejemplo n.º 12
0
print('loading flat images')
for y in range(0, len(floc)):
    inputPath = '{}{}_{:d}{}'.format(fn, flatextension, floc[y], fileextension)
    flat[y] = dxchange.reader.read_tiff(inputPath, slc=(sinoused, raysused))

print('loading dark images')
for y in range(0, numdrk):
    inputPath = '{}{}_{:d}{}'.format(fn, darkextension, y, fileextension)
    dark[y] = dxchange.reader.read_tiff(inputPath, slc=(sinoused, raysused))

print('normalizing')
tomo = tomo.astype(np.float32)
tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo)

tomopy.minus_log(tomo, out=tomo)

tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')
rec = tomopy.recon(tomo,
                   tomopy.angles(numangles, angle_offset,
                                 angle_offset - angularrange),
                   center=cor + npad,
                   algorithm='gridrec',
                   filter_name='butterworth',
                   filter_par=[.25, 2])
rec = rec[:, npad:-npad, npad:-npad]
rec /= pxsize  # convert reconstructed voxel values from 1/pixel to 1/cm
rec = tomopy.circ_mask(rec, 0)

print('writing recon')
dxchange.write_tiff_stack(rec, fname='rec/' + fn, start=sinoused[0])
    def reconstruct(self):
        self.pushLoad.setEnabled(False)
        self.pushReconstruct.setEnabled(False)
        self.pushReconstruct_all.setEnabled(False)
        self.slice_number.setEnabled(False)
        self.COR.setEnabled(False)
        self.brightness.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.speed_W.setEnabled(False)

        QtWidgets.QApplication.processEvents()
        print('def reconstruct')

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]

        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05    # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!)
        print('extend_FOV ', self.extend_FOV)


        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print(new_list.shape)

        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print(len(center_list))

        transposed_sinos = numpy.zeros((min(self.number_of_used_projections, self.A.shape[0]), 1, self.full_size), dtype=float)
        transposed_sinos[:,0,:] = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:]
        print('transposed_sinos_shape', transposed_sinos.shape)

        extended_sinos = tomopy.misc.morph.pad(transposed_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
        extended_sinos = tomopy.minus_log(extended_sinos)
        extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint
        extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)
        if self.checkBox_phase_2.isChecked() == True:
            extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

        if self.algorithm_list.currentText() == 'FBP_CUDA':
            options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra, options=options)
        else:
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=self.algorithm_list.currentText(),
                                  filter_name=self.filter_list.currentText())

        slices = slices[:,round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2) , round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2)]
        slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)
        original_reconstruction = slices[0, :, :]
        print(numpy.amin(original_reconstruction))
        print(numpy.amax(original_reconstruction))
        self.min.setText(str(numpy.amin(original_reconstruction)))
        self.max.setText(str(numpy.amax(original_reconstruction)))
        print('reconstructions done')


        myarray = (original_reconstruction - numpy.amin(original_reconstruction)) * self.brightness.value() / (numpy.amax(original_reconstruction) - numpy.amin(original_reconstruction))
        myarray = myarray.repeat(2, axis=0).repeat(2, axis=1)
        yourQImage = qimage2ndarray.array2qimage(myarray)
        self.test_reco.setPixmap(QPixmap(yourQImage))

        self.pushLoad.setEnabled(True)
        self.pushReconstruct.setEnabled(True)
        self.pushReconstruct_all.setEnabled(True)
        self.slice_number.setEnabled(True)
        self.COR.setEnabled(True)
        self.Offset_Angle.setEnabled(True)
        self.brightness.setEnabled(True)
        self.speed_W.setEnabled(True)
        print('Done!')
Ejemplo n.º 14
0
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm, binning):
    
    data_shape = get_dx_dims(h5fname, 'data')
    print(data_shape)
    ssino = int(data_shape[1] * nsino)
    rot_center+=data_shape[2]//4
    center_range = (rot_center-center_search_width, rot_center+center_search_width, 0.5)
    #print(sino,ssino, center_range)
    #print(center_range[0], center_range[1], center_range[2])

    # Select sinogram range to reconstruct
    sino = None
        
    start = ssino
    end = start + 1
    sino = (start, end)

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)
        
    # Flat-field correction of raw data.
    data = tomopy.normalize(proj, flat, dark, cutoff=1.4)

    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=2,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=150)

    # remove stripes
    # data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)


    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    # padding 
    N = data.shape[2]
    data_pad = np.zeros([data.shape[0],data.shape[1],3*N//2],dtype = "float32")
    data_pad[:,:,N//4:5*N//4] = data
    data_pad[:,:,0:N//4] = np.tile(np.reshape(data[:,:,0],[data.shape[0],data.shape[1],1]),(1,1,N//4))
    data_pad[:,:,5*N//4:] = np.tile(np.reshape(data[:,:,-1],[data.shape[0],data.shape[1],1]),(1,1,N//4))

    data = data_pad
  
 


    stack = np.empty((len(np.arange(*center_range)), data.shape[0], data.shape[2]))
  
    print(stack.shape)
    print(data.shape)




    index = 0
    for axis in np.arange(*center_range):
        stack[index] = data[:, 0, :]
        index = index + 1

     # Reconstruct the same slice with a range of centers.
    rec = tomopy.recon(stack, theta, center=np.arange(*center_range), sinogram_order=True, algorithm='gridrec', filter_name='parzen', nchunk=1)

    rec = rec[:,N//4:5*N//4,N//4:5*N//4]

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

    index = 0
    # Save images to a temporary folder.
    fname = os.path.dirname(h5fname) + '/' + 'try_rec/' + 'recon_' + os.path.splitext(os.path.basename(h5fname))[0]    
    for axis in np.arange(*center_range):
        rfname = fname + '_' + str('{0:.2f}'.format(axis-N//4) + '.tiff')
        dxchange.write_tiff(rec[index], fname=rfname, overwrite=True)
        index = index + 1

    print("Reconstructions: ", fname)
Ejemplo n.º 15
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
    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))
Ejemplo n.º 16
0
#theta = tomopy.angles(691, -78, 96)
if debug:
    print('## Debug: after reading data:')
    print('\n** Shape of the data:'+str(np.shape(prj)))
    print('** Shape of theta:'+str(np.shape(theta)))
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))

prj = tomopy.normalize(prj, flat, dark)
print('\n** Flat field correction done!')

if debug:
    print('## Debug: after normalization:')
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))

prj = tomopy.minus_log(prj)
print('\n** minus log applied!')

if debug:
    print('## Debug: after minus log:')
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))

prj = tomopy.misc.corr.remove_neg(prj, val=0.001)
prj = tomopy.misc.corr.remove_nan(prj, val=0.001)
prj[np.where(prj == np.inf)] = 0.001

if debug:
    print('## Debug: after cleaning bad values:')
    print('\n** Min and max val in prj before recon: %0.5f, %0.3f'  % (np.min(prj), np.max(prj)))

prj = tomopy.remove_stripe_ti(prj,4)
Ejemplo n.º 17
0
            # remove stripes
            proj = tomopy.remove_stripe_fw(proj,
                                           level=5,
                                           wname='sym16',
                                           sigma=1,
                                           pad=True)

            # phase retrieval
            #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-3,pad=True)

            # Find rotation center
            #rot_center = tomopy.find_center(proj, theta, init=rot_center, ind=start, tol=0.5)
            print(h5name, 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.
            fname = top + 'full_rec/' + prefix + h5name + '/recon'
            ##fname = top +'slice_rec/' + prefix + h5name + '_recon'
            print("Rec: ", fname)
            dxchange.write_tiff_stack(rec, fname=fname)
Ejemplo n.º 18
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "top", help="top directory where the tiff images are located: /data/")
    parser.add_argument("start",
                        nargs='?',
                        const=1,
                        type=int,
                        default=1,
                        help="index of the first image: 1000 (default 1)")

    args = parser.parse_args()

    top = args.top
    index_start = int(args.start)

    template = os.listdir(top)[0]

    nfile = len(fnmatch.filter(os.listdir(top), '*.tif'))
    index_end = index_start + nfile
    ind_tomo = range(index_start, index_end)

    fname = top + template

    print(nfile, index_start, index_end, fname)

    # Select the sinogram range to reconstruct.
    start = 0
    end = 512
    sino = (start, end)

    # Read the tiff raw data.
    ndata = dxchange.read_tiff_stack(fname, ind=ind_tomo, slc=(sino, None))

    print(ndata.shape)
    binning = 8
    ndata = tomopy.downsample(ndata, level=binning, axis=1)
    print(ndata.shape)

    # Normalize to 1 using the air counts
    ndata = tomopy.normalize_bg(ndata, air=5)

    ## slider(ndata)

    # Set data collection angles as equally spaced between 0-180 degrees.
    theta = tomopy.angles(ndata.shape[0])

    rot_center = 960
    print("Center of rotation: ", rot_center)

    ndata = tomopy.minus_log(ndata)

    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(ndata, theta, center=rot_center, algorithm='gridrec')

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

    # Write data as stack of TIFs.
    dxchange.write_tiff_stack(rec, fname='/local/dataraid/mark/rec/recon')
Ejemplo n.º 19
0
def transform(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.
    """

    import numpy as np
    import tomopy

    # Get the current volume as a numpy array.
    array = dataset.active_scalars

    dark = dataset.dark
    white = dataset.white
    angles = dataset.tilt_angles
    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 = dataset.create_child_dataset()
    child.active_scalars = array

    return_values = {}
    return_values['reconstruction'] = child
    return return_values
Ejemplo n.º 20
0
    ## Set path (without file suffix) to the micro-CT data to reconstruct.
    fname = 'data_dir/sample'

    ## Import Data.
    proj, flat, dark, theta = dx.exchange.read_aps_13bm(fname, format = 'netcdf4')

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

    ## Additional flat-field correction of raw data to negate need to mask.
    proj = tp.normalize_bg(proj, air = 10)

    ## Set rotation center.
    rot_center = tp.find_center_vo(proj)
    print('Center of rotation: ', rot_center)

    tp.minus_log(proj, out = proj)

    # Reconstruct object using Gridrec algorith.
    rec = tp.recon(proj, theta, center = rot_center, sinogram_order = False, algorithm = 'gridrec', filter_name = 'hann')
    rec = tp.remove_nan(rec)

    ## Writing data in netCDF3 .volume.
    ncfile = Dataset('filename.volume', 'w', format = 'NETCDF3_64BIT', clobber = True)
    NX = ncfile.createDimension('NX', rec.shape[2])
    NY = ncfile.createDimension('NY', rec.shape[1])
    NZ = ncfile.createDimension('NZ', rec.shape[0])
    volume = ncfile.createVariable('VOLUME', 'f4', ('NZ','NY','NX'))
    volume[:] = rec
    ncfile.close()
def reconstruct(filename,
                inputPath="",
                outputPath="",
                COR=COR,
                doOutliers=doOutliers,
                outlier_diff=outlier_diff,
                outlier_size=outlier_size,
                doFWringremoval=doFWringremoval,
                ringSigma=ringSigma,
                ringLevel=ringLevel,
                ringWavelet=ringWavelet,
                pad_sino=pad_sino,
                doPhaseRetrieval=doPhaseRetrieval,
                propagation_dist=propagation_dist,
                kev=kev,
                alphaReg=alphaReg,
                butterworthpars=butterworthpars,
                doPolarRing=doPolarRing,
                Rarc=Rarc,
                Rmaxwidth=Rmaxwidth,
                Rtmax=Rtmax,
                Rthr=Rthr,
                Rtmin=Rtmin,
                useAutoCOR=useAutoCOR,
                use360to180=use360to180,
                num_substacks=num_substacks,
                recon_slice=recon_slice):

    # Convert filename to list type if only one file name is given
    if type(filename) != list:
        filename = [filename]

    # If useAutoCor == true, a list of COR will be automatically calculated for all files
    # If a list of COR is given, only entries with boolean False will use automatic COR calculation
    if useAutoCOR == True or (len(COR) != len(filename)):
        logging.info('using auto COR for all input files')
        COR = [False] * len(filename)

    for x in range(len(filename)):
        logging.info('opening data set, checking metadata')

        fdata, gdata = read_als_832h5_metadata(inputPath[x] + filename[x] +
                                               '.h5')
        pxsize = float(
            gdata['pxsize']
        ) / 10.0  # convert from metadata (mm) to this script (cm)
        numslices = int(gdata['nslices'])

        # recon_slice == True, only center slice will be reconstructed
        # if integer is given, a specific
        if recon_slice != False:
            if (type(recon_slice) == int) and (recon_slice <= numslices):
                sinorange[recon_slice - 1, recon_slice]
            else:
                sinorange = [numslices // 2 - 1, numslices // 2]
        else:
            sinorange = [0, numslices]

        # Calculate number of substacks (chunks)
        substacks = num_substacks  #(sinorange[1]-sinorange[0]-1)//num_sino_per_substack+1

        if (sinorange[1] - sinorange[0]) >= substacks:
            num_sino_per_substack = (sinorange[1] -
                                     sinorange[0]) // num_substacks
        else:
            num_sino_per_substack = 1

        firstcor, lastcor = 0, int(gdata['nangles']) - 1
        projs, flat, dark, floc = dxchange.read_als_832h5(
            inputPath[x] + filename[x] + '.h5', ind_tomo=(firstcor, lastcor))
        projs = tomopy.normalize_nf(projs, flat, dark, floc)
        autocor = tomopy.find_center_pc(projs[0], projs[1], tol=0.25)

        if (type(COR[x]) == bool) or (COR[x] < 0) or (COR[x] == 'auto'):
            firstcor, lastcor = 0, int(gdata['nangles']) - 1
            projs, flat, dark, floc = dxchange.read_als_832h5(
                inputPath[x] + filename[x] + '.h5',
                ind_tomo=(firstcor, lastcor))
            projs = tomopy.normalize_nf(projs, flat, dark, floc)
            cor = tomopy.find_center_pc(projs[0], projs[1], tol=0.25)
        else:
            cor = COR[x]

        logging.info(
            'Dataset %s, has %d total slices, reconstructing slices %d through %d in %d substack(s), using COR: %f',
            filename[x], int(gdata['nslices']), sinorange[0], sinorange[1] - 1,
            substacks, cor)

        for y in range(0, substacks):
            logging.info('Starting dataset %s (%d of %d), substack %d of %d',
                         filename[x], x + 1, len(filename), y + 1, substacks)

            logging.info('Reading sinograms...')
            projs, flat, dark, floc = dxchange.read_als_832h5(
                inputPath[x] + filename[x] + '.h5',
                sino=(sinorange[0] + y * num_sino_per_substack,
                      sinorange[0] + (y + 1) * num_sino_per_substack, 1))

            logging.info(
                'Doing remove outliers, norm (nearest flats), and -log...')
            if doOutliers:
                projs = tomopy.remove_outlier(projs,
                                              outlier_diff,
                                              size=outlier_size,
                                              axis=0)
                flat = tomopy.remove_outlier(flat,
                                             outlier_diff,
                                             size=outlier_size,
                                             axis=0)
            tomo = tomopy.normalize_nf(projs, flat, dark, floc)
            tomo = tomopy.minus_log(tomo, out=tomo)  # in place logarithm

            # Use padding to remove halo in reconstruction if present
            if pad_sino:
                npad = int(
                    np.ceil(tomo.shape[2] * np.sqrt(2)) - tomo.shape[2]) // 2
                tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')
                cor_rec = cor + npad  # account for padding
            else:
                cor_rec = cor

            if doFWringremoval:
                logging.info('Doing ring (Fourier-wavelet) function...')
                tomo = tomopy.remove_stripe_fw(tomo,
                                               sigma=ringSigma,
                                               level=ringLevel,
                                               pad=True,
                                               wname=ringWavelet)

            if doPhaseRetrieval:
                logging.info('Doing Phase retrieval...')
                #tomo = tomopy.retrieve_phase(tomo, pixel_size=pxsize, dist=propagation_dist, energy=kev, alpha=alphaReg, pad=True)
                tomo = tomopy.retrieve_phase(tomo,
                                             pixel_size=pxsize,
                                             dist=propagation_dist,
                                             energy=kev,
                                             alpha=alphaReg,
                                             pad=True)

            logging.info(
                'Doing recon (gridrec) function and scaling/masking, with cor %f...',
                cor_rec)
            rec = tomopy.recon(tomo,
                               tomopy.angles(tomo.shape[0], 270, 90),
                               center=cor_rec,
                               algorithm='gridrec',
                               filter_name='butterworth',
                               filter_par=butterworthpars)
            #rec = tomopy.recon(tomo, tomopy.angles(tomo.shape[0], 180+angularrange/2, 180-angularrange/2), center=cor_rec, algorithm='gridrec', filter_name='butterworth', filter_par=butterworthpars)
            rec /= pxsize  # intensity values in cm^-1
            if pad_sino:
                rec = tomopy.circ_mask(rec[:, npad:-npad, npad:-npad], 0)
            else:
                rec = tomopy.circ_mask(rec, 0, ratio=1.0, val=0.0)

            if doPolarRing:
                logging.info('Doing ring (polar mean filter) function...')
                rec = tomopy.remove_ring(rec,
                                         theta_min=Rarc,
                                         rwidth=Rmaxwidth,
                                         thresh_max=Rtmax,
                                         thresh=Rthr,
                                         thresh_min=Rtmin)

            logging.info('Writing reconstruction slices to %s', filename[x])
            #dxchange.write_tiff_stack(rec, fname=outputPath+'alpha'+str(alphaReg)+'/rec'+filename[x]+'/rec'+filename[x], start=sinorange[0]+y*num_sino_per_substack)
            dxchange.write_tiff_stack(rec,
                                      fname=outputPath + 'recon_' +
                                      filename[x] + '/recon_' + filename[x],
                                      start=sinorange[0] +
                                      y * num_sino_per_substack)
        logging.info('Reconstruction Complete: ' + filename[x])
Ejemplo n.º 22
0
sino_start = 512
sino_end = 1536 + 512

ptheta = 720  # chunk size for reading
binning = 0

for k in range(int(np.ceil(ntheta / ptheta))):
    print(k)
    prj, flat, dark, theta = dxchange.read_aps_32id(
        file_name,
        sino=(sino_start, sino_end),
        proj=(ptheta * k, min(ntheta, ptheta * (k + 1))))

    prj = tomopy.normalize(prj, flat, dark)
    prj[prj <= 0] = 1
    prj = tomopy.minus_log(prj)
    # prj = tomopy.remove_stripe_fw(
    # prj, level=7, wname='sym16', sigma=1, pad=True)
    # prj = tomopy.remove_stripe_ti(prj,2)
    prj = tomopy.downsample(prj, level=binning)
    prj = tomopy.downsample(prj, level=binning, axis=1)

    # save data
    dxchange.write_tiff_stack(prj[:, :, 246:-246],
                              f'{file_name[:-3]}/data/d',
                              start=ptheta * k,
                              overwrite=True)

# save theta
np.save(file_name[:-3] + '/data/theta', theta)
print(theta)
Ejemplo n.º 23
0
    ## Import Data.
    proj, flat, dark, theta = dx.exchange.read_aps_13bm(fname,
                                                        format='netcdf4')

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

    ## Additional flat-field correction of raw data to negate need to mask.
    proj = tp.normalize_bg(proj, air=10)

    ## Set rotation center.
    rot_center = tp.find_center_vo(proj)
    print('Center of rotation: ', rot_center)

    tp.minus_log(proj, out=proj)

    # Reconstruct object using Gridrec algorith.
    rec = tp.recon(proj,
                   theta,
                   center=rot_center,
                   sinogram_order=False,
                   algorithm='gridrec',
                   filter_name='hann')
    rec = tp.remove_nan(rec)

    ## Writing data in netCDF3 .volume.
    ncfile = Dataset('filename.volume',
                     'w',
                     format='NETCDF3_64BIT',
                     clobber=True)
Ejemplo n.º 24
0
    # Select the sinogram range to reconstruct.
    start = 290
    end = 294

    # Read the APS 5-BM raw data
    proj, flat, dark = dxchange.read_aps_5bm(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)

    # remove stripes
    proj = tomopy.remove_stripe_fw(proj,level=7,wname='sym16',sigma=1,pad=True)

    # Set rotation center.
    rot_center = proj.shape[2] / 2.0
    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')
Ejemplo n.º 25
0
	inputPath = '{}_{:d}{}'.format(fn,y,fileextension)
	tomo[y] = dxchange.reader.read_tiff(inputPath,slc = (sinoused, raysused))

print('loading flat images')
for y in range(0,len(floc)):
	inputPath = '{}{}_{:d}{}'.format(fn,flatextension,floc[y],fileextension)
	flat[y] = dxchange.reader.read_tiff(inputPath,slc = (sinoused, raysused))

print('loading dark images')
for y in range(0,numdrk):
	inputPath = '{}{}_{:d}{}'.format(fn,darkextension,y,fileextension)
	dark[y] = dxchange.reader.read_tiff(inputPath,slc = (sinoused, raysused))	
	
print('normalizing')
tomo = tomo.astype(np.float32)
tomopy.normalize_nf(tomo, flat, dark, floc, out=tomo)

tomopy.minus_log(tomo, out=tomo)

tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')
rec = tomopy.recon(tomo, tomopy.angles(numangles, angle_offset, angle_offset-angularrange), center=cor+npad, algorithm='gridrec', filter_name='butterworth', filter_par=[.25, 2])
rec = rec[:, npad:-npad, npad:-npad]
rec /= pxsize  # convert reconstructed voxel values from 1/pixel to 1/cm
rec = tomopy.circ_mask(rec, 0)



print('writing recon')
dxchange.write_tiff_stack(rec, fname='rec/'+fn, start=sinoused[0])

    def reconstruct(self):
        self.pushReconstruct.setEnabled(False)
        self.pushAnalyze.setEnabled(False)
        self.scan_range.setEnabled(False)
        self.pushCorrect.setEnabled(False)
        self.filter_list.setEnabled(False)
        self.savgol_window.setEnabled(False)
        self.savgol_poly.setEnabled(False)

        QtWidgets.QApplication.processEvents()
        print('def reconstruct')

        if self.max_theta < 270:
            new_list = numpy.arange(self.number_of_projections
                                    ) * math.pi / self.number_of_projections
            print('180 Deg Scan detected')
        else:
            new_list = numpy.arange(
                self.number_of_projections
            ) * 2 * math.pi / self.number_of_projections
            print('360 Deg Scan detected')

        center_list = [self.COR + round(0.5 * self.full_size)
                       ] * (self.number_of_projections)

        sinos = numpy.zeros((2, self.full_size, self.number_of_projections),
                            dtype=float)
        sinos[0, :, :] = self.sino
        sinos[1, :, :] = self.corrected_sinogram
        transposed_sinos = numpy.transpose(sinos, axes=[2, 0, 1])
        print('transposed_sinos_shape', transposed_sinos.shape)

        extended_sinos = tomopy.misc.morph.pad(transposed_sinos,
                                               axis=2,
                                               npad=round(0.5 *
                                                          self.full_size),
                                               mode='edge')
        extended_sinos = tomopy.minus_log(extended_sinos)
        extended_sinos = (extended_sinos + 9.68) * 1000

        slices = tomopy.recon(extended_sinos,
                              new_list,
                              center=center_list,
                              algorithm='gridrec',
                              filter_name='shepp')
        slices = slices[:,
                        round(0.5 *
                              self.full_size):-round(0.5 * self.full_size),
                        round(0.5 *
                              self.full_size):-round(0.5 * self.full_size)]
        slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)

        slices = (slices + 100) * 320
        slices = numpy.clip(slices, 1, 65534)
        slices = slices.astype(numpy.uint16)

        self.corrected_reconstruction = slices[1, :, :]
        self.original_reconstruction = slices[0, :, :]
        print('reconstructions done')

        if os.path.isdir(self.path_out_corr +
                         '/Reconstruction_comparison') is False:
            os.mkdir(self.path_out_corr + '/Reconstruction_comparison')
            print('creating path_out_corr', '/Reconstruction_comparison',
                  self.path_out_corr, '/Reconstruction_comparison')

        img = Image.fromarray(self.corrected_reconstruction)
        self.filename_out3 = self.path_out_corr + '/Reconstruction_comparison' + self.namepart + 'reconstruction_corrected' + '.tif'
        img.save(self.filename_out3)
        img = Image.fromarray(self.original_reconstruction)
        self.filename_out4 = self.path_out_corr + '/Reconstruction_comparison' + self.namepart + 'reconstruction_original' + '.tif'
        img.save(self.filename_out4)
        print('reconstructions saved')

        myarray = (self.corrected_reconstruction -
                   31000) * 0.005 * self.brightness.value(
                   )  # * contrast - (contrast - 128)  # 2048 - 1920
        #myarray = (ima16 - 31000) * 0.005 * self.BrightnessSlider.value()
        myarray = myarray.repeat(2, axis=0).repeat(2, axis=1)
        yourQImage = qimage2ndarray.array2qimage(myarray)
        self.corrected_reco.setPixmap(QPixmap(yourQImage))

        myarray = (self.original_reconstruction -
                   31000) * 0.005 * self.brightness.value()
        #myarray = self.original_reconstruction * self.brightness.value()  # * contrast - (contrast - 128)  # 2048 - 1920
        myarray = myarray.repeat(2, axis=0).repeat(2, axis=1)
        yourQImage = qimage2ndarray.array2qimage(myarray)
        self.original_reco.setPixmap(QPixmap(yourQImage))

        self.tabWidget.setCurrentIndex(4)
        self.pushReconstruct.setEnabled(True)
        self.pushAnalyze.setEnabled(True)
        self.scan_range.setEnabled(True)
        self.pushCorrect.setEnabled(True)
        self.filter_list.setEnabled(True)
        self.savgol_window.setEnabled(True)
        self.savgol_poly.setEnabled(True)
        self.pushApplyVolume.setEnabled(True)
        print('reconstructions displayed')
    def reconstruct_all(self):
        self.pushLoad.setEnabled(False)
        self.pushReconstruct.setEnabled(False)
        self.slice_number.setEnabled(False)
        self.COR.setEnabled(False)
        self.brightness.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.speed_W.setEnabled(False)

        QtWidgets.QApplication.processEvents()
        print('def reconstruct complete volume')

        self.path_out_reconstructed_ask = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select folder for reconstructions.', self.path_klick)
        self.path_out_reconstructed_full = self.path_out_reconstructed_ask + '/'+ self.folder_name
        os.mkdir(self.path_out_reconstructed_full)

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]
        print('X-size', self.A.shape[2])
        print('Nr of projections', self.A.shape[0])
        print('Nr of slices', self.A.shape[1])

        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05    # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!)
        print('extend_FOV ', self.extend_FOV)


        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print(new_list.shape)

        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print(len(center_list))

        file_name_parameter = self.path_out_reconstructed_full + '/parameter.csv'
        with open(file_name_parameter, mode = 'w', newline='') as parameter_file:
            csv_writer = csv.writer(parameter_file, delimiter = ' ', quotechar=' ')
            csv_writer.writerow(['Path input                    ', self.path_in,' '])
            csv_writer.writerow(['Path output                   ', self.path_out_reconstructed_full,' '])
            csv_writer.writerow(['Number of used projections    ', str(self.number_of_used_projections),' '])
            csv_writer.writerow(['Center of rotation            ', str(self.COR.value()), ' '])
            csv_writer.writerow(['Dark field value              ', str(self.spinBox_DF.value()),' '])
            csv_writer.writerow(['Ring handling radius          ', str(self.spinBox_ringradius.value()),' '])
            csv_writer.writerow(['Rotation offset               ', str(self.Offset_Angle.value()), ' '])
            csv_writer.writerow(['Rotation speed [°/image]      ', str(self.speed_W.value()), ' '])
            csv_writer.writerow(['Phase retrieval               ', str(self.checkBox_phase_2.isChecked()), ' '])
            csv_writer.writerow(['Phase retrieval distance      ', str(self.doubleSpinBox_distance_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval energy        ', str(self.doubleSpinBox_Energy_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval alpha         ', str(self.doubleSpinBox_alpha_2.value()), ' '])
            csv_writer.writerow(['16-bit                        ', str(self.radioButton_16bit_integer.isChecked()), ' '])
            csv_writer.writerow(['16-bit integer low            ', str(self.int_low.value()), ' '])
            csv_writer.writerow(['16-bit integer high           ', str(self.int_high.value()), ' '])
            csv_writer.writerow(['Reconstruction algorithm      ', self.algorithm_list.currentText(), ' '])
            csv_writer.writerow(['Reconstruction filter         ', self.filter_list.currentText(), ' '])
            csv_writer.writerow(['Software Version              ', version, ' '])
            csv_writer.writerow(['binning                       ', '1x1x1', ' '])


        i = 0
        while (i < math.ceil(self.A.shape[1] / self.block_size)):

            print('Reconstructing block', i + 1, 'of', math.ceil(self.A.shape[1] / self.block_size))

            extended_sinos = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :]
            extended_sinos = tomopy.misc.morph.pad(extended_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
            extended_sinos = tomopy.minus_log(extended_sinos)
            extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint

            extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)
            if self.checkBox_phase_2.isChecked() == True:
                extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

            if self.algorithm_list.currentText() == 'FBP_CUDA':
                options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
                slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra,
                                      options=options)
            else:
                slices = tomopy.recon(extended_sinos, new_list, center=center_list,
                                      algorithm=self.algorithm_list.currentText(),
                                      filter_name=self.filter_list.currentText())

            slices = slices[:, round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2), round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2)]
            slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)

            if self.radioButton_16bit_integer.isChecked() == True:
                ima3 = 65535 * (slices - self.int_low.value()) / (self.int_high.value() - self.int_low.value())
                ima3 = numpy.clip(ima3, 1, 65534)
                slices_save = ima3.astype(numpy.uint16)

            if self.radioButton_32bit_float.isChecked() == True:
                slices_save = slices

            print('Reconstructed Volume is', slices_save.shape)

            a = 1
            while (a < self.block_size + 1) and (a < slices_save.shape[0] + 1):

                self.progressBar.setValue((a + (i * self.block_size)) * 100 / self.A.shape[1])

                filename2 = self.path_out_reconstructed_full + self.namepart + str(a + self.crop_offset + i * self.block_size).zfill(4) + self.filetype
                print('Writing Reconstructed Slices:', filename2)
                slice_save = slices_save[a - 1, :, :]
                img = Image.fromarray(slice_save)
                img.save(filename2)
                QtCore.QCoreApplication.processEvents()
                time.sleep(0.02)

                a = a + 1

            i = i + 1

        self.pushLoad.setEnabled(True)
        self.pushReconstruct.setEnabled(True)
        self.slice_number.setEnabled(True)
        self.COR.setEnabled(True)
        self.brightness.setEnabled(True)
        self.Offset_Angle.setEnabled(True)
        self.speed_W.setEnabled(True)
        print('Done!')
Ejemplo n.º 28
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 31      # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 1.17e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 65    # Energy of incident wave in keV
    # used pink beam

    alpha = 4*1e-4                       # Phase retrieval coeff.
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 2-BM raw data.
    # DIMAX saves 3 files: proj, flat, dark
    # when loading the data set select the proj file (larger size)

    fname = os.path.splitext(h5fname)[0]    
 
    fbase = fname.rsplit('_', 1)[0]
    fnum = fname.rsplit('_', 1)[1]
    fext = os.path.splitext(h5fname)[1]  

    fnum_flat = str("%4.4d" % (int(fnum)+1))
    fnum_dark = str("%4.4d" % (int(fnum)+2))

    fnproj = fbase + '_' + fnum + fext
    fnflat = fbase + '_' + fnum_flat + fext
    fndark = fbase + '_' + fnum_dark + fext
    
    print('proj', fnproj)
    print('flat', fnflat)
    print('dark', fndark)
    # Read APS 2-BM DIMAX raw data.
    proj, dum, dum2, theta = dxchange.read_aps_32id(fnproj, sino=sino)
    dum3, flat, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino)
    #flat, dum3, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino)          
    dum6, dum7, dark, dum8 = dxchange.read_aps_32id(fndark, sino=sino)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)        
    
    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    # padding 
    N = data.shape[2]
    data_pad = np.zeros([data.shape[0],data.shape[1],3*N//2],dtype = "float32")
    data_pad[:,:,N//4:5*N//4] = data
    data_pad[:,:,0:N//4] = np.tile(np.reshape(data[:,:,0],[data.shape[0],data.shape[1],1]),(1,1,N//4))
    data_pad[:,:,5*N//4:] = np.tile(np.reshape(data[:,:,-1],[data.shape[0],data.shape[1],1]),(1,1,N//4))

    data = data_pad
    rot_center = rot_center+N//4

    nframes = 8 
    nproj = 1500
    theta = np.linspace(0, np.pi*nframes, nproj*nframes, endpoint=False)
    rec = np.zeros(
            (nframes, data.shape[1], data.shape[2], data.shape[2]), dtype='float32')
    for time_frame in range(0, nframes):
        rec0 = tomopy.recon(data[time_frame*nproj:(time_frame+1)*nproj], theta[time_frame*nproj:(
               time_frame+1)*nproj], center=rot_center, algorithm='gridrec')
        # Mask each reconstructed slice with a circle.
        rec[time_frame] = tomopy.circ_mask(rec0, axis=0, ratio=0.95)
    rec = rec[:,:,N//4:5*N//4,N//4:5*N//4]

        
    print("Algorithm: ", algorithm)
    
    return rec
Ejemplo n.º 29
0
Archivo: rec.py Proyecto: tomopy/tomopy
def reconstruct(h5fname, sino, rot_center, args, blocked_views=None):

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    # Manage the missing angles:
    if blocked_views is not None:
        print("Blocked Views: ", blocked_views)
        proj = np.concatenate((proj[0:blocked_views[0], :, :],
                               proj[blocked_views[1]+1:-1, :, :]), axis=0)
        theta = np.concatenate((theta[0:blocked_views[0]],
                                theta[blocked_views[1]+1: -1]))

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1,
                                   pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    algorithm = args.algorithm
    ncores = args.ncores
    nitr = args.num_iter

    # always add algorithm
    _kwargs = {"algorithm": algorithm}

    # assign number of cores
    _kwargs["ncore"] = ncores

    # use the accelerated version
    if algorithm in ["mlem", "sirt"]:
        _kwargs["accelerated"] = True

    # don't assign "num_iter" if gridrec or fbp
    if algorithm not in ["fbp", "gridrec"]:
        _kwargs["num_iter"] = nitr

    sname = os.path.join(args.output_dir, 'proj_{}'.format(args.algorithm))
    print(proj.shape)
    tmp = np.zeros((proj.shape[0], proj.shape[2]))
    tmp[:,:] = proj[:,0,:]
    output_image(tmp, sname + "." + args.format)

    # Reconstruct object.
    with timemory.util.auto_timer(
        "[tomopy.recon(algorithm='{}')]".format(algorithm)):
        print("Starting reconstruction with kwargs={}...".format(_kwargs))
        rec = tomopy.recon(data, theta, **_kwargs)
    print("Completed reconstruction...")

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

    obj = np.zeros(rec.shape, dtype=rec.dtype)
    label = "{} @ {}".format(algorithm.upper(), h5fname)
    quantify_difference(label, obj, rec)

    return rec
			
		if useNormalize_nf:
			logging.info('Doing normalize (nearest flats)')
			tomo = tomopy.normalize_nf(projs, flat, dark, floc)
		else:
			logging.info('Doing normalize')
			tomo = tomopy.normalize(projs, flat, dark)
		
		
		#sinofilenametowrite = odirectory+'/rec'+iname[x]+'/'+iname[x]+'sino'
		#dxchange.write_tiff_stack(tomo, fname=sinofilenametowrite, start=sinorange[0]+y*num_sino_per_chunk,axis=1)
		projs = None
		flat = None
					
		logging.info('Doing -log')
		tomo = tomopy.minus_log(np.maximum(tomo,0.000000000001), out=tomo) # in place logarithm 
		
		angularrange = float(gdata['arange'])
		logging.info('angular range: %f', angularrange)


	
		# Use padding to remove halo in reconstruction if present
		if pad_sino:
			npad = int(np.ceil(tomo.shape[2] * np.sqrt(2)) - tomo.shape[2])//2
			tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')
			cor_rec = cor + npad # account for padding
		else:
			cor_rec = cor
	
Ejemplo n.º 31
0
def fast_tomo_recon(argv):
    """
    Reconstruct subset slices (sinograms) equally spaced within tomographic
    dataset
    """

    logger = logging.getLogger("fast_tomopy.fast_tomo_recon")

    # Parse arguments passed to function
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input", type=str, help="path to input raw " "dataset", required=True)
    parser.add_argument(
        "-o",
        "--output-file",
        type=str,
        help="full path to h5 output " "file",
        default=os.path.join(os.getcwd(), "fast-tomopy.h5"),
    )
    parser.add_argument("-sn", "--sino-num", type=int, help="Number of slices " "to reconstruct", default=5)
    parser.add_argument(
        "-a",
        "--algorithm",
        type=str,
        help="Reconstruction" " algorithm",
        default="gridrec",
        choices=[
            "art",
            "bart",
            "fbp",
            "gridrec",
            "mlem",
            "ospml_hybrid",
            "ospml_quad",
            "pml_hybrid",
            "pml_quad",
            "sirt",
        ],
    )
    parser.add_argument("-c", "--center", type=float, help="Center of rotation", default=None)
    parser.add_argument(
        "-fn",
        "--filter-name",
        type=str,
        help="Name of filter" " used for reconstruction",
        choices=["none", "shepp", "cosine", "hann", "hamming", "ramlak", "parzen", "butterworth"],
        default="butterworth",
    )
    parser.add_argument(
        "-rr",
        "--ring-remove",
        type=str,
        help="Ring removal " "method",
        choices=["Octopus", "Tomopy-FW", "Tomopy-T"],
        default="Tomopy-T",
    )
    parser.add_argument("-lf", "--log-file", type=str, help="log file name", default="fast-tomopy.log")

    args = parser.parse_args()

    fh = logging.FileHandler(args.log_file)
    fh.setLevel(logging.INFO)
    fh.setFormatter(formatter)
    logger.addHandler(fh)

    if os.path.isdir(os.path.dirname(args.output_file)) is False:
        raise IOError(2, "Directory of output file does not exist", args.output_file)

    # Read file metadata
    logger.info("Reading input file metadata")
    fdata, gdata = read_als_832h5_metadata(args.input)
    proj_total = int(gdata["nangles"])
    last = proj_total - 1
    sino_total = int(gdata["nslices"])
    ray_total = int(gdata["nrays"])
    px_size = float(gdata["pxsize"]) / 10  # cm

    # Set parameters for sinograms to read
    step = sino_total // (args.sino_num + 2)
    start = step
    end = step * (args.sino_num + 1)
    sino = (start, end, step)

    # Read full first and last projection to determine center of rotation
    if args.center is None:
        logger.info("Reading full first and last projection for COR")
        first_last, flats, darks = dx.read_als_832h5(args.input, ind_tomo=(0, last))
        first_last = tomopy.normalize(first_last, flats, darks)
        args.center = tomopy.find_center_pc(first_last[0, :, :], first_last[1, :, :], tol=0.1)
        logger.info("Detected center: %f", args.center)

    # Read and normalize raw sinograms
    logger.info("Reading raw data")
    tomo, flats, darks = dx.read_als_832h5(args.input, sino=sino)
    logger.info("Normalizing raw data")
    tomo = tomopy.normalize(tomo, flats, darks)
    tomo = tomopy.minus_log(tomo)

    # Remove stripes from sinograms (remove rings)
    logger.info("Preprocessing normalized data")
    if args.ring_remove == "Tomopy-FW":
        logger.info("Removing stripes from sinograms with %s", args.ring_remove)
        tomo = tomopy.remove_stripe_fw(tomo)
    elif args.ring_remove == "Tomopy-T":
        logger.info("Removing stripes from sinograms with %s", args.ring_remove)
        tomo = tomopy.remove_stripe_ti(tomo)

    # Pad sinograms with edge values
    npad = int(np.ceil(ray_total * np.sqrt(2)) - ray_total) // 2
    tomo = tomopy.pad(tomo, 2, npad=npad, mode="edge")
    args.center += npad  # account for padding

    filter_name = np.array(args.filter_name, dtype=(str, 16))
    theta = tomopy.angles(proj_total, 270, 90)

    logger.info("Reconstructing normalized data")
    # Reconstruct sinograms
    # rec = tomopy.minus_log(tomo, out=tomo)
    rec = tomopy.recon(tomo, theta, center=args.center, algorithm=args.algorithm, filter_name=filter_name)
    rec = tomopy.circ_mask(rec[:, npad:-npad, npad:-npad], 0)
    rec = rec / px_size

    # Remove rings from reconstruction
    if args.ring_remove == "Octopus":
        logger.info("Removing rings from reconstructions with %s", args.ring_remove)
        thresh = float(gdata["ring_threshold"])
        thresh_max = float(gdata["upp_ring_value"])
        thresh_min = float(gdata["low_ring_value"])
        theta_min = int(gdata["max_arc_length"])
        rwidth = int(gdata["max_ring_size"])
        rec = tomopy.remove_rings(
            rec,
            center_x=args.center,
            thresh=thresh,
            thresh_max=thresh_max,
            thresh_min=thresh_min,
            theta_min=theta_min,
            rwidth=rwidth,
        )

    # Write reconstruction data to new hdf5 file
    fdata["stage"] = "fast-tomopy"
    fdata["stage_flow"] = "/raw/" + fdata["stage"]
    fdata["stage_version"] = "fast-tomopy-0.1"
    # Generate a new uuid based on host ID and current time
    fdata["uuid"] = str(uuid.uuid1())

    gdata["Reconstruction_Type"] = "tomopy-gridrec"
    gdata["ring_removal_method"] = args.ring_remove
    gdata["rfilter"] = args.filter_name

    logger.info("Writing reconstructed data to h5 file")
    write_als_832h5(rec, args.input, fdata, gdata, args.output_file, step)

    return
Ejemplo n.º 32
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument("fname", help="Full file name: /data/fname.raw")
    parser.add_argument("--start", nargs='?', type=int, default=0, help="First image to read")
    parser.add_argument("--nimg", nargs='?', type=int, default=1, help="Number of images to read")
    parser.add_argument("--ndark", nargs='?', type=int, default=10, help="Number of dark images")
    parser.add_argument("--nflat", nargs='?', type=int, default=10, help="Number of white images")

    args = parser.parse_args()

    fname = args.fname
    start = args.start
    end = args.start + args.nimg

    nflat, ndark, nimg, height, width = read_adimec_header(fname)
    print("Image Size:", width, height)
    print("Dataset metadata (nflat, ndark, nimg:", nflat, ndark, nimg)

    # override nflat and ndark from header with the passed parameter
    # comment the two lines below if the meta data in the binary 
    # file for nflat and ndark is correct
    nflat = args.nflat
    ndark = args.ndark

    proj = read_adimec_stack(fname, img=(start, end))
    print("Projection:", proj.shape)
    # slider(proj)

    flat = read_adimec_stack(fname, img=(nimg-ndark-nflat, nimg-ndark))
    print("Flat:", flat.shape)
    # slider(flat)

    dark = read_adimec_stack(fname, img=(nimg-ndark, nimg))
    print("Dark:", dark.shape)
    # slider(dark)

    nproj = tomopy.normalize(proj, flat, dark)
    print("Normalized projection:", nproj.shape)
    # slider(proj)

    
    proj = nproj[:,100:110, :]
    print("Sino chunk:", proj.shape)
    slider(proj)
    
    theta = tomopy.angles(proj.shape[0])
    print(theta.shape)

    proj = tomopy.minus_log(proj)

    proj = tomopy.remove_nan(proj, val=0.0)
    proj = tomopy.remove_neg(proj, val=0.00)
    proj[np.where(proj == np.inf)] = 0.00

    rot_center = 1280
    # 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')
Ejemplo n.º 33
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 25       # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.143e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    #monochromator_energy = 24.9        # Energy of incident wave in keV
    # used pink beam

    alpha = 1e-02                       # Phase retrieval coeff.
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 2-BM raw data.
    # DIMAX saves 3 files: proj, flat, dark
    # when loading the data set select the proj file (larger size)

    fname = os.path.splitext(h5fname)[0]    
 
    fbase = fname.rsplit('_', 1)[0]
    fnum = fname.rsplit('_', 1)[1]
    fext = os.path.splitext(h5fname)[1]  

    fnum_flat = str("%4.4d" % (int(fnum)+1))
    fnum_dark = str("%4.4d" % (int(fnum)+2))

    fnproj = fbase + '_' + fnum + fext
    fnflat = fbase + '_' + fnum_flat + fext
    fndark = fbase + '_' + fnum_dark + fext

    fnflat = '/local/data/2018-11/Chawla/1G_A/1G_A_0002.hdf'
    fndark = '/local/data/2018-11/Chawla/1G_A/1G_A_0003.hdf'

    print('proj', fnproj)
    print('flat', fnflat)
    print('dark', fndark)
    # Read APS 2-BM DIMAX raw data.
    proj, dum, dum2, theta = dxchange.read_aps_32id(fnproj, sino=sino)
    dum3, flat, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino)      
    dum6, dum7, dark, dum8 = dxchange.read_aps_32id(fndark, sino=sino)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)        
    
    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
    rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    #rec = np.swapaxes(rec,0,2)
    
    return rec
Ejemplo n.º 34
0
def reconstruct(h5fname, sino, rot_center, binning, alpha, algorithm='gridrec'):

    sample_detector_distance = 31      # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 1.17e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 45    # Energy of incident wave in keV
    # used pink beam

    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 2-BM raw data.
    # DIMAX saves 3 files: proj, flat, dark
    # when loading the data set select the proj file (larger size)

    fname = os.path.splitext(h5fname)[0]    
 
    fbase = fname.rsplit('_', 1)[0]
    fnum = fname.rsplit('_', 1)[1]
    fext = os.path.splitext(h5fname)[1]  

    fnum_flat = str("%4.4d" % (int(fnum)+1))
    fnum_dark = str("%4.4d" % (int(fnum)+2))

    fnproj = fbase + '_' + fnum + fext
    fnflat = fbase + '_' + fnum_flat + fext
    fndark = fbase + '_' + fnum_dark + fext
    
    print('proj', fnproj)
    print('flat', fnflat)
    print('dark', fndark)
    # Read APS 2-BM DIMAX raw data.
    proj, dum, dum2, theta = dxchange.read_aps_32id(fnproj, sino=sino)
    dum3, flat, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino)
    #flat, dum3, dum4, dum5 = dxchange.read_aps_32id(fnflat, sino=sino)          
    dum6, dum7, dark, dum8 = dxchange.read_aps_32id(fndark, sino=sino)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)        
    
    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)


    # padding 
    N = data.shape[2]
    data_pad = np.zeros([data.shape[0],data.shape[1],3*N//2],dtype = "float32")
    data_pad[:,:,N//4:5*N//4] = data
    data_pad[:,:,0:N//4] = np.tile(np.reshape(data[:,:,0],[data.shape[0],data.shape[1],1]),(1,1,N//4))
    data_pad[:,:,5*N//4:] = np.tile(np.reshape(data[:,:,-1],[data.shape[0],data.shape[1],1]),(1,1,N//4))

    data = data_pad
    rot_center = rot_center+N//4
    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
    rec = rec[:,N//4:5*N//4,N//4:5*N//4]
    print("Algorithm: ", algorithm)


    # Mask each reconstructed slice with a circle.
    rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    #rec = np.swapaxes(rec,0,2)
    
    return rec
 def evaluate(self):
     self.tomo.value = tomopy.minus_log(self.tomo.value,
                                        ncore=self.ncore.value,
                                        out=self.out.value)
Ejemplo n.º 36
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec', options=None, num_iter=100, dark_file=None):

    sample_detector_distance = 10       # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.247e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 35           # Energy of incident wave in keV
    alpha = 1e-01                       # Phase retrieval coeff.
    zinger_level = 500                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    if dark_file is not None:
        proj_, flat, dark, theta_ = dxchange.read_aps_32id(dark_file, sino=sino)
        del proj_, theta_
        
    # zinger_removal
    proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    # flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    data = tomopy.remove_stripe_ti(data, alpha=1.5)
    data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)

    print(algorithm)
    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    elif algorithm == "astra_fbp":
        if options == 'linear':
            options = {'proj_type':'linear', 'method':'FBP'}
        else:
            options = {'proj_type':'cuda', 'method':'FBP_CUDA'}
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options, ncore=1)
    elif algorithm == "astra_sirt":
        extra_options = {'MinConstraint':0}
        options = {'proj_type':'cuda', 'method':'SIRT_CUDA', 'num_iter':num_iter, 'extra_options':extra_options}
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options)
    elif algorithm == tomopy.astra:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=tomopy.astra, options=options)
    else:
        try:
            rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
        except:
            rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm)
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
    rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    
    return rec
Ejemplo n.º 37
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 8  # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.247e-4  # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 24.9  # Energy of incident wave in keV
    alpha = 1e-02  # Phase retrieval coeff.
    zinger_level = 800  # Zinger level for projections
    zinger_level_w = 1000  # Zinger level for white

    # Read APS 32-BM raw data.
    h5fname_norm = '/local/data/2019-02/Dunand/In-situ_100_1/In-situ_100_1_0197.h5'
    proj1, flat, dark, theta1 = dxchange.read_aps_32id(h5fname_norm, sino=sino)
    proj, dummy, dummy1, theta = dxchange.read_aps_32id(h5fname, sino=sino)

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

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

    # remove stripes
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    #data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center / np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning)
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data,
                           theta,
                           center=rot_center,
                           algorithm=algorithm,
                           filter_name='parzen')

    print("Algorithm: ", algorithm)

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

    return rec
Ejemplo n.º 38
0
def tomo(params):
    fname = str(params.input_file_path)

    start = params.slice_start
    end = params.slice_end

    # Read raw data.
    if (params.full_reconstruction == False):
        end = start + 1

#    LOG.info('Slice start/end: %s', end)

    proj, flat, dark, theta = dxchange.read_aps_32id(fname, sino=(start, end))
    LOG.info('Slice start/end: %s, %s', start, end)
    LOG.info('Data successfully imported: %s', fname)
    LOG.info('Projections: %s', proj.shape)
    LOG.info('Flat: %s', flat.shape)
    LOG.info('Dark: %s', dark.shape)

    # Flat-field correction of raw data.
    data = tomopy.normalize(proj, flat, dark)
    LOG.info('Normalization completed')

    data = tomopy.downsample(data, level=int(params.binning))
    LOG.info('Binning: %s', params.binning)

    # remove stripes
    data = tomopy.remove_stripe_fw(data,
                                   level=5,
                                   wname='sym16',
                                   sigma=1,
                                   pad=True)
    LOG.info('Ring removal completed')

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-3,pad=True)

    # Find rotation center
    #rot_center = tomopy.find_center(proj, theta, init=290, ind=0, tol=0.5)

    # Set rotation center.
    rot_center = params.center / np.power(2, float(params.binning))
    LOG.info('Rotation center: %s', rot_center)

    data = tomopy.minus_log(data)
    LOG.info('Minus log compled')

    # Reconstruct object using Gridrec algorithm.
    LOG.info('Reconstruction started using %s',
             params.reconstruction_algorithm)
    if (str(params.reconstruction_algorithm) == 'sirt'):
        LOG.info('Iteration: %s', params.iteration_count)
        rec = tomopy.recon(data,
                           theta,
                           center=rot_center,
                           algorithm='sirt',
                           num_iter=params.iteration_count)
    else:
        LOG.info('Filter: %s', params.filter)
        rec = tomopy.recon(data,
                           theta,
                           center=rot_center,
                           algorithm='gridrec',
                           filter_name=params.filter)

    LOG.info('Reconstrion of %s completed', rec.shape)

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

    if (params.dry_run == False):
        # Write data as stack of TIFs.
        fname = str(params.output_path) + 'reco'
        dxchange.write_tiff_stack(rec, fname=fname, overwrite=True)
        LOG.info('Reconstrcution saved: %s', fname)

    if (params.full_reconstruction == False):
        return rec
Ejemplo n.º 39
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 30  # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 1.17e-4  # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 25.74  # Energy of incident wave in keV
    alpha = 1e-02  # Phase retrieval coeff.
    zinger_level = 1000  # Zinger level for projections
    zinger_level_w = 1000  # Zinger level for white

    miss_angles = [120, 130]
    # miss_angles = [200,300]

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    print(theta)
    # Manage the missing angles:
    proj = np.concatenate(
        (proj[0:miss_angles[0], :, :], proj[miss_angles[1] + 1:-1, :, :]),
        axis=0)
    theta = np.concatenate(
        (theta[0:miss_angles[0]], theta[miss_angles[1] + 1:-1]))

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

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

    # remove stripes
    data = tomopy.remove_stripe_fw(data,
                                   level=7,
                                   wname='sym16',
                                   sigma=1,
                                   pad=True)

    # phase retrieval
    # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center / np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning)
    data = tomopy.downsample(data, level=binning, axis=1)

    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data,
                           theta,
                           center=rot_center,
                           algorithm=algorithm,
                           filter_name='parzen')

    print("Algorithm: ", algorithm)

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

    return rec
Ejemplo n.º 40
0
# Flat field correct data
logger.info("Flat field correcting data")
proj.scatter(0)
tomopy.normalize(proj.local_arr, flat, dark, ncore=1, out=proj.local_arr)
np.clip(proj.local_arr, 1e-6, 1.0, proj.local_arr)
del flat, dark

# Remove Stripe
# NOTE: we need to change remove_strip_fw to take sinogram order data, since it internally rotates the data
#proj.scatter(1)
#proj.local_arr = tomopy.remove_stripe_fw(proj.local_arr, ncore=1)

# Take the minus log to prepare for reconstruction
#NOTE: no scatter required since minus_log doesn't care about order
tomopy.minus_log(proj.local_arr, ncore=1, out=proj.local_arr)

# Find rotation center per set of sinograms
logger.info("Finding center of rotation")
proj.scatter(1)
# NOTE: center finding doesn't work for my datasets :-(
#center = tomopy.find_center(proj.local_arr, theta, sinogram_order=True)
center = proj.shape[2] // 2
logger.info("Center for sinograms [%d:%d] is %f" % (proj.offset, proj.offset+proj.size, center))

alg = 'gridrec'
logger.info("Reconstructing using: %s" % alg)
# Reconstruct object using algorithm
proj.scatter(1)
rec = tomopy.recon(proj.local_arr,
                   theta,
Ejemplo n.º 41
0
def preprocess_data(prj, flat, dark, FF_norm=flat_field_norm, remove_rings = remove_rings, medfilt_size=medfilt_size, FF_drift_corr=flat_field_drift_corr, downspling=binning):

    if FF_norm:
        # normalize the prj
        print('\n*** Applying flat field correction:') 
        start_norm_time = time.time()
        prj = tomopy.normalize(prj, flat, dark)
        print('   done in %0.3f min' % ((time.time() - start_norm_time)/60))

    if FF_drift_corr:
        print('\n*** Applying flat field drift correction:')
        start_norm_bg_time = time.time()
        prj = tomopy.normalize_bg(prj, air=100)
        print('   done in %0.3f min' % ((time.time() - start_norm_bg_time)/60))

    # Applying -log
    print('\n*** Applying -log:') 
    start_log_time = time.time()
    prj = tomopy.minus_log(prj)
    print('   done in %0.3f min' % ((time.time() - start_log_time)/60))

    prj = tomopy.misc.corr.remove_neg(prj, val=0.000)
    prj = tomopy.misc.corr.remove_nan(prj, val=0.000)
    prj[np.where(prj == np.inf)] = 0.000
#    prj[np.where(prj == 0)] = 0.000
    print('\n*** Min and max val in prj before recon: %0.3f, %0.3f'  % (np.min(prj), np.max(prj)))

    if remove_rings:
        # remove ring artefacts
        tmp = prj[-1,:,:] # use to fixe the bug of remove_stripe_ti
        print('\n*** Applying ring removal algo:') 
        start_ring_time = time.time()
        prj = tomopy.remove_stripe_ti(prj,2)
    #    prj = tomopy.remove_stripe_sf(prj,10); prj = tomopy.misc.corr.remove_neg(prj, val=0.000) # remove the neg values coming from remove_stripe_sf
        print('   done in %0.3f min' % ((time.time() - start_ring_time)/60))
        prj[-1,:,:] = tmp # fixe the bug of remove_stripe_ti

    if phase_retrieval:
        # phase retrieval
        prj = tomopy.prep.phase.retrieve_phase(prj,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)


    # Filtering data with 2D median filter before downsampling and recon 
    if medfilt_size>1:
        start_filter_time = time.time()
        print('\n*** Applying median filter')
        #prj = tomopy.median_filter(prj,size=1)
        prj = ndimage.median_filter(prj,footprint=np.ones((1, medfilt_size, medfilt_size)))
        print('   done in %0.3f min' % ((time.time() - start_filter_time)/60))

    # Downsampling data:
    if downspling>0:
        print('\n** Applying downsampling')
        start_down_time = time.time()
        prj = tomopy.downsample(prj, level=binning)
        prj = tomopy.downsample(prj, level=binning, axis=1)
        print('   done in %0.3f min' % ((time.time() - start_down_time)/60))
        
    print('\n*** Shape of the data:'+str(np.shape(prj)))
    print('      Dimension of theta:'+str(np.shape(theta)))

    return prj
Ejemplo n.º 42
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 8        # Propagation distance of the wavefront in cm
    detector_pixel_size_x = 2.247e-4    # Detector pixel size in cm (5x: 1.17e-4, 2X: 2.93e-4)
    monochromator_energy = 24.9         # Energy of incident wave in keV
    alpha = 1e-02                       # Phase retrieval coeff.
    zinger_level = 800                  # Zinger level for projections
    zinger_level_w = 1000               # Zinger level for white

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)
        
    # zinger_removal
    # proj = tomopy.misc.corr.remove_outlier(proj, zinger_level, size=15, axis=0)
    # flat = tomopy.misc.corr.remove_outlier(flat, zinger_level_w, size=15, axis=0)

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

    # remove stripes
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    #data = tomopy.remove_stripe_ti(data, alpha=1.5)
    #data = tomopy.remove_stripe_sf(data, size=150)

    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=alpha,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    rot_center = rot_center/np.power(2, float(binning))
    data = tomopy.downsample(data, level=binning) 
    data = tomopy.downsample(data, level=binning, axis=1)
    # padding 
    N = data.shape[2]
    data_pad = np.zeros([data.shape[0],data.shape[1],3*N//2],dtype = "float32")
    data_pad[:,:,N//4:5*N//4] = data
    data_pad[:,:,0:N//4] = np.tile(np.reshape(data[:,:,0],[data.shape[0],data.shape[1],1]),(1,1,N//4))
    data_pad[:,:,5*N//4:] = np.tile(np.reshape(data[:,:,-1],[data.shape[0],data.shape[1],1]),(1,1,N//4))

    data = data_pad
    rot_center = rot_center+N//4
 
    # Reconstruct object.
    if algorithm == 'sirtfbp':
        rec = rec_sirtfbp(data, theta, rot_center)
    else:
        rec = tomopy.recon(data, theta, center=rot_center, algorithm=algorithm, filter_name='parzen')
    rec = rec[:,N//4:5*N//4,N//4:5*N//4]
        
    print("Algorithm: ", algorithm)

    # Mask each reconstructed slice with a circle.
#   rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
    
    return rec
if zoom_level:
    logger.info("Zoom images by {zoom_level}x")
    projs = zoom_array(projs, zoom_level)
    # NOTE: must scale center offset and pixel size
    center_offset *= zoom_level
    pixel_size *= zoom_level
    shifts *= zoom_level

# # 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:
Ejemplo n.º 44
0
    data = tomopy.normalize(proj, flat, dark)

    # remove stripes
    data = tomopy.prep.stripe.remove_stripe_fw(data,
                                               level=5,
                                               wname='sym16',
                                               sigma=1,
                                               pad=True)

    # phase retrieval
    data = tomopy.prep.phase.retrieve_phase(data,
                                            pixel_size=detector_pixel_size_x,
                                            dist=sample_detector_distance,
                                            energy=monochromator_energy,
                                            alpha=8e-3,
                                            pad=True)

    # Set rotation center.
    rot_center = rot_center

    data = tomopy.minus_log(data)

    # Reconstruct object using Gridrec algorithm.
    rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec')

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

    # Write data as stack of TIFs.
    dxchange.write_tiff_stack(rec, fname='recon_dir/tomo_00070')
Ejemplo n.º 45
0
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm,
            binning):

    data_shape = get_dx_dims(h5fname, 'data')
    print(data_shape)
    ssino = int(data_shape[1] * nsino)

    center_range = (rot_center - center_search_width,
                    rot_center + center_search_width, 0.5)
    #print(sino,ssino, center_range)
    #print(center_range[0], center_range[1], center_range[2])

    # Select sinogram range to reconstruct
    sino = None

    start = ssino
    end = start + 1
    sino = (start, end)

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

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

    # remove stripes
    # data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    stack = np.empty(
        (len(np.arange(*center_range)), data_shape[0], data_shape[2]))

    index = 0
    for axis in np.arange(*center_range):
        stack[index] = data[:, 0, :]
        index = index + 1

    # Reconstruct the same slice with a range of centers.
    rec = tomopy.recon(stack,
                       theta,
                       center=np.arange(*center_range),
                       sinogram_order=True,
                       algorithm='gridrec',
                       filter_name='parzen',
                       nchunk=1)

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

    index = 0
    # Save images to a temporary folder.
    fname = os.path.dirname(h5fname) + os.sep + 'try_rec/' + path_base_name(
        h5fname) + os.sep + 'recon_' + os.path.splitext(
            os.path.basename(h5fname))[0]
    for axis in np.arange(*center_range):
        rfname = fname + '_' + str('{0:.2f}'.format(axis) + '.tiff')
        dxchange.write_tiff(rec[index], fname=rfname, overwrite=True)
        index = index + 1

    print("Reconstructions: ", fname)
def reconstruct(filename,inputPath="", outputPath="", COR=COR, doOutliers=doOutliers, outlier_diff=outlier_diff, outlier_size=outlier_size, doFWringremoval=doFWringremoval, ringSigma=ringSigma,ringLevel=ringLevel, ringWavelet=ringWavelet,pad_sino=pad_sino,  doPhaseRetrieval=doPhaseRetrieval, propagation_dist=propagation_dist, kev=kev,alphaReg=alphaReg, butterworthpars=butterworthpars, doPolarRing=doPolarRing,Rarc=Rarc, Rmaxwidth=Rmaxwidth, Rtmax=Rtmax, Rthr=Rthr, Rtmin=Rtmin, useAutoCOR=useAutoCOR, use360to180=use360to180, num_substacks=num_substacks,recon_slice=recon_slice):

	# Convert filename to list type if only one file name is given
	if type(filename) != list:
		filename=[filename]

	# If useAutoCor == true, a list of COR will be automatically calculated for all files
	# If a list of COR is given, only entries with boolean False will use automatic COR calculation
	if useAutoCOR==True or (len(COR) != len(filename)):
		logging.info('using auto COR for all input files')
		COR = [False]*len(filename)

	for x in range(len(filename)):
		logging.info('opening data set, checking metadata')

		fdata, gdata = read_als_832h5_metadata(inputPath[x]+filename[x]+'.h5')
		pxsize = float(gdata['pxsize'])/10.0 # convert from metadata (mm) to this script (cm)
		numslices = int(gdata['nslices'])

		# recon_slice == True, only center slice will be reconstructed
		# if integer is given, a specific 		
		if recon_slice != False:
			if (type(recon_slice) == int) and (recon_slice <= numslices):
				sinorange [recon_slice-1, recon_slice]
			else:
				sinorange = [numslices//2-1, numslices//2]
		else:
			sinorange = [0, numslices]

		# Calculate number of substacks (chunks)
		substacks = num_substacks #(sinorange[1]-sinorange[0]-1)//num_sino_per_substack+1

		if (sinorange[1]-sinorange[0]) >= substacks:
			num_sino_per_substack = (sinorange[1]-sinorange[0])//num_substacks
		else:
			num_sino_per_substack = 1

	
		firstcor, lastcor = 0, int(gdata['nangles'])-1
		projs, flat, dark, floc = dxchange.read_als_832h5(inputPath[x]+filename[x]+'.h5', ind_tomo=(firstcor, lastcor))
		projs = tomopy.normalize_nf(projs, flat, dark, floc)
		autocor = tomopy.find_center_pc(projs[0], projs[1], tol=0.25)


		if (type(COR[x]) == bool) or (COR[x]<0) or (COR[x]=='auto'):
			firstcor, lastcor = 0, int(gdata['nangles'])-1
			projs, flat, dark, floc = dxchange.read_als_832h5(inputPath[x]+filename[x]+'.h5', ind_tomo=(firstcor, lastcor))
			projs = tomopy.normalize_nf(projs, flat, dark, floc)
			cor = tomopy.find_center_pc(projs[0], projs[1], tol=0.25)
		else:
			cor = COR[x]

		logging.info('Dataset %s, has %d total slices, reconstructing slices %d through %d in %d substack(s), using COR: %f',filename[x], int(gdata['nslices']), sinorange[0], sinorange[1]-1, substacks, cor)
		
		for y in range(0, substacks):
			logging.info('Starting dataset %s (%d of %d), substack %d of %d',filename[x], x+1, len(filename), y+1, substacks)

			logging.info('Reading sinograms...')
			projs, flat, dark, floc = dxchange.read_als_832h5(inputPath[x]+filename[x]+'.h5', sino=(sinorange[0]+y*num_sino_per_substack, sinorange[0]+(y+1)*num_sino_per_substack, 1)) 

			logging.info('Doing remove outliers, norm (nearest flats), and -log...')
			if doOutliers:
				projs = tomopy.remove_outlier(projs, outlier_diff, size=outlier_size, axis=0)
				flat = tomopy.remove_outlier(flat, outlier_diff, size=outlier_size, axis=0)
			tomo = tomopy.normalize_nf(projs, flat, dark, floc)
			tomo = tomopy.minus_log(tomo, out=tomo) # in place logarithm 
		
			# Use padding to remove halo in reconstruction if present
			if pad_sino:
				npad = int(np.ceil(tomo.shape[2] * np.sqrt(2)) - tomo.shape[2])//2
				tomo = tomopy.pad(tomo, 2, npad=npad, mode='edge')
				cor_rec = cor + npad # account for padding
			else:
				cor_rec = cor
		
			if doFWringremoval:
				logging.info('Doing ring (Fourier-wavelet) function...')
				tomo = tomopy.remove_stripe_fw(tomo, sigma=ringSigma, level=ringLevel, pad=True, wname=ringWavelet)		

			if doPhaseRetrieval:
				logging.info('Doing Phase retrieval...')
				#tomo = tomopy.retrieve_phase(tomo, pixel_size=pxsize, dist=propagation_dist, energy=kev, alpha=alphaReg, pad=True)	
				tomo = tomopy.retrieve_phase(tomo, pixel_size=pxsize, dist=propagation_dist, energy=kev, alpha=alphaReg, pad=True)		

			logging.info('Doing recon (gridrec) function and scaling/masking, with cor %f...',cor_rec)
			rec = tomopy.recon(tomo, tomopy.angles(tomo.shape[0], 270, 90), center=cor_rec, algorithm='gridrec', filter_name='butterworth', filter_par=butterworthpars)
			#rec = tomopy.recon(tomo, tomopy.angles(tomo.shape[0], 180+angularrange/2, 180-angularrange/2), center=cor_rec, algorithm='gridrec', filter_name='butterworth', filter_par=butterworthpars)		
			rec /= pxsize  # intensity values in cm^-1
			if pad_sino:
				rec = tomopy.circ_mask(rec[:, npad:-npad, npad:-npad], 0)
			else:
				rec = tomopy.circ_mask(rec, 0, ratio=1.0, val=0.0)
			
			if doPolarRing:
				logging.info('Doing ring (polar mean filter) function...')
				rec = tomopy.remove_ring(rec, theta_min=Rarc, rwidth=Rmaxwidth, thresh_max=Rtmax, thresh=Rthr, thresh_min=Rtmin)

			logging.info('Writing reconstruction slices to %s', filename[x])
			#dxchange.write_tiff_stack(rec, fname=outputPath+'alpha'+str(alphaReg)+'/rec'+filename[x]+'/rec'+filename[x], start=sinorange[0]+y*num_sino_per_substack)
			dxchange.write_tiff_stack(rec, fname=outputPath + 'recon_'+filename[x]+'/recon_'+filename[x], start=sinorange[0]+y*num_sino_per_substack)
		logging.info('Reconstruction Complete: '+ filename[x])
Ejemplo n.º 47
0
def rec_try(h5fname, nsino, rot_center, center_search_width, algorithm, binning, dark_file):
    
    data_shape = get_dx_dims(h5fname, 'data')
    print(data_shape)
    ssino = int(data_shape[1] * nsino)

    center_range = (rot_center-center_search_width, rot_center+center_search_width, 0.5)
    #print(sino,ssino, center_range)
    #print(center_range[0], center_range[1], center_range[2])

    # Select sinogram range to reconstruct
    sino = None
        
    start = ssino
    end = start + 1
    sino = (start, end)

    # Read APS 32-BM raw data.
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)
    if dark_file is not None:
        print('Reading white/dark from {}'.format(dark_file))
        proj_, flat, dark, theta_ = dxchange.read_aps_32id(dark_file, sino=sino)
        del proj_, theta_

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

    # remove stripes
    # data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)


    print("Raw data: ", h5fname)
    print("Center: ", rot_center)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    stack = np.empty((len(np.arange(*center_range)), data_shape[0], data_shape[2]))

    index = 0
    for axis in np.arange(*center_range):
        stack[index] = data[:, 0, :]
        index = index + 1

    # Reconstruct the same slice with a range of centers.
    rec = tomopy.recon(stack, theta, center=np.arange(*center_range), sinogram_order=True, algorithm='gridrec', filter_name='parzen', nchunk=1)

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

    index = 0
    # Save images to a temporary folder.
    #fname = os.path.dirname(h5fname) + os.sep + 'try_rec/' + path_base_name(h5fname) + os.sep + 'recon_' + os.path.splitext(os.path.basename(h5fname))[0]    
    fname = os.path.dirname(h5fname) + os.sep + 'centers/' + path_base_name(h5fname) + os.sep + 'recon_' + os.path.splitext(os.path.basename(h5fname))[0]    
    for axis in np.arange(*center_range):
        rfname = fname + '_' + str('{0:.2f}'.format(axis) + '.tiff')
        dxchange.write_tiff(rec[index], fname=rfname, overwrite=True)
        index = index + 1

    print("Reconstructions: ", fname)
Ejemplo n.º 48
0
    dark = dark[:, [start,end], :]   

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

    # remove stripes    
    data = tomopy.prep.stripe.remove_stripe_fw(data,level=5,wname='sym16',sigma=1,pad=True)

#    # phase retrieval
    #data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-3,pad=True)

    # Set rotation center.
    rot_center = 1552
    print(rot_center)
    
    data = tomopy.minus_log(data)

    # Use test_sirtfbp_iter = True to test which number of iterations is suitable for your dataset
    # Filters are saved in .mat files in "./¨
    test_sirtfbp_iter = True
    if test_sirtfbp_iter:
        nCol = data.shape[2]
        output_name = './test_iter/'
        num_iter = [50,100,150]
        filter_dict = sirtfilter.getfilter(nCol, theta, num_iter, filter_dir='./')
        for its in num_iter:
            tomopy_filter = sirtfilter.convert_to_tomopy_filter(filter_dict[its], nCol)
            rec = tomopy.recon(data, theta, center=rot_center, algorithm='gridrec', filter_name='custom2d', filter_par=tomopy_filter)
            output_name_2 = output_name + 'sirt_fbp_%iiter_slice_' % its
            dxchange.write_tiff_stack(data, fname=output_name_2, start=start, dtype='float32')
Ejemplo n.º 49
0
def reconstruct(h5fname, sino, nframes, frame, nproj, binning, tv, rot_center):

    # Read APS 32-BM raw data.
    print("Read data")
    proj, flat, dark, theta = dxchange.read_aps_32id(h5fname, sino=sino)

    print("Processing")
    if int(frame-nframes)>0:
        proj = proj[(frame-nframes/2)*nproj:(frame+nframes/2)*nproj,:,:]

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

    # remove stripes
    #print("Removing stripes")
    #data = tomopy.remove_stripe_fw(data,level=7,wname='sym16',sigma=1,pad=True)

    print("Raw data: ", h5fname)
    if (frame-nframes)>0:
        print("Frames for reconstruction:",(frame-nframes/2),"..",(frame+nframes/2))
    else:
        print("Frames for reconstruction:",(0),"..",(nframes))
    # Phase retrieval for tomobank id 00080
    # sample_detector_distance = 25
    # detector_pixel_size_x = 3.0e-4
    # monochromator_energy = 16

    # phase retrieval
    # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-03,pad=True)

    data = tomopy.minus_log(data)

    data = tomopy.remove_nan(data, val=0.0)
    data = tomopy.remove_neg(data, val=0.00)
    data[np.where(data == np.inf)] = 0.00

    # Binning 
    data = tomopy.downsample(data, level=binning, axis=2)
    if data.shape[1]>1:
       data = tomopy.downsample(data, level=binning, axis=1)

    theta = np.linspace(0,np.pi*nframes,nproj*nframes,endpoint=False)

    if tv:
	import rectv
	# Reconstruct. Iterative TV.
	[Ntheta,Nz,N] = data.shape
	Nzp = 4 # number of slices to process simultaniously by gpus
	M = nframes # number of basis functions, must be a multiple of nframes
	lambda0 = pow(2,-9) # regularization parameter 1
	lambda1 = pow(2,2) # regularization parameter 2 
	niters = 1024 # number of iterations
	ngpus = 1 # number of gpus

	data = np.ndarray.flatten(data.swapaxes(0,1)) # reorder input data for compatibility
	rec = np.zeros([N*N*Nz*M],dtype='float32') # memory for result

	# Make a class for tv
	cl = rectv.rectv(N,Ntheta,M,nframes,Nz,Nzp,ngpus,lambda0,lambda1)
	# Run iterations
	cl.itertvR_wrap(rec,data,niters) 

	rec = np.rot90(np.reshape(rec,[Nz,M,N,N]).swapaxes(0,1),axes=(2,3))/Ntheta*nframes*2 # reorder result for compatibility
	rec = rec[::M/nframes]
    else:
   	# Reconstruct object. FBP.
    	rec = np.zeros((nframes,data.shape[1],data.shape[2],data.shape[2]),dtype='float32')
	for time_frame in range(0,nframes):
		rec0 = tomopy.recon(data[time_frame*nproj:(time_frame+1)*nproj], theta[time_frame*nproj:(time_frame+1)*nproj], center=rot_center-np.mod(time_frame,2), algorithm='gridrec')        
		# Mask each reconstructed slice with a circle.
		rec[time_frame] = tomopy.circ_mask(rec0, axis=0, ratio=0.95)
    return rec