Example #1
0
    def __init__(self, graph, get_output=False, output_dims=2, scheduler=None, copy_inputs=False):
        self.output_tasks = []
        self.sched = scheduler if scheduler else Ufo.Scheduler()
        self._started = False
        self.copy_inputs = copy_inputs

        if isinstance(graph, Ufo.TaskGraph):
            self.graph = graph
            roots = self.graph.get_roots()
        elif isinstance(graph, Ufo.TaskNode):
            self.graph = Ufo.TaskGraph()
            roots = [graph]
        else:
            msg = 'graph is neither Ufo.TaskGraph nor Ufo.TaskNode'
            raise ValueError(msg)

        # Initialize inputs
        self.input_tasks = {}
        self.ufo_buffers = {}
        for root in roots:
            self.input_tasks[root] = []
            self.ufo_buffers[root] = []
            num_inputs = root.get_num_inputs()
            for i in range(num_inputs):
                self.input_tasks[root].append(Ufo.InputTask())
                self.ufo_buffers[root].append(None)
                self.graph.connect_nodes_full(self.input_tasks[root][i], root, i)

        if get_output:
            for i, leave in enumerate(self.graph.get_leaves()):
                self.output_tasks.append(Ufo.OutputTask())
                self.output_tasks[-1].props.num_dims = output_dims
                self.graph.connect_nodes(leave, self.output_tasks[-1])
Example #2
0
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
Example #3
0
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)
Example #4
0
    def __init__(self, graph, get_output=False):
        self.output_task = None
        self._started = False

        if isinstance(graph, Ufo.TaskGraph):
            self.graph = graph
            roots = self.graph.get_roots()
        elif isinstance(graph, Ufo.TaskNode):
            self.graph = Ufo.TaskGraph()
            roots = [graph]
        else:
            msg = 'graph is neither Ufo.TaskGraph nor Ufo.TaskNode'
            raise ValueError(msg)

        # Initialize inputs
        self.input_tasks = {}
        self.ufo_buffers = {}
        for root in roots:
            self.input_tasks[root] = []
            self.ufo_buffers[root] = []
            num_inputs = root.get_num_inputs()
            for i in range(num_inputs):
                self.input_tasks[root].append(Ufo.InputTask())
                self.ufo_buffers[root].append(None)
                self.graph.connect_nodes_full(self.input_tasks[root][i], root,
                                              i)

        if get_output:
            self.output_task = Ufo.OutputTask()
            leaves = self.graph.get_leaves()
            self.graph.connect_nodes(leaves[0], self.output_task)
Example #5
0
def compute_phase_spectrum_density(args):
    graph = Ufo.TaskGraph()
    scheduler = Ufo.Scheduler()

    build_power_spectrum_density_pipeline(args, graph, scheduler)
    # scheduler.run(graph) # runned inside for now
    duration = scheduler.props.time

    return duration
Example #6
0
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)
Example #7
0
    def generate_partial(append=False):
        graph = Ufo.TaskGraph()
        sched = Ufo.Scheduler()

        args.output_append = append
        writer = get_writer(args)

        sinos = create_sinogram_pipeline(args, graph)
        graph.connect_nodes(sinos, writer)
        sched.run(graph)
Example #8
0
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)
Example #9
0
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)
Example #10
0
    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)
Example #11
0
    def __init__(self, graph):
        self.input_task = Ufo.InputTask()

        if isinstance(graph, Ufo.TaskGraph):
            self.graph = graph
            roots = self.graph.get_roots()
            self.graph.connect_nodes(self.input_task, roots[0])
        elif isinstance(graph, Ufo.TaskNode):
            self.graph = Ufo.TaskGraph()
            self.graph.connect_nodes(self.input_task, graph)
        else:
            msg = 'graph is neither Ufo.TaskGraph nor Ufo.TaskNode'
            raise ValueError(msg)

        self.ufo_buffer = None
Example #12
0
def test_wrong_connection():
    from ufo import Read, FlatFieldCorrect, Write

    darks = Read()
    flats = Read()
    radios = Read()
    write = Write()
    ffc = FlatFieldCorrect()

    g = Ufo.TaskGraph()
    g.connect_nodes_full(radios.task, ffc.task, 0)
    g.connect_nodes_full(darks.task, ffc.task, 1)
    g.connect_nodes_full(flats.task, ffc.task, 0)
    g.connect_nodes(ffc.task, write.task)

    sched = Ufo.Scheduler()
    sched.run(g)
Example #13
0
    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
Example #14
0
    def start_one(index):
        gpu_index, region = regions[index]
        scheduler = Ufo.FixedScheduler()
        scheduler.set_resources(resources[index])
        graph = Ufo.TaskGraph()
        gpu = scheduler.get_resources().get_gpu_nodes()[gpu_index]
        region_index = run_number * len(resources) + index
        geometry = CTGeometry(args)
        if (len(args.center_position_z) == 1
                and np.modf(args.center_position_z[0])[0] == 0
                and geometry.is_simple_parallel_tomo):
            LOG.info(
                'Simple tomography with integer z center, changing to center_position_z + 0.5 '
                'to avoid interpolation')
            geometry.args.center_position_z = (
                geometry.args.center_position_z[0] + 0.5, )
        if not args.disable_projection_crop:
            if not args.dry_run and (args.y or args.height):
                LOG.debug(
                    '--y or --height specified, not optimizing projection region'
                )
            else:
                geometry.optimize_args(region=region)
        opt_args = geometry.args
        if args.dry_run:
            source = get_task('dummy-data',
                              number=args.number,
                              width=args.width,
                              height=args.height)
        else:
            source = None
        setup_graph(opt_args,
                    graph,
                    x_region,
                    y_region,
                    region,
                    source=source,
                    gpu=gpu,
                    index=region_index,
                    make_reader=True)
        LOG.debug('Pass: %d, device: %d, region: %s', run_number + 1,
                  gpu_index, region)
        scheduler.run(graph)

        return scheduler.props.time
Example #15
0
    def __init__(self, axis_pos=None):
        self.pm = PluginManager()
        self.fft = self.pm.get_task('fft', dimensions=1)
        self.ifft = self.pm.get_task('ifft', dimensions=1)
        self.fltr = self.pm.get_task('filter')
        self.backprojector = self.pm.get_task('backproject')

        if axis_pos:
            self.backprojector.props.axis_pos = axis_pos

        graph = Ufo.TaskGraph()
        graph.connect_nodes(self.fft, self.fltr)
        graph.connect_nodes(self.fltr, self.ifft)
        graph.connect_nodes(self.ifft, self.backprojector)

        super(Backproject, self).__init__(graph, get_output=True)

        self.output_task.props.num_dims = 2
Example #16
0
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))
Example #17
0
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)
Example #18
0
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)
Example #19
0
def test_broadcast():
    from ufo import Generate, Writer
    import glob

    with tempdir() as d:
        generate = Generate(number=5, width=512, height=512)
        write1 = Writer(filename=d.path('foo-%i.tif'))
        write2 = Writer(filename=d.path('bar-%i.tif'))

        g = Ufo.TaskGraph()
        g.connect_nodes(generate.task, write1.task)
        g.connect_nodes(generate.task, write2.task)

        sched = Ufo.Scheduler()
        sched.run(g)

        foos = glob.glob(d.path('foo-*'))
        bars = glob.glob(d.path('bar-*'))
        assert (len(foos) == 5)
        assert (len(bars) == 5)
Example #20
0
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))
Example #21
0
    def __init__(self, axis_pos=None, flat_row=None, dark_row=None):
        self.pm = PluginManager()
        self.sino_correction = self.pm.get_task('flat-field-correction')
        self.fft = self.pm.get_task('fft', dimensions=1)
        self.ifft = self.pm.get_task('ifft', dimensions=1)
        self.fltr = self.pm.get_task('filter')
        self.backprojector = self.pm.get_task('backproject')

        if axis_pos:
            self.backprojector.props.axis_pos = axis_pos

        self.sino_correction.props.sinogram_input = True

        graph = Ufo.TaskGraph()
        graph.connect_nodes(self.sino_correction, self.fft)
        graph.connect_nodes(self.fft, self.fltr)
        graph.connect_nodes(self.fltr, self.ifft)
        graph.connect_nodes(self.ifft, self.backprojector)

        super(FlatCorrectedBackproject, self).__init__(graph, get_output=True)

        self.flat_row = flat_row
        self.dark_row = dark_row
Example #22
0
def tomo(params):
    # Create reader and writer
    if params.projections and params.sinograms:
        raise RuntimeError("Cannot specify both --projections and --sinograms.")

    if params.projections is None and params.sinograms is None:
        reader, width, height = get_dummy_reader(params)
    else:
        if params.projections:
            reader, width, height = get_projection_reader(params)
        else:
            reader, width, height = get_sinogram_reader(params)

    axis = params.axis or width / 2.0

    if params.projections and params.resize:
        width /= params.resize
        height /= params.resize
        axis /= params.resize

    LOG.debug("Input dimensions: {}x{} pixels".format(width, height))

    writer = get_writer(pm, params)

    # Setup graph depending on the chosen method and input data
    g = Ufo.TaskGraph()

    if params.projections is not None:
        if params.number:
            count = len(range(params.start, params.start + params.number, params.step))
        else:
            count = len(get_filenames(params.projections))

        LOG.debug("Number of projections: {}".format(count))
        sino_output = get_task('transpose-projections', number=count)

        if params.darks and params.flats:
            g.connect_nodes(create_flat_correct_pipeline(params, g), sino_output)
        else:
            g.connect_nodes(reader, sino_output)

        if height:
            # Sinogram height is the one needed for further padding
            height = count
    else:
        sino_output = reader

    if params.method == 'fbp':
        fft = get_task('fft', dimensions=1)
        ifft = get_task('ifft', dimensions=1)
        fltr = get_task('filter', filter=params.projection_filter)
        bp = get_task('backproject', axis_pos=axis)

        if params.angle:
            bp.props.angle_step = params.angle

        if params.offset:
            bp.props.angle_offset = params.offset

        if width and height:
            # Pad the image with its extent to prevent reconstuction ring
            pad = get_task('pad')
            crop = get_task('crop')
            setup_padding(pad, crop, width, height, params.projection_padding_mode)

            LOG.debug("Padding input to: {}x{} pixels".format(pad.props.width, pad.props.height))

            g.connect_nodes(sino_output, pad)
            g.connect_nodes(pad, fft)
            g.connect_nodes(fft, fltr)
            g.connect_nodes(fltr, ifft)
            g.connect_nodes(ifft, crop)
            g.connect_nodes(crop, bp)
        else:
            if params.crop_width:
                ifft.props.crop_width = int(params.crop_width)
                LOG.debug("Cropping to {} pixels".format(ifft.props.crop_width))

            g.connect_nodes(sino_output, fft)
            g.connect_nodes(fft, fltr)
            g.connect_nodes(fltr, ifft)
            g.connect_nodes(ifft, bp)

        g.connect_nodes(bp, writer)

    if params.method in ('sart', 'sirt', 'sbtv', 'asdpocs'):
        projector = pm.get_task_from_package('ir', 'parallel-projector')
        projector.set_properties(model='joseph', is_forward=False)

        projector.set_properties(axis_position=axis)
        projector.set_properties(step=params.angle if params.angle else np.pi / 180.0)

        method = pm.get_task_from_package('ir', params.method)
        method.set_properties(projector=projector, num_iterations=params.num_iterations)

        if params.method in ('sart', 'sirt'):
            method.set_properties(relaxation_factor=params.relaxation_factor)

        if params.method == 'asdpocs':
            minimizer = pm.get_task_from_package('ir', 'sirt')
            method.set_properties(df_minimizer=minimizer)

        if params.method == 'sbtv':
            # FIXME: the lambda keyword is preventing from the following
            # assignment ...
            # method.props.lambda = params.lambda
            method.set_properties(mu=params.mu)

        g.connect_nodes(sino_output, method)
        g.connect_nodes(method, writer)

    if params.method == 'dfi':
        oversampling = params.oversampling or 1
        pad = get_task('zeropad', center_of_rotation=axis, oversampling=oversampling)
        fft = get_task('fft', dimensions=1, auto_zeropadding=0)
        dfi = get_task('dfi-sinc')
        ifft = get_task('ifft', dimensions=2)
        swap_forward = get_task('swap-quadrants')
        swap_backward = get_task('swap-quadrants')

        if params.angle:
            dfi.props.angle_step = params.angle

        g.connect_nodes(sino_output, 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)

        if width:
            crop = get_task('crop')
            crop.set_properties(from_center=True, width=width, height=width)
            g.connect_nodes(swap_backward, crop)
            g.connect_nodes(crop, writer)
        else:
            g.connect_nodes(swap_backward, writer)

    scheduler = Ufo.Scheduler()

    if hasattr(scheduler.props, 'enable_tracing'):
        LOG.debug("Use tracing: {}".format(params.enable_tracing))
        scheduler.props.enable_tracing = params.enable_tracing

    scheduler.run(g)
    duration = scheduler.props.time
    LOG.info("Execution time: {} s".format(duration))

    return duration
Example #23
0
 def reset(self):
     self.graph = Ufo.TaskGraph()
Example #24
0
    def __init__(self, args, resources=None, gpu_index=0, do_normalization=False,
                 region=None, copy_inputs=False):
        if args.width is None or args.height is None:
            raise GeneralBackprojectError('width and height must be set in GeneralBackprojectArgs')
        scheduler = Ufo.FixedScheduler()
        if resources:
            scheduler.set_resources(resources)
        gpu = scheduler.get_resources().get_gpu_nodes()[gpu_index]

        self.args = copy.deepcopy(args)
        x_region, y_region, z_region = get_reconstruction_regions(self.args, store=True,
                                                                  dtype=float)
        set_projection_filter_scale(self.args)
        if region is not None:
            self.args.region = region
        LOG.debug('Creating reconstructor for gpu %d, region: %s', gpu_index, self.args.region)
        geometry = CTGeometry(self.args)
        if not self.args.disable_projection_crop:
            geometry.optimize_args()
        self.args = geometry.args

        regions = make_runs([gpu], [gpu_index], x_region, y_region, self.args.region,
                            DTYPE_CL_SIZE[self.args.store_type],
                            slices_per_device=self.args.slices_per_device,
                            slice_memory_coeff=self.args.slice_memory_coeff,
                            data_splitting_policy=self.args.data_splitting_policy)
        if len(regions) > 1:
            raise GeneralBackprojectError('Region does not fit to the GPU memory')

        graph = Ufo.TaskGraph()

        # Normalization
        self.ffc = None
        self.do_normalization = do_normalization
        if do_normalization:
            self.ffc = get_task('flat-field-correct', processing_node=gpu)
            self.ffc.props.fix_nan_and_inf = self.args.fix_nan_and_inf
            self.ffc.props.absorption_correct = self.args.absorptivity
            self._darks_averaged = False
            self._flats_averaged = False
            self.dark_avg = get_task('average', processing_node=gpu)
            self.flat_avg = get_task('average', processing_node=gpu)
            graph.connect_nodes_full(self.dark_avg, self.ffc, 1)
            graph.connect_nodes_full(self.flat_avg, self.ffc, 2)

        (first, last) = setup_graph(self.args, graph, x_region, y_region, self.args.region,
                                    source=self.ffc, gpu=gpu, index=gpu_index, do_output=False,
                                    make_reader=False)
        output_dims = 2
        if args.slice_metric:
            output_dims = 1
            metric = self.args.slice_metric
            if args.slice_metric == 'sag':
                metric = 'sum'
                gradient_task = get_task('gradient', processing_node=gpu, direction='both_abs')
                graph.connect_nodes(last, gradient_task)
                last = gradient_task
            measure_task = get_task('measure', processing_node=gpu, axis=-1, metric=metric)
            graph.connect_nodes(last, measure_task)
        elif first == last:
            # There are no other processing steps other than back projection
            LOG.debug('Only back projection, no other processing')
            graph = first

        super().__init__(graph, get_output=True, output_dims=output_dims, scheduler=scheduler,
                         copy_inputs=copy_inputs)

        if self.do_normalization:
            # Setup input tasks for normalization images averaging. Our parent picks up only the two
            # averagers and not the ffc's zero port for projections.
            self.input_tasks[self.ffc] = [Ufo.InputTask()]
            self.ufo_buffers[self.ffc] = [None]
            self.graph.connect_nodes_full(self.input_tasks[self.ffc][0], self.ffc, 0)