Appendix A: HDF5 event files structure
The HDF5 files created by the event generator consist of a collection of arrays containing the properties of the neutrinos and other secondary particles (taus, for instance). The array keys and contents are the following:
azimuths, the arrival azimuth angles in radians.
zeniths, the arrival zenith angles in radians.
xx, yy, and zz, the x, y and z coordinates in meters for the point where the particles interact or decay.
event_ids, the event identification numbers
n_interaction, the interaction number. 1 indicates a neutrino interaction, 2 and greater indicates decay or interaction of a lepton created after the neutrino interaction.
flavors, neutrino flavors. 12 for electron neutrino, 14 for muon neutrino, and 16 for tau neutrino. Antineutrinos are represented by \(-12\), \(-14\), and \(-16\). A value of 15 indicates a tau lepton. The numbers are following the standard of [30].
energies, the particle energies in electronvolts
interaction_type, the interaction type. ’cc’ for charged current, and ’nc’ for neutral current. ’tau_had’, ’tau_em’, ’tau_mu’ indicate the tau decays into the hadronic, electromagnetic and muonic channels respectively.
inelasticities, the inelasticities for the neutrino interactions and the tau decays, that is, the energy fractions taken by the product cascades.
In these HDF5 files we also save as attributes the number of events and the characteristics of the fiducial and total simulated volumes, along with maximum and minimum energies and angles for the neutrinos.
Appendix B: NuRadioMC HDF5 output files structure
NuRadioMC creates as output an HDF5 file with information on the events and on the simulation outcome. The user can choose between saving all the information for all events or only for those that have triggered. The NuRadioMC HDF5 output files contain all the values that can be found in the event files (Appendix A), along with the following additional arrays:
triggered, with ones indicating a triggering event and zeroes a non-triggering event.
weights, the weights given to each event as a consequence of propagation through the Earth.
multiple_triggers, indicates if the triggering condition has been met individually for each simulated trigger. The first axis of this array gives the event number, and the second the type of trigger.
The rest of the output arrays are stored in several HDF5 groups, each group corresponding to a simulated station. The following arrays (except for the SNRs array) contained within the station group are multidimensional. Their first axis is the event number, and the second one the antenna. Each group for a given station contains:
SNRs, the signal to noise ratios for each event defined as the maximum signal amplitude divided by the RMS noise.
triggered, with ones indicating a triggering station and zeroes a non-triggering station.
multiple_triggers, indicates if the triggering condition has been met individually for each simulated trigger. The first axis of this array gives the event number, and the second the type of trigger.
maximum_amplitudes, the maximum amplitudes for the voltages of each antenna.
maximum_amplitudes_envelope, the maximum amplitudes of the voltage envelope of each antenna.
travel_distances, the distances traveled by the rays. There can be up to two, one for each ray-tracing solution. The third axis of the array indicates the ray-tracing solution. The same principle applies to all arrays containing ray-tracing information.
travel_times, the times taken by the rays from emitter to observer.
ray_tracing_C0, \(C_0\) parameters for the ray tracing solutions.
ray_tracing_C1, \(C_1\) parameters for the ray tracing solutions.
ray_tracing_solution_type, strings containing the type of ray tracing solutions: direct, reflected, or refracted.
The following arrays of the HDF5 group contain three-dimensional vectors, and therefore they have a fourth axis that allows us to find the x, y, and z components of said vectors.
launch_vectors, the launch vectors for the ray tracing solutions.
receive_vectors, the receive vectors for the ray tracing solutions.
polarization, the polarization of the electric field.
In the attributes of the output files the names of the simulated triggers (using the string trigger_names) can be found.
Appendix C: Analytic ray tracing
The analytic ray tracing in NuRadioMC provides a novel and fast solution of the ray-tracing problem. For completeness we provide the full derivation of the analytic solution, the path, the path length and the travel time.
Appendix C.1: Derivation of analytic solution
In this section, we will derive the analytic solution to the ray tracing problem. Fermat’s principle states that the optical path of a ray of light travelling between two points is stationary. Suppose the index of refraction depends on one coordinate in a three-dimensional Cartesian coordinate system:
$$\begin{aligned} n(x,y,z) = n(z) \end{aligned}$$
(C.1)
Further, let \(dx/dz = \dot{x}\) and \(dy/dz = \dot{y}\), so that the metric may be expressed as:
$$\begin{aligned} ds = \sqrt{dx^2 + dy^2 + dz^2} = dz \sqrt{\dot{x}^2 + \dot{y}^2 + 1} \end{aligned}$$
(C.2)
The symmetry of n(z) implies that the coordinate system may be rotated such that \(\dot{x} = 0\). Thus the metric becomes
$$\begin{aligned} ds = dz \sqrt{\dot{y}^2 + 1} \end{aligned}$$
(C.3)
Inserting this metric into Fermat’s Principle gives
$$\begin{aligned} S&= \int _A^B n ds \end{aligned}$$
(C.4)
$$\begin{aligned} \delta S&= 0 \end{aligned}$$
(C.5)
$$\begin{aligned} \delta \int _A^B n(z) \sqrt{1+ \dot{y}^2} dz&= 0 \end{aligned}$$
(C.6)
Defining \(u = \dot{y}\) and applying the Euler-Lagrange equations yields
$$\begin{aligned} \dot{u} = -\frac{\dot{n}}{n}(u^3+u) \end{aligned}$$
(C.7)
Letting \(v = -\ln n\), Eq. C.7 simplifies to
$$\begin{aligned} \dot{u} = \dot{v}(u^3+u) \end{aligned}$$
(C.8)
Noting that \(\dot{v} = dv/dz\), and applying the chain rule gives
$$\begin{aligned} \frac{du}{dz} \frac{dz}{dv} = \frac{du}{dv} = u^3 + u \end{aligned}$$
(C.9)
Rearranging and then integrating gives
$$\begin{aligned} \int \frac{du}{u^3 + u}&= \int dv \end{aligned}$$
(C.10)
$$\begin{aligned} \ln u - \frac{1}{2}\ln (u^2 + 1)&= v + C_0 \end{aligned}$$
(C.11)
Equation C.11 may be solved for dz/dy after re-scaling \(C_0\):
$$\begin{aligned} \frac{dz}{dy} = \pm \sqrt{C_0^2 n^2 - 1} \end{aligned}$$
(C.12)
In the case of South Pole and Moore’s Bay glacial ice, it is found that n(z) is described to within a few percent by an exponential function [68] which allows us to proceed further in solving for the ray-path.
$$\begin{aligned} n(z) = n_{ice} - \varDelta _n \exp (z/z_0) \end{aligned}$$
(C.13)
Let \(\gamma =\varDelta _n \exp (z/z_0)\), which implies
$$\begin{aligned} n(z)&= n_{ice}-\gamma \end{aligned}$$
(C.14)
$$\begin{aligned} dz&= \gamma ^{-1} z_0 d\gamma \end{aligned}$$
(C.15)
Inserting Eq. C.13 into Eq. C.12 and integrating, with \(b = 2 n_{ice}\) and \(c = n_{ice}^2 - C_0^{-2}\):
$$\begin{aligned} \int \frac{d\gamma }{\gamma (\gamma ^2 - b\gamma + c)^{1/2}} = \pm C_0 \left( \frac{y}{z_0} + C_1\right) \end{aligned}$$
(C.16)
The second integration constant is \(C_1\). Intriguingly, for depths much greater than the scale height (\(|z_i| \gg z_0\), \(z_i < 0\)), the integral in Eq. C.16 has a singularity in the denominator when the ray is initially horizontal. This is discussed further below. The solution to Eq. C.16 is available in standard tables. The solution with y as a function of z via \(\gamma \) is:
$$\begin{aligned} y(z)= & {} \pm C_0^{-1} c^{-1/2} z_0 \nonumber \\&\ln \left( \frac{\gamma }{2 c^{1/2} (\gamma ^2 - b\gamma +c)^{1/2} -b\gamma + 2c} \right) \mp z_0 C_1 \nonumber \\ \end{aligned}$$
(C.17)
Let the function within the logarithm in Eq. C.17 be \(F(\gamma )\):
$$\begin{aligned} F(\gamma ) = \frac{\gamma }{2 c^{1/2} (\gamma ^2 - b\gamma +c)^{1/2} -b\gamma + 2c} \end{aligned}$$
(C.18)
Inserting Eq. C.18 into Eq. C.17, we recover a function which returns the ray path as a function of depth:
$$\begin{aligned} y(z) = \pm C_0^{-1} c^{-1/2} z_0 \ln \left( F(\gamma ) \right) \mp z_0 C_1 \end{aligned}$$
(C.19)
Because the ice model is horizontally symmetric, the constant \(C_1\) is set by the choice of origin. All that remains is to understand the physical meaning of \(C_0\). Let the initial angle with respect to the horizontal be \(\theta _i\), which should obey
$$\begin{aligned} \frac{dy}{dz}&= \cot (\theta _i) \end{aligned}$$
(C.20)
$$\begin{aligned} \frac{dy}{d\gamma }&= z_0 \gamma ^{-1} \cot (\theta _i) \end{aligned}$$
(C.21)
Given Eq. C.19, Eq. C.21 may be solved in terms of \(F(\gamma )\). The result is
$$\begin{aligned} \tan \theta _i = \pm C_0 c^{1/2} \frac{F(\gamma )}{\gamma F'(\gamma )} \end{aligned}$$
(C.22)
Inserting the definition of c and solving for \(C_0\):
$$\begin{aligned} C_0(\gamma ,\theta _i) = \pm n_{ice}^{-1} \left( \frac{\gamma ^2 F'^2(\gamma )}{F^2(\gamma )}\tan ^2\theta _i + 1 \right) ^{1/2} \end{aligned}$$
(C.23)
The right-hand side of Eq. C.23 resembles a secant function. Restricting to initial depths much greater than the scale depth (\(|z_i| \gg z_0\), \(z_i < 0\)) causes
$$\begin{aligned} \frac{\gamma ^2 F'^2(\gamma )}{F^2(\gamma )} \rightarrow 1 \end{aligned}$$
(C.24)
If this limit is taken, then Eq. C.23 simplifies:
$$\begin{aligned} C_0(\gamma ,\theta _i) = \pm n_{ice}^{-1} \left( \tan ^2\theta _i + 1 \right) ^{1/2} = \pm n_{ice}^{-1} \sec \theta _i \end{aligned}$$
(C.25)
\(C_0\) is a constant that depends on the boundary conditions, so Eq. C.25 may be inverted:
$$\begin{aligned} n_{ice} \cos \theta _i = \pm C_0^{-1} \end{aligned}$$
(C.26)
Equation C.26 is Snell’s Law, because \(C_0\) is constant and \(\theta _i\) is defined with respect to the horizontal. Thus, in the limit (\(|z_i| \gg z_0\), \(z_i < 0\)) the singularity in Eq. C.16 is for \(\cos \theta _i = \pm 1\), i.e. horizontal propagation. Further, in the limit (\(|z_i| \gg z_0\), \(z_i < 0\)) the factor in front of Eq. C.19, \(C_0^{-1} c^{-1/2}\), simplifies:
$$\begin{aligned} c&= n_{ice}^2 - C_0^{-2} \end{aligned}$$
(C.27)
$$\begin{aligned} c^{-1/2}&= \left( n_{ice}^2 - C_0^{-2} \right) ^{-1/2} \end{aligned}$$
(C.28)
$$\begin{aligned} C_0^{-1} c^{-1/2}&= \left( C_0^2 n_{ice}^2 - 1 \right) ^{-1/2} \end{aligned}$$
(C.29)
$$\begin{aligned} C_0^{-1} c^{-1/2}&= \cot (\theta _i) \end{aligned}$$
(C.30)
In the last step, Eq. C.12 has been used. Thus, the closed form of y(z) is
$$\begin{aligned} y(z) = \pm z_0 \cot {\theta _i} \ln \left( F(\gamma ) \right) \end{aligned}$$
(C.31)
If the depth z does not satisfy the limit (\(|z_i| \gg z_0\), \(z_i < 0\)), \(C_0\) must first be obtained from Eq. C.23, and then inserted into Eq. C.19 to obtain the ray-tracing path.
Appendix C.2: Putting the analytic solution into practical usability
In this section, we demonstrate how to efficiently solve the analytic equations for the ray path derived in Appendix C.1. Without loss of generality, we can use only the positive solution which corresponds to rays propagating into the positive y direction. Equally, we can only consider rays in the \(y-z\) plane. This is because such a start configuration can always be achieved with a simple coordinate transformation.
In addition, it is sufficient to only compute solution from a deeper to a shallower position without loss of generality by flipping the initial condition. Hence we can always reduce the problem to finding all possible path’s between two points
$$\begin{aligned} \mathbf {x}_1= & {} (y_1, z_1)^T \quad \mathrm {and}\quad \mathbf {x}_2 = (y_2, z_2)^T \nonumber \\&\mathrm { with }\, y_1< y_2\quad \mathrm {and}\quad z_1 < z_2 \,. \end{aligned}$$
(C.32)
The analytic solution only describes the “first part” of the solution until the turning point. This is the position where the ray either hits the surface and is reflected down, or it reaches the point where the propagation direction of the ray becomes horizontal (i.e. into the y direction) due to continuous refraction. This is of course a consequence of the solution being y(z) and not z(y) which is needed to describe the ray path in a single analytic function (because z(y) is not bijective).
The turning point is the position where the second root of Eq. (10) becomes undefined, i.e., for
$$\begin{aligned} \gamma ^2 - b \gamma + c = 0 \Rightarrow \gamma _\mathrm {turn} = \frac{1}{2} b - \sqrt{\frac{b^2}{4} - c}. \end{aligned}$$
(C.33)
The \(z_\mathrm {turn}\) position can be calculated from \(\gamma _\mathrm {turn}\). If \(z_\mathrm {turn}\) is positive, the turning points is above the surface. Hence, the ray is reflected off the surface and \(z_\mathrm {turn}\) is set to zero. Then, \(y_\mathrm {turn}\) can be calculated by inserting \(z_\mathrm {turn}\) into Eq. (10).
Hence, from an implementation perspective, we have two distinct cases: either we have a direct ray (\(y_2 < y_\mathrm {turn}\)) or we have a reflected or refracted ray (\(y_2 > y_\mathrm {turn}\)).
Appendix C.3: Determination of free parameters
Now, we present how to determine the two free parameters \(C_0\) and \(C_1\) in a fast and robust way from the initial condition that the ray path goes through the points \(\mathbf {x}_1\) and \(\mathbf {x}_2\). The parameter \(C_1\) is given by
$$\begin{aligned} C_1 = y_1 - y(z_1, C_0 = C'_0, C_1=0) \, \end{aligned}$$
(C.34)
with y() being Eq. (10) evaluated for \(C_0 = C'_0\) and \(C_1 = 0\).
The parameter \(C_0\) needs to be determined numerically by minimizing the following objective function:
$$\begin{aligned} \chi ^2 = \left( y_2 - y'(z_2, C_0, C_1)\right) ^2 \, . \end{aligned}$$
(C.35)
As Eq. (10) describes only half of the solution, we first check if \(\mathbf {x}_2\) is before or after the turning point. It is after the turning point if \(y_\mathrm {turn} < y_2\). Then the following coordinate transformation is performed.
$$\begin{aligned} y'(z_2, C_0, C_1) = 2 \, y_\mathrm {turn} - y(z_2, C_0, C_1) \, . \end{aligned}$$
(C.36)
To increase the numerical stability of the minimizer it is useful to perform the following coordinate transformation
$$\begin{aligned} D = \ln (C_0 - 1/n_\mathrm {ice}) \, . \end{aligned}$$
(C.37)
Then Eq. (10) is defined for all values of D.
For typical geometries not just one but two solutions are present. Once one solution is found, the second solution can be determined fast and efficiently using the Brent root finding algorithm [102], and using the displacement in y at position \(\mathbf {x}_2\) as objective function (cf. Fig. 16 right). Utilization of Brent’s algorithm is possible because for a second solution to exists, \(\varDelta y\) needs to change sign in one of the open intervals \((-\infty , C_0^1)\) and \((C_0^1, \infty )\), where \(C_0^1\) is the first solution.
Appendix C.4: Derivative of analytic ray tracing path
The derivative of the analytic ray tracing solution is given by
$$\begin{aligned}&\frac{d y(z)}{d z} \nonumber \\&\quad =\left( -\sqrt{c}{\mathrm{e}^{{\frac{z}{{ z_0}}}}}b{ \varDelta _n}+2 \,\sqrt{-b{ \varDelta _n}\,{\mathrm{e}^{{\frac{z}{{ z_0}}}}}+{{ \varDelta _n}}^{2}{\mathrm{e}^{2\,{\frac{z}{{ z_0}}}}}+c}\, c+2\,{c}^{3/2} \right) \nonumber \\&\qquad \times \left( 2\,\sqrt{c}\sqrt{-b{ \varDelta _n}\,{\mathrm{e}^{{ \frac{z}{{ z_0}}}}}+{{ \varDelta _n}}^{2}{\mathrm{e}^{2\,{\frac{z}{{ z_0}}}}}+c}-b{ \varDelta _n}\,{\mathrm{e}^{{\frac{z}{{ z_0}}}}}+ 2\,c \right) ^{-1}\nonumber \\&\qquad \times {\frac{1}{\sqrt{-b{ \varDelta _n}\,{\mathrm{e}^{{ \frac{z}{{ z_0}}}}}+{{ \varDelta _n}}^{2}{\mathrm{e}^{2\,{\frac{z}{{ z_0}}}}}+c}}}{\frac{1}{\sqrt{{{ C_0}}^{2}{{ n_\mathrm {ice}}}^{2} -1}}} \, . \end{aligned}$$
(C.38)
Appendix C.5: Analytic solution of path length and travel time
In this section, the analytic solution of the path length and travel time for an exponential index-of-refraction profile is derived.
To find the path(s) between two given points in the ice, \((r_0, z_0)\) and \((r_1, z_1)\), we need to find the launch angle(s) \(\theta _0\) of the ray(s). The radial coordinate r is equivalent to the y coordinate used in the previous sections, since we are restricted to the vertical plane where the wave propagates. Given the launch angle \(\theta _0\) then we can find \(\theta \) as a function of z using Snell’s Law:
$$\begin{aligned}&n(z) \sin (\theta (z)) = n(z_0) \sin (\theta _0) \end{aligned}$$
(C.39)
$$\begin{aligned}&\theta (z) = \arcsin \left( \frac{n(z_0) \sin (\theta _0)}{n(z)} \right) \end{aligned}$$
(C.40)
Since we know the radial distance between our starting and ending points, we can calculate the launch angle by first working out the radial distance integral as a function of launch angle, and then inverting it.
$$\begin{aligned} \frac{dr}{dz}= & {} \frac{dr}{ds} \frac{ds}{dz} = \tan (\theta )\\ \int _{r_0}^{r_1}\ dr= & {} \int _{z_0}^{z_1} \tan (\theta )\ dz \end{aligned}$$
And then using Eq. C.40, this becomes
$$\begin{aligned} r_1 - r_0 = \int _{z_0}^{z_1} \tan \left( \arcsin \left( \frac{n(z_0) \sin (\theta _0)}{n(z)} \right) \right) \ dz \end{aligned}$$
(C.41)
To calculate the launch angle(s) for ray(s) between our two points, solve this equation for \(\theta _0\). While we will continue solving this problem in generality for any n(z) now, in a following section we will simplify the answer for a specific ice model.
Once we know the launch angle of our path we have all we need to calculate its properties. The total path length can be calculated by integrating \(\frac{dz}{ds}\):
$$\begin{aligned} s =&\int _{z_0}^{z_1} \frac{1}{\cos (\theta )}\ dz \end{aligned}$$
(C.42)
$$\begin{aligned} =&\int _{z_0}^{z_1} \sec \left( \arcsin \left( \frac{n(z_0) \sin (\theta _0)}{n(z)} \right) \right) \ dz \end{aligned}$$
(C.43)
The time of flight t along the path can be calculated by combining \(\frac{dz}{ds}\) with the following differential equation for the time of flight (where c is the speed of light):
$$\begin{aligned} \frac{dt}{ds} = \frac{n(z)}{c} \end{aligned}$$
(C.44)
Which then gives
$$\begin{aligned} \frac{dt}{dz}= & {} \frac{dt}{ds} \frac{ds}{dz} = \frac{n(z)}{c} \frac{1}{\cos (\theta )}\nonumber \\ t= & {} \int _{z_0}^{z_1} \frac{n(z)}{c} \frac{1}{\cos (\theta )}\ dz \end{aligned}$$
(C.45)
$$\begin{aligned}= & {} \frac{1}{c} \int _{z_0}^{z_1} n(z) \sec \left( \arcsin \left( \frac{n(z_0) \sin (\theta _0)}{n(z)} \right) \right) \ dz\nonumber \\ \end{aligned}$$
(C.46)
For an exponential index-of-refraction profile of the form
$$\begin{aligned} n(z) = n_\text {ice} - \varDelta _n e^{z/z_0} \end{aligned}$$
(C.47)
we can finish the calculations. We will use a few substitutions to make our equations clearer. The substitutions are as follows, where n(z) is as above, \(z_0\) is the starting depth, and \(\theta _0\) is the launch angle:
$$\begin{aligned} \begin{aligned} \beta&= n(z_0) \sin (\theta _0) \\ \alpha&= n_\text {ice}^2 - \beta ^2 \\ \gamma&= n(z)^2 - \beta ^2 \\ \ell _1&= n_\text {ice} n(z) - \beta ^2 - \sqrt{\alpha \gamma } \\ \ell _2&= n(z) + \sqrt{\gamma } \end{aligned} \end{aligned}$$
(C.48)
Plugging in our ice model, the radial distance integral in equation C.41 becomes
$$\begin{aligned} r_1 - r_0 = \left. \frac{\beta }{\sqrt{\alpha }} \left( -z + z_0 \log \left( \ell _1\right) \right) \right| _{z_0}^{z_1} \end{aligned}$$
(C.49)
after equation C.48’s substitutions. Solving this equation for the launch angle is an alternative approach to find the ray tracing path. Unfortunately, since the launch angle appears in so many places (\(\alpha \), \(\beta \), and \(\ell _1\)), this equation is not invertible and so cannot be directly solved for \(\theta _0\). As a result, root-finding algorithms will need to be used to calculate the launch angle(s) for the ray(s) between \((r_0, z_0)\) and \((r_1, z_1)\). In the NuRadioMC code, we calculate the ray paths using the approach of Sect. Appendix C.2 and just calculate the launch angle from the parameter \(C_0\) of the analytic ray-tracing path.
Plugging in our ice model and substituting according to equation C.48, the path length (equation C.42) becomes
$$\begin{aligned} s = \left. \frac{n_\text {ice}}{\sqrt{\alpha }} \left( -z + z_0 \log (\ell _1)\right) + z_0 \log (\ell _2) \right| _{z_0}^{z_1} \end{aligned}$$
(C.50)
By the same process, the time of flight (equation C.45) becomes
$$\begin{aligned} t = \left. \frac{1}{c} \left( z_0 \left( \sqrt{\gamma } + n_\text {ice} \log (\ell _2) + \log (\ell _1) \frac{n_\text {ice}^2}{\sqrt{\alpha }}\right) - z \frac{n_\text {ice}^2}{\sqrt{\alpha }}\right) \right| _{z_0}^{z_1} \end{aligned}$$
(C.51)
Note that these integrals are specifically for a direct path. For an indirect path, the bounds must be changed to reflect the fact that the path goes up to \(z_\text {turn}\) before coming back down to \(z_1\).
Appendix C.6: Derivation of focusing correction
Here, we derive how ray density per unit area changes. The geometry in case of straight line propagation is depicted in Fig. 17. We read off that \(a = R \, \sin \varDelta \theta \). In the limit of \(\varDelta \theta<< 1\) we get \(a = R \, \varDelta \theta \). The relation between the length a and vertical displacement \(\varDelta z\) is given by \(a = \sin \theta \, \varDelta z\). Thus, we get
$$\begin{aligned} R = \frac{\varDelta z}{\varDelta \theta } \sin \theta \end{aligned}$$
(C.52)
and in the limit \(\varDelta z \Rightarrow 0\)
$$\begin{aligned} R = \frac{\mathrm {d}z}{\mathrm {d}\theta } \sin \theta \, . \end{aligned}$$
(C.53)
The area \(\mathrm {d}A\) perpendicular to a ray is given by
$$\begin{aligned} \mathrm {d}A&= R \mathrm {d}\theta \times R \sin \theta \mathrm {d}\phi \, , \end{aligned}$$
(C.54)
and will change due to ray bending to
$$\begin{aligned} \mathrm {d}A&= \frac{\mathrm {d}z}{\mathrm {d}\theta } \sin \theta \mathrm {d}\theta \times R \sin \theta \mathrm {d}\phi \, . \end{aligned}$$
(C.55)
Appendix D: FFT normalization in NuRadioMC
In NuRadioMC we use a real fast Fourier transform (rFFT) as it only deals with real valued signals in the time-domain. Furthermore, we assume that the number of samples in the time domain is even. Then, \(n_t\) bins (with real values) in the time domain correspond to \(n_f = n_t / 2 + 1\) bins (with complex values) in the frequency domain where the first bin is the zero frequency component. This is because we exploit the symmetry between negative and positive frequencies for real valued input and only compute the positive frequency components.
The rFFT is normalized such that Parseval’s theorem holds without any additional normalization factor, i.e.,
$$\begin{aligned} \sum \limits _{m=0}^{n_t-1} x_m^2 = \sum \limits _{k=0}^{n_t/2} \tilde{X}_k^2 \, . \end{aligned}$$
(D.56)
where \(x_m\) are the time domain samples of the signal, and \(\tilde{X}_k\) are the frequency domain samples. In the case of electric fields, the dimensions of both \(x_m\) and \(\tilde{X}_k\) are voltage/length.
This means that the energy fluence, i.e., the time integral over the pulse amplitudes, calculated in the frequency domain and in the time domain give the same results which is a useful physical property. Then, the rFFT and inverse rFFT is defined as
$$\begin{aligned} \tilde{X}_k = \frac{\sqrt{2}}{\sqrt{N}} \times \sum \limits _{m=0}^{n_t-1} x_m \exp \left( -2\pi i \frac{mk}{n_t}\right) \,, k = 0, \ldots , n_t/2 \end{aligned}$$
(D.57)
and
$$\begin{aligned} x_m \!= \!\frac{1}{\sqrt{2} \sqrt{N}} \times 2\sum \limits _{k=0}^{n_t/2} \tilde{X}_k \exp \left( 2\pi i \frac{mk}{n_t}\right) \,, m \!=\! 0, \ldots , n_t-1 \end{aligned}$$
(D.58)
We added an additional factor of \(\sqrt{2}\) with respect to the standard orthogonal normalization to compensate for the negative frequencies that we did not compute so that the Eq. (D.56) holds.
Appendix D.1: Relation to a continuous Fourier transform
In literature, one also finds the continuous Fourier transform with different conventions for the normalization. One typical choice is to define the Fourier transform as
$$\begin{aligned} \tilde{E}(\nu ) = \int \limits _{-\infty }^\infty dt \exp \left( i 2 \pi \nu t\right) E(t) \end{aligned}$$
(D.59)
and
$$\begin{aligned} E(t) = \int \limits _{-\infty }^\infty d\nu \exp \left( -i 2 \pi \nu t\right) \tilde{E}(\nu ) \, . \end{aligned}$$
(D.60)
If the signal in the time domain has units V/m the units in the frequency domain become V/m/Hz. A common task is to transform a frequency-domain parameterization of the Askaryan signal into the time domain via a discrete Fourier transform. For the definition of Eq. (D.59), the corresponding discrete inverse transform is
$$\begin{aligned} x_m&= \frac{1}{n_t} \times 2\sum \limits _{k=0}^{n_t/2} \tilde{X}_k / \varDelta t \exp \left( 2\pi i \frac{mk}{n_t}\right) \end{aligned}$$
(D.61)
$$\begin{aligned}&= 2\sum \limits _{k=0}^{n_t/2} \tilde{X}_k \varDelta f \exp \left( 2\pi i \frac{mk}{n_t}\right) \, \end{aligned}$$
(D.62)
where we exploit the relation \(\varDelta t = 1/(n_t \varDelta f)\) of a discrete Fourier transform. The additional factor of 2 was added because we only sum over the positive frequencies here. This factor of 2 is already part of real FFT packages such as numpy.fft and does not need to be taken into account by the user (see Sect. Appendix D.3 for details).
Appendix D.2: Adjustments to different normalizations
All publications of a frequency-domain parameterization of the Askaryan signal that is based on the ZHS model use an unusual normalization of the continuous Fourier transform where an additional factor of 2 is added to the forward transform (Eq. D.59), and correspondingly a factor of 1/2 in the backward transform (Eq. D.60) (see e.g. [47]). Therefore, Eq. (D.62) needs an additional factor of 1/2 if a ZHS parameterization is used.
Appendix D.3: Implementation details
Most parts of the code use the numpy real fft routines. The default normalization has the direct transforms unscaled and the inverse transforms are scaled by \(1/n_t\). Hence, a analytic parametrization of the amplitudes in the frequency domain \(A(\nu )\) with units V/m/Hz can be transformed into the time domain via
If \(A(\nu )\) is a parametrization from a ZHS paper, we get the correct time domain representation via
All other Fourier transforms are normalized such that Eq. (D.56) is satisfied which is achieved with numpy via:
Appendix E: Detector simulation
The code snippet in List. 4 shows a typical detector simulation. With just a few lines of code, we can calculate the antenna response, downsample the time trace to the detector sampling rate, bandpass filter the signal and simulate a high/low trigger with a 2 out of 4 antennas coincidence logic.