Modules
flexDATA includes three modules: geometry, data and display.
A wide range of acquisition geometries can be defined using the geometry module. For I/O operations and some utilities for out-of-memory arrays are implemented in the data module. Basic display utilities can be found in display module.
flexdata.geometry module
This module contains acquisition geometry classes: circular, linear, helical. The circular class corresponds to the simplest case of circular orbit cone-beam CT with minimal number of parameters. Additional parameters can be use to define a non-conventional geometry. For instance: offsets and rotations (‘det_roll’, ‘det_tan’, ‘det_ort’, etc.), axis tilts (‘axs_roll’, ‘axs_pitch’), volume transformations (‘vol_tra’, ‘vol_rot’), recostruction resolution and anisotropic sampling (‘img_pixel’, ‘det_sample’, ‘vol_sample’).
- flexdata.geometry.astra_projection_geom(geom, data_shape, index=None)[source]
Initialize ASTRA projection geometry.
- Args:
geom : geometry class data_shape: [detector_count_z, theta_count, detector_count_x] index : if provided - sequence of the rotation angles
- flexdata.geometry.astra_volume_geom(geom, vol_shape, slice_first=None, slice_last=None)[source]
Initialize ASTRA volume geometry.
- class flexdata.geometry.basic(src2obj=None, det2obj=None, det_pixel=None, img_pixel=None, unit='mm')[source]
Bases:
object
Base geometry class. Needs only SDD, ODD and pixel size to initialize. Use ‘parameters’ to store parameters and ‘description’ to store relevant metadata.
- astra_projection_geom(data_shape, index=None)[source]
Get ASTRA projection geometry.
- Args:
data_shape: [detector_count_z, theta_count, detector_count_x] index : if provided - sequence of the rotation angles
- Returns:
geometry : ASTRA cone-beam geometry.
- astra_volume_geom(vol_shape, slice_first=None, slice_last=None)[source]
Initialize ASTRA volume geometry.
- Args:
vol_shape : volume array shape slice_first: first slice of an ROI to update slice_last : last slice of an ROI to update
- property det2obj
Detector-to-object distance.
- property det_sample
Pixel shape.
- detector_bounds(proj_shape)[source]
Get the boundaries of the detector at the start of the scan in length units.
- from_astra_cone_vec(vectors)[source]
Take vectors from ASTRA ‘cone_vec’ geometry. This will override any other parameters.
- from_matrix(R, T)[source]
Rotates and translates the reconstruction volume.
- Args:
R (3x3 array): rotation matrix T (1x3 array): translation vector
- get_detector_orbit(proj_count=None, index=None)[source]
Get the detector orbit. In the base class it is a circular orbit.
- Args:
proj_count: number of projections index : index of the projection subset
- Returns:
src_pos : array of the source positions. Can be generated by circular_orbit(…), for instance.
- get_source_orbit(proj_count=None, index=None)[source]
Get the source orbit. In the base class it is a circular orbit.
- Args:
proj_count: number of projections index : index of the projection subset
- Returns:
src_pos : array of the source positions. Can be generated by circular_orbit(…), for instance.
- get_vectors(proj_count, index=None)[source]
Get source, detector and detector orientation vectors.
- Args:
angle_count : number of rotation angles index : index of angles that should be used
- log(message)[source]
Add a message to the geometry changelog.
This changelog will be saved with the geometry in a toml file.
- Parameters:
message – A message to log (single line).
- Returns:
None
- Return type:
NoneType
- property magnification
Magnification.
- property pixel
Pixel size (mm).
- property src2det
Source-to-detector distance.
- property src2obj
Source-to-object distance.
- property vol_sample
Voxel shape.
- volume_xyz(shape, offset=[0.0, 0.0, 0.0])[source]
Coordinate grid in units of the geometry.
- Args:
shape : volume shape offset: offset in length units
- property voxel
Voxel size (mm).
- class flexdata.geometry.circular(src2obj=None, det2obj=None, det_pixel=None, img_pixel=None, ang_range=(0, 360), unit='mm')[source]
Bases:
basic
Circular orbit geometry class. Includes additional parameters such as detector and source shifts and rotations.
- get_detector_orbit(proj_count=None, index=None)[source]
Get the detector orbit.
- Args:
proj_count: number of projections index : index of the projection subset
- Returns:
det_pos : array of the detector positions. det_tan : array of detector tangential directional vector det_rad : array of detector radial directional vector det_orth: array of detector orthogonal directional vector
- flexdata.geometry.circular_orbit(radius, thetas, roll=0, pitch=0, yaw=0, origin=[0, 0, 0], tan_shift=0, index=None)[source]
Generate a circular orbit vector.
- Args:
radius : orbit radius angle_count: number of rotation angles roll, pitch: define orientation of the rotation axis yaw : initial angular position origin : xyz vector of the orbit centre tan_shift : tangential shift from the default position (scalar or array) index : index of the subset of total rotation angles
- Returns:
position : position vector tangent : tangent direction radius : radal direction orthogonal : orthogonal direction
- flexdata.geometry.detector_bounds(geom, proj_shape)[source]
Get the boundaries of the detector in length units.
- flexdata.geometry.detector_size(geom, proj_shape)[source]
Get the size of detector in length units.
- flexdata.geometry.get_vectors(geom, angle_count, index=None)[source]
Get source, detector and detector orientation vectors.
- Args:
geom : geometry class angle_count : number of rotation angles index : index of angles that should be used
- class flexdata.geometry.helical(src2obj=None, det2obj=None, det_pixel=None, img_pixel=None, axis_range=(0, 100), ang_range=(0, 720), unit='mm')[source]
Bases:
circular
Helical orbit geometry class. Similar to the ‘circular’ class with additional parameter of helix
- class flexdata.geometry.linear(src2obj=None, det2obj=None, det_pixel=None, img_pixel=None, src_hrz_rng=(0, 1), src_vrt_rng=(0, 1), det_hrz_rng=(1, 0), det_vrt_rng=(1, 0), unit='mm')[source]
Bases:
basic
A simple linear orbit geometry class.
- flexdata.geometry.linear_orbit(hrz_rng, rad_rng, vrt_rng, proj_count, index=None)[source]
Generate a linear orbit vector.
- Args:
hrz_rng: horizontal range of motion rad_rng: radial range of motion vrt_rng: vertical range of motion
- Returns:
position : position vector tangent : tangent direction radius : radal direction orthogonal : orthogonal direction
- flexdata.geometry.tiles_shape(shape, geometry_list)[source]
Compute the size of the stiched dataset.
- Args:
shape: shape of a single projection stack. geometry_list: list of geometries.
flexdata.data module
This module contains some input / output routines for stacks of images and parsers for translating scanner log files into geometry definitions.
Most of the basic image formats are supported through imageio module. Raw binaries and matlab binary files can be loaded.
Utility functions to hande big arrays of data. All routines support memmap arrays. However, some operations will need enough memory for at least one copy of the data for intermediate results. This can be improved through better use of memmaps.
- flexdata.data.add_dim(array_1, array_2, dim=None)[source]
Add two arrays with arbitrary dimensions. We assume that one or two dimensions match.
- flexdata.data.bin(array, dim=None, geometry=None)[source]
Simple binning of the data along the chosen direction.
- flexdata.data.cast2type(array, dtype, bounds=None)[source]
Cast from float to int or float to float rescaling values if needed.
- flexdata.data.convolve_filter(array, filtr)[source]
Apply a filter defined in Fourier space (a CTF) via convolution.
- Args:
array : data array (implicit) filtr : a filter defined in Fourier space (1D - 3D)
- flexdata.data.convolve_kernel(array, kernel)[source]
Apply a kernel defined in real space (center in the center of the array) via convolution.
- Args:
array (ndarray) : data array (implicit) kernel(ndarray) : real space kernel (1D - 3D)
- flexdata.data.crop(array, dim, width, geometry=None)[source]
Crop an array along the given dimension. Provide geometry if cropping the projection data, it will update the detector center.
- flexdata.data.deconvolve_filter(array, filtr, epsilon)[source]
Inverse convolution with Tikhonov regularization.
- Args:
array (ndarray) : data array (implicit) filtr (ndarray) : Fourier space filter (1D - 3D) epsilon : regularization parameter axes : list of axes to apply deconvolution to.
- flexdata.data.deconvolve_kernel(array, kernel, epsilon, axes=(0, 2))[source]
Inverse convolution with Tikhonov regularization.
- Args:
array (ndarray) : data array (implicit) filtr (ndarray) : Fourier space filter (1D - 3D) epsilon : regularization parameter axes : list of axes to apply deconvolution to.
- flexdata.data.divergence(array, axes=[0, 1, 2])[source]
Compute the divergence of an array.
- Args:
axes : list of axes where the divergence is applied.
- Returns:
ndarray: divergence of the input array
- flexdata.data.file_to_dictionary(file_path, separator=':', translation=None, strip_quotes=False, stop_at=None)[source]
Read a text file and return a dictionary with records.
- Args:
file_path (str): file to read separator (str): separator between the keys and values translation (dict): dictionary for translating initial keys to a new naming strip_quotes (bool): if True, remove double quotes (”) from values stop_at (str): if set, stop all parsing at section containing stop_at
- flexdata.data.flipdim(array, transpose=[1, 0, 2], updown=True)[source]
Convert a given numpy array (sorted: index, hor, vert) to ASTRA-compatible projections stack
- flexdata.data.free_disk(path)[source]
Return amount of free memory on disk in GB.
- Args:
percent (bool): percentage of the total or in GB.
- flexdata.data.free_memory(percent=False)[source]
Return amount of free RAM memory in GB.
- Args:
percent (bool): percentage of the total or in GB.
- flexdata.data.geom_diff(geom1, geom2, full_diff=False)[source]
Returns a dictionary with changed values in two geometries. Diff is computed per item as: geom1[item] - geom2[item].
If full_diff is True, also returns added, removed and unchanged dict items.
Useful if you’d like to see if corrections have been made in one geometry with respect to a second another.
Either provide a path, geometry object or dictionary to geom2 or geom1.
- Parameters:
geom1 – First path, geometry object or dictionary.
geom2 – Second path, geometry object or dictionary.
full_diff – If set to True also shows added, removed and unchanged.
- Returns:
Geometry dictionary
- flexdata.data.get_files_sorted(path, name)[source]
Sort file entries using the natural (human) sorting
- flexdata.data.gradient(array, axes=[0, 1, 2])[source]
Compute the gradient of an array.
- Args:
axes : list of axes to apply gradient to.
- Returns:
ndarray: shape = (3, k, l, m) where k,l,m - dimensions of the input array.
- class flexdata.data.logger[source]
Bases:
object
A class for logging and printing messages.
- file = ''
- flexdata.data.medipix2astra(array)[source]
Convert a given numpy array (sorted: index, hor, vert) to ASTRA-compatible projections stack
- class flexdata.data.memmap(filename, dtype=<class 'numpy.uint8'>, mode='r+', offset=0, shape=None, order='C')[source]
Bases:
memmap
Standard memmaps don’t seem to reliably delete files that are created on disk. This fixes it…
- flexdata.data.mult_dim(array_1, array_2, dim=None)[source]
Multiply a 3D array by a 1D or a 2D vector along one of the dimensions.
- flexdata.data.pad(array, dim, width, mode='edge', geometry=None)[source]
Pad an array along a given dimension. numpy.pad seems to be very memory hungry! Don’t use it for large arrays.
- Args:
array: input array dim : dim to apply the ramp width: width of the ramp mode :’linear’ - creates linear decay of intensity; ‘edge’ - smears data in a costant manner; ‘zero’ - sets values to zeroes. geometry: geometry record to update (updates detector offset).
- flexdata.data.parse_flexray_datasettings(path, sample=1)[source]
Read the data settings file of FLexRay scanner and return dictionaries with parameters of the scan.
- Args:
path (str): path to the files location sample (int): subsampling of the input data
- Returns:
geometry : circular geometry class
- flexdata.data.parse_flexray_metadatatoml(path, sample=1)[source]
Read the metafile produced by the Flexray script generator.
- Args:
path (str): path to the files location sample (int): subsampling of the input data
- Returns:
geometry : circular geometry class
- flexdata.data.parse_flexray_scansettings(path, sample=1)[source]
Read the log file of FLexRay scanner and return dictionaries with parameters of the scan.
- Args:
path (str): path to the files location sample (int): subsampling of the input data
- Returns:
geometry : circular geometry class
- flexdata.data.ramp(array, dim, width, mode='linear')[source]
Create ramps at the ends of the array (without changing its size).
- Args:
array: input array dim : dim to apply the ramp width: width of the ramp mode :’linear’ - creates linear decay of intensity; ‘edge’ - smears data in a costant manner; ‘zero’ - sets values to zeroes.
- flexdata.data.raw2astra(array)[source]
Convert a given numpy array (sorted: index, hor, vert) to ASTRA-compatible projections stack
- flexdata.data.read_flexray(path, *, sample=1, skip=1, memmap=None, proj_number=None, correct, correct_vol_center=True)[source]
Convenience function for reading projection data from the FLex-Ray scanner. Read, dark-, flat-field images and scan parameters. Also apply a geometry correction profile (correct.correct()), and adjust the vertical volume center to the vertical source/detector positions (correct.correct_vol_center()). Finally detect and try to handle missing projection images.
- Args:
path (str): path to flexray data. skip (int): read every ## image sample (int): keep every ## x ## pixel memmap (str): output a memmap array using the given path proj_number (int): force projection number (treat lesser numbers as missing) correct (str): geometry correction profile to apply correct_vol_center (bool): if True (default), correct vertical volume position
- Returns:
proj (numpy.array): projections stack flat (numpy.array): reference flat field images dark (numpy.array): dark field images geom (geometry) : description of the geometry, physical settings and comments
- flexdata.data.read_geometrytoml(path, sample=1)[source]
Read a native meta file.
- Args:
path (str): path to the file location sample (int): subsampling of the input data
- Returns:
geometry : circular geometry class
- flexdata.data.read_image(file, sample=1, shape=None, format=None, dtype=None)[source]
Read a single image. Use sampling and roi parameters to reduce the array size. Use shape, format and dtype to force file reading settings.
- flexdata.data.read_raw_toml(file_path)[source]
Read a toml file.
- Args:
file_path (str): read file form that location
- flexdata.data.read_stack(path, name, skip=1, sample=1, shape=None, dtype=None, format=None, transpose=[1, 0, 2], updown=True, memmap=None, success=None)[source]
Read stack of files and return a numpy array.
- Args:
path (str): path to the files location name (str): common part of the files name skip (int): read every so many files sample (int): sampling factor in x/y direction shape (array): shape of the files. Use it when the format is ‘raw’. dtype (str or numpy.dtype): data type of the files format (str): file format (‘tif’, ‘raw’, etc) flipdim (bool): apply dimension switch for ASTRA compatibility memmap (str): if provided, return a disk mapped array to save RAM success(array): map of the files that could be loaded (equals 0 in case of a read failure)
- Returns:
numpy.array : 3D array with the first dimension representing the image index
- flexdata.data.rewrite_memmap(old_array, new_array)[source]
Reshaping memmaps is tough. We will recreate one instead hoping that this will not overflow our RAM… This is a dirty qick fix! Try to use resize instead!
- flexdata.data.shape_alike(array_1, array_2)[source]
- Make sure two arrays have the same shape by padding either array_1 or array_2:
Returns: array1, array2 - reshaped.
- flexdata.data.stack_shape(path, name, skip=1, sample=1, shape=None, dtype=None, format=None)[source]
Determine the shape of stack on disk.
- Args:
path (str): path to the files location name (str): common part of the files name skip (int): read every so many files sample (int): sampling factor in x/y direction shape (array): shape of the files. Use it when the format is ‘raw’. dtype (str or numpy.dtype): data type of the files format (str): file format (‘tif’, ‘raw’, etc)
- flexdata.data.write_astra(filename, data_shape, geom)[source]
Write an astra-readable projection geometry vector.
- flexdata.data.write_geometrytoml(path, geometry, overwrite=False)[source]
Write a geometry.toml file
- Args:
path (str): location to write geometry.toml to geometry (dict): geometry overwrite (bool): if True, allow overwriting existing file. Default False
- flexdata.data.write_image(filename, image, compress=0)[source]
Write a single image. Use compression if needed (0-9).
- flexdata.data.write_stack(path, name, data, dim=1, skip=1, dtype=None, zip=False, format='tiff', updown=False)[source]
Write an image stack.
- Args:
path (str): destination path name (str): first part of the files name data (numpy.array): data to write dim (int): dimension along which array is separated into images skip (int): how many images to skip in between dtype (type): forse this data type compress (str): use None, ‘zip’ or ‘jp2’. format (str): file extension (‘raw’, ‘tiff’, ‘jp2’, etc)
flexdata.display module
This module contains a few simple routines for displaying data: * 2D displays like: slice, projection, etc. * Interactive slicer: pyqt_graph * Other displays: mesh, color_project
- flexdata.display.color_project(array, dim=1, sample=2, bounds=[0.01, 0.1], title=None, cmap='nipy_spectral', file=None)[source]
Create a pseudo color projection of a 3D volume.
- flexdata.display.max_projection(array, dim=0, bounds=None, title=None, cmap='gray', file=None)[source]
Projection of maximum values.
- flexdata.display.mesh(stl_mesh)[source]
Display an stl mesh. Use flexcalc.generate_stl(volume) to generate mesh.
- flexdata.display.min_projection(array, dim=0, title=None, cmap='gray', file=None)[source]
Projection of minimum values.
- flexdata.display.plot(x, y=None, semilogy=False, title=None, legend=None)[source]
A standard 2D plot.
- flexdata.display.plot2d(x, y=None, semilogy=False, title=None, legend=None)[source]
A standard 2D plot.
- flexdata.display.plot3d(x, y, z, connected=False, title=None)[source]
Plot a 3D line or a scatter plot.
- flexdata.display.projection(array, dim=1, bounds=None, title=None, cmap='gray', file=None)[source]
A simple projection of the volume along one of the dimensions.