aboutsummaryrefslogtreecommitdiff
path: root/muon.c
diff options
context:
space:
mode:
authortlatorre <tlatorre@uchicago.edu>2018-07-05 13:51:53 -0400
committertlatorre <tlatorre@uchicago.edu>2018-07-05 13:51:53 -0400
commit1ee8128fedd3e42f083389704d8be59eef6184bf (patch)
tree938b4b3734eff377a644a88456bc754179d0d70b /muon.c
parenta6c4f3c3de90441347dfe6b25c1c404a7ae930e9 (diff)
downloadsddm-1ee8128fedd3e42f083389704d8be59eef6184bf.tar.gz
sddm-1ee8128fedd3e42f083389704d8be59eef6184bf.tar.bz2
sddm-1ee8128fedd3e42f083389704d8be59eef6184bf.zip
add functions to compute the range and dE/dx for muons in water
Diffstat (limited to 'muon.c')
-rw-r--r--muon.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/muon.c b/muon.c
new file mode 100644
index 0000000..ab79666
--- /dev/null
+++ b/muon.c
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gsl/gsl_errno.h>
+#include <gsl/gsl_spline.h>
+
+static int initialized = 0;
+
+static double *x, *dEdx, *csda_range;
+static size_t size;
+
+static gsl_interp_accel *acc_dEdx;
+static gsl_spline *spline_dEdx;
+
+static gsl_interp_accel *acc_range;
+static gsl_spline *spline_range;
+
+static int init()
+{
+ int i, j;
+ char line[256];
+ char *str;
+ double value;
+ int n;
+
+ FILE *f = fopen("muE_water_liquid.txt", "r");
+
+ if (!f) {
+ fprintf(stderr, "failed to open muE_water_liquid.txt: %s", strerror(errno));
+ return -1;
+ }
+
+ i = 0;
+ n = 0;
+ /* For the first pass, we just count how many values there are. */
+ while (fgets(line, sizeof(line), f)) {
+ size_t len = strlen(line);
+ if (len && (line[len-1] != '\n')) {
+ fprintf(stderr, "got incomplete line on line %i: '%s'\n", i, line);
+ goto err;
+ }
+
+ i += 1;
+
+ /* Skip the first 10 lines since it's just a header. */
+ if (i <= 10) continue;
+
+ if (!len) continue;
+ else if (line[0] == '#') continue;
+ else if (strstr(line, "Minimum ionization")) continue;
+ else if (strstr(line, "Muon critical energy")) continue;
+
+ str = strtok(line," \n");
+
+ while (str) {
+ value = strtod(str, NULL);
+ str = strtok(NULL," \n");
+ }
+
+ n += 1;
+ }
+
+ x = malloc(sizeof(double)*n);
+ dEdx = malloc(sizeof(double)*n);
+ csda_range = malloc(sizeof(double)*n);
+ size = n;
+
+ i = 0;
+ n = 0;
+ /* Now, we actually store the values. */
+ rewind(f);
+ while (fgets(line, sizeof(line), f)) {
+ size_t len = strlen(line);
+ if (len && (line[len-1] != '\n')) {
+ fprintf(stderr, "got incomplete line on line %i: '%s'\n", i, line);
+ goto err;
+ }
+
+ i += 1;
+
+ /* Skip the first 10 lines since it's just a header. */
+ if (i <= 10) continue;
+
+ if (!len) continue;
+ else if (line[0] == '#') continue;
+ else if (strstr(line, "Minimum ionization")) continue;
+ else if (strstr(line, "Muon critical energy")) continue;
+
+ str = strtok(line," \n");
+
+ j = 0;
+ while (str) {
+ value = strtod(str, NULL);
+ /* According to the file, the values are stored for wavelengths
+ * between 230 and 700 in 1 nm increments. */
+ switch (j) {
+ case 0:
+ x[n] = value;
+ break;
+ case 7:
+ dEdx[n] = value;
+ break;
+ case 8:
+ csda_range[n] = value;
+ break;
+ }
+ j += 1;
+ str = strtok(NULL," \n");
+ }
+
+ n += 1;
+ }
+
+ fclose(f);
+
+ acc_dEdx = gsl_interp_accel_alloc();
+ spline_dEdx = gsl_spline_alloc(gsl_interp_linear, size);
+ gsl_spline_init(spline_dEdx, x, dEdx, size);
+
+ acc_range = gsl_interp_accel_alloc();
+ spline_range = gsl_spline_alloc(gsl_interp_linear, size);
+ gsl_spline_init(spline_range, x, csda_range, size);
+
+ initialized = 1;
+
+ return 0;
+
+err:
+ fclose(f);
+
+ return -1;
+}
+
+double get_range(double T)
+{
+ if (!initialized) {
+ if (init()) {
+ exit(1);
+ }
+ }
+
+ return gsl_spline_eval(spline_range, T, acc_range);
+}
+double get_dEdx(double T)
+{
+ if (!initialized) {
+ if (init()) {
+ exit(1);
+ }
+ }
+
+ return gsl_spline_eval(spline_dEdx, T, acc_dEdx);
+}