예제 #1
0
def reconstruct(h5fname, sino, rot_center, binning, algorithm='gridrec'):

    sample_detector_distance = 3  # 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 = 22.7  # 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)
    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
예제 #2
0
def remove_stripe(data, params):

    log.info('  *** remove stripe:')
    if (params.remove_stripe_method == 'fw'):
        log.info('  *** *** fourier wavelet')
        data = tomopy.remove_stripe_fw(data,
                                       level=params.fw_level,
                                       wname=params.fw_filter,
                                       sigma=params.fw_sigma,
                                       pad=params.fw_pad)
        log.info('  *** ***  *** fw level %d ' % params.fw_level)
        log.info('  *** ***  *** fw wname %s ' % params.fw_filter)
        log.info('  *** ***  *** fw sigma %f ' % params.fw_sigma)
        log.info('  *** ***  *** fw pad %r ' % params.fw_pad)
    elif (params.remove_stripe_method == 'ti'):
        log.info('  *** *** titarenko')
        data = tomopy.remove_stripe_ti(data,
                                       nblock=params.ti_nblock,
                                       alpha=params.ti_alpha)
        log.info('  *** ***  *** ti nblock %d ' % params.ti_nblock)
        log.info('  *** ***  *** ti alpha %f ' % params.ti_alpha)
    elif (params.remove_stripe_method == 'sf'):
        log.info('  *** *** smoothing filter')
        data = tomopy.remove_stripe_sf(data, size == params.sf_size)
        log.info('  *** ***  *** sf size %d ' % params.sf_size)
    elif (params.remove_stripe_method == 'none'):
        log.warning('  *** *** OFF')

    return data
예제 #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

    # 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
예제 #4
0
파일: matt.py 프로젝트: Plasmonics/util
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!")
예제 #5
0
 def test_sf(self):
     # Prepare some test data
     prj = self.phantom_prj()
     # Prepare parameters (different from tomopy_cli or tomopy defaults)
     params = make_params()
     params.remove_stripe_method = 'sf'
     params.sf_size = 7
     result = remove_stripe(np.copy(prj), params)
     # Compare results
     expected = tomopy.remove_stripe_sf(np.copy(prj), size=7)
     np.testing.assert_array_equal(result, expected)
예제 #6
0
파일: matt.py 프로젝트: decarlof/txm_util
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!")
예제 #7
0
                if (int(key) > 6):            
                    proj, flat, dark, theta = read_aps_2bm_custom(fname, sino=sino)
                else:
                    proj, flat, dark, theta = dxchange.read_aps_2bm(fname, sino=sino)

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

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

                # remove stripes
                #proj = tomopy.remove_stripe_fw(proj,level=5,wname='sym16',sigma=1,pad=True)
                proj = tomopy.remove_stripe_ti(proj,2)
                proj = tomopy.remove_stripe_sf(proj,10)

                # 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(index, 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)
예제 #8
0
파일: rec_loop.py 프로젝트: Plasmonics/util
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
예제 #9
0
    start = 600
    end = 900

    # Read the APS 1-ID raw data.
    proj, flat, dark = dxchange.read_aps_1id(fname, sino=(start, end))

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

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

    ndata = tomopy.remove_stripe_ti(ndata)
    ndata = tomopy.remove_stripe_sf(ndata)
    
    # phase retrieval
    # ndata = tomopy.prep.phase.retrieve_phase(ndata, 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(ndata, theta, init=1024, ind=0, tol=0.5)
    rot_center = 576

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

    ndata = tomopy.minus_log(ndata)

    rec_method = None
예제 #10
0
                if sino_chunk_end > sino_end:
                    break

                sino = (sino_chunk_start, sino_chunk_end)

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

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

                # remove stripes
                #proj = tomopy.remove_stripe_fw(proj,level=5,wname='sym16',sigma=1,pad=True)
                proj = tomopy.remove_stripe_ti(proj, 2)
                proj = tomopy.remove_stripe_sf(proj, 10)

                # 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(index, rot_center)

                proj = tomopy.minus_log(proj)

                # Reconstruct object using Gridrec algorithm.
                rec = tomopy.recon(proj,
                                   theta,
                                   center=rot_center,
                                   algorithm='gridrec')
예제 #11
0
 def evaluate(self):
     self.tomo.value = tomopy.remove_stripe_sf(self.tomo.value,
                                               size=self.size.value,
                                               ncore=self.ncore.value,
                                               nchunk=self.nchunk.value)
예제 #12
0
    start = 600
    end = 900

    # Read the APS 1-ID raw data.
    proj, flat, dark = dxchange.read_aps_1id(fname, sino=(start, end))

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

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

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

    ndata = tomopy.remove_stripe_ti(ndata)
    ndata = tomopy.remove_stripe_sf(ndata)

    # phase retrieval
    # ndata = tomopy.prep.phase.retrieve_phase(ndata, 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(ndata, theta, init=1024, ind=0, tol=0.5)
    rot_center = 576

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

    ndata = tomopy.minus_log(ndata)

    rec_method = None
예제 #13
0
파일: rec_new.py 프로젝트: Plasmonics/util
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
예제 #14
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 = 1e-5 * 2**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 = 1
    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
예제 #15
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
예제 #16
0
# Read APS 32-BM raw data.
proj, flat, dark, theta = dxchange.read_aps_32id(h5fname)

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

# Open DataExchange file
f = dx.File(fname, mode='w')

# Write the Data Exchange HDF5 file.

f.add_entry(dx.Entry.data(data={'value': data, 'units': 'counts'}))
예제 #17
0
# Read APS 32-BM raw data.
proj, flat, dark, theta = dxchange.read_aps_32id(h5fname)
    
# 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)



# Open DataExchange file
f = dx.File(fname, mode='w') 

# Write the Data Exchange HDF5 file.

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

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

    outputPath = inputPath if outputPath is None else outputPath

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

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

    print(", reading metadata")

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

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

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

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

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

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

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

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

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

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

    function_list = []

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

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

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

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

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


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

                elif func_name == 'do_360_to_180':

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

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

                    anglelist = anglelist[:numangles]

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

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

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

        curtemp = 1 - curtemp
        curfunc = dofunc
        if curfunc == len(function_list):
            break
        axis = slice_dir[function_list[curfunc]]
    print("cleaning up temp files")
    for tmpfile in tempfilenames:
        try:
            os.remove(tmpfile)
        except OSError:
            pass
    print("End Time: " +
          time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))
    print('It took {:.3f} s to process {}'.format(time.time() - start_time,
                                                  inputPath + filename))
예제 #20
0
파일: rec.py 프로젝트: decarlof/txm_util
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)
예제 #21
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)
예제 #22
0
파일: rec.py 프로젝트: decarlof/txm_util
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=2,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
예제 #23
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