def measure_ufo(out_path, metric, axis, width, height): pm = Ufo.PluginManager() sched = Ufo.Scheduler() graph = Ufo.TaskGraph() input_path = 'data/measure.tif' image = make_input(width, height) tifffile.imsave(input_path, image) reader = pm.get_task('read') measure = pm.get_task('measure') output = Ufo.OutputTask() reader.props.path = input_path measure.props.axis = axis measure.props.metric = metric graph.connect_nodes(reader, measure) graph.connect_nodes(measure, output) sched.run(graph) buf = output.get_output_buffer() gpu_result = ufo.numpy.asarray(buf) write_image(out_path, gpu_result)
def _run(params, x_region, y_region, regions, index): """Execute one pass on all possible GPUs with slice ranges given by *regions*.""" from gi.repository import Ufo pm = Ufo.PluginManager() graph = Ufo.TaskGraph() scheduler = Ufo.FixedScheduler() gpus = scheduler.get_resources().get_gpu_nodes() num_gpus = len(gpus) broadcast = Ufo.CopyTask() source = _setup_source(params, pm, graph) graph.connect_nodes(source, broadcast) for i, region in enumerate(regions): subindex = index * num_gpus + i _setup_graph(pm, graph, subindex, x_region, y_region, region, params, broadcast, gpu=gpus[i]) scheduler.run(graph) duration = scheduler.props.time LOG.info('Execution time: {} s'.format(duration)) return duration
def create_preprocessing_pipeline(args, graph, source=None, processing_node=None): pm = Ufo.PluginManager() if not (args.width and args.height): width, height = determine_shape(args, args.projections) if not width: raise RuntimeError("Could not determine width from the input") if not args.width: args.width = width if not args.height: args.height = height - args.y LOG.debug('Image width x height: %d x %d', args.width, args.height) if source: current = source elif args.darks and args.flats: current = create_flat_correct_pipeline(args, graph, processing_node=processing_node) else: current = get_task('read') set_node_props(current, args) if not args.projections: raise RuntimeError('--projections not set') setup_read_task(current, args.projections, args) if args.absorptivity: absorptivity = get_task('calculate', processing_node=processing_node) absorptivity.props.expression = '-log(v)' graph.connect_nodes(current, absorptivity) current = absorptivity if args.transpose_input: transpose = get_task('transpose') graph.connect_nodes(current, transpose) current = transpose tmp = args.width args.width = args.height args.height = tmp if args.projection_filter != 'none': pf_first, pf_last = create_projection_filtering_pipeline( args, graph, processing_node=processing_node) graph.connect_nodes(current, pf_first) current = pf_last if args.energy is not None and args.propagation_distance is not None: pr_first, pr_last = create_phase_retrieval_pipeline( args, graph, processing_node=processing_node) graph.connect_nodes(current, pr_first) current = pr_last return current
def run_flat_correct(args): graph = Ufo.TaskGraph() sched = Ufo.Scheduler() pm = Ufo.PluginManager() out_task = get_writer(args) flat_task = create_flat_correct_pipeline(args, graph) graph.connect_nodes(flat_task, out_task) sched.run(graph)
def run_preprocessing(args): graph = Ufo.TaskGraph() sched = Ufo.Scheduler() pm = Ufo.PluginManager() out_task = get_writer(args) current = create_preprocessing_pipeline(args, graph) graph.connect_nodes(current, out_task) sched.run(graph)
def run_flat_correct(args): graph = Ufo.TaskGraph() sched = Ufo.Scheduler() pm = Ufo.PluginManager() out_task = pm.get_task('write') out_task.props.filename = args.output flat_task = create_flat_correct_pipeline(args, graph) graph.connect_nodes(flat_task, out_task) sched.run(graph)
def generate_partial(append=False): pm = Ufo.PluginManager() graph = Ufo.TaskGraph() sched = Ufo.Scheduler() writer = pm.get_task('write') writer.props.filename = args.output writer.props.append = append sinos = create_sinogram_pipeline(args, graph) graph.connect_nodes(sinos, writer) sched.run(graph)
def create_phase_retrieval_pipeline(args, graph, processing_node=None): LOG.debug('Creating phase retrieval pipeline') pm = Ufo.PluginManager() # Retrieve phase phase_retrieve = get_task('retrieve-phase', processing_node=processing_node) pad_phase_retrieve = get_task('pad', processing_node=processing_node) crop_phase_retrieve = get_task('crop', processing_node=processing_node) fft_phase_retrieve = get_task('fft', processing_node=processing_node) ifft_phase_retrieve = get_task('ifft', processing_node=processing_node) width = args.width height = args.height default_padded_width = next_power_of_two(width) default_padded_height = next_power_of_two(height) if not args.retrieval_padded_width: args.retrieval_padded_width = default_padded_width if not args.retrieval_padded_height: args.retrieval_padded_height = default_padded_height fmt = 'Phase retrieval padding: {}x{} -> {}x{}' LOG.debug( fmt.format(width, height, args.retrieval_padded_width, args.retrieval_padded_height)) x = (args.retrieval_padded_width - width) / 2 y = (args.retrieval_padded_height - height) / 2 pad_phase_retrieve.props.x = x pad_phase_retrieve.props.y = y pad_phase_retrieve.props.width = args.retrieval_padded_width pad_phase_retrieve.props.height = args.retrieval_padded_height pad_phase_retrieve.props.addressing_mode = args.retrieval_padding_mode crop_phase_retrieve.props.x = x crop_phase_retrieve.props.y = y crop_phase_retrieve.props.width = width crop_phase_retrieve.props.height = height phase_retrieve.props.method = args.retrieval_method phase_retrieve.props.energy = args.energy phase_retrieve.props.distance = args.propagation_distance phase_retrieve.props.pixel_size = args.pixel_size phase_retrieve.props.regularization_rate = args.regularization_rate phase_retrieve.props.thresholding_rate = args.thresholding_rate fft_phase_retrieve.props.dimensions = 2 ifft_phase_retrieve.props.dimensions = 2 graph.connect_nodes(pad_phase_retrieve, fft_phase_retrieve) graph.connect_nodes(fft_phase_retrieve, phase_retrieve) graph.connect_nodes(phase_retrieve, ifft_phase_retrieve) graph.connect_nodes(ifft_phase_retrieve, crop_phase_retrieve) return (pad_phase_retrieve, crop_phase_retrieve)
def initialize(self): self.data = self.get("DataStore").data() self.graph = Ufo.TaskGraph() self.sched = Ufo.Scheduler() manager = Ufo.PluginManager() self.read = manager.get_task('memory-in') self.sino = manager.get_task('transpose-projections') self.pad = manager.get_task('pad') self.fft = manager.get_task('fft') self.fltr = manager.get_task('filter') self.ifft = manager.get_task('ifft') self.bp = manager.get_task('backproject') self.crop = manager.get_task('crop') self.write= manager.get_task('memory-out') self.LogInfo("initialized, UFO Reconstruction") return True
def ufo_dfi(tomo, center, recon, theta, **kwargs): """ Reconstruct object using UFO's Direct Fourier pipeline """ import gi gi.require_version('Ufo', '0.0') from gi.repository import Ufo theta = theta[1] - theta[0] center = center[0] g = Ufo.TaskGraph() pm = Ufo.PluginManager() sched = Ufo.Scheduler() input_task = Ufo.InputTask() output_task = Ufo.OutputTask() pad = pm.get_task('zeropad') fft = pm.get_task('fft') ifft = pm.get_task('ifft') dfi = pm.get_task('dfi-sinc') swap_forward = pm.get_task('swap-quadrants') swap_backward = pm.get_task('swap-quadrants') pad.set_properties(oversampling=1, center_of_rotation=center) fft.set_properties(dimensions=1, auto_zeropadding=False) ifft.set_properties(dimensions=2) dfi.set_properties(angle_step=theta) g.connect_nodes(input_task, pad) g.connect_nodes(pad, fft) g.connect_nodes(fft, dfi) g.connect_nodes(dfi, swap_forward) g.connect_nodes(swap_forward, ifft) g.connect_nodes(ifft, swap_backward) g.connect_nodes(swap_backward, output_task) args = (input_task, output_task, tomo, recon) thread = threading.Thread(target=_process_data, args=args) thread.start() sched.run(g) thread.join() logger.info("UFO+DFI run time: {}s".format(sched.props.time))
def transpose_ufo(width, height, path): pm = Ufo.PluginManager() graph = Ufo.TaskGraph() sched = Ufo.Scheduler() input_path = 'data/transpose.tif' image = make_input(width, height) tifffile.imsave(input_path, image) reader = pm.get_task('read') transpose = pm.get_task('transpose') writer = pm.get_task('write') reader.props.path = input_path writer.props.filename = path graph.connect_nodes(reader, transpose) graph.connect_nodes(transpose, writer) sched.run(graph)
def test_core_issue_64_fixed_expansion(): g = Ufo.TaskGraph() pm = Ufo.PluginManager() sched = Ufo.FixedScheduler() arch = Ufo.ArchGraph() gpus = arch.get_gpu_nodes() sched.set_gpu_nodes(arch, gpus) generate = pm.get_task('generate') null = pm.get_task('null') generate.set_properties(number=5, width=512, height=512) for gpu in gpus: median = pm.get_task('median-filter') median.set_proc_node(gpu) g.connect_nodes(generate, median) g.connect_nodes(median, null) sched.run(g)
def ufo_fbp(tomo, center, recon, theta, **kwargs): """ Reconstruct object using UFO's FBP pipeline """ import gi gi.require_version('Ufo', '0.0') from gi.repository import Ufo width = tomo.shape[2] theta = theta[1] - theta[0] center = center[0] g = Ufo.TaskGraph() pm = Ufo.PluginManager() sched = Ufo.Scheduler() input_task = Ufo.InputTask() output_task = Ufo.OutputTask() fft = pm.get_task('fft') ifft = pm.get_task('ifft') fltr = pm.get_task('filter') backproject = pm.get_task('backproject') ifft.set_properties(crop_width=width) backproject.set_properties(axis_pos=center, angle_step=theta, angle_offset=np.pi) g.connect_nodes(input_task, fft) g.connect_nodes(fft, fltr) g.connect_nodes(fltr, ifft) g.connect_nodes(ifft, backproject) g.connect_nodes(backproject, output_task) args = (input_task, output_task, tomo, recon) thread = threading.Thread(target=_process_data, args=args) thread.start() sched.run(g) thread.join() logger.info("UFO+FBP run time: {}s".format(sched.props.time))
def create_projection_filtering_pipeline(args, graph, processing_node=None): pm = Ufo.PluginManager() pad = get_task('pad', processing_node=processing_node) crop = get_task('crop', processing_node=processing_node) fft = get_task('fft', processing_node=processing_node) ifft = get_task('ifft', processing_node=processing_node) fltr = get_task('filter', processing_node=processing_node) setup_padding(pad, crop, args.width, args.height, args.projection_padding_mode) fft.props.dimensions = 1 ifft.props.dimensions = 1 fltr.props.filter = args.projection_filter fltr.props.scale = args.projection_filter_scale graph.connect_nodes(pad, fft) graph.connect_nodes(fft, fltr) graph.connect_nodes(fltr, ifft) graph.connect_nodes(ifft, crop) return (pad, crop)
def create_sinogram_pipeline(args, graph): """Create sinogram generating pipeline based on arguments from *args*.""" pm = Ufo.PluginManager() sinos = pm.get_task('transpose-projections') if args.number: region = (args.start, args.start + args.number, args.step) num_projections = len(range(*region)) else: num_projections = len(get_filenames(args.projections)) sinos.props.number = num_projections if args.darks and args.flats: start = create_flat_correct_pipeline(args, graph) else: start = pm.get_task('read') start.props.path = args.projections set_node_props(start, args) graph.connect_nodes(start, sinos) return sinos
import os import logging import glob import tempfile import sys import numpy as np from gi.repository import Ufo from tofu.preprocess import create_flat_correct_pipeline from tofu.util import (set_node_props, setup_read_task, get_filenames, get_first_filename, next_power_of_two, read_image, determine_shape) from tofu.tasks import get_writer LOG = logging.getLogger(__name__) pm = Ufo.PluginManager() def get_task(name, **kwargs): task = pm.get_task(name) task.set_properties(**kwargs) return task def get_dummy_reader(params): if params.width is None and params.height is None: raise RuntimeError("You have to specify --width and --height when generating data.") width, height = params.width, params.height reader = get_task('dummy-data', width=width, height=height, number=params.number or 1) return reader, width, height
def __init__(self): self.env = Environment(Ufo.PluginManager()) self.task_names = self.env.pm.get_all_task_names()
def have_camera_plugin(): from gi.repository import Ufo return 'camera' in Ufo.PluginManager().get_all_task_names()
def create_flat_correct_pipeline(args, graph): """ Create flat field correction pipeline. All the settings are provided in *args*. *graph* is used for making the connections. Returns the flat field correction task which can be used for further pipelining. """ pm = Ufo.PluginManager() if args.projections is None or args.flats is None or args.darks is None: raise RuntimeError( "You must specify --projections, --flats and --darks.") def get_task(name, **kwargs): """Get task *name* with properties *kwargs*.""" task = pm.get_task(name) task.set_properties(**kwargs) return task reader = get_task('read') dark_reader = get_task('read') flat_before_reader = get_task('read') ffc = get_task('flat-field-correct', dark_scale=args.dark_scale, absorption_correct=args.absorptivity, fix_nan_and_inf=args.fix_nan_and_inf) mode = args.reduction_mode.lower() roi_args = make_subargs(args, ['y', 'height', 'y_step']) set_node_props(reader, args) set_node_props(dark_reader, roi_args) set_node_props(flat_before_reader, roi_args) for r, path in ((reader, args.projections), (dark_reader, args.darks), (flat_before_reader, args.flats)): setup_read_task(r, path, args) LOG.debug( "Doing flat field correction using reduction mode `{}'".format(mode)) if args.flats2: flat_after_reader = get_task('read') setup_read_task(flat_after_reader, args.flats2, args) set_node_props(flat_after_reader, roi_args) num_files = len(get_filenames(args.projections)) can_read = len(range(args.start, num_files, args.step)) number = args.number if args.number else num_files num_read = min(can_read, number) flat_interpolate = get_task('interpolate', number=num_read) if args.resize: LOG.debug("Resize input data by factor of {}".format(args.resize)) proj_bin = get_task('bin', size=args.resize) dark_bin = get_task('bin', size=args.resize) flat_bin = get_task('bin', size=args.resize) graph.connect_nodes(reader, proj_bin) graph.connect_nodes(dark_reader, dark_bin) graph.connect_nodes(flat_before_reader, flat_bin) reader, dark_reader, flat_before_reader = proj_bin, dark_bin, flat_bin if args.flats2: flat_bin = get_task('bin', size=args.resize) graph.connect_nodes(flat_after_reader, flat_bin) flat_after_reader = flat_bin if mode == 'median': dark_stack = get_task('stack', number=len(get_filenames(args.darks))) dark_reduced = get_task('flatten', mode='median') flat_before_stack = get_task('stack', number=len(get_filenames(args.flats))) flat_before_reduced = get_task('flatten', mode='median') graph.connect_nodes(dark_reader, dark_stack) graph.connect_nodes(dark_stack, dark_reduced) graph.connect_nodes(flat_before_reader, flat_before_stack) graph.connect_nodes(flat_before_stack, flat_before_reduced) if args.flats2: flat_after_stack = get_task('stack', number=len(get_filenames(args.flats2))) flat_after_reduced = get_task('flatten', mode='median') graph.connect_nodes(flat_after_reader, flat_after_stack) graph.connect_nodes(flat_after_stack, flat_after_reduced) elif mode == 'average': dark_reduced = get_task('average') flat_before_reduced = get_task('average') graph.connect_nodes(dark_reader, dark_reduced) graph.connect_nodes(flat_before_reader, flat_before_reduced) if args.flats2: flat_after_reduced = get_task('average') graph.connect_nodes(flat_after_reader, flat_after_reduced) else: raise ValueError('Invalid reduction mode') graph.connect_nodes_full(reader, ffc, 0) graph.connect_nodes_full(dark_reduced, ffc, 1) if args.flats2: graph.connect_nodes_full(flat_before_reduced, flat_interpolate, 0) graph.connect_nodes_full(flat_after_reduced, flat_interpolate, 1) graph.connect_nodes_full(flat_interpolate, ffc, 2) else: graph.connect_nodes_full(flat_before_reduced, ffc, 2) return ffc
def __init__(self): self._wrapped = Ufo.PluginManager()
import logging from gi.repository import Ufo LOG = logging.getLogger(__name__) PLUGIN_MANAGER = Ufo.PluginManager() def get_task(name, processing_node=None, **kwargs): task = PLUGIN_MANAGER.get_task(name) task.set_properties(**kwargs) if processing_node and task.uses_gpu(): LOG.debug("Assigning task '%s' to node %d", name, processing_node.get_index()) task.set_proc_node(processing_node) return task def get_writer(params): if 'dry_run' in params and params.dry_run: LOG.debug("Discarding data output") return get_task('null', download=True) outname = params.output LOG.debug("Writing output to {}".format(outname)) writer = get_task('write', filename=outname) writer.props.append = params.output_append if params.output_bitdepth != 32: writer.props.bits = params.output_bitdepth
def create_phase_retrieval_pipeline(args, graph, processing_node=None): LOG.debug('Creating phase retrieval pipeline') pm = Ufo.PluginManager() # Retrieve phase phase_retrieve = get_task('retrieve-phase', processing_node=processing_node) pad_phase_retrieve = get_task('pad', processing_node=processing_node) crop_phase_retrieve = get_task('crop', processing_node=processing_node) fft_phase_retrieve = get_task('fft', processing_node=processing_node) ifft_phase_retrieve = get_task('ifft', processing_node=processing_node) last = crop_phase_retrieve width = args.width height = args.height default_padded_width = next_power_of_two(width) default_padded_height = next_power_of_two(height) if not args.retrieval_padded_width: args.retrieval_padded_width = default_padded_width if not args.retrieval_padded_height: args.retrieval_padded_height = default_padded_height fmt = 'Phase retrieval padding: {}x{} -> {}x{}' LOG.debug( fmt.format(width, height, args.retrieval_padded_width, args.retrieval_padded_height)) x = (args.retrieval_padded_width - width) / 2 y = (args.retrieval_padded_height - height) / 2 pad_phase_retrieve.props.x = x pad_phase_retrieve.props.y = y pad_phase_retrieve.props.width = args.retrieval_padded_width pad_phase_retrieve.props.height = args.retrieval_padded_height pad_phase_retrieve.props.addressing_mode = args.retrieval_padding_mode crop_phase_retrieve.props.x = x crop_phase_retrieve.props.y = y crop_phase_retrieve.props.width = width crop_phase_retrieve.props.height = height phase_retrieve.props.method = args.retrieval_method phase_retrieve.props.energy = args.energy phase_retrieve.props.distance = args.propagation_distance phase_retrieve.props.pixel_size = args.pixel_size phase_retrieve.props.regularization_rate = args.regularization_rate phase_retrieve.props.thresholding_rate = args.thresholding_rate phase_retrieve.props.frequency_cutoff = args.frequency_cutoff fft_phase_retrieve.props.dimensions = 2 ifft_phase_retrieve.props.dimensions = 2 graph.connect_nodes(pad_phase_retrieve, fft_phase_retrieve) graph.connect_nodes(fft_phase_retrieve, phase_retrieve) graph.connect_nodes(phase_retrieve, ifft_phase_retrieve) graph.connect_nodes(ifft_phase_retrieve, crop_phase_retrieve) calculate = get_task('calculate', processing_node=processing_node) if args.retrieval_method == 'tie': expression = '(isinf (v) || isnan (v) || (v <= 0)) ? 0.0f :' if args.delta is not None: import numpy as np lam = 6.62606896e-34 * 299792458 / (args.energy * 1.60217733e-16) # Compute mju from the fact that beta = 10^-regularization_rate * delta # and mju = 4 * Pi * beta / lambda mju = 4 * np.pi * 10**-args.regularization_rate * args.delta / lam # Take the logarithm to obtain the projected thickness expression += '-log ({} * v) * {}'.format( 2 / 10**args.regularization_rate, 1 / mju) else: expression += '-log (v)' else: expression = '(isinf (v) || isnan (v)) ? 0.0f : -v' calculate.props.expression = expression graph.connect_nodes(crop_phase_retrieve, calculate) last = calculate return (pad_phase_retrieve, last)