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
def convert(params): head_tail = os.path.split(params.old_projection_file_name) new_hdf_file_name = head_tail[0] + os.sep + os.path.splitext( head_tail[1])[0] + '.h5' print('converting data file: %s in new format: %s' % (params.old_projection_file_name, new_hdf_file_name)) print('using %s as dark and %s as white field' % (params.old_dark_file_name, params.old_white_file_name)) 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(params.old_projection_file_name, tomo_grp) flat = dxreader.read_hdf5(params.old_white_file_name, flat_grp) dark = dxreader.read_hdf5(params.old_dark_file_name, dark_grp) theta = dxreader.read_hdf5(params.old_projection_file_name, theta_grp) # Open DataExchange file f = dx.File(new_hdf_file_name, mode='w') f.add_entry(dx.Entry.data(data={'value': tomo, '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'})) f.add_entry(dx.Entry.data(theta={'value': theta, 'units': 'degrees'})) f.close()
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
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. """ 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 (theta is None): theta_size = dxreader.read_dx_dims(fname, 'data')[0] theta = np.linspace(0., np.pi, theta_size) else: theta = theta * np.pi / 180. return tomo, flat, dark, theta
def read_aps_32id(fname, exchange_rank=0, proj=None, sino=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 recontruct. 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) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ 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)) flat = dxreader.read_hdf5(fname, flat_grp, slc=(None, sino)) dark = dxreader.read_hdf5(fname, dark_grp, slc=(None, sino)) theta = dxreader.read_hdf5(fname, theta_grp, slc=None) if theta == None: pass else: theta = theta * np.pi / 180. return tomo, flat, dark, theta
def print_hdf5_item_structure(g, offset=' '): """Prints the input file/group/dataset (g) name and begin iterations on its content""" if isinstance(g, h5py.File): print(g.file, 'File:', g.name) elif isinstance(g, h5py.Dataset): #print ('Dataset: ', g.name) #, g.dtype if g.name == '/exchange/theta': print('theta array') elif g.name == '/exchange/data': print('data array') elif g.name == '/exchange/data_white': print('data white') elif g.name == '/exchange/data_dark': print('data dark') else: print(g.name, '=', dxreader.read_hdf5(fname, g.name)) elif isinstance(g, h5py.Group): print('Group:', g.name) else: print('WORNING: UNKNOWN ITEM IN HDF5 FILE', g.name) sys.exit("EXECUTION IS TERMINATED") if isinstance(g, h5py.File) or isinstance(g, h5py.Group): for key, val in dict(g).iteritems(): subg = val #print (offset, key )#," ", subg.name #, val, subg.len(), type(subg), print_hdf5_item_structure(subg, offset + ' ')
def print_hdf5_item_structure(g, offset=' ') : """Prints the input file/group/dataset (g) name and begin iterations on its content""" if isinstance(g, h5py.File) : print (g.file, 'File:', g.name) elif isinstance(g, h5py.Dataset) : #print ('Dataset: ', g.name) #, g.dtype if g.name == '/exchange/theta': print('theta array') elif g.name == '/exchange/data': print('data array') elif g.name == '/exchange/data_white': print('data white') elif g.name == '/exchange/data_dark' : print('data dark') else: print (g.name, '=', dxreader.read_hdf5(fname, g.name)) elif isinstance(g, h5py.Group) : print ('Group:', g.name) else : print ('WORNING: UNKNOWN ITEM IN HDF5 FILE', g.name) sys.exit ( "EXECUTION IS TERMINATED" ) if isinstance(g, h5py.File) or isinstance(g, h5py.Group) : for key,val in dict(g).iteritems() : subg = val #print (offset, key )#," ", subg.name #, val, subg.len(), type(subg), print_hdf5_item_structure(subg, offset + ' ')
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
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
def read_aps_32id(fname, exchange_rank=0, proj=None, sino=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 recontruct. 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) Returns ------- ndarray 3D tomographic data. ndarray 3D flat field data. ndarray 3D dark field data. """ 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']) tomo = dxreader.read_hdf5(fname, tomo_grp, slc=(proj, sino)) flat = dxreader.read_hdf5(fname, flat_grp, slc=(None, sino)) dark = dxreader.read_hdf5(fname, dark_grp, slc=(None, sino)) return tomo, flat, dark
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_grp = 'Prefiltered_images' theta_grp = '/'.join(['exchange', 'theta']) tomo = dxreader.read_hdf5(fname, tomo_grp, slc=(proj, sino)) theta = dxreader.read_hdf5(fname, theta_grp, slc=(proj, )) if (theta is None): ##theta_size = dxreader.read_dx_dims(fname, 'data')[0] theta_size = get_dx_dims(fname, 'Prefiltered_images')[0] #logger.warn('Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset' % (str(theta_size))) print( 'Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset' % (str(theta_size))) theta = np.linspace(0., np.pi, theta_size) else: theta = theta * np.pi / 180. return tomo, theta
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_grp = 'Prefiltered_images' theta_grp = '/'.join(['exchange', 'theta']) tomo = dxreader.read_hdf5(fname, tomo_grp, slc=(proj, sino)) theta = dxreader.read_hdf5(fname, theta_grp, slc=(proj, )) if (theta is None): ##theta_size = dxreader.read_dx_dims(fname, 'data')[0] theta_size = get_dx_dims(fname, 'Prefiltered_images')[0] #logger.warn('Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset' % (str(theta_size))) print('Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset' % (str(theta_size))) theta = np.linspace(0. , np.pi, theta_size) else: theta = theta * np.pi / 180. return tomo, theta
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), dtype=np.uint16) flats = dxreader.read_hdf5(fname, 'img_bkg', slc=(None, sino), dtype=np.uint16) darks = dxreader.read_hdf5(fname, 'img_dark', slc=(None, sino), dtype=np.uint16) theta = dxreader.read_hdf5(fname, 'angle', slc=(proj, )) theta = np.deg2rad(theta) return tomo, flats, darks, theta
def main(arg): parser = argparse.ArgumentParser( description='Push a dxchange/HDF5 data set to Slicerecon.') parser.add_argument("fname", help="file name of a tomographic dataset") parser.add_argument("--type", nargs='?', type=str, default="slice", help="reconstruction type: full (default slice)") parser.add_argument( "--nsino", nargs='?', type=float, default=0.5, help= "location of the sinogram used by slice reconstruction (0 top, 1 bottom): 0.5 (default 0.5)" ) parser.add_argument( "--nsinoheight", nargs='?', type=int, default=16, help= "amount of vertical detector pixels to use, has to be a multiple of 2") parser.add_argument( "--tv", nargs='?', type=bool, default=False, help= "Use Total variation reconstruction method (Gridrec otherwise): False (default False)" ) parser.add_argument("--frame", nargs='?', type=str, default=92, help="time frame with motion: 92 (default 92)") parser.add_argument( '--dataset', default='data', help= 'which dataset to use from the HDF5 file, {data,data_dark,data_white}') parser.add_argument('--binning', nargs='?', type=int, default=1, help="binning factor") parser.add_argument( '--sample', type=int, default=1, help= 'the binning to use on the detector, and how many projections to skip') parser.add_argument('--host', default="localhost", help='the projection server host') parser.add_argument('--port', type=int, default=5558, help='the projection server port') parser.add_argument('--skipgeometry', action='store_true', help='assume the geometry packet is already sent') args = parser.parse_args() fname = args.fname if not os.path.isfile(fname): print("HDF5/dx file not found.") return nsino = float(args.nsino) nsinoheight = int(args.nsinoheight) binning = int(args.binning) subsampling = int( args.sample) # taking 1 per (subsampling) instead of all the frames nproj = 600 # number of projections per 180 degrees interval, this is coded scene_id = 0 assert ((nproj / subsampling).is_integer()) assert ((nsinoheight / 2).is_integer()) proj_count = int( nproj / subsampling ) # this should be the --group-size on the server, because we want # reconstructions from a sampled 180 shot print("Note: call the SliceRecon server with --group-size", proj_count, "to get reconstruction from 180 degrees angles") data_size = get_dx_dims(fname, 'data') # Select sinogram range to reconstruct. ssino = int(data_size[1] * nsino) sino_start = ssino - nsinoheight / 2 * pow(2, binning) sino_end = ssino + nsinoheight / 2 * pow(2, binning) sino = (int(sino_start), int(sino_end)) # Read APS 32-BM raw data, for the sake of darks and flats print("Reading flats, darks ...") proj, flat, dark, _ = dxchange.read_aps_32id( fname, proj=1, sino=sino) # angles give nonsense values # Phase retrieval for tomobank id 00080 # sample_detector_distance = 25 # detector_pixel_size_x = 3.0e-4 # monochromator_energy = 16 # Phase retrieval # data = tomopy.prep.phase.retrieve_phase(data,pixel_size=detector_pixel_size_x,dist=sample_detector_distance,energy=monochromator_energy,alpha=8e-03,pad=True) # @todo Fix center of rotation shift! # rot_center = data.shape[2]/2 # Detector dimensions rows = proj.shape[1] cols = proj.shape[2] # parallel beam data is easy, the geometry volume is never bigger than the projection volume rx = np.ceil(data_size[2] / 2) # max radius in the x,y plane rz = np.ceil(data_size[1] / 2) # max radius in the z axis pub = tp.publisher(args.host, args.port) if not args.skipgeometry: window_min_point = [-rx, -rx, -rz] # x,y,z window_max_point = [rx, rx, rz] # x,y,z angles = np.linspace(0, 2 * np.pi, proj_count, endpoint=False) # np.mod(theta[0:nproj], np.pi) pub.send( tp.geometry_specification_packet(scene_id, window_min_point, window_max_point)) pub.send( tp.parallel_beam_geometry_packet(scene_id, rows, cols, proj_count, angles)) # We're not sending flats and darks to the SliceRecon server (see below) because (i) buffer may not be large # enough and (ii) we will want to do preprocessing of the projection data here anyway # already_linear_flatdarks = False # pub.send(tp.scan_settings_packet(scene_id, dark.shape[0], flat.shape[0], already_linear_flatdarks)) # for i in np.arange(0, 2): # pub.send(tp.projection_packet(0, i, [rows, cols], np.ascontiguousarray(dark[i, :, :].flatten()))) # # for i in np.arange(0, 2): # pub.send(tp.projection_packet(1, i, [rows, cols], np.ascontiguousarray(flat[i, :, :].flatten()))) # I'm circumventing the dxchange.read_aps_32id, as it cannot select specific projections (always loading the full # dataset) exchange_base = "exchange" tomo_grp = '/'.join([exchange_base, 'data']) j = 0 for i in np.arange(1, data_size[0], subsampling): print("Pushing ", i, " of ", data_size[0]) data = dxreader.read_hdf5(fname, tomo_grp, slc=((int(i), int(i) + 1), sino)) # Flat-field correction of raw data. data = tomopy.normalize(data, flat, dark) # Remove stripes (not so suitable for realtime really!) # data = tomopy.remove_stripe_fw(data, level=7, wname='sym16', sigma=1, pad=True) # Log filter # 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 packet_type = 2 # projection packet pub.send( tp.projection_packet(packet_type, j, [rows, cols], np.ascontiguousarray(data[0].flatten()))) j = j + 1
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. """ 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 (theta is None): theta_size = dxreader.read_dx_dims(fname, 'data')[0] logger.warn('Generating "%s" [0-180] deg angles for missing "exchange/theta" dataset' % (str(theta_size))) theta = np.linspace(0. , np.pi, theta_size) else: theta = theta * np.pi / 180. return tomo, flat, dark, theta
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