REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestComponentFormula.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 
55 #include "TRestComponentFormula.h"
56 
57 #include <numeric>
58 
59 #include "TKey.h"
60 
61 ClassImp(TRestComponentFormula);
62 
67 
82 TRestComponentFormula::TRestComponentFormula(const char* cfgFileName, const std::string& name)
83  : TRestComponent(cfgFileName) {
84  Initialize();
85 
87 
89 }
90 
95 
102 
103  SetSectionName(this->ClassName());
104 
105  FillHistograms();
106 }
107 
116 Double_t TRestComponentFormula::GetFormulaRate(std::vector<Double_t> point) {
117  if (fVariables.size() != point.size()) {
118  RESTError << "Point should have same dimensions as number of variables!" << RESTendl;
119  return 0;
120  }
121 
122  Double_t result = 0;
123  for (auto& formula : fFormulas) {
124  for (size_t n = 0; n < fVariables.size(); n++) formula.SetParameter(fVariables[n].c_str(), point[n]);
125 
126  result += formula.EvalPar(nullptr);
127  }
128 
129  Double_t normFactor = 1;
130  for (size_t n = 0; n < GetDimensions(); n++) {
131  normFactor *= (fRanges[n].Y() - fRanges[n].X()) / fNbins[n];
132  }
133 
134  return normFactor * result / units(fFormulaUnits);
135 }
136 
150  if (fFormulas.empty()) return;
151 
152  if (GetDimensions() == 0) {
153  RESTError << "TRestComponentFormula::FillHistograms. No variables defined!" << RESTendl;
154  RESTError << "Did you add a <cVariable entry?" << RESTendl;
155  return;
156  }
157 
158  RESTInfo << "Generating N-dim histogram for " << GetName() << RESTendl;
159 
160  TString hName = "formula";
161 
162  Int_t* bins = new Int_t[fNbins.size()];
163  Double_t* xlow = new Double_t[fNbins.size()];
164  Double_t* xhigh = new Double_t[fNbins.size()];
165 
166  for (size_t n = 0; n < fNbins.size(); n++) {
167  bins[n] = fNbins[n];
168  xlow[n] = fRanges[n].X();
169  xhigh[n] = fRanges[n].Y();
170  }
171 
172  THnD* hNd = new THnD(hName, hName, fNbins.size(), bins, xlow, xhigh);
173 
174  // Calculate the bin width in each dimension
175  std::vector<double> binWidths;
176  for (size_t i = 0; i < fNbins.size(); ++i) {
177  double width = static_cast<double>(xhigh[i] - xlow[i]) / bins[i];
178  binWidths.push_back(width);
179  }
180 
181  // Nested loop to iterate over each bin and print its center
182  std::vector<int> binIndices(fNbins.size(), 0); // Initialize bin indices to 0 in each dimension
183 
184  bool carry = false;
185  while (!carry) {
186  // Calculate the center of the current bin in each dimension
187  std::vector<double> binCenter;
188  for (size_t i = 0; i < fNbins.size(); ++i)
189  binCenter.push_back(xlow[i] + (binIndices[i] + 0.5) * binWidths[i]);
190 
191  hNd->Fill(binCenter.data(), GetFormulaRate(binCenter));
192 
193  // Update bin indices for the next iteration
194  carry = true;
195  for (size_t i = 0; i < fNbins.size(); ++i) {
196  binIndices[i]++;
197  if (binIndices[i] < bins[i]) {
198  carry = false;
199  break;
200  }
201  binIndices[i] = 0;
202  }
203  }
204 
205  fNodeDensity.clear();
206  fNodeDensity.push_back(hNd);
207  fActiveNode = 0; // For the moment only 1-node!
208 }
209 
215 
216  RESTMetadata << " " << RESTendl;
217  RESTMetadata << "Formula units: " << fFormulaUnits << RESTendl;
218 
219  if (!fFormulas.empty()) {
220  RESTMetadata << " " << RESTendl;
221  RESTMetadata << " == Contributions implemented inside the component ==" << RESTendl;
222 
223  for (const auto& x : fFormulas)
224  RESTMetadata << "- " << x.GetName() << " = " << x.GetExpFormula() << RESTendl;
225 
226  RESTMetadata << " " << RESTendl;
227  }
228 
229  RESTMetadata << "----" << RESTendl;
230 }
231 
237 
238  if (!fFormulas.empty()) return;
239 
241  fFormulaUnits = GetParameter("formulaUnits");
242 
243  auto ele = GetElement("formula");
244  while (ele != nullptr) {
245  std::string name = GetParameter("name", ele, "");
246  std::string expression = GetParameter("expression", ele, "");
247 
248  if (expression.empty()) {
249  RESTWarning << "TRestComponentFormula::InitFromConfigFile. Invalid formula" << RESTendl;
250  } else {
251  TFormula formula(name.c_str(), expression.c_str());
252 
253  for (Int_t n = 0; n < formula.GetNpar(); n++) {
254  if (std::find(fVariables.begin(), fVariables.end(), formula.GetParName(n)) ==
255  fVariables.end()) {
256  RESTError << "Variable : " << formula.GetParName(n) << " not found in component! "
257  << RESTendl;
258  RESTError << "TRestComponentFormula evaluation will lead to wrong results!" << RESTendl;
259  }
260  }
261 
262  for (const auto& varName : fVariables) formula.SetParameter(varName.c_str(), 0.0);
263 
264  fFormulas.push_back(formula);
265  }
266 
267  ele = GetNextElement(ele);
268  }
269 }
It defines an analytical component model distribution in a given parameter space (tipically x,...
std::string fFormulaUnits
The formulas should be expressed in the following units.
std::vector< TFormula > fFormulas
A vector of formulas that will be added up to integrate a given rate.
~TRestComponentFormula()
Default destructor.
void Initialize() override
It will initialize the data frame with the filelist and column names (or observables) that have been ...
void InitFromConfigFile() override
It customizes the retrieval of XML data values of this class.
void FillHistograms() override
It will produce a histogram with the distribution using the formula contributions.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
Double_t GetFormulaRate(std::vector< Double_t > point)
It returns the intensity/rate (in seconds) corresponding to the formula evaluated at the position of ...
TRestComponentFormula()
Default constructor.
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::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< 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.
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.
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.
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
@ REST_Info
+show most of the information for each steps