Source code for dxchange.exchange

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# #########################################################################
# Copyright (c) 2015, UChicago Argonne, LLC. All rights reserved.         #
#                                                                         #
# Copyright 2015. UChicago Argonne, LLC. This software was produced       #
# under U.S. Government contract DE-AC02-06CH11357 for Argonne National   #
# Laboratory (ANL), which is operated by UChicago Argonne, LLC for the    #
# U.S. Department of Energy. The U.S. Government has rights to use,       #
# reproduce, and distribute this software.  NEITHER THE GOVERNMENT NOR    #
# UChicago Argonne, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR        #
# ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is     #
# modified to produce derivative works, such modified software should     #
# be clearly marked, so as not to confuse it with the version available   #
# from ANL.                                                               #
#                                                                         #
# Additionally, redistribution and use in source and binary forms, with   #
# or without modification, are permitted provided that the following      #
# conditions are met:                                                     #
#                                                                         #
#     * Redistributions of source code must retain the above copyright    #
#       notice, this list of conditions and the following disclaimer.     #
#                                                                         #
#     * Redistributions in binary form must reproduce the above copyright #
#       notice, this list of conditions and the following disclaimer in   #
#       the documentation and/or other materials provided with the        #
#       distribution.                                                     #
#                                                                         #
#     * Neither the name of UChicago Argonne, LLC, Argonne National       #
#       Laboratory, ANL, the U.S. Government, nor the names of its        #
#       contributors may be used to endorse or promote products derived   #
#       from this software without specific prior written permission.     #
#                                                                         #
# THIS SOFTWARE IS PROVIDED BY UChicago Argonne, LLC AND CONTRIBUTORS     #
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       #
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS       #
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UChicago     #
# Argonne, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,        #
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,    #
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;        #
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER        #
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT      #
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN       #
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         #
# POSSIBILITY OF SUCH DAMAGE.                                             #
# #########################################################################

"""
Module for describing beamline/experiment specific data recipes.
"""

from __future__ import (absolute_import,
                        division,
                        print_function,
                        unicode_literals,
                        )

import os.path
import re
import fnmatch
import logging
import numpy as np
import dxchange.reader as dxreader

__authors__ = "Doga Gursoy, Luis Barroso-Luque, Francesco De Carlo"
__copyright__ = "Copyright (c) 2015-2016, UChicago Argonne, LLC."
__version__ = "0.1.0"
__docformat__ = "restructuredtext en"
__all__ = ['read_als_832',
           'read_als_832h5',
           'read_anka_topotomo',
           'read_aps_tomoscan_hdf5',
           'read_aps_1id',
           'read_aps_2bm',
           'read_aps_5bm',
           'read_aps_7bm',
           'read_aps_8bm',
           'read_aps_13bm',
           'read_aps_13id',
           'read_aps_26id',
           'read_aps_32id',
           'read_aus_microct',
           'read_diamond_l12',
           'read_elettra_syrmep',
           'read_esrf_id19',
           'read_lnls_imx',
           'read_nsls2_fxi18_h5',
           'read_petraIII_p05',
           'read_sls_tomcat',
           'read_nexus']

logger = logging.getLogger(__name__)


[docs]def read_als_832(fname, ind_tomo=None, normalized=False, proj=None, sino=None): """ Read ALS 8.3.2 standard data format. Parameters ---------- fname : str Path to file name without indices and extension. ind_tomo : list of int, optional Indices of the projection files to read. normalized : boolean, optional If False, darks and flats will not be read. This should only be used for cases where tomo is already normalized. 8.3.2 has a plugin that normalization is preferred to be done with prior to tomopy reconstruction. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ # File definitions. fname = os.path.abspath(fname) if not normalized: tomo_name = fname + '_0000_0000.tif' flat_name = fname + 'bak_0000.tif' dark_name = fname + 'drk_0000.tif' log_file = fname + '.sct' else: if "output" not in fname: raise Exception( 'Please provide the normalized output directory as input') tomo_name = fname + '_0.tif' fname = fname.split( 'output')[0] + fname.split('/')[len(fname.split('/')) - 1] log_file = fname + '.sct' # Read metadata from ALS log file. contents = open(log_file, 'r') for line in contents: if '-nangles' in line: nproj = int(re.findall(r'\d+', line)[0]) if '-num_bright_field' in line: nflat = int(re.findall(r'\d+', line)[0]) if '-i0cycle' in line: inter_bright = int(re.findall(r'\d+', line)[1]) if '-num_dark_fields' in line: ndark = int(re.findall(r'\d+', line)[0]) contents.close() if ind_tomo is None: ind_tomo = list(range(0, nproj)) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] if not normalized: ind_flat = list(range(0, nflat)) if inter_bright > 0: ind_flat = list(range(0, nproj, inter_bright)) flat_name = fname + 'bak_0000_0000.tif' ind_dark = list(range(0, ndark)) # Read image data from tiff stack. tomo = dxreader.read_tiff_stack(tomo_name, ind=ind_tomo, digit=4, slc=(sino, None)) if not normalized: # Adheres to 8.3.2 flat/dark naming conventions: # ----Flats---- # root_namebak_xxxx_yyyy # For datasets that take flat at the start and end of its scan, # xxxx is in incrementals of one, and yyyy is either 0000 or the # last projection. For datasets that take flat while they scan # (when the beam fluctuates during scans), # xxxx is always 0000, and yyyy is in intervals given by log file. if inter_bright == 0: a = [0, nproj - 1] list_flat = dxreader._list_file_stack(flat_name, ind_flat, digit=4) for x in ind_flat: body = os.path.splitext(list_flat[x])[0] + "_" ext = os.path.splitext(list_flat[x])[1] for y, z in enumerate(a): y = body + '{0:0={1}d}'.format(z, 4) + ext if z == 0: list_flat[x] = y else: list_flat.append(y) list_flat = sorted(list_flat) for m, image in enumerate(list_flat): _arr = dxreader.read_tiff(image) if m == 0: dx = len(ind_flat * 2) dy, dz = _arr.shape flat = np.zeros((dx, dy, dz)) flat[m] = _arr flat = dxreader._slice_array(flat, (None, sino)) else: flat = dxreader.read_tiff_stack(flat_name, ind=ind_flat, digit=4, slc=(sino, None)) # Adheres to 8.3.2 flat/dark naming conventions: # ----Darks---- # root_namedrk_xxxx_yyyy # All datasets thus far that take darks at the start and end of # its scan, so xxxx is in incrementals of one, and yyyy is either # 0000 or the last projection. list_dark = dxreader._list_file_stack(dark_name, ind_dark, digit=4) for x in ind_dark: body = os.path.splitext(list_dark[x])[0] + '_' ext = os.path.splitext(list_dark[x])[1] body = body + '{0:0={1}d}'.format(nproj - 1, 4) + ext list_dark[x] = body list_dark = sorted(list_dark) for m, image in enumerate(list_dark): _arr = dxreader.read_tiff(image) if m == 0: dx = len(ind_dark) dy, dz = _arr.shape dark = np.zeros((dx, dy, dz)) dark[m] = _arr dark = dxreader._slice_array(dark, (None, sino)) else: flat = np.ones(1) dark = np.zeros(1) return tomo, flat, dark
[docs]def read_als_832h5(fname, ind_tomo=None, ind_flat=None, ind_dark=None, proj=None, sino=None): """ Read ALS 8.3.2 hdf5 file with stacked datasets. Parameters ---------- fname : str Path to hdf5 file. ind_tomo : list of int, optional Indices of the projection files to read. ind_flat : list of int, optional Indices of the flat field files to read. ind_dark : list of int, optional Indices of the dark field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. list of int Indices of flat field data within tomography projection list """ with dxreader.find_dataset_group(fname) as dgroup: dname = dgroup.name.split('/')[-1] tomo_name = dname + '_0000_0000.tif' flat_name = dname + 'bak_0000.tif' dark_name = dname + 'drk_0000.tif' # Read metadata from dataset group attributes keys = list(dgroup.attrs.keys()) if 'nangles' in keys: nproj = int(dgroup.attrs['nangles']) if 'i0cycle' in keys: inter_bright = int(dgroup.attrs['i0cycle']) if 'num_bright_field' in keys: nflat = int(dgroup.attrs['num_bright_field']) else: nflat = dxreader._count_proj(dgroup, flat_name, nproj, inter_bright=inter_bright) if 'num_dark_fields' in keys: ndark = int(dgroup.attrs['num_dark_fields']) else: ndark = dxreader._count_proj(dgroup, dark_name, nproj) # Create arrays of indices to read projections, flats and darks if ind_tomo is None: ind_tomo = list(range(0, nproj)) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] ind_dark = list(range(0, ndark)) group_dark = [nproj - 1] ind_flat = list(range(0, nflat)) if inter_bright > 0: group_flat = list(range(0, nproj, inter_bright)) if group_flat[-1] != nproj - 1: group_flat.append(nproj - 1) elif inter_bright == 0: group_flat = [0, nproj - 1] else: group_flat = None tomo = dxreader.read_hdf5_stack( dgroup, tomo_name, ind_tomo, slc=(None, sino)) flat = dxreader.read_hdf5_stack( dgroup, flat_name, ind_flat, slc=(None, sino), out_ind=group_flat) dark = dxreader.read_hdf5_stack( dgroup, dark_name, ind_dark, slc=(None, sino), out_ind=group_dark) return tomo, flat, dark, dxreader._map_loc(ind_tomo, group_flat)
[docs]def read_anka_topotomo( fname, ind_tomo, ind_flat, ind_dark, proj=None, sino=None): """ Read ANKA TOPO-TOMO standard data format. Parameters ---------- fname : str Path to data folder name without indices and extension. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. ind_dark : list of int, optional Indices of the dark field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'radios', 'image_00000.tif') flat_name = os.path.join(fname, 'flats', 'image_00000.tif') dark_name = os.path.join(fname, 'darks', 'image_00000.tif') if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo = dxreader.read_tiff_stack( tomo_name, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( flat_name, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( dark_name, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark
[docs]def read_aps_1id(fname, ind_tomo=None, proj=None, sino=None, layer=0): """ Read APS 1-ID standard data format. Parameters ---------- fname : str Path to file name without indices and extension. ind_tomo : list of int, optional Indices of the projection files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) layer: int, optional Specify the layer to reconstruct Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ # File definitions. fname = os.path.abspath(fname) _fname = fname + '000001.tif' log_file = fname + 'TomoStillScan.dat' # parse the log/metadata file _metadf = dxreader.read_aps_1id_metafile(log_file) # meta data for layer to reconstruct try: _layerdf = _metadf[_metadf['layerID'] == layer] except: print("Valid layers for reconstruction are: {}".format(_metadf['layerID'].unique())) # -- queery image data meta for given layer # still/projection images prj_start = _layerdf.loc[_layerdf['type'] == 'still', 'nSeq'].values[0] nprj = _layerdf.loc[_layerdf['type'] == 'still', 'nSeq'].shape[0] # dark field images dark_start = _layerdf.loc[_layerdf['type'] == 'post_dark', 'nSeq'].values[0] ndark = _layerdf.loc[_layerdf['type'] == 'post_dark', 'nSeq'].shape[0] # white/flat field images (only use pre_white) # NOTE: The beam condition might change overtime, therefore flat field # images are taken both before and after the experiment. # The implementation here assumes the beam is stable throughout the # experiment flat_start = _layerdf.loc[_layerdf['type'] == 'pre_white', 'nSeq'].values[0] nflat = _layerdf.loc[_layerdf['type'] == 'pre_white', 'nSeq'].shape[0] if ind_tomo is None: ind_tomo = list(range(prj_start, prj_start + nprj)) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] ind_flat = list(range(flat_start, flat_start + nflat)) ind_dark = list(range(dark_start, dark_start + ndark)) tomo = dxreader.read_tiff_stack( _fname, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( _fname, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( _fname, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark
[docs]def read_aps_2bm(fname, proj=None, sino=None): """ Read APS 2-BM standard data format. Parameters ---------- fname : str Path to hdf5 file. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ return read_aps_tomoscan_hdf5(fname, proj=proj, sino=sino)
[docs]def read_aps_5bm(fname, sino=None): """ Read APS 5-BM standard data format. Parameters ---------- fname : str Path to data folder. sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'sdat0000.xmt') flat_name = os.path.join(fname, 'snor0000.xmt') dark_name = os.path.join(fname, 'sdarkfile.xmt') ntomo = len(fnmatch.filter(os.listdir(fname), 'sdat*')) ind_tomo = range(0, ntomo) nflat = len(fnmatch.filter(os.listdir(fname), 'snor*')) ind_flat = range(0, nflat) tomo = dxreader.read_tiff_stack(tomo_name, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack(flat_name, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff(dark_name, slc=(sino, None)) # array bite swapping for index in ind_tomo: tomo[index] = tomo[index].byteswap() for index in ind_flat: flat[index] = flat[index].byteswap() dark = dark.byteswap() return tomo, flat, dark
[docs]def read_aps_7bm(fname, proj=None, sino=None): """ Read APS 7-BM standard data format. Parameters ---------- fname : str Path to hdf5 file. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. array Projection angles in radian. """ tomo_grp = '/'.join(['exchange', 'data']) theta_grp = '/'.join(['exchange', 'theta']) tomo = dxreader.read_hdf5(fname, tomo_grp, slc=(proj, sino)) theta = dxreader.read_hdf5(fname, theta_grp, slc=(proj, )) return tomo, theta
[docs]def read_aps_8bm(image_directory, ind_tomo, ind_flat, image_file_pattern='image_00000.xrm', flat_file_pattern='ref_00000.xrm', proj=None, sino=None): """ Read APS 8-BM tomography data from a stack of xrm files. Parameters ---------- image_directory : str Path to data folder name without indices and extension. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. image_file_pattern: string Specify how the projection files are named. flat_file_pattern: string Specify how the flat reference files are named. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. dictionary Image set metadata. """ image_directory = os.path.abspath(image_directory) tomo_name = os.path.join(image_directory, 'radios', image_file_pattern) flat_name = os.path.join(image_directory, 'flats', flat_file_pattern) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo, metadata = dxreader.read_xrm_stack( tomo_name, ind=ind_tomo, slc=(sino, None)) flat, _ = dxreader.read_xrm_stack( flat_name, ind=ind_flat, slc=(sino, None)) return tomo, flat, metadata
[docs]def read_aps_13bm(fname, file_format, proj=None, sino=None): """ Read APS 13-BM standard data format. Searches directory for all necessary files, and then combines the separate flat fields. Parameters ---------- fname : str Path to hdf5 file. format : str Data format. 'spe' or 'netcdf4' proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. """ if file_format == 'netcdf4': base_name = fname[0:-4] tomo = dxreader.read_netcdf4(base_name + '2.nc', 'array_data', slc=(proj, sino)) flat1 = dxreader.read_netcdf4(base_name + '1.nc', 'array_data', slc=(None, sino)) flat2 = dxreader.read_netcdf4(base_name + '3.nc', 'array_data', slc=(None, sino)) flat = np.concatenate((flat1, flat2), axis = 0) del flat1, flat2 setup = base_name + '.setup' setup = open(setup, 'r') setup_data = setup.readlines() result = {} for line in setup_data: words = line[:-1].split(':',1) result[words[0].lower()] = words[1] dark = float(result['dark_current']) dark = flat*0+dark theta = np.linspace(0.0, np.pi, tomo.shape[0]) return tomo, flat, dark, theta if file_format == 'hdf5': return read_aps_tomoscan_hdf5(fname, proj=proj, sino=sino) return None
[docs]def read_aps_13id( fname, group='/xrfmap/roimap/sum_cor', proj=None, sino=None): """ Read APS 13-ID standard data format. Parameters ---------- fname : str Path to hdf5 file. group : str, optional Path to the group inside hdf5 file where data is located. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. """ tomo = dxreader.read_hdf5(fname, group, slc=(None, proj, sino)) tomo = np.swapaxes(tomo, 0, 1) tomo = np.swapaxes(tomo, 1, 2).copy() return tomo
[docs]def read_aps_26id(image_directory, ind_tomo, ind_flat, image_file_pattern='image_00000.xrm', flat_file_pattern='ref_00000.xrm', proj=None, sino=None): """ Read APS 26-ID tomography data from a stack of xrm files. Parameters ---------- fname : str Path to data folder name without indices and extension. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. dictionary Image set metadata. """ return read_aps_8bm(image_directory, ind_tomo, ind_flat, image_file_pattern, flat_file_pattern, proj, sino)
[docs]def read_aps_32id(fname, exchange_rank=0, proj=None, sino=None, dtype=None): """ Read APS 32-ID standard data format. Parameters ---------- fname : str Path to hdf5 file. exchange_rank : int, optional exchange_rank is added to "exchange" to point tomopy to the data to reconstruct. if rank is not set then the data are raw from the detector and are located under exchange = "exchange/...", to process data that are the result of some intemedite processing step then exchange_rank = 1, 2, ... will direct tomopy to process "exchange1/...", proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) dtype : numpy datatype, optional Convert data to this datatype on read if specified. Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. ndarray 1D theta in radian. """ return read_aps_tomoscan_hdf5(fname, exchange_rank=exchange_rank, proj=proj, sino=sino)
[docs]def read_aps_tomoscan_hdf5(fname, exchange_rank=0, proj=None, sino=None, dtype=None): """ Read APS tomoscan HDF5 format. Parameters ---------- fname : str Path to hdf5 file. exchange_rank : int, optional exchange_rank is added to "exchange" to point tomopy to the data to reconstruct. if rank is not set then the data are raw from the detector and are located under exchange = "exchange/...", to process data that are the result of some intermediate processing step then exchange_rank = 1, 2, ... will direct tomopy to process "exchange1/...", proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) dtype : numpy datatype, optional Convert data to this datatype on read if specified. Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. ndarray 1D theta in radian. """ if exchange_rank > 0: exchange_base = 'exchange{:d}'.format(int(exchange_rank)) else: exchange_base = "exchange" tomo_grp = '/'.join([exchange_base, 'data']) flat_grp = '/'.join([exchange_base, 'data_white']) dark_grp = '/'.join([exchange_base, 'data_dark']) theta_grp = '/'.join([exchange_base, 'theta']) tomo = dxreader.read_hdf5(fname, tomo_grp, slc=(proj, sino), dtype=dtype) flat = dxreader.read_hdf5(fname, flat_grp, slc=(None, sino), dtype=dtype) dark = dxreader.read_hdf5(fname, dark_grp, slc=(None, sino), dtype=dtype) theta = dxreader.read_hdf5(fname, theta_grp, slc=None) if (flat is None) or ((flat.shape[0]==1) and (flat.max() == 0)): try: # See if flat_field_value is in the file flat_field_value = dxreader.read_hdf5(fname, '/process/acquisition/flat_fields/flat_field_value')[0] flat = tomo[0,:,:] * 0 + flat_field_value except: logger.warn('No flat field data or flat_field_value') if (dark is None) or ((dark.shape[0]==1) and (dark.max() == 0)): try: # See if dark_field_value is in the file dark_field_value = dxreader.read_hdf5(fname, '/process/acquisition/dark_fields/dark_field_value')[0] dark = tomo[0,:,:] * 0 + dark_field_value except: logger.warn('No dark field data or dark_field_value') if theta is None: try: # See if the rotation start, step, num_angles are in the file rotation_start = dxreader.read_hdf5(fname, '/process/acquisition/rotation/rotation_start')[0] rotation_step = dxreader.read_hdf5(fname, '/process/acquisition/rotation/rotation_step')[0] num_angles = dxreader.read_hdf5(fname, '/process/acquisition/rotation/num_angles')[0] if num_angles != tomo.shape[0]: logger.warn('num_angles(%d) is not the same as tomo.shape[0](%d)', num_angles, tomo.shape[0]) theta = rotation_start + rotation_step*range(num_angles) except: theta_size = tomo.shape[0] logger.warn('Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset', str(theta_size)) theta = np.linspace(0. , 180, theta_size) theta = np.deg2rad(theta) return tomo, flat, dark, theta
[docs]def read_nexus(fname, proj=None, sino=None, dtype=None, data_path="/entry1/tomo_entry/data/", angle_path="/entry1/tomo_entry/data/", image_key_path="/entry1/instrument/image_key/image_key"): """ Read NeXus tomo HDF5 format. Parameters ---------- fname : str Path to hdf5 file. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) dtype : numpy datatype, optional Convert data to this datatype on read if specified. data_path : string, optional hdf file path location of the data image_key_path : string, optional hdf file path location of the image type keys. 0 = projection, 1 = flat, 2 = dark Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. ndarray 1D theta in radian. """ dataset_grp = '/'.join([data_path, 'data']) theta_grp = '/'.join([data_path, 'rotation_angle']) dataset = read_hdf5(fname, dataset_grp, slc=(proj, sino), dtype=dtype) angles = read_hdf5(fname, theta_grp, slc=None) # Get the indices of where the data, flat and dark are the dataset with h5.File(fname, "r") as file: data_indices = [] darks_indices = [] flats_indices = [] for i, key in enumerate(file[image_key_path]): if int(key) == 0: data_indices.append(i) elif int(key) == 1: flats_indices.append(i) elif int(key) == 2: darks_indices.append(i) darks = [dataset[x] for x in darks_indices] flats = [dataset[x] for x in flats_indices] tomo = [dataset[x] for x in data_indices] theta = [angles[x] for x in data_indices] theta = np.deg2rad(theta) return tomo, flat, dark, theta
[docs]def read_aus_microct(fname, ind_tomo, ind_flat, ind_dark, proj=None, sino=None): """ Read Australian Synchrotron micro-CT standard data format. Parameters ---------- fname : str Path to data folder. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. ind_dark : list of int Indices of the dark field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'SAMPLE_T_0000.tif') flat_name = os.path.join(fname, 'BG__BEFORE_00.tif') dark_name = os.path.join(fname, 'DF__BEFORE_00.tif') if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo = dxreader.read_tiff_stack( tomo_name, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( flat_name, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( dark_name, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark
[docs]def read_esrf_id19(fname, proj=None, sino=None): """ Read ESRF ID-19 standard data format. Parameters ---------- fname : str Path to edf file. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'tomo.edf') flat_name = os.path.join(fname, 'flat.edf') dark_name = os.path.join(fname, 'dark.edf') tomo = dxreader.read_edf(tomo_name, slc=(proj, sino)) flat = dxreader.read_edf(flat_name, slc=(None, sino)) dark = dxreader.read_edf(dark_name, slc=(None, sino)) return tomo, flat, dark
[docs]def read_diamond_l12(fname, ind_tomo, proj=None): """ Read Diamond Light Source L12 (JEEP) standard data format. Parameters ---------- fname : str Path to data folder. ind_tomo : list of int Indices of the projection files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'im_001000.tif') flat_name = os.path.join(fname, 'flat_000000.tif') ind_flat = list(range(0, 1)) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo = dxreader.read_tiff_stack(tomo_name, ind=ind_tomo) flat = dxreader.read_tiff_stack(flat_name, ind=ind_flat) return tomo, flat
[docs]def read_elettra_syrmep( fname, ind_tomo, ind_flat, ind_dark, proj=None, sino=None): """ Read Elettra SYRMEP standard data format. Parameters ---------- fname : str Path to data folder. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. ind_dark : list of int Indices of the dark field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join(fname, 'tomo_0001.tif') flat_name = os.path.join(fname, 'flat_1.tif') dark_name = os.path.join(fname, 'dark_1.tif') if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo = dxreader.read_tiff_stack( tomo_name, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( flat_name, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( dark_name, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark
[docs]def read_lnls_imx(folder, proj=None, sino=None): """ Read LNLS IMX standard data format. Parameters ---------- folder : str Path to sample folder (containing tomo.h5, flat.h5, dark.h5) proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ folder = os.path.abspath(folder) tomo_name = os.path.join(folder, 'tomo.h5') flat_name = os.path.join(folder, 'tomo_flat_before.h5') dark_name = os.path.join(folder, 'tomo_dark_before.h5') tomo = dxreader.read_hdf5(tomo_name, 'images', slc=(proj, sino)) flat = dxreader.read_hdf5(flat_name, 'flats', slc=(None, sino)) dark = dxreader.read_hdf5(dark_name, 'darks', slc=(None, sino)) return tomo, flat, dark
[docs]def read_nsls2_fxi18_h5(fname, proj=None, sino=None): """ Read LNLS IMX standard data format. Parameters ---------- fname : str Path to h5 file. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. ndarray 1D theta in radian. """ tomo = dxreader.read_hdf5(fname, 'img_tomo', slc=(proj, sino)) flats = dxreader.read_hdf5(fname, 'img_bkg', slc=(None, sino)) darks = dxreader.read_hdf5(fname, 'img_dark', slc=(None, sino)) theta = dxreader.read_hdf5(fname, 'angle', slc=(proj,)) theta = np.deg2rad(theta) return tomo, flats, darks, theta
[docs]def read_petraIII_p05( fname, ind_tomo, ind_flat, ind_dark, proj=None, sino=None): """ Read Petra-III P05 standard data format. Parameters ---------- fname : str Path to data folder. ind_tomo : list of int Indices of the projection files to read. ind_flat : list of int Indices of the flat field files to read. ind_dark : list of int Indices of the dark field files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ fname = os.path.abspath(fname) tomo_name = os.path.join( fname, 'scan_0002', 'ccd', 'pco01', 'ccd_0000.tif') flat_name = os.path.join( fname, 'scan_0001', 'ccd', 'pco01', 'ccd_0000.tif') dark_name = os.path.join( fname, 'scan_0000', 'ccd', 'pco01', 'ccd_0000.tif') if proj is not None: ind_tomo = ind_tomo[slice(*proj)] tomo = dxreader.read_tiff_stack( tomo_name, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( flat_name, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( dark_name, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark
[docs]def read_sls_tomcat(fname, ind_tomo=None, proj=None, sino=None): """ Read SLS TOMCAT standard data format. Parameters ---------- fname : str Path to file name without indices and extension. ind_tomo : list of int, optional Indices of the projection files to read. proj : {sequence, int}, optional Specify projections to read. (start, end, step) sino : {sequence, int}, optional Specify sinograms to read. (start, end, step) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ # File definitions. fname = os.path.abspath(fname) _fname = fname + '0001.tif' log_file = fname + '.log' # Read metadata from SLS log file. contents = open(log_file, 'r') for line in contents: ls = line.split() if len(ls) > 1: if ls[0] == 'Number' and ls[2] == 'projections': nproj = int(ls[4]) elif ls[0] == 'Number' and ls[2] == 'flats': nflat = int(ls[4]) elif ls[0] == 'Number' and ls[2] == 'darks': ndark = int(ls[4]) contents.close() dark_start = 1 dark_end = ndark + 1 flat_start = dark_end flat_end = flat_start + nflat proj_start = flat_end proj_end = proj_start + nproj if ind_tomo is None: ind_tomo = list(range(proj_start, proj_end)) if proj is not None: ind_tomo = ind_tomo[slice(*proj)] ind_flat = list(range(flat_start, flat_end)) ind_dark = list(range(dark_start, dark_end)) tomo = dxreader.read_tiff_stack( _fname, ind=ind_tomo, slc=(sino, None)) flat = dxreader.read_tiff_stack( _fname, ind=ind_flat, slc=(sino, None)) dark = dxreader.read_tiff_stack( _fname, ind=ind_dark, slc=(sino, None)) return tomo, flat, dark