REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestExperiment.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 
41 #include "TRestExperiment.h"
42 
43 ClassImp(TRestExperiment);
44 
49 
54 
69 TRestExperiment::TRestExperiment(const char* cfgFileName, const std::string& name)
70  : TRestMetadata(cfgFileName) {
72 }
73 
79  SetSectionName(this->ClassName());
80 
81  if (!fRandom) {
82  delete fRandom;
83  fRandom = nullptr;
84  }
85 
86  fRandom = new TRandom3(fSeed);
87  fSeed = fRandom->TRandom::GetSeed();
88 }
89 
90 void TRestExperiment::GenerateMockDataSet(Bool_t useAverage) {
91  fUseAverage = useAverage;
92 
93  if (!fBackground) {
94  RESTError << "TRestExperiment::GenerateMockData. Background component was not initialized!"
95  << RESTendl;
96  return;
97  }
98 
99  if (fExposureTime <= 0) {
100  RESTError << "The experimental exposure time has not been defined" << RESTendl;
101  RESTError << "This time is required to create the mock dataset" << RESTendl;
102  }
103 
104  Double_t meanCounts = GetBackground()->GetTotalRate() * fExposureTime * units("s");
105 
106  Int_t N = fRandom->Poisson(meanCounts);
107  if (fUseAverage) N = (Int_t)meanCounts;
108  RESTInfo << "Experiment: " << GetName() << " Generating mock dataset. Counts: " << N << RESTendl;
109 
110  ROOT::RDF::RNode df = fBackground->GetMonteCarloDataFrame(N);
111 
112  fExperimentalData.SetDataFrame(df);
113  fExperimentalData.SetTotalTimeInSeconds(fExposureTime * units("s"));
114 
116 
117  fMockData = true;
118  fDataReady = true;
119 }
120 
121 void TRestExperiment::SetExperimentalDataSet(const std::string& filename) {
122  fExperimentalDataSet = SearchFile(filename);
124 
128 
129  fMockData = false;
130  fDataReady = true;
131 
132  if (!fSignal || !fBackground) {
133  RESTWarning << "TRestExperiment::SetExperimentalDataSet. Signal and background components must "
134  "be available before atempt to load experimental data"
135  << RESTendl;
136  fDataReady = false;
137  return;
138  }
139 
140  std::vector<std::string> columns = fExperimentalData.GetDataFrame().GetColumnNames();
141  for (const auto& v : fSignal->GetVariables()) {
142  if (std::find(columns.begin(), columns.end(), v) == columns.end()) {
143  RESTError << "TRestExperiment::SetExperimentalDataSetFile a component variable was not found in "
144  "the dataset!"
145  << RESTendl;
146  fDataReady = false;
147  return;
148  }
149  }
150 }
151 
157 
158  int cont = 0;
160  while (md != nullptr) {
161  if (md->InheritsFrom("TRestComponent")) {
162  TRestComponent* comp = (TRestComponent*)md;
163  if (ToLower(comp->GetNature()) == "background")
164  fBackground = comp;
165  else if (ToLower(comp->GetNature()) == "signal")
166  fSignal = comp;
167  else
168  RESTWarning << "TRestExperiment::InitFromConfigFile. Unknown component!" << RESTendl;
169  }
170  cont++;
171  md = (TRestMetadata*)this->InstantiateChildMetadata(cont);
172  }
173 
174  auto ele = GetElement("addComponent");
175  if (ele != nullptr) {
176  std::string filename = GetParameter("filename", ele, "");
177  std::string component = GetParameter("component", ele, "");
178 
179  if (filename.empty())
180  RESTWarning
181  << "TRestExperiment. There is a problem with `filename` definition inside <addComponent."
182  << RESTendl;
183  if (component.empty())
184  RESTWarning
185  << "TRestExperiment. There is a problem with `component` definition inside <addComponent."
186  << RESTendl;
187 
188  if (TRestTools::fileExists(filename) && TRestTools::isRootFile(filename)) {
189  TFile* file = TFile::Open(filename.c_str(), "READ");
190  if (file != nullptr) {
191  TRestComponent* comp = file->Get<TRestComponent>(component.c_str());
192  if (comp) {
193  if (ToLower(comp->GetNature()) == "signal")
194  fSignal = comp;
195  else if (ToLower(comp->GetNature()) == "background")
196  fBackground = comp;
197  else
198  RESTError << "TRestExperiment::InitFromConfigFile. Component : " << component
199  << ". Nature unknown!" << RESTendl;
200  } else
201  RESTError << "TRestExperiment::InitFromConfigFile. Component : " << component
202  << " not found! File : " << filename << RESTendl;
203  }
204  }
205  }
206 
207  if (fExposureTime > 0 && fExperimentalDataSet.empty()) {
208  GenerateMockDataSet(fUseAverage);
209  } else if (fExposureTime == 0 && !fExperimentalDataSet.empty()) {
211  } else {
212  RESTWarning << "The exposure time is not zero but a experimental data filename was defined!"
213  << RESTendl;
214  RESTWarning << "The exposure time will be recovered from the dataset duration. To avoid confusion is"
215  << RESTendl;
216  RESTWarning << "better that you set exposure time to zero inside the RML definition," << RESTendl;
217  RESTError
218  << " or do not define a dataset if you wish to generate mock data using the exposure time given"
219  << RESTendl;
220  }
221 
222  if (!fSignal) {
223  RESTError << "TRestExperiment : " << GetName() << RESTendl;
224  RESTError << "There was a problem initiazing the signal component!" << RESTendl;
225  return;
226  }
227 
228  if (!fBackground) {
229  RESTError << "TRestExperiment : " << GetName() << RESTendl;
230  RESTError << "There was a problem initiazing the background component!" << RESTendl;
231  return;
232  }
233 
235  if (fSignal->GetVariables() != fBackground->GetVariables()) {
236  RESTError << "TRestExperiment : " << GetName() << RESTendl;
237  RESTError << "Background and signal components got different variable names or variable ordering!"
238  << RESTendl;
239  RESTError << "This will lead to undesired results during Likelihood calculation!" << RESTendl;
240  return;
241  }
242 
243  if (fSignal->GetNbins() != fBackground->GetNbins()) {
244  RESTError << "TRestExperiment : " << GetName() << RESTendl;
245  RESTError << "Background and signal components got different binning values!" << RESTendl;
246  RESTError << "This will lead to undesired results during Likelihood calculation!" << RESTendl;
247  return;
248  }
249 
250  cont = 0;
251  std::vector<TVector2> bckRanges = fBackground->GetRanges();
252  std::vector<TVector2> sgnlRanges = fSignal->GetRanges();
253  for (const TVector2& sRange : sgnlRanges) {
254  if (sRange.X() != bckRanges[cont].X() || sRange.Y() != bckRanges[cont].Y()) {
255  RESTError << "TRestExperiment : " << GetName() << RESTendl;
256  RESTError << "Background and signal components got different range definitions!" << RESTendl;
257  RESTError << "This will lead to undesired results during Likelihood calculation!" << RESTendl;
258  return;
259  }
260  cont++;
261  }
262 
263  Initialize();
264 }
265 
271 
272  RESTMetadata << "Random seed : " << fSeed << RESTendl;
273  RESTMetadata << " " << RESTendl;
274  if (fExposureTime > 0) {
275  RESTMetadata << " - Exposure time : " << fExposureTime * units("s") << " seconds" << RESTendl;
276  RESTMetadata << " - Exposure time : " << fExposureTime * units("hr") << " hours" << RESTendl;
277  RESTMetadata << " - Exposure time : " << fExposureTime * units("day") << " days" << RESTendl;
278  }
279 
280  if (fSignal) RESTMetadata << " - Signal component : " << fSignal->GetName() << RESTendl;
281 
282  if (fBackground) RESTMetadata << " - Background component : " << fBackground->GetName() << RESTendl;
283 
284  if (fMockData) {
285  RESTMetadata << " " << RESTendl;
286  if (fMockData) {
287  RESTMetadata << "The dataset was MC-generated" << RESTendl;
288  if (fUseAverage)
289  RESTMetadata
290  << " - The number of counts in dataset was generated with the mean background counts"
291  << RESTendl;
292 
293  } else {
294  RESTMetadata << "The dataset was loaded from an existing dataset file" << RESTendl;
295  if (!fExperimentalDataSet.empty())
296  RESTMetadata << " - Experimental dataset file : " << fExperimentalDataSet << RESTendl;
297  }
298  }
299 
300  RESTMetadata << " - Experimental counts : " << fExperimentalCounts << RESTendl;
301 
302  RESTMetadata << "----" << RESTendl;
303 }
It defines a background/signal model distribution in a given parameter space (tipically x,...
Double_t GetTotalRate()
This method integrates the rate to all the parameter space defined in the density function....
void Import(const std::string &fileName)
This function imports metadata from a root file it import metadata info from the previous dataSet whi...
ROOT::RDF::RNode GetDataFrame() const
Gives access to the RDataFrame.
Definition: TRestDataSet.h:129
Double_t GetTotalTimeInSeconds() const
It returns the accumulated run time in seconds.
Definition: TRestDataSet.h:166
It includes a model definition and experimental data used to obtain a final experimental sensitivity.
UInt_t fSeed
Seed used in random generator.
Int_t fExperimentalCounts
It keeps track on the number of counts inside the dataset.
TRestComponent * fBackground
A pointer to the background component.
Bool_t fDataReady
Only if it is true we will be able to calculate the LogLikelihood.
TRestComponent * fSignal
A pointer to the signal component.
void InitFromConfigFile() override
It customizes the retrieval of XML data values of this class.
void Initialize() override
It will initialize the data frame with the filelist and column names (or observables) that have been ...
~TRestExperiment()
Default destructor.
TRestExperiment()
Default constructor.
TRestDataSet fExperimentalData
It contains the experimental data (should contain same columns as the components)
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
TRandom3 * fRandom
Internal process random generator.
Bool_t fUseAverage
The mock dataset will be generated using the mean counts instead of a real MonteCarlo.
void SetExperimentalDataSet(const std::string &filename)
std::string fExperimentalDataSet
It defines the filename used to load the dataset.
Double_t fExposureTime
The exposure time. If 0 it will be extracted from the tracking dataset (In us, standard REST unit)
Bool_t fMockData
If enabled it means that the experimental data was MC-generated.
A base class for any REST metadata class.
Definition: TRestMetadata.h:74
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.
TRestMetadata * InstantiateChildMetadata(int index, std::string pattern="")
This method will retrieve a new TRestMetadata instance of a child element of the present TRestMetadat...
virtual void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string SearchFile(std::string filename)
Search files in current directory and directories specified in "searchPath" section.
std::string fConfigFileName
Full name of the rml file.
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.
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:733
std::string ToLower(std::string in)
Convert string to its lower case. Alternative of TString::ToLower.