REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestAxionHelioscopeSignal.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 https://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 https://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
77#include "TRestAxionHelioscopeSignal.h"
78
79#include <numeric>
80
81#include "TKey.h"
82
84
89
104TRestAxionHelioscopeSignal::TRestAxionHelioscopeSignal(const char* cfgFileName, const std::string& name)
105 : TRestComponent(cfgFileName) {
106 Initialize();
107
109
111}
112
117 if (fField) delete fField;
118}
119
126
127 SetSectionName(this->ClassName());
128 SetLibraryVersion(LIBRARY_VERSION);
129
130 if (fField == nullptr) fField = new TRestAxionField();
131}
132
141Double_t TRestAxionHelioscopeSignal::GetSignalRate(std::vector<Double_t> point, Double_t mass) {
142 if (GetDimensions() != point.size()) {
143 RESTError << "Point should have same dimensions as number of variables!" << RESTendl;
144 return 0;
145 }
146
147 if (GetDimensions() != 1) {
148 RESTError << "Point should have only 1-dimension! Energy" << RESTendl;
149 return 0;
150 }
151
152 Double_t flux = fFlux->GetFluxAtEnergy(point[0], mass); // cm-2 s-1 keV-1
153
154 Double_t probability = 0;
155 if (fConversionType == "IAXO") {
156 probability =
158
159 // We assume all flux ends up inside the spot. No XY dependency of signal.
160 Double_t apertureArea = TMath::Pi() * fMagnetRadius * units("cm") * fMagnetRadius * units("cm");
161
162 flux *= fBores * apertureArea;
163 }
164
165 Double_t signal = flux * probability;
166
167 Double_t normFactor = 1;
169 for (size_t n = 0; n < GetDimensions(); n++) {
170 normFactor *= (fRanges[n].Y() - fRanges[n].X()) / fNbins[n];
171 }
172
173 return normFactor * signal; // s-1
174}
175
181Double_t TRestAxionHelioscopeSignal::GetSignalRate(Double_t mass, Double_t Eo, Double_t Ef) {
182 Double_t dE = 0.5;
183
184 Double_t signal = 0;
185 for (Double_t en = Eo; en < Ef; en += dE) {
186 Double_t flux = fFlux->GetFluxAtEnergy(en, mass); // cm-2 s-1 keV-1
187
189 Double_t probability = 0;
190 if (fConversionType == "IAXO") {
191 probability =
193
194 // We assume all flux ends up inside the spot. No XY dependency of signal.
195 Double_t apertureArea = TMath::Pi() * fMagnetRadius * units("cm") * fMagnetRadius * units("cm");
196 flux *= fBores * apertureArea;
197 }
198 signal += flux * probability;
199 }
200
201 return signal * dE; // s-1
202}
203
213 if (!HasNodes()) return;
214 fNodeDensity.clear();
215
216 RESTInfo << "Generating N-dim histogram for " << GetName() << RESTendl;
217
218 int nIndex = 0;
219 for (const auto& node : fParameterizationNodes) {
220 TString hName = fParameter + "_" + DoubleToString(node);
221
222 Int_t* bins = new Int_t[fNbins.size()];
223 Double_t* xlow = new Double_t[fNbins.size()];
224 Double_t* xhigh = new Double_t[fNbins.size()];
225
226 for (size_t n = 0; n < fNbins.size(); n++) {
227 bins[n] = fNbins[n];
228 xlow[n] = fRanges[n].X();
229 xhigh[n] = fRanges[n].Y();
230 }
231
232 THnD* hNd = new THnD(hName, hName, fNbins.size(), bins, xlow, xhigh);
233
234 // Calculate the bin width in each dimension
235 std::vector<double> binWidths;
236 for (size_t i = 0; i < fNbins.size(); ++i) {
237 double width = static_cast<double>(xhigh[i] - xlow[i]) / bins[i];
238 binWidths.push_back(width);
239 }
240
241 // Nested loop to iterate over each bin and print its center
242 std::vector<int> binIndices(fNbins.size(), 0); // Initialize bin indices to 0 in each dimension
243
244 bool carry = false;
245 while (!carry) {
246 // Calculate the center of the current bin in each dimension
247 std::vector<double> binCenter;
248 for (size_t i = 0; i < fNbins.size(); ++i)
249 binCenter.push_back(xlow[i] + (binIndices[i] + 0.5) * binWidths[i]);
250
251 hNd->Fill(binCenter.data(), GetSignalRate(binCenter, node));
252
253 // Update bin indices for the next iteration
254 carry = true;
255 for (size_t i = 0; i < fNbins.size(); ++i) {
256 binIndices[i]++;
257 if (binIndices[i] < bins[i]) {
258 carry = false;
259 break;
260 }
261 binIndices[i] = 0;
262 }
263 }
264
265 fNodeDensity.push_back(hNd);
266 fActiveNode = nIndex;
267 nIndex++;
268 }
269}
270
276
277 RESTMetadata << "Magnet bores : " << fBores << RESTendl;
278 RESTMetadata << "Magnet radius : " << fMagnetRadius * units("cm") << " cm" << RESTendl;
279 RESTMetadata << "Magnet length : " << fMagnetLength * units("m") << " m" << RESTendl;
280 RESTMetadata << "Magnet field : " << fMagnetStrength * units("T") << " T" << RESTendl;
281 RESTMetadata << " " << RESTendl;
282
283 RESTMetadata << "Optics efficiency : " << fOpticsEfficiency << RESTendl;
284 RESTMetadata << "Window efficiency : " << fWindowEfficiency << RESTendl;
285
286 RESTMetadata << "----" << RESTendl;
287}
288
294
295 if (fVariables.size() != 1) {
296 RESTError << "TRestAxionHelioscopeSignal::InitFromConfigFile."
297 << " Signal should be build with just 1-variable. Energy." << RESTendl;
298 } else if (fVariables[0] != "energy") {
299 RESTError << "The first variable should be energy. We recommend to name that variable as \"energy\"."
300 << RESTendl;
301 RESTError << "Please, double-check the variables definition inside "
302 "TRestAxionHelioscopeSignal::TRestComponent."
303 << RESTendl;
304 }
305
306 if (fFlux) {
307 delete fFlux;
308 fFlux = nullptr;
309 }
310 fFlux = (TRestAxionSolarFlux*)this->InstantiateChildMetadata("TRestAxionSolarQCDFlux");
311 fFlux->Initialize();
312
313 if (fGas) {
314 delete fGas;
315 fGas = nullptr;
316 }
317 fGas = (TRestAxionBufferGas*)this->InstantiateChildMetadata("TRestAxionBufferGas");
318
319 if (fField == nullptr) fField = new TRestAxionField();
320
321 fField->SetMagneticField(GetMagnetStrength());
322 fField->SetCoherenceLength(GetMagnetLength());
324
326}
A metadata class to define the gas properties used in axion search calculations.
A basic class to define analytical axion-photon conversion calculations for axion helioscopes.
void AssignBufferGas(TRestAxionBufferGas *buffGas)
It assigns a gas buffer medium to the calculation.
Double_t GammaTransmissionProbability(Double_t Ea, Double_t ma, Double_t mg=0, Double_t absLength=0)
Performs the calculation of axion-photon conversion probability using directly equation (11) from van...
It allows to build a signal model using a given helioscope configuration and solar axion flux compone...
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
Double_t fOpticsEfficiency
If optics is present we may add an efficiency for Ngamma calculation.
Double_t fMagnetLength
It defines the magnet length in standard REST units (mm)
Double_t fMagnetRadius
It defines the magnet aperture radius in standard REST units (mm)
void Initialize() override
It will initialize the data frame with the filelist and column names (or observables) that have been ...
Int_t fBores
It defines the number of bores or TPCs (number of magnetic volumes)
TRestAxionField * fField
It provides access to axion-photon conversion probabilites calculations.
void InitFromConfigFile() override
It customizes the retrieval of XML data values of this class.
Double_t fWindowEfficiency
If an x-ray window is present we may add an efficiency for Ngamma calculation.
TRestAxionHelioscopeSignal()
Default constructor.
TRestAxionSolarFlux * fFlux
It defines the solar flux we use inside our magnetic field. Must be defined.
void FillHistograms() override
It will produce a histogram with the distribution using the formula contributions.
Double_t GetSignalRate(std::vector< Double_t > point, Double_t mass=0)
It returns the intensity/rate (in seconds) corresponding to the class defined helioscope configuratio...
std::string fConversionType
It defines the helioscope type (IAXO/AMELIE)
~TRestAxionHelioscopeSignal()
Default destructor.
Double_t fMagnetStrength
It defines the magnetic field strength in T.
TRestAxionBufferGas * fGas
It defines the gas mixture we use inside our magnetic field. Vacuum if it is nullptr.
A metadata class to load tabulated solar axion fluxes.
void Initialize()
It is required in order to load solar flux tables into memory.
Double_t GetFluxAtEnergy(Double_t energy, Double_t m=0)
It returns a flux in cm-2 s-1 keV-1 at the energy given by argument.
It defines a background/signal model distribution in a given parameter space (tipically x,...
void InitFromConfigFile() override
It customizes the retrieval of XML data values of this class.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
Int_t fActiveNode
It is used to define the node that will be accessed for rate retrieval.
std::string fParameter
It is used to parameterize a set of distribution densities (e.g. WIMP or axion mass)
std::vector< Int_t > fNbins
The number of bins in which we should divide each variable.
void Initialize() override
It initializes the random number. We avoid to define the section name here since we will never define...
std::vector< TVector2 > fRanges
The range of each of the variables used to create the PDF distribution.
std::vector< Double_t > fParameterizationNodes
It defines the nodes of the parameterization (Initialized by the dataset)
Bool_t HasNodes()
It returns true if any nodes have been defined.
std::vector< std::string > fVariables
A list with the branches that will be used to create the distribution space.
std::vector< THnD * > fNodeDensity
The generated N-dimensional variable space density for a given node.
endl_t RESTendl
Termination flag object for TRestStringOutput.
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.
TRestMetadata * InstantiateChildMetadata(int index, std::string pattern="")
This method will retrieve a new TRestMetadata instance of a child element of the present TRestMetadat...
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string fConfigFileName
Full name of the rml file.
@ REST_Info
+show most of the information for each steps
std::string DoubleToString(Double_t d, std::string format="%8.6e")
Gets a string from a double.