REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
Loading...
Searching...
No Matches
TRestWimpUtils.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
44
45#include <TMath.h>
46#include <TRestWimpUtils.h>
47
53const double TRestWimpUtils::GetRelativeNuclearCS(const double wimpMass, const double Anum) {
54 const double reducedMass = GetReducedMass(wimpMass, Anum);
55 const double reducedMassSingle = GetReducedMass(wimpMass, 1.);
56 return pow(Anum * GEV_PER_UMA * reducedMass / reducedMassSingle, 2.);
57}
58
63const double TRestWimpUtils::GetReducedMass(const double wimpMass, const double Anum) {
64 // WIMP mass in GeV
65 return wimpMass * GEV_PER_UMA * Anum / (wimpMass + Anum * GEV_PER_UMA);
66}
67
73const double TRestWimpUtils::GetHelmFormFactor(const double recoilEnergy, const double Anum) {
74 // Momentum transfer in keV
75 const double q = sqrt(2. * Anum * GEV_PER_UMA * 1E6 * recoilEnergy);
76 const double s = 0.9; // Femtometers-Skin thickness of the nucleus
77 const double qs = q * s / HC_KEV_FM;
78 // Parametrization of atomic nuclei
79 const double RN = sqrt(pow(1.23 * std::cbrt(Anum) - 0.60, 2) +
80 (7. / 3.) * pow(TMath::Pi(), 2) * 0.52 * 0.52 - 5. * s * s);
81 const double qR = q * RN / HC_KEV_FM;
82 // First Bessel function
83 const double bessel1 = sin(qR) / (qR * qR) - cos(qR) / qR;
84 // Form factor
85 double formFactor = 3. * bessel1 / qR * exp(-0.5 * qs * qs);
86
87 return formFactor;
88}
89
95const double TRestWimpUtils::GetVMin(const double wimpMass, const double Anum, const double recoilEnergy) {
96 const double reducedMass = GetReducedMass(wimpMass, Anum);
97 return sqrt(Anum * GEV_PER_UMA * recoilEnergy * 1E-6 / (2. * reducedMass * reducedMass)) * LIGHT_SPEED;
98}
99
104const double TRestWimpUtils::GetVelocityDistribution(const double v, const double vLab, const double vRMS,
105 const double vEscape) {
106 const double vAdim = vRMS / vLab;
107 const double Nesc = erf(vAdim) - (2. / sqrt(TMath::Pi())) * (vAdim)*exp(-vAdim * vAdim);
108 const double xMax = std::min(1., (vEscape * vEscape - vLab * vLab - v * v) / (2. * vLab * v));
109 return v * Nesc / (vLab * vRMS * sqrt(TMath::Pi())) *
110 (exp(-(v - vLab) * (v - vLab) / (vRMS * vRMS)) -
111 exp(-(v * v + vLab * vLab + 2 * v * vLab * xMax) / (vRMS * vRMS)));
112}
113
121const double TRestWimpUtils::GetDifferentialCrossSection(const double wimpMass, const double crossSection,
122 const double velocity, const double recoilEnergy,
123 const double Anum) {
124 const double cs = GetRelativeNuclearCS(wimpMass, Anum) * crossSection;
125 const double reducedMass = GetReducedMass(wimpMass, Anum);
126 const double Emax = 1E6 / LIGHT_SPEED / LIGHT_SPEED * 2. * reducedMass * reducedMass * velocity *
127 velocity / (Anum * GEV_PER_UMA);
128 const double formFactor = GetHelmFormFactor(recoilEnergy, Anum);
129
130 return cs * formFactor * formFactor / Emax;
131}
132
138const double TRestWimpUtils::GetRecoilRate(const double wimpMass, const double crossSection,
139 const double recoilEnergy, const double Anum, const double vLab,
140 const double vRMS, const double vEscape, const double wimpDensity,
141 const double abundance) {
142 const double vMin = GetVMin(wimpMass, Anum, recoilEnergy);
143 const double vMax = vEscape + vLab;
144 const double nNuclei = abundance * N_AVOGADRO * 1E3 / Anum; // Number of atoms
145
146 if (vMin > vMax) return 0;
147
148 double rate = 0;
149 const double velStep = 0.1; // km/s
150
151 for (double v = vMin; v < vMax; v += velStep) {
152 const double flux = 1E5 * v * wimpDensity / wimpMass;
153 const double diffRate = flux *
154 GetDifferentialCrossSection(wimpMass, crossSection, v, recoilEnergy, Anum) *
155 GetVelocityDistribution(v, vLab, vRMS, vEscape);
156 rate += diffRate * velStep;
157 }
158
159 return rate * SECONDS_PER_DAY * nNuclei;
160}
161
166const double TRestWimpUtils::GetQuenchingFactor(const double recoilEnergy, const double Anum,
167 const double Znum) {
168 const double deltaE = 0.0001, Emin = 0.1, resolution = 0.1; // keV
169 double g, Er = recoilEnergy, Ev;
170
171 do {
172 Er -= resolution;
173 g = 0.66 * pow(Znum, 5. / 18.) / sqrt(Anum) * pow(recoilEnergy, 1. / 6.);
174 } while ((Er / (1 + g) * g) > Emin);
175
176 do {
177 Er += deltaE;
178 g = 0.66 * pow(Znum, 5. / 18.) / sqrt(Anum) * pow(Er, 1. / 6.);
179 Ev = (Er / (1 + g) * g);
180 } while (recoilEnergy > Ev);
181
182 return (1 + g) / g;
183}
constexpr double GEV_PER_UMA
Physics constants.
const double GetRelativeNuclearCS(const double wimpMass, const double Anum)
Generic functions for different calculations.