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
105
110
125TRestDataSetCalibration::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
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:127
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:70
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.