REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestDataSetCalibration.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 
99 
100 #include "TRestDataSetCalibration.h"
101 
102 #include "TRestDataSet.h"
103 
104 ClassImp(TRestDataSetCalibration);
105 
110 
125 TRestDataSetCalibration::TRestDataSetCalibration(const char* configFilename, std::string name)
126  : TRestMetadata(configFilename) {
128  Initialize();
129 
131 }
132 
137 
143 
150  Initialize();
152 
153  TiXmlElement* peakDefinition = GetElement("peak");
154  while (peakDefinition != nullptr) {
155  std::string energy = GetFieldValue("energy", peakDefinition);
156  if (energy.empty() || energy == "Not defined") {
157  RESTError << "< peak variable key does not contain energy!" << RESTendl;
158  exit(1);
159  } else {
160  fEnergyPeaks.push_back(StringToDouble(energy));
161  }
162 
163  peakDefinition = GetNextElement(peakDefinition);
164  }
165 
166  if (fEnergyPeaks.empty()) {
167  RESTError << "Energy peaks not provided, exiting..." << RESTendl;
168  exit(1);
169  }
170 
171  if (fOutputFileName == "") fOutputFileName = GetParameter("outputFileName", "");
172 }
173 
182  PrintMetadata();
183 
184  TRestDataSet dataSet;
185  dataSet.Import(fDataSetName);
186 
187  dataSet.PrintMetadata();
188 
189  std::unique_ptr<TH1F> spectrum;
190  std::unique_ptr<TGraph> gr;
191  std::unique_ptr<TF1> linearFit;
192 
193  if (fCalibFile.empty()) {
194  auto histo = dataSet.GetDataFrame().Histo1D(
195  {"spectrum", "spectrum", fNBins, fCalibRange.X(), fCalibRange.Y()}, fCalObservable);
196  spectrum = std::unique_ptr<TH1F>(static_cast<TH1F*>(histo->DrawClone()));
197 
198  // Get position of the maximum
199  const double max = spectrum->GetBinCenter(spectrum->GetMaximumBin());
200  // Get ratio between maximum and energy peak
201  const double ratio = max / fEnergyPeaks.front();
202 
203  RESTDebug << "Max peak position " << max << RESTendl;
204 
205  std::vector<TF1*> gauss;
206  gr = std::unique_ptr<TGraph>(new TGraph());
207  gr->SetName("grFit");
208 
209  int c = 0;
210  for (const auto& energy : fEnergyPeaks) {
211  std::string fName = "g" + std::to_string(c);
212  double pos = energy * ratio;
213  double start = pos * 0.85;
214  double end = pos * 1.15;
215  TF1* g = new TF1(fName.c_str(), "gaus", start, end);
216  RESTDebug << "Fitting gaussian " << pos << " " << start << " " << end << RESTendl;
217  spectrum->Fit(g, "R+");
218  gauss.emplace_back(g);
219  gr->SetPoint(c, g->GetParameter(1), energy);
220  fCalibPeaks.push_back(g->GetParameter(1));
221  fCalibFWHM.push_back(g->GetParameter(2) * 235. / g->GetParameter(1));
222  c++;
223  }
224 
226 
227  gr->SetPoint(c, 0, 0);
228 
229  gr->Draw("AP");
230  linearFit = std::unique_ptr<TF1>(new TF1("linearFit", "pol1"));
231  gr->Fit("linearFit", "S");
232  } else {
233  TFile* f = TFile::Open(fCalibFile.c_str());
234  if (f == nullptr) {
235  RESTError << "Cannot open calibration file " << fCalibFile << RESTendl;
236  exit(1);
237  }
238  RESTInfo << "Opening " << fCalibFile << RESTendl;
239  gr = std::unique_ptr<TGraph>(f->Get<TGraph>("grFit"));
240  linearFit = std::unique_ptr<TF1>(f->Get<TF1>("linearFit"));
241  }
242 
243  fSlope = linearFit->GetParameter(1);
244  fIntercept = linearFit->GetParameter(0);
245 
246  RESTDebug << "Slope " << fSlope << " Intercept " << fIntercept << RESTendl;
247 
248  auto df = dataSet.GetDataFrame();
249 
250  auto calibrate = [&linearFit](double val) {
251  return linearFit->GetParameter(1) * val + linearFit->GetParameter(0);
252  };
253  df = df.Define("calib_Energy", calibrate, {fCalObservable});
254 
255  dataSet.SetDataFrame(df);
256 
257  if (!fOutputFileName.empty()) {
259  dataSet.Export(fOutputFileName);
260  TFile* f = TFile::Open(fOutputFileName.c_str(), "UPDATE");
261  this->Write();
262  if (gr) gr->Write();
263  if (linearFit) linearFit->Write();
264  // if(lFit)lFit->Write();
265  // spectrumFit->Write();
266  if (spectrum) spectrum->Write();
267  f->Close();
268  }
269  }
270 }
271 
277 
278  RESTMetadata << " Energy peaks to calibrate: ";
279  for (const auto& peak : fEnergyPeaks) RESTMetadata << peak << " keV; ";
280  RESTMetadata << RESTendl;
281  RESTMetadata << " Calibrated peak position: ";
282  for (const auto& peak : fCalibPeaks) RESTMetadata << peak << " ADC; ";
283  RESTMetadata << RESTendl;
284  RESTMetadata << " Calibrated FWHM: ";
285  for (const auto& fwhm : fCalibFWHM) RESTMetadata << fwhm << " %; ";
286  RESTMetadata << RESTendl;
287  RESTMetadata << "Observable to calibrate: " << fCalObservable << RESTendl;
288  RESTMetadata << "Calibration range: (" << fCalibRange.X() << ", " << fCalibRange.Y() << ")" << RESTendl;
289  RESTMetadata << "Number of bins: " << fNBins << RESTendl;
290  RESTMetadata << "Slope: " << fSlope << " keV/ADC" << RESTendl;
291  RESTMetadata << "Intercept: " << fIntercept << " keV" << RESTendl;
292  RESTMetadata << "----" << RESTendl;
293 }
This class is meant to perform the calibration of different runs.
void Calibrate()
Performs the calibration of a given dataSet. If no calibration file is provided, it performs the gaus...
TVector2 fCalibRange
Range to be calibrated.
Double_t fIntercept
Intercept of the calibration fit.
TRestDataSetCalibration()
Default constructor.
Int_t fNBins
Number of bins used in the calibration.
std::string fCalibFile
Name of the calibration file to be used.
void Initialize() override
Function to initialize input/output event members and define the section name.
~TRestDataSetCalibration()
Default destructor.
std::string fDataSetName
Name of the dataSet inside the config file.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestDataSetCalibration.
Double_t fSlope
Slope from the calibration fit.
std::vector< double > fCalibPeaks
Vector containing calibrated peaks in ADCs.
std::vector< double > fEnergyPeaks
Vector containing expected energy peaks in keV must be sorted.
std::string fOutputFileName
Name of the output file.
std::vector< double > fCalibFWHM
Vector containing calibrated sigma in ADCs.
void InitFromConfigFile() override
Function to initialize some variables from configfile, in case that the variable is not found in the ...
std::string fCalObservable
Calibration variable to be used.
It allows to group a number of runs that satisfy given metadata conditions.
Definition: TRestDataSet.h:34
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestDataSet.
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
void Export(const std::string &filename, std::vector< std::string > excludeColumns={})
It will generate an output file with the dataset compilation. Only the selected branches and the file...
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.
virtual void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
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.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
overwriting the write() method with fStore considered
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
@ REST_Debug
+show the defined debug messages
static std::string GetFileNameExtension(const std::string &fullname)
Gets the file extension as the substring found after the latest ".".
Definition: TRestTools.cxx:823
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.