aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2019-05-08 13:54:18 +0200
committerThomas White <taw@physics.org>2019-05-14 10:02:50 +0200
commit59770f9bffbd47de5b518244a6dfcfbdfc8dad09 (patch)
tree43cd4f4bc25ca028b6af045737ad8e92426f8594 /tests
parentda02f33cf3722fb1533c4277f3b1cfcf079d4b2f (diff)
Move Histogram out of API
It's only used by two test programs
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt4
-rw-r--r--tests/histogram.c280
-rw-r--r--tests/histogram.h64
-rw-r--r--tests/integration_check.c3
-rw-r--r--tests/prof2d_check.c3
5 files changed, 350 insertions, 4 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index beb141c3..af22977e 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -28,7 +28,7 @@ target_include_directories(centering_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(centering_check ${COMMON_LIBRARIES})
add_test(centering_check centering_check)
-add_executable(integration_check integration_check.c)
+add_executable(integration_check integration_check.c histogram.c)
target_include_directories(integration_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(integration_check PRIVATE ${COMMON_LIBRARIES})
if (CURSES_FOUND)
@@ -47,7 +47,7 @@ target_include_directories(prediction_gradient_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(prediction_gradient_check ${COMMON_LIBRARIES})
add_test(prediction_gradient_check prediction_gradient_check)
-add_executable(prof2d_check prof2d_check.c)
+add_executable(prof2d_check prof2d_check.c histogram.c)
target_include_directories(prof2d_check PRIVATE ${COMMON_INCLUDES})
target_link_libraries(prof2d_check PRIVATE ${COMMON_LIBRARIES})
if (CURSES_FOUND)
diff --git a/tests/histogram.c b/tests/histogram.c
new file mode 100644
index 00000000..69acd987
--- /dev/null
+++ b/tests/histogram.c
@@ -0,0 +1,280 @@
+/*
+ * histogram.c
+ *
+ * Quick histogram functions
+ *
+ * Copyright © 2013-2014 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2013-2014 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+
+#include "histogram.h"
+
+/** \file histogram.h */
+
+struct _histogram
+{
+ int n_vals;
+ int max_vals;
+ double *vals;
+
+ double min;
+ double max;
+
+ int full;
+
+ int n_bins;
+ double bin_width;
+
+ int *bins;
+
+ int plot_height;
+ int peak;
+ double mean;
+ double stddev;
+};
+
+
+Histogram *histogram_init()
+{
+ Histogram *hi;
+
+ hi = malloc(sizeof(struct _histogram));
+ if ( hi == NULL ) return NULL;
+
+ hi->n_vals = 0;
+ hi->max_vals = 0;
+ hi->vals = NULL;
+ hi->full = 0;
+
+ hi->max = -INFINITY;
+ hi->min = INFINITY;
+
+ hi->bins = NULL;
+ hi->n_bins = 50;
+
+ hi->plot_height = 10;
+
+ return hi;
+}
+
+
+void histogram_free(Histogram *hi)
+{
+ free(hi);
+}
+
+
+void histogram_add_value(Histogram *hi, double val)
+{
+ if ( hi->n_vals == hi->max_vals ) {
+ double *new_vals;
+ new_vals = realloc(hi->vals, (hi->max_vals+512)*sizeof(double));
+ if ( new_vals == NULL ) {
+ hi->full = 1;
+ fprintf(stderr, "Histogram %p full.\n", hi);
+ return;
+ }
+ hi->max_vals += 512;
+ hi->vals = new_vals;
+ }
+
+ hi->vals[hi->n_vals++] = val;
+
+ if ( val > hi->max ) hi->max = val;
+ if ( val < hi->min ) hi->min = val;
+}
+
+
+static void calc_bins(Histogram *hi)
+{
+ int i;
+
+ if ( hi->bins != NULL ) {
+ free(hi->bins);
+ }
+
+ hi->bins = calloc(hi->n_bins, sizeof(int));
+ if ( hi->bins == NULL ) {
+ fprintf(stderr, "Failed to allocate bins.\n");
+ return;
+ }
+
+ hi->bin_width = (hi->max - hi->min)/hi->n_bins;
+
+ for ( i=0; i<hi->n_vals; i++ ) {
+
+ int j;
+
+ j = (hi->vals[i] - hi->min) / hi->bin_width;
+
+ /* Tidy up rounding errors */
+ if ( j < 0 ) j = 0;
+ if ( j >= hi->n_bins ) j = hi->n_bins - 1;
+
+ hi->bins[j]++;
+
+ }
+
+ hi->peak = 0;
+ for ( i=0; i<hi->n_bins; i++ ) {
+ if ( hi->bins[i] > hi->peak ) hi->peak = hi->bins[i];
+ }
+}
+
+
+static void calc_stddev(Histogram *hi)
+{
+ double sum = 0.0;
+ int i;
+
+ for ( i=0; i<hi->n_vals; i++ ) {
+ sum += hi->vals[i];
+ }
+ hi->mean = sum / hi->n_vals;
+
+ sum = 0.0;
+ for ( i=0; i<hi->n_vals; i++ ) {
+ sum += pow(hi->vals[i] - hi->mean, 2.0);
+ }
+ hi->stddev = sqrt(sum / hi->n_vals);
+}
+
+
+int *histogram_get_data(Histogram *hi, int *n)
+{
+ calc_bins(hi);
+ *n = hi->n_bins;
+ return hi->bins;
+}
+
+
+void histogram_show(Histogram *hi)
+{
+ int i;
+ int *bins;
+ double lines_per_count;
+ char tmp[32];
+ size_t n_left, n_mid, n_right;
+
+ calc_bins(hi);
+ calc_stddev(hi);
+
+ bins = malloc(hi->n_bins*sizeof(int));
+ if ( bins == NULL ) {
+ fprintf(stderr, "Couldn't scale bins\n");
+ return;
+ }
+
+ lines_per_count = (double)hi->plot_height / hi->peak;
+
+ for ( i=0; i<hi->n_bins; i++ ) {
+ bins[i] = hi->bins[i] * lines_per_count;
+ }
+
+ for ( i=hi->plot_height-1; i>=0; i-- ) {
+
+ int j;
+
+ for ( j=0; j<hi->n_bins; j++ ) {
+ if ( bins[j] > i ) {
+ printf("*");
+ } else {
+ printf(" ");
+ }
+ }
+ printf("\n");
+
+ }
+
+ printf("|");
+ for ( i=1; i<hi->n_bins-1; i++ ) {
+ double bin_low, bin_high;
+ bin_low = hi->min + i*hi->bin_width;
+ bin_high = hi->min + (i+1)*hi->bin_width;
+ if ( (bin_low < 0.0) && (bin_high > 0.0) ) {
+ printf("+");
+ } else {
+ printf("-");
+ }
+ }
+ printf("|\n");
+
+ snprintf(tmp, 31, "%.2f", hi->min);
+ n_left = strlen(tmp);
+ snprintf(tmp, 31, "%.2f", hi->max);
+ n_right = strlen(tmp);
+ n_mid = hi->n_bins - (n_left + n_right);
+
+ printf("%.2f", hi->min);
+ for ( i=0; i<n_mid; i++ ) printf(" ");
+ printf("%.2f\n", hi->max);
+
+ printf("Mean = %.2f, Std dev = %.2f\n", hi->mean, hi->stddev);
+
+ free(bins);
+}
+
+
+double histogram_get_min(Histogram *hi)
+{
+ return hi->min;
+}
+
+
+double histogram_get_max(Histogram *hi)
+{
+ return hi->max;
+}
+
+
+int histogram_get_num_bins(Histogram *hi)
+{
+ return hi->n_bins;
+}
+
+
+void histogram_set_min(Histogram *hi, double min)
+{
+ hi->min = min;
+}
+
+
+void histogram_set_max(Histogram *hi, double max)
+{
+ hi->max = max;
+}
+
+
+void histogram_set_num_bins(Histogram *hi, int n)
+{
+ hi->n_bins = n;
+}
diff --git a/tests/histogram.h b/tests/histogram.h
new file mode 100644
index 00000000..2b9d4928
--- /dev/null
+++ b/tests/histogram.h
@@ -0,0 +1,64 @@
+/*
+ * histogram.h
+ *
+ * Quick histogram functions
+ *
+ * Copyright © 2013-2014 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2013-2014 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef HISTOGRAM_H
+#define HISTOGRAM_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file histogram.h
+ * Quick histogram functions
+ */
+
+typedef struct _histogram Histogram;
+
+extern Histogram *histogram_init();
+extern void histogram_free(Histogram *hi);
+extern void histogram_add_value(Histogram *hi, double val);
+extern void histogram_show(Histogram *hi);
+
+extern int *histogram_get_data(Histogram *hi, int *n);
+extern double histogram_get_min(Histogram *hi);
+extern double histogram_get_max(Histogram *hi);
+extern int histogram_get_num_bins(Histogram *hi);
+extern void histogram_set_min(Histogram *hi, double min);
+extern void histogram_set_max(Histogram *hi, double max);
+extern void histogram_set_num_bins(Histogram *hi, int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HISTOGRAM_H */
diff --git a/tests/integration_check.c b/tests/integration_check.c
index 65241612..a6ceb2c4 100644
--- a/tests/integration_check.c
+++ b/tests/integration_check.c
@@ -36,7 +36,8 @@
#include <image.h>
#include <utils.h>
-#include <histogram.h>
+
+#include "histogram.h"
#include "../libcrystfel/src/integration.c"
diff --git a/tests/prof2d_check.c b/tests/prof2d_check.c
index 8b9de871..803e60c4 100644
--- a/tests/prof2d_check.c
+++ b/tests/prof2d_check.c
@@ -36,7 +36,8 @@
#include <image.h>
#include <utils.h>
-#include <histogram.h>
+
+#include "histogram.h"
#include "../libcrystfel/src/integration.c"