diff options
author | tlatorre <tlatorre@uchicago.edu> | 2018-08-14 10:08:27 -0500 |
---|---|---|
committer | tlatorre <tlatorre@uchicago.edu> | 2018-08-14 10:08:27 -0500 |
commit | 24c8bcfe7f76b20124e2862ea050f815c0f768e7 (patch) | |
tree | e5bdbd638a2c7f38f1c094cc9e95cbdfe05b9481 /muon.c | |
parent | 0b7f199c0d93074484ea580504485a32dc29f5e2 (diff) | |
download | sddm-24c8bcfe7f76b20124e2862ea050f815c0f768e7.tar.gz sddm-24c8bcfe7f76b20124e2862ea050f815c0f768e7.tar.bz2 sddm-24c8bcfe7f76b20124e2862ea050f815c0f768e7.zip |
move everything to src directory
Diffstat (limited to 'muon.c')
-rw-r--r-- | muon.c | 260 |
1 files changed, 0 insertions, 260 deletions
@@ -1,260 +0,0 @@ -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <gsl/gsl_errno.h> -#include <gsl/gsl_spline.h> -#include <math.h> -#include "optics.h" -#include "quantum_efficiency.h" -#include "solid_angle.h" -#include "pdg.h" -#include "vector.h" -#include "muon.h" -#include "sno.h" -#include "scattering.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 const double MUON_CRITICAL_ENERGY = 1.029e6; - -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); - 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, double rho) -{ - /* Returns the approximate range a muon with kinetic energy `T` will travel - * in water before losing all of its energy. This range is interpolated - * based on data from the PDG which uses the continuous slowing down - * approximation. - * - * `T` should be in MeV, and `rho` should be in g/cm^3. - * - * Return value is in cm. - * - * See http://pdg.lbl.gov/2018/AtomicNuclearProperties/adndt.pdf. */ - if (!initialized) { - if (init()) { - exit(1); - } - } - - return gsl_spline_eval(spline_range, T, acc_range)/rho; -} - -double get_T(double T0, double x, double rho) -{ - /* Returns the approximate kinetic energy of a muon in water after - * travelling `x` cm with an initial kinetic energy `T`. - * - * `T` should be in MeV, `x` in cm, and `rho` in g/cm^3. - * - * Return value is in MeV. - * - * See http://pdg.lbl.gov/2018/AtomicNuclearProperties/adndt.pdf. */ - double a, b, range, T; - - if (!initialized) { - if (init()) { - exit(1); - } - } - - range = get_range(T0, rho); - - /* This comes from Equation 33.42 in the PDG Passage of Particles Through - * Matter article. */ - b = log(1 + T0/MUON_CRITICAL_ENERGY)/range; - /* Now we compute the ionization energy loss from the known range and b. */ - a = b*T0/(exp(b*range)-1.0); - - /* Compute the kinetic energy after travelling a distance `x` in the - * continuous slowing down approximation. */ - T = -a/b + (T0+a/b)*exp(-b*x); - - if (T < 0) return 0; - - return T; -} - -double get_dEdx(double T, double rho) -{ - /* Returns the approximate dE/dx for a muon in water with kinetic energy - * `T`. - * - * `T` should be in MeV and `rho` in g/cm^3. - * - * Return value is in MeV/cm. - * - * See http://pdg.lbl.gov/2018/AtomicNuclearProperties/adndt.pdf. */ - if (!initialized) { - if (init()) { - exit(1); - } - } - - return gsl_spline_eval(spline_dEdx, T, acc_dEdx)/rho; -} - -double get_expected_charge(double x, double T, double *pos, double *dir, double *pmt_pos, double *pmt_normal, double r) -{ - double pmt_dir[3], cos_theta, n, wavelength0, omega, theta0, E, p, beta, z, rho, R; - - z = 1.0; - - SUB(pmt_dir,pmt_pos,pos); - normalize(pmt_dir); - - if (DOT(pmt_dir,pmt_normal) > 0) return 0; - - /* Calculate the cosine of the angle between the track direction and the - * vector to the PMT. */ - cos_theta = DOT(dir,pmt_dir); - - /* Calculate total energy */ - E = T + MUON_MASS; - p = sqrt(E*E - MUON_MASS*MUON_MASS); - beta = p/E; - - omega = get_solid_angle_approx(pos,pmt_pos,pmt_normal,r); - - R = NORM(pos); - - if (R <= AV_RADIUS) { - rho = HEAVY_WATER_DENSITY; - } else { - rho = WATER_DENSITY; - } - - /* FIXME: I just calculate delta assuming 400 nm light. */ - wavelength0 = 400.0; - n = get_index(rho, wavelength0, 10.0); - - if (beta < 1/n) return 0; - - /* FIXME: is this formula valid for muons? */ - theta0 = get_scattering_rms(x,p,beta,z,rho); - - /* FIXME: add angular response and scattering/absorption. */ - return 2*omega*2*M_PI*FINE_STRUCTURE_CONSTANT*z*z*(1-(1/(beta*beta*n*n)))*get_probability(beta, cos_theta, theta0)/(sqrt(2*M_PI)*theta0); -} |