From 2eeefe2db3bb9f2e54cc00e7aa657f599c2115ea Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Mon, 27 Jan 2020 05:27:25 +0100 Subject: Add metadata about buffer plane and sequential number. Provide filter to allow trough only the buffers acquired at the specified detector plane --- src/CMakeLists.txt | 1 + src/meson.build | 3 + src/ufo-roof-buffer.c | 5 +- src/ufo-roof-buffer.h | 2 +- src/ufo-roof-build-task.c | 15 ++- src/ufo-roof-plane-task.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++ src/ufo-roof-plane-task.h | 53 +++++++++++ tests/roof.py | 22 +++-- 8 files changed, 324 insertions(+), 10 deletions(-) create mode 100644 src/ufo-roof-plane-task.c create mode 100644 src/ufo-roof-plane-task.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95f7160..0967ffb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 2.6) set(ufofilter_SRCS ufo-roof-read-task.c ufo-roof-build-task.c + ufo-roof-plane-task.c ) set(common_SRCS diff --git a/src/meson.build b/src/meson.build index 8f3529e..8a03a57 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ plugins = [ 'roof-read', 'roof-build', + 'roof-plane', ] roof_common_src = [ @@ -15,6 +16,8 @@ roof_plugin_src = { 'roof-build': [ 'ufo-roof-buffer.c', ], + 'roof-plane': [ + ], } # standard plugins diff --git a/src/ufo-roof-buffer.c b/src/ufo-roof-buffer.c index bac940c..32598c9 100644 --- a/src/ufo-roof-buffer.c +++ b/src/ufo-roof-buffer.c @@ -139,7 +139,7 @@ gboolean ufo_roof_buffer_set_fragment(UfoRoofBuffer *buffer, guint stream_id, gu -gboolean ufo_roof_buffer_get_dataset(UfoRoofBuffer *buffer, gpointer output_buffer, GError **error) { +gboolean ufo_roof_buffer_get_dataset(UfoRoofBuffer *buffer, gpointer output_buffer, gulong *seqid, GError **error) { guint buffer_id = buffer->current_id % buffer->ring_size; void *dataset_buffer = buffer->ring_buffer + buffer_id * buffer->dataset_size; @@ -147,9 +147,10 @@ gboolean ufo_roof_buffer_get_dataset(UfoRoofBuffer *buffer, gpointer output_buff if (buffer->n_fragments[buffer_id] < buffer->fragments_per_dataset) return FALSE; memcpy(output_buffer, dataset_buffer, buffer->dataset_size); + if (seqid) *seqid = buffer->current_id; buffer->n_fragments[buffer_id] = 0; buffer->current_id += 1; - return TRUE; + return TRUE; } diff --git a/src/ufo-roof-buffer.h b/src/ufo-roof-buffer.h index 7ebaec9..3d7ad2d 100644 --- a/src/ufo-roof-buffer.h +++ b/src/ufo-roof-buffer.h @@ -31,6 +31,6 @@ UfoRoofBuffer *ufo_roof_buffer_new(UfoRoofConfig *cfg, guint n_dims, guint max_d void ufo_roof_buffer_free(UfoRoofBuffer *buf); gboolean ufo_roof_buffer_set_fragment(UfoRoofBuffer *buffer, guint stream_id, guint fragment_id, gconstpointer fragment, GError **error); -gboolean ufo_roof_buffer_get_dataset(UfoRoofBuffer *buffer, gpointer output_buffer, GError **error); +gboolean ufo_roof_buffer_get_dataset(UfoRoofBuffer *buffer, gpointer output_buffer, gulong *seqid, GError **error); #endif diff --git a/src/ufo-roof-build-task.c b/src/ufo-roof-build-task.c index 8af44db..93cb133 100644 --- a/src/ufo-roof-build-task.c +++ b/src/ufo-roof-build-task.c @@ -253,7 +253,10 @@ ufo_roof_build_task_generate (UfoTask *task, UfoRequisition *requisition) { gboolean ready = FALSE; + gulong seqid; GError *gerr = NULL; + GValue ival = G_VALUE_INIT; + GValue lval = G_VALUE_INIT; UfoRoofBuildTaskPrivate *priv = UFO_ROOF_BUILD_TASK_GET_PRIVATE (task); UfoRoofConfig *cfg = priv->cfg; @@ -264,7 +267,7 @@ ufo_roof_build_task_generate (UfoTask *task, if (priv->stop) return FALSE; - ready = ufo_roof_buffer_get_dataset(buf, output_buffer, &gerr); + ready = ufo_roof_buffer_get_dataset(buf, output_buffer, &seqid, &gerr); if (gerr) roof_print_error(gerr); if (priv->build == BUILD_UFO) { @@ -281,6 +284,16 @@ ufo_roof_build_task_generate (UfoTask *task, } } + // Metadata: plane and sequential number within the plane + g_value_init (&ival, G_TYPE_UINT); + g_value_init (&lval, G_TYPE_ULONG); + g_value_set_uint (&ival, 1 + seqid % cfg->n_planes); + ufo_buffer_set_metadata (output, "plane", &ival); + g_value_set_ulong (&lval, seqid / cfg->n_planes); + ufo_buffer_set_metadata (output, "seqid", &lval); + g_value_unset(&lval); + g_value_unset(&ival); + // FIXME: Or shall we start from counting from the ID of the first registerd dataset if ((priv->number)&&(buf->current_id >= priv->number)) { // printf("%u datasets processed, stopping\n", buf->current_id); diff --git a/src/ufo-roof-plane-task.c b/src/ufo-roof-plane-task.c new file mode 100644 index 0000000..25c2bfa --- /dev/null +++ b/src/ufo-roof-plane-task.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2011-2015 Karlsruhe Institute of Technology + * + * This file is part of Ufo. + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "ufo-roof-plane-task.h" + + +struct _UfoRoofPlaneTaskPrivate { + gboolean ready; // Indicates if data is ready for generation + guint plane; // Selected plane (0 - pass everything trough) +}; + +static void ufo_task_interface_init (UfoTaskIface *iface); + +G_DEFINE_TYPE_WITH_CODE (UfoRoofPlaneTask, ufo_roof_plane_task, UFO_TYPE_TASK_NODE, + G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK, + ufo_task_interface_init)) + +#define UFO_ROOF_PLANE_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_ROOF_PLANE_TASK, UfoRoofPlaneTaskPrivate)) + +enum { + PROP_0, + PROP_PLANE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +UfoNode * +ufo_roof_plane_task_new (void) +{ + return UFO_NODE (g_object_new (UFO_TYPE_ROOF_PLANE_TASK, NULL)); +} + +static void +ufo_roof_plane_task_setup (UfoTask *task, + UfoResources *resources, + GError **error) +{ +} + +static void +ufo_roof_plane_task_get_requisition (UfoTask *task, + UfoBuffer **inputs, + UfoRequisition *requisition, + GError **error) +{ + ufo_buffer_get_requisition (inputs[0], requisition); +/* int i; +// UfoRoofPlaneTaskPrivate *priv; + UfoRequisition in_req; + +// priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE (task); + ufo_buffer_get_requisition (inputs[0], &in_req); + + requisition->n_dims = in_req.n_dims; + for (i = 0; i < in_req.n_dims; i++) + requisition->dims[i] = in_req.dims[i];*/ +} + +static guint +ufo_roof_plane_task_get_num_inputs (UfoTask *task) +{ + return 1; +} + +static guint +ufo_roof_plane_task_get_num_dimensions (UfoTask *task, + guint input) +{ + return 2; +} + +static UfoTaskMode +ufo_roof_plane_task_get_mode (UfoTask *task) +{ + return UFO_TASK_MODE_CPU|UFO_TASK_MODE_REDUCTOR; +} + +static gboolean +ufo_roof_plane_task_process (UfoTask *task, + UfoBuffer **inputs, + UfoBuffer *output, + UfoRequisition *requisition) +{ + UfoRoofPlaneTaskPrivate *priv; + + priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE (task); + + if (priv->plane) { + int buf_plane; + GValue *value; + + value = ufo_buffer_get_metadata(inputs[0], "plane"); + buf_plane = g_value_get_uint(value); + if (buf_plane != priv->plane) + return TRUE; + } + + ufo_buffer_copy(inputs[0], output); + ufo_buffer_copy_metadata (inputs[0], output); + priv->ready = TRUE; + + return FALSE; +} + +static gboolean +ufo_roof_plane_task_generate (UfoTask *task, + UfoBuffer *output, + UfoRequisition *requisition) +{ + UfoRoofPlaneTaskPrivate *priv; + + priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE (task); + if (!priv->ready) return FALSE; + +/* + GValue *value = ufo_buffer_get_metadata(output, "plane"); + guint buf_plane = g_value_get_uint(value); + printf("Passing buffer for plane %u\n", buf_plane); +*/ + + priv->ready = FALSE; + + return TRUE; +} + + +static void +ufo_roof_plane_task_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + UfoRoofPlaneTaskPrivate *priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE (object); + + switch (property_id) { + case PROP_PLANE: + priv->plane = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +ufo_roof_plane_task_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + UfoRoofPlaneTaskPrivate *priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE (object); + + switch (property_id) { + case PROP_PLANE: + g_value_set_uint (value, priv->plane); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +ufo_roof_plane_task_finalize (GObject *object) +{ + G_OBJECT_CLASS (ufo_roof_plane_task_parent_class)->finalize (object); +} + +static void +ufo_task_interface_init (UfoTaskIface *iface) +{ + iface->setup = ufo_roof_plane_task_setup; + iface->get_num_inputs = ufo_roof_plane_task_get_num_inputs; + iface->get_num_dimensions = ufo_roof_plane_task_get_num_dimensions; + iface->get_mode = ufo_roof_plane_task_get_mode; + iface->get_requisition = ufo_roof_plane_task_get_requisition; + iface->process = ufo_roof_plane_task_process; + iface->generate = ufo_roof_plane_task_generate; + +} + +static void +ufo_roof_plane_task_class_init (UfoRoofPlaneTaskClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->set_property = ufo_roof_plane_task_set_property; + oclass->get_property = ufo_roof_plane_task_get_property; + oclass->finalize = ufo_roof_plane_task_finalize; + + properties[PROP_PLANE] = + g_param_spec_uint ("plane", + "Detector planes", + "Only passes trough the data for the selecte plane", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE); + + for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++) + g_object_class_install_property (oclass, i, properties[i]); + + g_type_class_add_private (oclass, sizeof(UfoRoofPlaneTaskPrivate)); +} + +static void +ufo_roof_plane_task_init(UfoRoofPlaneTask *self) +{ + self->priv = UFO_ROOF_PLANE_TASK_GET_PRIVATE(self); +} diff --git a/src/ufo-roof-plane-task.h b/src/ufo-roof-plane-task.h new file mode 100644 index 0000000..7794065 --- /dev/null +++ b/src/ufo-roof-plane-task.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011-2013 Karlsruhe Institute of Technology + * + * This file is part of Ufo. + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __UFO_ROOF_PLANE_TASK_H +#define __UFO_ROOF_PLANE_TASK_H + +#include + +G_BEGIN_DECLS + +#define UFO_TYPE_ROOF_PLANE_TASK (ufo_roof_plane_task_get_type()) +#define UFO_ROOF_PLANE_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UFO_TYPE_ROOF_PLANE_TASK, UfoRoofPlaneTask)) +#define UFO_IS_ROOF_PLANE_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UFO_TYPE_ROOF_PLANE_TASK)) +#define UFO_ROOF_PLANE_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_ROOF_PLANE_TASK, UfoRoofPlaneTaskClass)) +#define UFO_IS_ROOF_PLANE_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UFO_TYPE_ROOF_PLANE_TASK)) +#define UFO_ROOF_PLANE_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UFO_TYPE_ROOF_PLANE_TASK, UfoRoofPlaneTaskClass)) + +typedef struct _UfoRoofPlaneTask UfoRoofPlaneTask; +typedef struct _UfoRoofPlaneTaskClass UfoRoofPlaneTaskClass; +typedef struct _UfoRoofPlaneTaskPrivate UfoRoofPlaneTaskPrivate; + +struct _UfoRoofPlaneTask { + UfoTaskNode parent_instance; + + UfoRoofPlaneTaskPrivate *priv; +}; + +struct _UfoRoofPlaneTaskClass { + UfoTaskNodeClass parent_class; +}; + +UfoNode *ufo_roof_plane_task_new (void); +GType ufo_roof_plane_task_get_type (void); + +G_END_DECLS + +#endif diff --git a/tests/roof.py b/tests/roof.py index 931c32f..1941aa8 100644 --- a/tests/roof.py +++ b/tests/roof.py @@ -14,7 +14,7 @@ class RoofConfig: self.streams = 1 self.bit_depth = 8 self.convert = False if ((not args.output) or (re.compile('\.raw$').search(args.output))) else True - self.build = "raw" if args.plain else "ufo" if self.convert else "sino" + self.build = "raw" if args.noroof else "ufo" if self.convert else "sino" with open(config) as json_file: cfg = json.load(json_file) @@ -27,11 +27,13 @@ class RoofConfig: self.bit_depth = cfg["hardware"]["bit_depth"] parser = argparse.ArgumentParser() -parser.add_argument('-c', '--config', dest="config", default="roof.json", help="ROOF configuration (JSON)") -parser.add_argument('-o', '--output', dest="output", default=None, help="Output file") -parser.add_argument('-n', '--number', dest="number", default=None, type=int, help="Specify number of frames to capture") -parser.add_argument('-p', '--plain', dest="plain", default=False, type=bool, help="Plain network test (no ROOF structures)") +parser.add_argument('-c', '--config', dest="config", default="roof.json", help="ROOF configuration (JSON)") +parser.add_argument('-o', '--output', dest="output", default=None, help="Output file") +parser.add_argument('-n', '--number', dest="number", default=None, type=int, help="Specify number of frames to capture (limits number of captured frames irrespective of further filtering)") +parser.add_argument('-p', '--plane', dest="plane", default=None, type=int, help="Only process the specified detector plane (indexed from 1)") +parser.add_argument( '--no-roof', dest="noroof", default=False, type=bool, help="Disable ROOF, only network testing (no sinogram building, store linearly)") #parser.add_argument('-r', '--raw', dest="raw", default=False, type=bool, help="Store raw data, ignore processed") +#parser.add_argument('-v', '--visualize', dest='visualize', default=False, type=bool, help="Visualize data") args = parser.parse_args() @@ -54,6 +56,9 @@ else: build = pm.get_task('roof-build') build.set_properties(config=args.config, number=args.number, build=cfg.build) +plane = pm.get_task('roof-plane') if args.plane else None +if plane: plane.set_properties(plane=args.plane) + for id in range(cfg.streams): read = pm.get_task('roof-read') read.set_properties(config=args.config, id=id) @@ -62,7 +67,12 @@ for id in range(cfg.streams): #read_task.set_properties(path='/home/data/*.tif', start=10, number=100) #graph.connect_nodes_full(read, write, 0) -graph.connect_nodes(build, write) + +if plane: + graph.connect_nodes(build, plane) + graph.connect_nodes(plane, write) +else: + graph.connect_nodes(build, write) -- cgit v1.2.1