|
@@ -48,6 +48,12 @@
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
+typedef enum {
|
|
|
+ PARAM_Z,
|
|
|
+ PARAM_CENTER,
|
|
|
+ PARAM_LAMINO
|
|
|
+} Param;
|
|
|
+
|
|
|
struct _UfoAnkaBackprojectTaskPrivate {
|
|
|
/* private */
|
|
|
gboolean generated;
|
|
@@ -68,7 +74,7 @@ struct _UfoAnkaBackprojectTaskPrivate {
|
|
|
/* properties */
|
|
|
GValueArray *x_region;
|
|
|
GValueArray *y_region;
|
|
|
- GValueArray *z_region;
|
|
|
+ GValueArray *region;
|
|
|
GValueArray *center;
|
|
|
GValueArray *projection_offset;
|
|
|
float sines[BURST], cosines[BURST];
|
|
@@ -76,6 +82,8 @@ struct _UfoAnkaBackprojectTaskPrivate {
|
|
|
gfloat overall_angle;
|
|
|
gfloat tomo_angle;
|
|
|
gfloat lamino_angle;
|
|
|
+ gfloat z;
|
|
|
+ Param parameter;
|
|
|
};
|
|
|
|
|
|
static void ufo_task_interface_init (UfoTaskIface *iface);
|
|
@@ -90,13 +98,15 @@ enum {
|
|
|
PROP_0,
|
|
|
PROP_X_REGION,
|
|
|
PROP_Y_REGION,
|
|
|
- PROP_Z_REGION,
|
|
|
+ PROP_Z,
|
|
|
+ PROP_REGION,
|
|
|
PROP_PROJECTION_OFFSET,
|
|
|
PROP_CENTER,
|
|
|
PROP_NUM_PROJECTIONS,
|
|
|
PROP_OVERALL_ANGLE,
|
|
|
PROP_TOMO_ANGLE,
|
|
|
PROP_LAMINO_ANGLE,
|
|
|
+ PROP_PARAMETER,
|
|
|
N_PROPERTIES
|
|
|
};
|
|
|
|
|
@@ -150,7 +160,7 @@ determine_x_extrema (gfloat extrema[2], GValueArray *x_extrema, GValueArray *y_e
|
|
|
*/
|
|
|
static void
|
|
|
determine_y_extrema (gfloat extrema[2], GValueArray *x_extrema, GValueArray *y_extrema,
|
|
|
- GValueArray *z_extrema, gfloat tomo_angle, gfloat lamino_angle,
|
|
|
+ gfloat z_extrema[2], gfloat tomo_angle, gfloat lamino_angle,
|
|
|
gfloat y_center)
|
|
|
{
|
|
|
gfloat sin_tomo, cos_tomo, sin_lamino, cos_lamino;
|
|
@@ -174,8 +184,8 @@ determine_y_extrema (gfloat extrema[2], GValueArray *x_extrema, GValueArray *y_e
|
|
|
|
|
|
extrema[0] = sin_tomo * x_min - cos_tomo * y_min;
|
|
|
extrema[1] = sin_tomo * x_max - cos_tomo * y_max;
|
|
|
- extrema[0] = extrema[0] * cos_lamino + EXTRACT_INT (z_extrema, 0) * sin_lamino + y_center;
|
|
|
- extrema[1] = extrema[1] * cos_lamino + EXTRACT_INT (z_extrema, 1) * sin_lamino + y_center + 1;
|
|
|
+ extrema[0] = extrema[0] * cos_lamino + z_extrema[0] * sin_lamino + y_center;
|
|
|
+ extrema[1] = extrema[1] * cos_lamino + z_extrema[1] * sin_lamino + y_center + 1;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -239,7 +249,7 @@ determine_x_region (gint result[2], GValueArray *x_extrema, GValueArray *y_extre
|
|
|
* [0, projection height).
|
|
|
*/
|
|
|
static void
|
|
|
-determine_y_region (gint result[2], GValueArray *x_extrema, GValueArray *y_extrema, GValueArray *z_extrema,
|
|
|
+determine_y_region (gint result[2], GValueArray *x_extrema, GValueArray *y_extrema, gfloat z_extrema[2],
|
|
|
gfloat tomo_angle, gfloat lamino_angle, gfloat y_center, gint height)
|
|
|
{
|
|
|
gfloat extrema[2];
|
|
@@ -340,7 +350,7 @@ ufo_anka_backproject_task_setup (UfoTask *task,
|
|
|
UfoAnkaBackprojectTaskPrivate *priv;
|
|
|
cl_int cl_error;
|
|
|
gint i;
|
|
|
- gchar vector_kernel_name[30];
|
|
|
+ gchar vector_kernel_name[30], *kernel_filename;
|
|
|
|
|
|
if (!g_sprintf (vector_kernel_name, "backproject_burst_%d", BURST)) {
|
|
|
g_warning ("Error making burst kernel name");
|
|
@@ -348,9 +358,23 @@ ufo_anka_backproject_task_setup (UfoTask *task,
|
|
|
|
|
|
priv = UFO_ANKA_BACKPROJECT_TASK_GET_PRIVATE (task);
|
|
|
priv->context = ufo_resources_get_context (resources);
|
|
|
- priv->vector_kernel = ufo_resources_get_kernel (resources, "ankabackprojectburst.cl",
|
|
|
+ switch (priv->parameter) {
|
|
|
+ case PARAM_Z:
|
|
|
+ kernel_filename = g_strdup ("z_kernel.cl");
|
|
|
+ break;
|
|
|
+ case PARAM_CENTER:
|
|
|
+ kernel_filename = g_strdup ("center_kernel.cl");
|
|
|
+ break;
|
|
|
+ case PARAM_LAMINO:
|
|
|
+ kernel_filename = g_strdup ("lamino_kernel.cl");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ g_warning ("Unkown varying parameter");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ priv->vector_kernel = ufo_resources_get_kernel (resources, kernel_filename,
|
|
|
vector_kernel_name, error);
|
|
|
- priv->scalar_kernel = ufo_resources_get_kernel (resources, "ankabackprojectburst.cl",
|
|
|
+ priv->scalar_kernel = ufo_resources_get_kernel (resources, kernel_filename,
|
|
|
"backproject_burst_1", error);
|
|
|
priv->sampler = clCreateSampler (priv->context,
|
|
|
(cl_bool) FALSE,
|
|
@@ -379,6 +403,8 @@ ufo_anka_backproject_task_setup (UfoTask *task,
|
|
|
case 16: priv->table_size = sizeof (cl_float16); break;
|
|
|
default: g_warning ("Unsupported vector size"); break;
|
|
|
}
|
|
|
+
|
|
|
+ g_free (kernel_filename);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -387,17 +413,24 @@ ufo_anka_backproject_task_get_requisition (UfoTask *task,
|
|
|
UfoRequisition *requisition)
|
|
|
{
|
|
|
UfoAnkaBackprojectTaskPrivate *priv;
|
|
|
+ gfloat start, stop, step;
|
|
|
|
|
|
priv = UFO_ANKA_BACKPROJECT_TASK_GET_PRIVATE (task);
|
|
|
+ start = EXTRACT_FLOAT (priv->region, 0);
|
|
|
+ stop = EXTRACT_FLOAT (priv->region, 1);
|
|
|
+ step = EXTRACT_FLOAT (priv->region, 2);
|
|
|
|
|
|
if (!priv->num_projections) {
|
|
|
g_warning ("Number of projections has not been set");
|
|
|
}
|
|
|
+ if (step == 0.0f) {
|
|
|
+ g_warning ("Step in region is 0");
|
|
|
+ }
|
|
|
|
|
|
requisition->n_dims = 3;
|
|
|
requisition->dims[0] = REGION_SIZE (priv->x_region);
|
|
|
requisition->dims[1] = REGION_SIZE (priv->y_region);
|
|
|
- requisition->dims[2] = REGION_SIZE (priv->z_region);
|
|
|
+ requisition->dims[2] = (gint) ceil ((stop - start) / step);
|
|
|
}
|
|
|
|
|
|
static guint
|
|
@@ -446,7 +479,7 @@ ufo_anka_backproject_task_process (UfoTask *task,
|
|
|
gsize table_size;
|
|
|
gboolean scalar;
|
|
|
/* regions stripped off the "to" value */
|
|
|
- gfloat x_region[2], y_region[2], z_region[2], center[2], sin_lamino, cos_lamino;
|
|
|
+ gfloat x_region[2], y_region[2], z_region[2], x_center[2], z_ends[2], lamino_angles[2], y_center, sin_lamino, cos_lamino;
|
|
|
gint x_copy_region[2], y_copy_region[2];
|
|
|
cl_kernel kernel;
|
|
|
cl_command_queue cmd_queue;
|
|
@@ -487,20 +520,38 @@ ufo_anka_backproject_task_process (UfoTask *task,
|
|
|
x_region[1] = (gfloat) EXTRACT_INT (priv->x_region, 2);
|
|
|
y_region[0] = (gfloat) EXTRACT_INT (priv->y_region, 0);
|
|
|
y_region[1] = (gfloat) EXTRACT_INT (priv->y_region, 2);
|
|
|
- z_region[0] = (gfloat) EXTRACT_INT (priv->z_region, 0);
|
|
|
- z_region[1] = (gfloat) EXTRACT_INT (priv->z_region, 2);
|
|
|
- center[0] = EXTRACT_FLOAT (priv->center, 0) - EXTRACT_INT (priv->projection_offset, 0);
|
|
|
- center[1] = EXTRACT_FLOAT (priv->center, 1) - EXTRACT_INT (priv->projection_offset, 1);
|
|
|
+ if (priv->parameter == PARAM_Z) {
|
|
|
+ z_ends[0] = z_region[0] = EXTRACT_FLOAT (priv->region, 0);
|
|
|
+ z_region[1] = EXTRACT_FLOAT (priv->region, 2);
|
|
|
+ z_ends[1] = EXTRACT_FLOAT (priv->region, 1);
|
|
|
+ } else {
|
|
|
+ z_ends[0] = priv->z;
|
|
|
+ z_ends[1] = priv->z + 1.0f;
|
|
|
+ }
|
|
|
+ if (priv->parameter == PARAM_CENTER) {
|
|
|
+ x_center[0] = EXTRACT_FLOAT (priv->region, 0) - EXTRACT_INT (priv->projection_offset, 0);
|
|
|
+ x_center[1] = EXTRACT_FLOAT (priv->region, 2);
|
|
|
+ } else {
|
|
|
+ x_center[0] = x_center[1] = EXTRACT_FLOAT (priv->center, 0) - EXTRACT_INT (priv->projection_offset, 0);
|
|
|
+ }
|
|
|
+ y_center = EXTRACT_FLOAT (priv->center, 1) - EXTRACT_INT (priv->projection_offset, 1);
|
|
|
+ if (priv->parameter == PARAM_LAMINO) {
|
|
|
+ lamino_angles[0] = EXTRACT_FLOAT (priv->region, 0);
|
|
|
+ lamino_angles[1] = EXTRACT_FLOAT (priv->region, 2);
|
|
|
+ } else {
|
|
|
+ lamino_angles[0] = lamino_angles[1] = priv->lamino_angle;
|
|
|
+ }
|
|
|
sin_lamino = sinf (priv->lamino_angle);
|
|
|
cos_lamino = cosf (priv->lamino_angle);
|
|
|
scalar = priv->count >= priv->num_projections / BURST * BURST ? 1 : 0;
|
|
|
|
|
|
/* If COPY_PROJECTION_REGION is True we copy only the part necessary */
|
|
|
/* for a given tomographic and laminographic angle */
|
|
|
- if (COPY_PROJECTION_REGION) {
|
|
|
+ /* TODO: Extend the region determination to be able to handle PARAM_LAMINO */
|
|
|
+ if (COPY_PROJECTION_REGION && priv->parameter != PARAM_LAMINO) {
|
|
|
determine_x_region (x_copy_region, priv->x_region, priv->y_region, tomo_angle,
|
|
|
EXTRACT_FLOAT (priv->center, 0), in_req.dims[0]);
|
|
|
- determine_y_region (y_copy_region, priv->x_region, priv->y_region, priv->z_region,
|
|
|
+ determine_y_region (y_copy_region, priv->x_region, priv->y_region, z_ends,
|
|
|
tomo_angle, priv->lamino_angle, EXTRACT_FLOAT (priv->center, 1),
|
|
|
in_req.dims[1]);
|
|
|
origin[0] = x_copy_region[0];
|
|
@@ -559,10 +610,12 @@ ufo_anka_backproject_task_process (UfoTask *task,
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_mem), &out_mem));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_sampler), &priv->sampler));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_int3), real_size));
|
|
|
- UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), center));
|
|
|
+ UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), x_center));
|
|
|
+ UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), (cl_float *) &y_center));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), x_region));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), y_region));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), z_region));
|
|
|
+ UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float2), lamino_angles));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), &sin_lamino));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), &cos_lamino));
|
|
|
UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, table_size, sines));
|
|
@@ -605,7 +658,7 @@ ufo_anka_backproject_task_finalize (GObject *object)
|
|
|
priv = UFO_ANKA_BACKPROJECT_TASK_GET_PRIVATE (object);
|
|
|
g_value_array_free (priv->x_region);
|
|
|
g_value_array_free (priv->y_region);
|
|
|
- g_value_array_free (priv->z_region);
|
|
|
+ g_value_array_free (priv->region);
|
|
|
g_value_array_free (priv->projection_offset);
|
|
|
g_value_array_free (priv->center);
|
|
|
|
|
@@ -667,9 +720,13 @@ ufo_anka_backproject_task_set_property (GObject *object,
|
|
|
array = (GValueArray *) g_value_get_boxed (value);
|
|
|
set_region (array, &priv->y_region);
|
|
|
break;
|
|
|
- case PROP_Z_REGION:
|
|
|
+ case PROP_Z:
|
|
|
+ priv->z = g_value_get_float (value);
|
|
|
+ break;
|
|
|
+ case PROP_REGION:
|
|
|
array = (GValueArray *) g_value_get_boxed (value);
|
|
|
- set_region (array, &priv->z_region);
|
|
|
+ g_value_array_free (priv->region);
|
|
|
+ priv->region = g_value_array_copy (array);
|
|
|
break;
|
|
|
case PROP_PROJECTION_OFFSET:
|
|
|
array = (GValueArray *) g_value_get_boxed (value);
|
|
@@ -693,6 +750,15 @@ ufo_anka_backproject_task_set_property (GObject *object,
|
|
|
case PROP_LAMINO_ANGLE:
|
|
|
priv->lamino_angle = g_value_get_float (value);
|
|
|
break;
|
|
|
+ case PROP_PARAMETER:
|
|
|
+ if (!g_strcmp0 (g_value_get_string (value), "z")) {
|
|
|
+ priv->parameter = PARAM_Z;
|
|
|
+ } else if (!g_strcmp0 (g_value_get_string (value), "x-center")) {
|
|
|
+ priv->parameter = PARAM_CENTER;
|
|
|
+ } else if (!g_strcmp0 (g_value_get_string (value), "lamino-angle")) {
|
|
|
+ priv->parameter = PARAM_LAMINO;
|
|
|
+ }
|
|
|
+ break;
|
|
|
default:
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
break;
|
|
@@ -714,8 +780,11 @@ ufo_anka_backproject_task_get_property (GObject *object,
|
|
|
case PROP_Y_REGION:
|
|
|
g_value_set_boxed (value, priv->y_region);
|
|
|
break;
|
|
|
- case PROP_Z_REGION:
|
|
|
- g_value_set_boxed (value, priv->z_region);
|
|
|
+ case PROP_Z:
|
|
|
+ g_value_set_float (value, priv->z);
|
|
|
+ break;
|
|
|
+ case PROP_REGION:
|
|
|
+ g_value_set_boxed (value, priv->region);
|
|
|
break;
|
|
|
case PROP_PROJECTION_OFFSET:
|
|
|
g_value_set_boxed (value, priv->projection_offset);
|
|
@@ -735,6 +804,19 @@ ufo_anka_backproject_task_get_property (GObject *object,
|
|
|
case PROP_LAMINO_ANGLE:
|
|
|
g_value_set_float (value, priv->lamino_angle);
|
|
|
break;
|
|
|
+ case PROP_PARAMETER:
|
|
|
+ switch (priv->parameter) {
|
|
|
+ case PARAM_Z:
|
|
|
+ g_value_set_string (value, "z");
|
|
|
+ break;
|
|
|
+ case PARAM_CENTER:
|
|
|
+ g_value_set_string (value, "x-center");
|
|
|
+ break;
|
|
|
+ case PARAM_LAMINO:
|
|
|
+ g_value_set_string (value, "lamino-angle");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
default:
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
break;
|
|
@@ -785,11 +867,20 @@ ufo_anka_backproject_task_class_init (UfoAnkaBackprojectTaskClass *klass)
|
|
|
region_vals,
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
- properties[PROP_Z_REGION] =
|
|
|
- g_param_spec_value_array ("z-region",
|
|
|
- "Z region for reconstruction as (from, to, step)",
|
|
|
- "Z region for reconstruction as (from, to, step)",
|
|
|
- region_vals,
|
|
|
+ properties[PROP_Z] =
|
|
|
+ g_param_spec_float ("z",
|
|
|
+ "Z coordinate of the reconstructed slice",
|
|
|
+ "Z coordinate of the reconstructed slice",
|
|
|
+ -G_MAXFLOAT,
|
|
|
+ G_MAXFLOAT,
|
|
|
+ 0.0f,
|
|
|
+ G_PARAM_READWRITE);
|
|
|
+
|
|
|
+ properties[PROP_REGION] =
|
|
|
+ g_param_spec_value_array ("region",
|
|
|
+ "Region for the parameter along z-axis as (from, to, step)",
|
|
|
+ "Region for the parameter along z-axis as (from, to, step)",
|
|
|
+ float_region_vals,
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
properties[PROP_PROJECTION_OFFSET] =
|
|
@@ -844,6 +935,13 @@ ufo_anka_backproject_task_class_init (UfoAnkaBackprojectTaskClass *klass)
|
|
|
0.0f,
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
+ properties[PROP_PARAMETER] =
|
|
|
+ g_param_spec_string ("parameter",
|
|
|
+ "Which paramter will be varied along the z-axis",
|
|
|
+ "Which paramter will be varied along the z-axis, from \"z\", \"x-center\", \"lamino-angle\"",
|
|
|
+ "z",
|
|
|
+ G_PARAM_READWRITE);
|
|
|
+
|
|
|
for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
|
|
|
g_object_class_install_property (oclass, i, properties[i]);
|
|
|
|
|
@@ -867,14 +965,15 @@ ufo_anka_backproject_task_init(UfoAnkaBackprojectTask *self)
|
|
|
g_value_set_float (&float_zero, 0.0f);
|
|
|
self->priv->x_region = g_value_array_new (3);
|
|
|
self->priv->y_region = g_value_array_new (3);
|
|
|
- self->priv->z_region = g_value_array_new (3);
|
|
|
+ self->priv->region = g_value_array_new (3);
|
|
|
+ self->priv->z = 0.0f;
|
|
|
self->priv->projection_offset = g_value_array_new (2);
|
|
|
self->priv->center = g_value_array_new (2);
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
g_value_array_insert (self->priv->x_region, i, &int_zero);
|
|
|
g_value_array_insert (self->priv->y_region, i, &int_zero);
|
|
|
- g_value_array_insert (self->priv->z_region, i, &int_zero);
|
|
|
+ g_value_array_insert (self->priv->region, i, &float_zero);
|
|
|
if (i < 2) {
|
|
|
g_value_array_insert (self->priv->projection_offset, i, &int_zero);
|
|
|
g_value_array_insert (self->priv->center, i, &float_zero);
|
|
@@ -885,6 +984,7 @@ ufo_anka_backproject_task_init(UfoAnkaBackprojectTask *self)
|
|
|
self->priv->overall_angle = G_PI;
|
|
|
self->priv->tomo_angle = -G_MAXFLOAT;
|
|
|
self->priv->lamino_angle = 0.0f;
|
|
|
+ self->priv->parameter = PARAM_Z;
|
|
|
self->priv->count = 0;
|
|
|
self->priv->generated = FALSE;
|
|
|
}
|