Exemple #1
0
def get_tilted_sinogram(fname, target_slice, tilt, preprocess_data=True):
    """
    Get a sinogram that is tilted about the theta-axis from the specified dataset.
    The tilting axis is assumed to be along the center of the FOV width.
    :param fname: name of the dataset.
    :param target_slice: the slice number where the tilting axis lies.
    :param tilt: tilting angle in degree. Positive = anticlockwise; negative = clockwise.
    :return: tilted sinogram.
    """
    shape = read_data_adaptive(fname, shape_only=True)
    fov2 = shape[2] / 2.
    tilt = np.deg2rad(tilt)
    range_l = target_slice + fov2 * np.tan(tilt)
    range_r = target_slice - fov2 * np.tan(tilt)
    if tilt > 0:
        range_l = int(np.ceil(range_l)) + 1
        range_r = int(np.floor(range_r))
    else:
        range_l = int(np.floor(range_l))
        range_r = int(np.ceil(range_r)) + 1
    dat, flt, drk, _ = read_data_adaptive(fname,
                                          sino=(min([range_l, range_r]),
                                                max([range_l, range_r])))
    if preprocess_data:
        dat = tomopy.normalize(dat, flt, drk)
        dat = preprocess(dat)
    else:
        dat[np.isnan(dat)] = 0

    tilted_block = rotate(dat, tilt, axes=(1, 2), reshape=True)
    mid_slice = int(dat.shape[1] / 2)

    return tilted_block[:, mid_slice:mid_slice + 1, :]
Exemple #2
0
def load_sino(filename, sino_n, normalize=True, data_format='aps_32id'):
    internal_print('Loading {:s}, slice {:d}'.format(filename, sino_n))
    sino_n = int(sino_n)
    sino, flt, drk, _ = read_data_adaptive(filename,
                                           sino=(sino_n, sino_n + 1),
                                           data_format=data_format)
    if not normalize:
        flt[:, :, :] = flt.max()
        drk[:, :, :] = 0
    sino = tomopy.normalize(sino, flt, drk)
    # 1st slice of each tile of some samples contains mostly abnormally large values which should be removed.
    if sino.max() > 1e2:
        sino[np.abs(sino) > 1] = 1
    return np.squeeze(sino)
Exemple #3
0
def save_partial_frames(file_grid,
                        save_folder,
                        prefix,
                        frame=0,
                        data_format='aps_32id'):
    for (y, x), value in np.ndenumerate(file_grid):
        print(value)
        if (value != None):
            prj, flt, drk, _ = read_data_adaptive(value,
                                                  proj=(frame, frame + 1),
                                                  data_format=data_format)
            prj = tomopy.normalize(prj, flt, drk)
            prj = preprocess(prj)
            fname = prefix + 'Y' + str(y).zfill(2) + '_X' + str(x).zfill(2)
            dxchange.write_tiff(np.squeeze(prj),
                                fname=os.path.join(save_folder,
                                                   'partial_frames', fname))
Exemple #4
0
def save_partial_raw(file_list, save_folder, data_format='aps_32id'):
    for value in file_list:
        if (value != None):
            prj, flt, drk, _ = read_data_adaptive(value,
                                                  proj=(0, 1),
                                                  data_format=data_format)
            fname = value
            dxchange.write_tiff_stack(np.squeeze(flt),
                                      fname=os.path.join(
                                          save_folder, 'partial_flats', fname))
            dxchange.write_tiff_stack(np.squeeze(drk),
                                      fname=os.path.join(
                                          save_folder, 'partial_darks', fname))
            prj = prj.astype('float32')
            dxchange.write_tiff(np.squeeze(prj),
                                fname=os.path.join(save_folder,
                                                   'partial_frames_raw',
                                                   fname))
Exemple #5
0
def recon_hdf5(src_fanme,
               dest_folder,
               sino_range,
               sino_step,
               shift_grid,
               center_vec=None,
               center_eq=None,
               dtype='float32',
               algorithm='gridrec',
               tolerance=1,
               chunk_size=20,
               save_sino=False,
               sino_blur=None,
               flattened_radius=120,
               mode='180',
               test_mode=False,
               phase_retrieval=None,
               ring_removal=True,
               crop=None,
               num_iter=None,
               pad_length=0,
               read_theta=True,
               **kwargs):
    """
    center_eq: a and b parameters in fitted center position equation center = a*slice + b.
    """

    if not os.path.exists(dest_folder):
        try:
            os.mkdir(dest_folder)
        except:
            pass
    sino_ini = int(sino_range[0])
    sino_end = int(sino_range[1])
    sino_ls_all = np.arange(sino_ini, sino_end, sino_step, dtype='int')
    alloc_set = allocate_mpi_subsets(sino_ls_all.size,
                                     size,
                                     task_list=sino_ls_all)
    sino_ls = alloc_set[rank]

    # prepare metadata
    f = h5py.File(src_fanme)
    dset = f['exchange/data']
    full_shape = dset.shape
    if read_theta:
        _, _, _, theta = read_data_adaptive(src_fanme, proj=(0, 1))
    else:
        theta = tomopy.angles(full_shape[0])
    if center_eq is not None:
        a, b = center_eq
        center_ls = sino_ls_all * a + b
        center_ls = np.round(center_ls)
        for iblock in range(int(sino_ls.size / chunk_size) + 1):
            internal_print('Beginning block {:d}.'.format(iblock))
            t0 = time.time()
            istart = iblock * chunk_size
            iend = np.min([(iblock + 1) * chunk_size, sino_ls.size])
            sub_sino_ls = sino_ls[istart:iend - 1]
            center = np.take(center_ls, sub_sino_ls)
            data = np.zeros([dset.shape[0], len(sub_sino_ls), dset.shape[2]])
            for ind, i in enumerate(sub_sino_ls):
                data[:, ind, :] = dset[:, i, :]
            data[np.isnan(data)] = 0
            data = data.astype('float32')
            data = tomopy.remove_stripe_ti(data, alpha=4)
            if sino_blur is not None:
                for i in range(data.shape[1]):
                    data[:, i, :] = gaussian_filter(data[:, i, :], sino_blur)
            if phase_retrieval:
                data = tomopy.retrieve_phase(data, kwargs['pixel_size'],
                                             kwargs['dist'], kwargs['energy'],
                                             kwargs['alpha'])
            if pad_length != 0:
                data = pad_sinogram(data, pad_length)
            data = tomopy.remove_stripe_ti(data, alpha=4)
            if ring_removal:
                rec0 = tomopy.recon(data,
                                    theta,
                                    center=center + pad_length,
                                    algorithm=algorithm,
                                    **kwargs)
                rec = tomopy.remove_ring(np.copy(rec0))
                cent = int((rec.shape[1] - 1) / 2)
                xx, yy = np.meshgrid(np.arange(rec.shape[2]),
                                     np.arange(rec.shape[1]))
                mask0 = ((xx - cent)**2 +
                         (yy - cent)**2 <= flattened_radius**2)
                mask = np.zeros(rec.shape, dtype='bool')
                for i in range(mask.shape[0]):
                    mask[i, :, :] = mask0
                rec[mask] = (rec[mask] + rec0[mask]) / 2
            else:
                rec = tomopy.recon(data,
                                   theta,
                                   center=center + pad_length,
                                   algorithm=algorithm,
                                   **kwargs)
            if pad_length != 0:
                rec = rec[:, pad_length:pad_length + full_shape[2],
                          pad_length:pad_length + full_shape[2]]
            rec = tomopy.remove_outlier(rec, tolerance)
            rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
            if crop is not None:
                crop = np.asarray(crop)
                rec = rec[:, crop[0, 0]:crop[1, 0], crop[0, 1]:crop[1, 1]]
            for i in range(rec.shape[0]):
                slice = sub_sino_ls[i]
                dxchange.write_tiff(
                    rec[i, :, :],
                    fname=os.path.join(
                        dest_folder, 'recon/recon_{:05d}.tiff').format(slice))
                if save_sino:
                    dxchange.write_tiff(
                        data[:, i, :],
                        fname=os.path.join(
                            dest_folder, 'sino/recon_{:05d}_{:d}.tiff').format(
                                slice, int(center[i])))
            iblock += 1
            internal_print('Block {:d} finished in {:.2f} s.'.format(
                iblock,
                time.time() - t0))
    else:
        # divide chunks
        grid_bins = np.append(np.ceil(shift_grid[:, 0, 0]), full_shape[1])
        chunks = []
        center_ls = []
        istart = 0
        counter = 0
        # irow should be 0 for slice 0
        irow = np.searchsorted(grid_bins, sino_ls[0], side='right') - 1

        for i in range(sino_ls.size):
            counter += 1
            sino_next = i + 1 if i != sino_ls.size - 1 else i
            if counter >= chunk_size or sino_ls[sino_next] >= grid_bins[
                    irow + 1] or sino_next == i:
                iend = i + 1
                chunks.append((istart, iend))
                istart = iend
                center_ls.append(center_vec[irow])
                if sino_ls[sino_next] >= grid_bins[irow + 1]:
                    irow += 1
                counter = 0

        # reconstruct chunks
        iblock = 1
        for (istart, iend), center in zip(chunks, center_ls):
            internal_print('Beginning block {:d}.'.format(iblock))
            t0 = time.time()
            internal_print('Reading data...')
            sub_sino_ls = sino_ls[istart:iend]
            data = np.zeros([dset.shape[0], len(sub_sino_ls), dset.shape[2]])
            for ind, i in enumerate(sub_sino_ls):
                data[:, ind, :] = dset[:, i, :]
            if mode == '360':
                overlap = 2 * (dset.shape[2] - center)
                data = tomosaic.sino_360_to_180(data,
                                                overlap=overlap,
                                                rotation='right')
                theta = tomopy.angles(data.shape[0])
            data[np.isnan(data)] = 0
            data = data.astype('float32')
            if sino_blur is not None:
                for i in range(data.shape[1]):
                    data[:, i, :] = gaussian_filter(data[:, i, :], sino_blur)
            if phase_retrieval:
                data = tomopy.retrieve_phase(data, kwargs['pixel_size'],
                                             kwargs['dist'], kwargs['energy'],
                                             kwargs['alpha'])
            if pad_length != 0:
                data = pad_sinogram(data, pad_length)
            data = tomopy.remove_stripe_ti(data, alpha=4)
            if ring_removal:
                rec0 = tomopy.recon(data,
                                    theta,
                                    center=center + pad_length,
                                    algorithm=algorithm,
                                    **kwargs)
                rec = tomopy.remove_ring(np.copy(rec0))
                cent = int((rec.shape[1] - 1) / 2)
                xx, yy = np.meshgrid(np.arange(rec.shape[2]),
                                     np.arange(rec.shape[1]))
                mask0 = ((xx - cent)**2 +
                         (yy - cent)**2 <= flattened_radius**2)
                mask = np.zeros(rec.shape, dtype='bool')
                for i in range(mask.shape[0]):
                    mask[i, :, :] = mask0
                rec[mask] = (rec[mask] + rec0[mask]) / 2
            else:
                rec = tomopy.recon(data,
                                   theta,
                                   center=center + pad_length,
                                   algorithm=algorithm,
                                   **kwargs)
            if pad_length != 0:
                rec = rec[:, pad_length:pad_length + full_shape[2],
                          pad_length:pad_length + full_shape[2]]
            rec = tomopy.remove_outlier(rec, tolerance)
            rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)

            if crop is not None:
                crop = np.asarray(crop)
                rec = rec[:, crop[0, 0]:crop[1, 0], crop[0, 1]:crop[1, 1]]

            for i in range(rec.shape[0]):
                slice = sub_sino_ls[i]
                if test_mode:
                    dxchange.write_tiff(
                        rec[i, :, :],
                        fname=os.path.join(
                            dest_folder,
                            'recon/recon_{:05d}_{:d}.tiff').format(
                                slice, center),
                        dtype=dtype)
                else:
                    dxchange.write_tiff(
                        rec[i, :, :],
                        fname=os.path.join(
                            dest_folder,
                            'recon/recon_{:05d}.tiff').format(slice),
                        dtype=dtype)
                if save_sino:
                    dxchange.write_tiff(
                        data[:, i, :],
                        fname=os.path.join(
                            dest_folder, 'sino/recon_{:05d}_{:d}.tiff').format(
                                slice, center),
                        dtype=dtype)
            internal_print('Block {:d} finished in {:.2f} s.'.format(
                iblock,
                time.time() - t0))
            iblock += 1
    return
Exemple #6
0
def recon_single(fname,
                 center,
                 dest_folder,
                 sino_range=None,
                 chunk_size=50,
                 read_theta=True,
                 pad_length=0,
                 phase_retrieval=False,
                 ring_removal=True,
                 algorithm='gridrec',
                 flattened_radius=40,
                 crop=None,
                 remove_padding=True,
                 **kwargs):

    prj_shape = read_data_adaptive(fname, shape_only=True)
    if read_theta:
        theta = read_data_adaptive(fname, proj=(0, 1), return_theta=True)
    else:
        theta = tomopy.angles(prj_shape[0])
    if sino_range is None:
        sino_st = 0
        sino_end = prj_shape[1]
        sino_step = 1
    else:
        sino_st, sino_end = sino_range[:2]
        if len(sino_range) == 3:
            sino_step = sino_range[-1]
        else:
            sino_step = 1
    chunks = np.arange(0, sino_end, chunk_size * sino_step, dtype='int')
    for chunk_st in chunks:
        t0 = time.time()
        chunk_end = min(chunk_st + chunk_size * sino_step, prj_shape[1])
        data, flt, drk = read_data_adaptive(fname,
                                            sino=(chunk_st, chunk_end,
                                                  sino_step),
                                            return_theta=False)
        data = tomopy.normalize(data, flt, drk)
        data = data.astype('float32')
        data = tomopy.remove_stripe_ti(data, alpha=4)
        if phase_retrieval:
            data = tomopy.retrieve_phase(data, kwargs['pixel_size'],
                                         kwargs['dist'], kwargs['energy'],
                                         kwargs['alpha'])
        if pad_length != 0:
            data = pad_sinogram(data, pad_length)
        if ring_removal:
            data = tomopy.remove_stripe_ti(data, alpha=4)
            rec0 = tomopy.recon(data,
                                theta,
                                center=center + pad_length,
                                algorithm=algorithm,
                                **kwargs)
            rec = tomopy.remove_ring(np.copy(rec0))
            cent = int((rec.shape[1] - 1) / 2)
            xx, yy = np.meshgrid(np.arange(rec.shape[2]),
                                 np.arange(rec.shape[1]))
            mask0 = ((xx - cent)**2 + (yy - cent)**2 <= flattened_radius**2)
            mask = np.zeros(rec.shape, dtype='bool')
            for i in range(mask.shape[0]):
                mask[i, :, :] = mask0
            rec[mask] = (rec[mask] + rec0[mask]) / 2
        else:
            rec = tomopy.recon(data,
                               theta,
                               center=center + pad_length,
                               algorithm=algorithm,
                               **kwargs)
        if pad_length != 0 and remove_padding:
            rec = rec[:, pad_length:pad_length + prj_shape[2],
                      pad_length:pad_length + prj_shape[2]]
        rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)
        if crop is not None:
            crop = np.asarray(crop)
            rec = rec[:, crop[0, 0]:crop[1, 0], crop[0, 1]:crop[1, 1]]
        for i in range(rec.shape[0]):
            slice = chunk_st + sino_step * i
            internal_print('Saving slice {}'.format(slice))
            dxchange.write_tiff(
                rec[i, :, :],
                fname=os.path.join(dest_folder,
                                   'recon_{:05d}.tiff').format(slice),
                dtype='float32')
        internal_print('Block finished in {:.2f} s.'.format(time.time() - t0))
Exemple #7
0
def recon_block(grid,
                shift_grid,
                src_folder,
                dest_folder,
                slice_range,
                sino_step,
                center_vec,
                ds_level=0,
                blend_method='max',
                blend_options=None,
                tolerance=1,
                sinogram_order=False,
                algorithm='gridrec',
                init_recon=None,
                ncore=None,
                nchunk=None,
                dtype='float32',
                crop=None,
                save_sino=False,
                assert_width=None,
                sino_blur=None,
                color_correction=False,
                flattened_radius=120,
                normalize=True,
                test_mode=False,
                mode='180',
                phase_retrieval=None,
                data_format='aps_32id',
                read_theta=True,
                ring_removal=True,
                **kwargs):
    """
    Reconstruct dsicrete HDF5 tiles, blending sinograms only.
    """

    sino_ini = int(slice_range[0])
    sino_end = int(slice_range[1])
    mod_start_slice = 0
    center_vec = np.asarray(center_vec)
    center_pos_cache = 0
    sino_ls = np.arange(sino_ini, sino_end, sino_step, dtype='int')

    alloc_set = allocate_mpi_subsets(sino_ls.size, size, task_list=sino_ls)
    for i_slice in alloc_set[rank]:
        internal_print('############################################')
        internal_print('Reconstructing ' + str(i_slice))
        row_sino, center_pos = create_row_sinogram(
            grid, shift_grid, src_folder, i_slice, center_vec, ds_level,
            blend_method, blend_options, assert_width, sino_blur,
            color_correction, normalize, mode, phase_retrieval, data_format)
        if row_sino is None:
            continue
        if read_theta:
            _, _, _, theta = read_data_adaptive(os.path.join(
                src_folder, grid[0, 0]),
                                                proj=(0, 1),
                                                return_theta=True)
        if ring_removal:
            rec0 = recon_slice(row_sino,
                               theta,
                               center_pos,
                               sinogram_order=sinogram_order,
                               algorithm=algorithm,
                               init_recon=init_recon,
                               ncore=ncore,
                               nchunk=nchunk,
                               **kwargs)
            rec = tomopy.remove_ring(np.copy(rec0))
            cent = int((rec.shape[1] - 1) / 2)
            xx, yy = np.meshgrid(np.arange(rec.shape[2]),
                                 np.arange(rec.shape[1]))
            mask0 = ((xx - cent)**2 + (yy - cent)**2 <= flattened_radius**2)
            mask = np.zeros(rec.shape, dtype='bool')
            for i in range(mask.shape[0]):
                mask[i, :, :] = mask0
            rec[mask] = (rec[mask] + rec0[mask]) / 2
        else:
            rec = recon_slice(row_sino,
                              theta,
                              center_pos,
                              sinogram_order=sinogram_order,
                              algorithm=algorithm,
                              init_recon=init_recon,
                              ncore=ncore,
                              nchunk=nchunk,
                              **kwargs)
        #rec = tomopy.remove_outlier(rec, tolerance)
        rec = tomopy.circ_mask(rec, axis=0, ratio=0.95)

        internal_print('Center:            {:d}'.format(center_pos))
        rec = np.squeeze(rec)
        # correct recon position shifting due to center misalignment
        if center_pos_cache == 0:
            center_pos_cache = center_pos
        center_diff = center_pos - center_pos_cache
        if center_diff != 0:
            rec = np.roll(rec, -center_diff, axis=0)
        if not crop is None:
            crop = np.asarray(crop)
            rec = rec[crop[0, 0]:crop[1, 0], crop[0, 1]:crop[1, 1]]

        if test_mode:
            dxchange.write_tiff(rec,
                                fname=os.path.join(
                                    dest_folder,
                                    'recon/recon_{:05d}_{:04d}.tiff'.format(
                                        i_slice, center_pos)),
                                dtype=dtype)
        else:
            dxchange.write_tiff(rec,
                                fname=os.path.join(
                                    dest_folder,
                                    'recon/recon_{:05d}.tiff'.format(i_slice)),
                                dtype=dtype)
        if save_sino:
            dxchange.write_tiff(np.squeeze(row_sino),
                                fname=os.path.join(
                                    dest_folder,
                                    'sino/sino_{:05d}.tiff'.format(i_slice)),
                                overwrite=True)
    return
Exemple #8
0
def main(arg):

    parser = argparse.ArgumentParser()
    parser.add_argument("--src_folder",
                        help="folder where the H5 files are located",
                        default='data_raw_1x')
    parser.add_argument("--frame", help="frame to preview", default=None)
    parser.add_argument("--pano", help="Preview Panorama", default=None)
    args = parser.parse_args()

    src_folder = args.src_folder

    method = 'pyramid'
    margin = 50
    pyramid_options = {'depth': 5, 'blur': 0.4}

    f_pattern = 1
    prefix = ''
    file_list = tomosaic.get_files(src_folder, prefix, type='h5')
    print(file_list)
    file_grid = tomosaic.start_file_grid(file_list, pattern=f_pattern)
    file_grid = np.fliplr(file_grid)
    print(file_grid)
    data_format = 'aps_32id'

    try:
        shift_grid = tomosaic.util.file2grid("shifts.txt")
        shift_grid = tomosaic.absolute_shift_grid(shift_grid, file_grid)
    except:
        print('Refined shift is not provided. Using pre-set shift values. ')
        shift_grid = tomosaic.start_shift_grid(file_grid, x_shift, y_shift)

    if (args.frame != None):
        frame = int(args.frame)
        for f in file_list:
            dat, flt, drk, _ = read_data_adaptive(os.path.join(src_folder, f),
                                                  proj=(frame, frame + 1),
                                                  data_format=data_format)
            #dat = tomopy.normalize(dat, flt, drk)
            #dat = tomopy.minus_log(dat)
            f = os.path.splitext(os.path.basename(f))[0]
            dxchange.write_tiff(flt.mean(0),
                                os.path.join('preview_flats', f),
                                dtype='float32',
                                overwrite=True)
            dxchange.write_tiff(drk.mean(0),
                                os.path.join('preview_darks', f),
                                dtype='float32',
                                overwrite=True)
            dxchange.write_tiff(dat,
                                os.path.join('preview_frames', f),
                                dtype='float32',
                                overwrite=True)

    if (args.pano != None):
        pano = int(args.pano)
        buff = build_panorama('data_raw_1x',
                              file_grid,
                              shift_grid.astype(int),
                              frame=pano,
                              data_format=data_format,
                              method=method,
                              blend_options=pyramid_options)
        dxchange.write_tiff(buff,
                            'preview_panos/{}_norm'.format(pano),
                            dtype='float32',
                            overwrite=True)
    dat[np.where(np.isnan(dat) == True)] = 0
    if blur is not None:
        dat = gaussian_filter(dat, blur)

    return dat


shift_grid = tomosaic.start_shift_grid(file_grid, x_shift,
                                       y_shift).astype('int')
shift_grid = tomosaic.util.file2grid("shifts.txt")
shift_grid = (tomosaic.absolute_shift_grid(shift_grid, file_grid) / 4.)
print(shift_grid)
root = os.getcwd()
os.chdir(src_folder)
last_none = False
buff = np.zeros([1, 1])
for (y, x), value in np.ndenumerate(file_grid):
    if value != None:
        prj, flt, drk, _ = read_data_adaptive(value, proj=(frame, frame + 1))
        prj = tomopy.normalize(prj, flt, drk)
        prj = preprocess(np.copy(prj))
        buff = blend(buff, np.squeeze(prj), shift_grid[y, x, :], method=method)
        print(y, x)

os.chdir(root)

dxchange.write_tiff(buff,
                    'panos/{}_norm'.format(frame),
                    dtype='float32',
                    overwrite=True)