Browse Source

Add roll-angle parameter

which specifies the sample angular misalignment to the side.
Tomas Farago 8 years ago
parent
commit
61c2459ff3

+ 1 - 0
src/kernels/templates/center_template.in

@@ -1,5 +1,6 @@
         pixel.x = mad(voxel.x, cosines{1}, mad(voxel.y, sines{1}, x_center_current));
         pixel.y = mad(tmp_x, sines{1}, mad(tmp_y, cosines{1}, tmp));
+        rotate ();
         result {2}= read_imagef (projection_{0}, sampler, pixel).x;
 %nl
         voxel.x = mad((float) idx, x_region.y, x_region.x);

+ 9 - 0
src/kernels/templates/common.in

@@ -1,3 +1,10 @@
+#define rotate()    pixel.x -= x_center.x; \
+                    pixel.y -= y_center; \
+                    pixel.x = pixel.x * cos_roll + pixel.y * sin_roll; \
+                    pixel.y = -pixel.x * sin_roll + pixel.y * cos_roll; \
+                    pixel.x += x_center.x; \
+                    pixel.y += y_center;
+
 kernel void backproject_burst_{0} (
 {1}
                                     global float *volume,
@@ -14,6 +21,8 @@ kernel void backproject_burst_{0} (
                                     const float{2} sines,
                                     const float{2} cosines,
                                     const float norm_factor,
+                                    const float sin_roll,
+                                    const float cos_roll,
                                     const int cumulate)
 {{
     int idx = get_global_id (0);

+ 1 - 0
src/kernels/templates/lamino_template.in

@@ -1,5 +1,6 @@
         pixel.x = mad(voxel.x, cosines{1}, mad(voxel.y, sines{1}, x_center.x));
         pixel.y = mad(tmp_x, sines{1}, mad(tmp_y, cosines{1}, tmp));
+        rotate ();
         result {2}= read_imagef (projection_{0}, sampler, pixel).x;
 %nl
         voxel.x = mad((float) idx, x_region.y, x_region.x);

+ 1 - 0
src/kernels/templates/z_template.in

@@ -1,5 +1,6 @@
         pixel.x = mad(voxel.x, cosines{1}, mad(voxel.y, sines{1}, x_center.x));
         pixel.y = mad(tmp_x, sines{1}, mad(tmp_y, cosines{1}, tmp));
+        rotate ();
         result {2}= read_imagef (projection_{0}, sampler, pixel).x;
 %nl
         voxel.x = mad((float) idx, x_region.y, x_region.x);

+ 24 - 1
src/ufo-anka-backproject-task.c

@@ -82,6 +82,7 @@ struct _UfoAnkaBackprojectTaskPrivate {
     gfloat tomo_angle;
     gfloat lamino_angle;
     gfloat z;
+    gfloat roll_angle;
     Param parameter;
 };
 
@@ -106,6 +107,7 @@ enum {
     PROP_TOMO_ANGLE,
     PROP_LAMINO_ANGLE,
     PROP_PARAMETER,
+    PROP_ROLL_ANGLE,
     N_PROPERTIES
 };
 
@@ -303,7 +305,7 @@ ufo_anka_backproject_task_process (UfoTask *task,
     gboolean scalar;
     /* regions stripped off the "to" value */
     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, norm_factor;
+           y_center, sin_lamino, cos_lamino, norm_factor, sin_roll, cos_roll;
     gint x_copy_region[2], y_copy_region[2];
     cl_kernel kernel;
     cl_command_queue cmd_queue;
@@ -368,6 +370,9 @@ ufo_anka_backproject_task_process (UfoTask *task,
     }
     sin_lamino = sinf (priv->lamino_angle);
     cos_lamino = cosf (priv->lamino_angle);
+    /* Minus the value because we are rotating back */
+    sin_roll = sinf (-priv->roll_angle);
+    cos_roll = cosf (-priv->roll_angle);
     scalar = priv->count >= priv->num_projections / BURST * BURST ? 1 : 0;
 
     /* If COPY_PROJECTION_REGION is True we copy only the part necessary  */
@@ -446,6 +451,8 @@ ufo_anka_backproject_task_process (UfoTask *task,
         UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, table_size, sines));
         UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, table_size, cosines));
         UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), &norm_factor));
+        UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), &sin_roll));
+        UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i++, sizeof (cl_float), &cos_roll));
         UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (kernel, i, sizeof (cl_int), (cl_int *) &cumulate));
 
         profiler = ufo_task_node_get_profiler (UFO_TASK_NODE (task));
@@ -576,6 +583,9 @@ ufo_anka_backproject_task_set_property (GObject *object,
         case PROP_LAMINO_ANGLE:
             priv->lamino_angle = g_value_get_float (value);
             break;
+        case PROP_ROLL_ANGLE:
+            priv->roll_angle = g_value_get_float (value);
+            break;
         case PROP_PARAMETER:
             if (!g_strcmp0 (g_value_get_string (value), "z")) {
                 priv->parameter = PARAM_Z;
@@ -630,6 +640,9 @@ ufo_anka_backproject_task_get_property (GObject *object,
         case PROP_LAMINO_ANGLE:
             g_value_set_float (value, priv->lamino_angle);
             break;
+        case PROP_ROLL_ANGLE:
+            g_value_set_float (value, priv->roll_angle);
+            break;
         case PROP_PARAMETER:
             switch (priv->parameter) {
                 case PARAM_Z:
@@ -761,6 +774,15 @@ ufo_anka_backproject_task_class_init (UfoAnkaBackprojectTaskClass *klass)
                             0.0f,
                             G_PARAM_READWRITE);
 
+    properties[PROP_ROLL_ANGLE] =
+        g_param_spec_float ("roll-angle",
+                            "Sample angular misalignment to the side (roll) in radians",
+                            "Sample angular misalignment to the side (roll) in radians (CW is positive)",
+                            0.0f,
+                            (float) G_PI / 2,
+                            0.0f,
+                            G_PARAM_READWRITE);
+
     properties[PROP_PARAMETER] =
         g_param_spec_string ("parameter",
                              "Which paramter will be varied along the z-axis",
@@ -810,6 +832,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->roll_angle = 0.0f;
     self->priv->parameter = PARAM_Z;
     self->priv->count = 0;
     self->priv->generated = FALSE;