summaryrefslogtreecommitdiffstats
path: root/src/kernels/phase-retrieval.cl
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernels/phase-retrieval.cl')
-rw-r--r--src/kernels/phase-retrieval.cl59
1 files changed, 57 insertions, 2 deletions
diff --git a/src/kernels/phase-retrieval.cl b/src/kernels/phase-retrieval.cl
index fa6db33..273bb4c 100644
--- a/src/kernels/phase-retrieval.cl
+++ b/src/kernels/phase-retrieval.cl
@@ -20,7 +20,7 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#define COMMON_SETUP_TIE \
+#define COMMON_FREQUENCY_SETUP \
const int width = get_global_size(0); \
const int height = get_global_size(1); \
int idx = get_global_id(0); \
@@ -28,13 +28,23 @@
float n_idx = (idx >= width >> 1) ? idx - width : idx; \
float n_idy = (idy >= height >> 1) ? idy - height : idy; \
n_idx = n_idx / width; \
- n_idy = n_idy / height; \
+ n_idy = n_idy / height;
+
+#define COMMON_SETUP_TIE \
+ COMMON_FREQUENCY_SETUP; \
float sin_arg = prefac.x * (n_idx * n_idx) + prefac.y * (n_idy * n_idy); \
#define COMMON_SETUP \
COMMON_SETUP_TIE; \
float sin_value = sin(sin_arg);
+#define CTF_MULTI_SETUP \
+ float prefac = M_PI * wavelength * (n_idx * n_idx / pixel_size / pixel_size + n_idy * n_idy / pixel_size / pixel_size);
+
+/* b/d * cos + sin = d/b * (b/d * sin + cos); 10^R = d/b */
+#define CTF_MULTI_VALUE(prefac, dist, regularize_rate) (pow(10, (regularize_rate)) * sin ((prefac) * (dist)) + cos ((prefac) * (dist)))
+
+
kernel void
tie_method(float2 prefac, float regularize_rate, float binary_filter_rate, float frequency_cutoff, global float *output)
{
@@ -92,3 +102,48 @@ mult_by_value(global float *input, global float *values, global float *output)
* same filter value. */
output[idx] = input[idx] * values[idx >> 1];
}
+
+/**
+ * Compute the sum of the CTF^2 for the later division.
+ */
+kernel void
+ctf_multidistance_square(global float *distances,
+ unsigned int num_distances,
+ float wavelength,
+ float pixel_size,
+ float regularize_rate,
+ global float *output)
+{
+ COMMON_FREQUENCY_SETUP;
+ CTF_MULTI_SETUP;
+ float result = 0.0f;
+ float value;
+
+ for (unsigned int i = 0; i < num_distances; i++) {
+ value = CTF_MULTI_VALUE(prefac, distances[i], regularize_rate);
+ result += value * value;
+ }
+
+ output[idy * width + idx] = num_distances * 0.5f * pow(10, regularize_rate) / (result + pow(10, -regularize_rate));
+}
+
+/**
+ * Apply the CTF to a projection at a specific distance.
+ */
+kernel void
+ctf_multidistance_apply_distance(global float *input,
+ float dist,
+ unsigned int num_distances,
+ float wavelength,
+ float pixel_size,
+ float regularize_rate,
+ global float *output)
+{
+ COMMON_FREQUENCY_SETUP;
+ CTF_MULTI_SETUP;
+ int index = idy * 2 * width + 2 * idx;
+ float value = CTF_MULTI_VALUE(prefac, dist, regularize_rate) / num_distances;
+
+ output[index] += input[index] * value;
+ output[index + 1] += input[index + 1] * value;
+}