REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
Loading...
Searching...
No Matches
src/TRestWimpSensitivity.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
113
114#include "TRestWimpSensitivity.h"
115#include "TRestWimpUtils.h"
116
117ClassImp(TRestWimpSensitivity);
118
119using namespace std;
120
128TRestWimpSensitivity::TRestWimpSensitivity(const char* configFilename, const string& name)
129 : TRestMetadata(configFilename) {
130 Initialize();
131
133}
138
143 SetSectionName(this->ClassName());
144 SetLibraryVersion(LIBRARY_VERSION);
145}
146
156
162 fNuclei.clear();
163
164 TiXmlElement* ElementDef = GetElement("addElement");
165 while (ElementDef) {
166 TRestWimpNucleus nucleus;
167 nucleus.fNucleusName = GetFieldValue("nucleusName", ElementDef);
168 nucleus.fAnum = StringToDouble(GetFieldValue("anum", ElementDef));
169 nucleus.fZnum = StringToInteger(GetFieldValue("znum", ElementDef));
170 nucleus.fAbundance = StringToDouble(GetFieldValue("abundance", ElementDef));
171 fNuclei.emplace_back(nucleus);
172 ElementDef = GetNextElement(ElementDef);
173 }
174}
175
180std::map<std::string, TH1D*> TRestWimpSensitivity::GetRecoilSpectra(const double wimpMass,
181 const double crossSection) {
182 std::map<std::string, TH1D*> recoilMap;
183
184 const int nBins = (fEnergySpectra.Y() - fEnergySpectra.X()) / fEnergySpectraStep;
185
186 for (auto& nucl : fNuclei) {
187 std::string histName = "RecoilSpc_" + std::string(nucl.fNucleusName);
188 TH1D* recoilSpc =
189 new TH1D(histName.c_str(), histName.c_str(), nBins, fEnergySpectra.X(), fEnergySpectra.Y());
190 for (int i = 1; i < recoilSpc->GetNbinsX(); i++) {
191 const double recoilEnergy = recoilSpc->GetBinCenter(i);
192 const double recoilRate =
193 TRestWimpUtils::GetRecoilRate(wimpMass, crossSection, recoilEnergy, nucl.fAnum, fLabVelocity,
194 fRmsVelocity, fEscapeVelocity, fWimpDensity, nucl.fAbundance);
195 recoilSpc->SetBinContent(i, recoilRate);
196 }
197 recoilMap[std::string(nucl.fNucleusName)] = recoilSpc;
198 }
199
200 return recoilMap;
201}
202
206const Double_t TRestWimpSensitivity::GetSensitivity(const double wimpMass) {
207 if (fNuclei.empty()) {
208 RESTError << "Please add at least one element to the rml file" << RESTendl;
209 }
210
212
213 const int nBins = (fEnergySpectra.Y() - fEnergySpectra.X()) / fEnergySpectraStep;
214
215 TH1D recoilSpc("recoilSpc", "recoilSpc", nBins, fEnergySpectra.X(), fEnergySpectra.Y());
216
217 double bckCounts = 0;
218
219 for (int i = 1; i < recoilSpc.GetNbinsX(); i++) {
220 const double en = recoilSpc.GetBinCenter(i);
221 if (en < fEnergyRange.X() || en > fEnergyRange.Y()) continue;
222 bckCounts += fBackground * fEnergySpectraStep;
223 }
224 bckCounts *= fExposure;
225
226 double signalCounts = 0, prob = 0;
227
228 do {
229 prob = 0;
230 for (int mu = signalCounts; mu < (signalCounts + bckCounts + 10000); mu++) {
231 if (bckCounts <= 1.e3)
232 prob += TMath::Poisson(mu + bckCounts, bckCounts);
233 else if (bckCounts > 1.e3)
234 prob += TMath::Gaus(mu + bckCounts, bckCounts, TMath::Sqrt(bckCounts), true);
235 }
236 signalCounts++;
237 } while (fabs(prob - 0.1) > 0.01 && signalCounts < 1E6);
238
239 double nMeas = 0;
240 const double crossSection = 1E-45;
241
242 for (auto& nucl : fNuclei) {
243 recoilSpc.Reset();
244
245 for (int i = 1; i < recoilSpc.GetNbinsX(); i++) {
246 const double recoilEnergy = recoilSpc.GetBinCenter(i);
247 const double recoilRate =
248 TRestWimpUtils::GetRecoilRate(wimpMass, crossSection, recoilEnergy, nucl.fAnum, fLabVelocity,
249 fRmsVelocity, fEscapeVelocity, fWimpDensity, nucl.fAbundance);
250 recoilSpc.SetBinContent(i, recoilRate);
251 }
252
253 for (int i = 1; i < recoilSpc.GetNbinsX(); i++) {
254 double recoilEnergy = recoilSpc.GetBinCenter(i);
255 // const double recoilRate = recoilSpc.GetBinContent(i);
257 recoilEnergy *= quenchingFactor[std::string(nucl.fNucleusName)]->GetBinContent(i);
258
259 if (recoilEnergy < fEnergyRange.X() || recoilEnergy > fEnergyRange.Y()) continue;
260 nMeas += recoilSpc.GetBinContent(i) * fEnergySpectraStep;
261 }
262 }
263
264 if (nMeas == 0) return 0;
265
266 const double sensitivity = signalCounts * 1E-45 / (nMeas * fExposure);
267
268 return sensitivity;
269}
270
276 if (!quenchingFactor.empty()) return;
277
278 std::cout << "Calculating quenching factor " << std::endl;
279
280 const int nBins = (fEnergySpectra.Y() - fEnergySpectra.X()) / fEnergySpectraStep;
281
282 for (auto& nucl : fNuclei) {
283 std::string histName = "QF_" + std::string(nucl.fNucleusName);
284 TH1D* QF =
285 new TH1D(histName.c_str(), histName.c_str(), nBins, fEnergySpectra.X(), fEnergySpectra.Y());
286 for (int i = 1; i < QF->GetNbinsX(); i++) {
287 const double recoilEnergy = QF->GetBinCenter(i);
288 const double qF = TRestWimpUtils::GetQuenchingFactor(recoilEnergy, nucl.fAnum, nucl.fZnum);
289 if (!isnan(qF) && qF > 0)
290 QF->SetBinContent(i, 1. / qF);
291 else
292 QF->SetBinContent(i, 0);
293 }
294 quenchingFactor[std::string(nucl.fNucleusName)] = QF;
295 }
296}
297
302const std::string TRestWimpSensitivity::BuildOutputFileName(const std::string& extension) {
303 std::stringstream ss;
304 ss << "WimpSensitivity_";
305
306 for (auto& nucl : fNuclei) ss << nucl.fNucleusName << "_" << nucl.fAbundance << "_";
307
308 ss << "WD_" << fWimpDensity << "_";
309 ss << "Vel_" << fLabVelocity << "_" << fRmsVelocity << "_" << fEscapeVelocity << "_";
310 ss << "Bck_" << fBackground << "_";
311 ss << "RecEn_" << fEnergySpectra.X() << "_" << fEnergySpectra.Y() << "_" << fEnergySpectraStep << "_";
312 ss << "EnRange_" << fEnergyRange.X() << "_" << fEnergyRange.Y() << "_";
313
315 ss << "usingQF";
316 else
317 ss << "noQF";
318
319 ss << extension;
320
321 std::cout << "Output File " << ss.str() << std::endl;
322
323 return ss.str();
324}
325
330std::map<std::string, TH1D*> TRestWimpSensitivity::GetFormFactor() {
331 std::map<std::string, TH1D*> formFactor;
332
333 const int nBins = (fEnergySpectra.Y() - fEnergySpectra.X()) / fEnergySpectraStep;
334
335 for (auto& nucl : fNuclei) {
336 std::string histName = "FF_" + std::string(nucl.fNucleusName);
337 TH1D* FF =
338 new TH1D(histName.c_str(), histName.c_str(), nBins, fEnergySpectra.X(), fEnergySpectra.Y());
339 for (int i = 1; i < FF->GetNbinsX(); i++) {
340 const double recoilEnergy = FF->GetBinCenter(i);
341 const double helmFF = TRestWimpUtils::GetHelmFormFactor(recoilEnergy, nucl.fAnum);
342 FF->SetBinContent(i, helmFF * helmFF);
343 }
344 formFactor[std::string(nucl.fNucleusName)] = FF;
345 }
346
347 return formFactor;
348}
349
356
357 for (auto& nucl : fNuclei) nucl.PrintNucleus();
358
359 RESTMetadata << "WimpDensity: " << fWimpDensity << " GeV/cm3" << RESTendl;
360 RESTMetadata << "WimpVelocity; VLab: " << fLabVelocity << " VRMS: " << fRmsVelocity
361 << " VEscape: " << fEscapeVelocity << " km/s" << RESTendl;
362 RESTMetadata << "Exposure: " << fExposure << " kg*day" << RESTendl;
363 RESTMetadata << "Background Level: " << fBackground << " c/keV/day" << RESTendl;
364 RESTMetadata << "Recoil energy range: (" << fEnergySpectra.X() << ", " << fEnergySpectra.Y()
365 << ") Step: " << fEnergySpectraStep << " keV" << RESTendl;
366 RESTMetadata << "Sensitivity energy range: (" << fEnergyRange.X() << ", " << fEnergyRange.Y() << ") keV"
367 << RESTendl;
368 RESTMetadata << "Use quenching factor: " << fUseQuenchingFactor << RESTendl;
369 RESTMetadata << "+++++" << RESTendl;
370}
A base class for any REST metadata class.
virtual void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
virtual void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
std::string GetFieldValue(std::string parName, TiXmlElement *e)
Returns the field value of an xml element which has the specified name.
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string fConfigFileName
Full name of the rml file.
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
A class to store different nucleus parameters.
Double_t fAnum
Atomic number in amus.
TString fNucleusName
Nucleus name.
Double_t fAbundance
Abundance, in mass percentage.
Int_t fZnum
Number of protons.
void Initialize() override
Initialization of TRestWimpSensitivity members.
Double_t fExposure
Detector exposure in kg*day.
~TRestWimpSensitivity()
Default destructor.
void InitFromConfigFile() override
Initialization of TRestWimpSensitivity members through a RML file.
std::map< std::string, TH1D * > GetRecoilSpectra(const double wimpMass, const double crossSection)
Get recoil spectra for a given WIMP mass and cross section.
Double_t fEscapeVelocity
WIMP escape velocity (km/s)
TVector2 fEnergySpectra
Energy range for the recoil spectra in keV.
Double_t fEnergySpectraStep
Energy step for the recoil spectra in keV.
void PrintMetadata() override
Prints on screen the details about WIMP parameters, stored in TRestWimpSensitivity.
const Double_t GetSensitivity(const double wimpMass)
Get sensitivity for a give WIMP mass.
TVector2 fEnergyRange
Energy range for the sensitivity prospects in keV.
Double_t fBackground
Detector background level in c/keV/day.
std::map< std::string, TH1D * > quenchingFactor
Map containing quenching factor for a nucleus.
void CalculateQuenchingFactor()
Calculate Quenching factor and stores in a map.
Bool_t fUseQuenchingFactor
Use or not quenching factor.
Double_t fRmsVelocity
WIMP RMS velocity (km/s)
Double_t fWimpDensity
WIMP density in GeV/cm3.
Double_t fLabVelocity
WIMP velocity in the lab (Earth) frame reference in km/s.
void ReadNuclei()
Initialization of TRestWimpSensitivity members through a RML file.
TRestWimpSensitivity(const char *configFilename, const std::string &name="")
Constructor loading data from a config file.
std::map< std::string, TH1D * > GetFormFactor()
Return a map of histograms with the Form Factor of the different elements.
const std::string BuildOutputFileName(const std::string &extension=".txt")
Return output file format with different parameters used in the calculation.
std::vector< TRestWimpNucleus > fNuclei
A vector containing TRestWimpNucleus with different nucleus parameters.
Double_t StringToDouble(std::string in)
Gets a double from a string.
Int_t StringToInteger(std::string in)
Gets an integer from a string.