aboutsummaryrefslogtreecommitdiff
path: root/utils/plot-root-results
blob: 51df7cc9d03cd4951d3ff5fb52382939b7e314ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python
# Copyright (c) 2019, Anthony Latorre <tlatorre at uchicago>
#
# This program 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.
#
# This program 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
# this program. If not, see <https://www.gnu.org/licenses/>.

from __future__ import print_function, division
import numpy as np

if __name__ == '__main__':
    import ROOT
    import argparse
    from os.path import split
    from sddm.plot import despine
    from sddm import setup_matplotlib

    parser = argparse.ArgumentParser("plot ROOT fit results")
    parser.add_argument("filename", help="input file")
    parser.add_argument("--save", action="store_true", default=False, help="save plots")
    args = parser.parse_args()

    setup_matplotlib(args.save)

    import matplotlib.pyplot as plt

    root_file = ROOT.TFile(args.filename)

    head, tail = split(args.filename)

    if tail.startswith("e_") or tail.startswith("electron"):
        prefix = "electron"
    elif tail.startswith("mu_") or tail.startswith("muon"):
        prefix = "muon"
    else:
        prefix = ""

    try:
        if root_file.Get("h1"):
            for hist_number, tf1_number in zip([1,2,4,5],[1,2,3,None]):
                h = root_file.Get("h%i" % hist_number)
                if tf1_number:
                    f = root_file.Get("f%i" % tf1_number)

                bins = [h.GetXaxis().GetBinLowEdge(i) for i in range(1,h.GetNbinsX()+1)] + [h.GetXaxis().GetBinUpEdge(h.GetNbinsX())]
                hist = [h.GetBinContent(i) for i in range(1,h.GetNbinsX()+1)]

                bins = np.array(bins)
                hist = np.array(hist)

                bincenters = (bins[1:] + bins[:-1])/2

                norm = np.trapz(hist,bincenters)

                hist /= norm

                fig = plt.figure()
                plt.hist(bincenters,weights=hist,bins=bins,histtype='step')
                x = np.linspace(bins[0],bins[-1],10000)
                if tf1_number:
                    plt.plot(x,[f(xval)/norm for xval in x],color='red')
                despine(fig,trim=True)
                if hist_number == 1:
                    plt.gca().set_xlim(-1,1)
                    plt.ylabel("Arbitrary Units")
                    plt.xlabel(r"$\cos\theta$")
                    if args.save:
                        plt.savefig("%s_shower_angular_distribution.pdf" % prefix)
                        plt.savefig("%s_shower_angular_distribution.eps" % prefix)
                    else:
                        plt.title("%s Shower Angular Distribution" % prefix.capitalize())
                elif hist_number == 2:
                    plt.ylabel("Arbitrary Units")
                    plt.xlabel(r"Distance along Track (cm)")
                    if args.save:
                        plt.savefig("%s_shower_position_distribution.pdf" % prefix)
                        plt.savefig("%s_shower_position_distribution.eps" % prefix)
                    else:
                        plt.title("%s Shower Position Distribution" % prefix.capitalize())
                elif hist_number == 4:
                    plt.ylabel("Arbitrary Units")
                    plt.xlabel(r"$\cos\theta$")
                    if args.save:
                        plt.savefig("%s_delta_ray_angular_distribution.pdf" % prefix)
                        plt.savefig("%s_delta_ray_angular_distribution.eps" % prefix)
                    else:
                        plt.title("%s Delta Ray Angular Distribution" % prefix.capitalize())
                elif hist_number == 5:
                    plt.ylabel("Arbitrary Units")
                    plt.xlabel(r"Distance along Track (cm)")
                    if args.save:
                        plt.savefig("%s_delta_ray_position_distribution.pdf" % prefix)
                        plt.savefig("%s_delta_ray_position_distribution.eps" % prefix)
                    else:
                        plt.title("%s Delta Ray Position Distribution" % prefix.capitalize())
        else:
            for graph_name, tf1_number, ylabel in zip(["g_dir_alpha","g_dir_beta","g_pos_alpha","g_pos_beta","g_dir_alpha_delta","g_dir_beta_delta"],
                                                      [1,2,None,None,3,4],
                                                      [r"$\alpha$",r"$\beta$",r"$k$",r"$\theta$",r"$\alpha$",r"$\beta$"]):
                g = root_file.Get(graph_name)
                if tf1_number:
                    f = g.GetFunction("f%i" % tf1_number)

                x = [g.GetX()[i] for i in range(g.GetN())]
                y = [g.GetY()[i] for i in range(g.GetN())]
                yerr = [g.GetEY()[i] for i in range(g.GetN())]

                x = np.array(x)
                y = np.array(y)
                yerr = np.array(yerr)

                fig = plt.figure()
                plt.errorbar(x,y,yerr=yerr,fmt='o')
                x = np.linspace(x[0],x[-1],10000)
                if tf1_number:
                    plt.plot(x,[f(xval) for xval in x],color='red')
                despine(fig,trim=True)
                plt.xlabel("Kinetic Energy (MeV)")
                plt.ylabel(ylabel)

                if graph_name == "g_dir_alpha":
                    if args.save:
                        plt.savefig("%s_shower_angular_distribution_alpha.pdf" % prefix)
                        plt.savefig("%s_shower_angular_distribution_alpha.eps" % prefix)
                    else:
                        plt.title("%s Shower Angular Distribution" % prefix.capitalize())
                elif graph_name == "g_dir_beta":
                    if args.save:
                        plt.savefig("%s_shower_angular_distribution_beta.pdf" % prefix)
                        plt.savefig("%s_shower_angular_distribution_beta.eps" % prefix)
                    else:
                        plt.title("%s Shower Position Distribution" % prefix.capitalize())
                elif graph_name == "g_pos_alpha":
                    if args.save:
                        plt.savefig("%s_shower_position_distribution_alpha.pdf" % prefix)
                        plt.savefig("%s_shower_position_distribution_alpha.eps" % prefix)
                    else:
                        plt.title("%s Shower Position Distribution" % prefix.capitalize())
                elif graph_name == "g_pos_beta":
                    if args.save:
                        plt.savefig("%s_shower_position_distribution_beta.pdf" % prefix)
                        plt.savefig("%s_shower_position_distribution_beta.eps" % prefix)
                    else:
                        plt.title("%s Shower Position Distribution" % prefix.capitalize())
                elif graph_name == "g_dir_alpha_delta":
                    if args.save:
                        plt.savefig("%s_delta_ray_angular_distribution_alpha.pdf" % prefix)
                        plt.savefig("%s_delta_ray_angular_distribution_alpha.eps" % prefix)
                    else:
                        plt.title("%s Delta Ray Angular Distribution" % prefix.capitalize())
                elif graph_name == "g_dir_beta_delta":
                    if args.save:
                        plt.savefig("%s_delta_ray_angular_distribution_beta.pdf" % prefix)
                        plt.savefig("%s_delta_ray_angular_distribution_beta.eps" % prefix)
                    else:
                        plt.title("%s Delta Ray Position Distribution" % prefix.capitalize())

        plt.show()
    
    finally:
        root_file.Close()
span class="p">,y,LEN(x)); } double electron_get_angular_pdf(double cos_theta, double alpha, double beta, double mu) { /* Returns the probability density that a photon in the wavelength range * 200 nm - 800 nm is emitted at an angle cos_theta. * * The angular distribution is modelled by the pdf: * * f(cos_theta) ~ exp(-abs(cos_theta-mu)^alpha/beta) * * where alpha and beta are constants which depend on the initial energy of * the particle. * * There is no nice closed form solution for the integral of this function, * so we just compute it on the fly. To make things faster, we keep track * of the last alpha, beta, and mu parameters that were passed in so we * avoid recomputing the normalization factor. */ size_t i; static double last_alpha, last_beta, last_mu, norm; static int first = 1; static double x[10000], y[10000]; if (first || alpha != last_alpha || beta != last_beta || mu != last_mu) { norm = electron_get_angular_pdf_norm(alpha, beta, mu); last_alpha = alpha; last_beta = beta; last_mu = mu; for (i = 0; i < LEN(x); i++) { x[i] = -1.0 + 2.0*i/(LEN(x)-1); y[i] = electron_get_angular_pdf_no_norm(x[i], alpha, beta, mu)/norm; } first = 0; } return interp1d(cos_theta,x,y,LEN(x)); } static int init() { int i, j; char line[256]; char *str; double value; int n; FILE *f = open_file("e_water_liquid.txt", "r"); if (!f) { fprintf(stderr, "failed to open e_water_liquid.txt: %s\n", 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 8 lines since it's just a header. */ if (i <= 8) continue; if (!len) continue; else if (line[0] == '#') continue; str = strtok(line," \n"); while (str) { value = strtod(str, NULL); str = strtok(NULL," \n"); } n += 1; } x = malloc(sizeof(double)*n); dEdx_rad = 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 8 lines since it's just a header. */ if (i <= 8) continue; if (!len) continue; else if (line[0] == '#') continue; str = strtok(line," \n"); j = 0; while (str) { value = strtod(str, NULL); switch (j) { case 0: x[n] = value; break; case 2: dEdx_rad[n] = value; break; case 3: dEdx[n] = value; break; case 4: csda_range[n] = value; break; } j += 1; str = strtok(NULL," \n"); } n += 1; } fclose(f); acc_dEdx_rad = gsl_interp_accel_alloc(); spline_dEdx_rad = gsl_spline_alloc(gsl_interp_linear, size); gsl_spline_init(spline_dEdx_rad, x, dEdx_rad, size); 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; } /* Returns the maximum kinetic energy for an electron in the range tables. * * If you call electron_get_range() or electron_get_dEdx() with a kinetic * energy higher you will get a GSL interpolation error. */ double electron_get_max_energy(void) { if (!initialized) { if (init()) { exit(1); } } return x[size-1]; } double electron_get_range(double T, double rho) { /* Returns the approximate range a electron 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 electron_get_dEdx_rad(double T, double rho) { /* Returns the approximate radiative dE/dx for a electron 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); } } if (T < spline_dEdx_rad->x[0]) return spline_dEdx_rad->y[0]; return gsl_spline_eval(spline_dEdx_rad, T, acc_dEdx_rad)*rho; } double electron_get_dEdx(double T, double rho) { /* Returns the approximate dE/dx for a electron 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); } } if (T < spline_dEdx->x[0]) return spline_dEdx->y[0]; return gsl_spline_eval(spline_dEdx, T, acc_dEdx)*rho; }