Belle II Software development
CDCDedxHadBGAlgorithm.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <cdc/calibration/CDCdEdx/CDCDedxHadBGAlgorithm.h>
10
11using namespace Belle2;
12
13//-----------------------------------------------------------------
14// Implementation
15//-----------------------------------------------------------------
17 CalibrationAlgorithm("CDCDedxHadronCollector"),
18 m_ismakePlots(true),
19 m_suffix("")
20{
21 // Set module properties
22 setDescription("A calibration algorithm for CDC dE/dx hadron Beta Gamma curve and resolution fitting");
23}
24
25//-----------------------------------------------------------------
26// Run the calibration
27//-----------------------------------------------------------------
29{
30
31 gROOT->SetBatch();
33
34 //existing hadron bg mean and reso payload for merging
35 if (!m_DBMeanPars.isValid() || !m_DBSigmaPars.isValid())
36 B2FATAL("There is no valid payload for Beta-Gamma saturation");
37
38 // particle list
39 std::vector< std::string > particles = {"muon", "kaon", "proton", "pion", "electron"};
40
41 // check we have enough data
42 for (int i = 0; i < int(particles.size()); i++) {
43 std::string p = particles[i];
44 auto tree = getObjectPtr<TTree>(Form("%s", p.data()));
45 if (!tree) return c_NotEnoughData;
46 }
47
48 gSystem->Exec("mkdir -p plots/HadronPrep");
49 gSystem->Exec("mkdir -p plots/HadronCal/BGfits");
50 gSystem->Exec("mkdir -p plots/HadronCal/Resofits");
51 gSystem->Exec("mkdir -p plots/HadronCal/Monitoring");
52
53 // Write beta-gamma curve mean and resolution parameters in text file
55 mg.setParameters();
56 mg.printParameters("parameters.inital.curve");
57
59 sg.setParameters();
60 sg.printParameters("parameters.inital.sigma");
61
62 m_bgcurve = "parameters.inital.curve";
63 m_bgsigma = "parameters.inital.sigma";
64
65 HadronCalibration hadcal;
66 std::string filename = " ";
67
68 for (int iter = 0; iter < m_iter; ++iter) {
69
70 std::string sfx = Form("%s_iter%d", m_suffix.data(), iter);
71 filename = Form("widget_corrected_NewHSpars_1D_%s.root", sfx.data());
72
73 // prepare sample to perform bg curve fittting and draw the monitoring plots
74 prepareSample(particles, filename, sfx);
75
76 // create the HadronCalibration object and fit the prepared samples
77 hadcal.plotBGMonitoring(particles, filename, sfx);
78
79 //bg fit
80 hadcal.fitBGCurve(particles, filename, m_bgcurve, sfx);
81 m_bgcurve = "parameters.bgcurve.fit";
82
83 //dedx reso vs ionz fit
84 hadcal.fitSigmavsIonz(particles, filename, m_bgsigma, sfx);
85 m_bgsigma = "parameters.ionz.fit";
86
87 //dedx reso vs nHits fit
88 SigmaFits(particles, sfx, "nhit");
89 m_bgsigma = "parameters.sigmanhit.fit";
90
91 //dedx reso vs costh fit
92 SigmaFits(particles, sfx, "costh");
93 m_bgsigma = "parameters.sigmacos.fit";
94
95 }
96
97 filename = Form("widget_corrected_NewHSpars_1D_%s_final.root", m_suffix.data());
98 prepareSample(particles, filename, Form("%s_final", m_suffix.data()));
99 hadcal.plotBGMonitoring(particles, filename, Form("%s_final", m_suffix.data()));
100
101 B2INFO("Saving calibration for: " << m_suffix << "");
103
104 return c_OK;
105}
106
107
108//------------------------------------
110{
111 int cruns = 0;
112 for (auto expRun : getRunList()) {
113 if (cruns == 0)B2INFO("CDCDedxHadBGAlgorithm: start exp " << expRun.first << " and run " << expRun.second << "");
114 cruns++;
115 }
116
117 const auto erStart = getRunList()[0];
118 int estart = erStart.first;
119 int rstart = erStart.second;
120
121 updateDBObjPtrs(1, erStart.second, erStart.first);
122
123 m_suffix = Form("e%dr%d", estart, rstart);
124 B2INFO("tool exp = " << estart << ", run = " << rstart << ", m_suffix = " << m_suffix << "");
125}
126
127//--------------------------
129{
130
131 std::ifstream fins("parameters.sigmacos.fit"), fin("parameters.bgcurve.fit");
132
133 if (!fin.good()) B2FATAL("\t WARNING: CANNOT FIND parameters.bgcurve.fit!");
134 if (!fins.good()) B2FATAL("\tWARNING: CANNOT FIND parameters.sigmacos.fit!");
135
136 int par;
137 double meanpars, sigmapars;
138 std::vector<double> v_meanpars, v_sigmapars;
139
140 B2INFO("\t --> Curve parameters");
141 for (int i = 0; i < 15; ++i) {
142 fin >> par >> meanpars;
143 v_meanpars.push_back(meanpars);
144 B2INFO("\t\t (" << i << ")" << v_meanpars[i]);
145 }
146
147 fin.close();
148
149 B2INFO("\t --> Sigma parameters");
150 for (int i = 0; i < 17; ++i) {
151 fins >> par >> sigmapars;
152 v_sigmapars.push_back(sigmapars);
153 B2INFO("\t\t (" << i << ")" << v_sigmapars[i]);
154 }
155 fins.close();
156
157 B2INFO("dE/dx Calibration done for " << v_meanpars.size() << " CDC Beta Gamma curve");
158 CDCDedxMeanPars* gains = new CDCDedxMeanPars(0, v_meanpars);
159 saveCalibration(gains, "CDCDedxMeanPars");
160
161
162 B2INFO("dE/dx Calibration done for " << v_sigmapars.size() << " CDC Beta Gamma resolution");
163 CDCDedxSigmaPars* sgains = new CDCDedxSigmaPars(0, v_sigmapars);
164 saveCalibration(sgains, "CDCDedxSigmaPars");
165}
166
167void CDCDedxHadBGAlgorithm::prepareSample(std::vector< std::string > particles, const std::string& filename, const std::string& sfx)
168{
169
170 TFile* outfile = new TFile(filename.data(), "RECREATE");
171
172 for (int i = 0; i < int(particles.size()); ++i) {
173
174 std::string p = particles[i];
175 auto tree = getObjectPtr<TTree>(Form("%s", p.data()));
176
177 HadronBgPrep prep(m_bgpar[p][0], m_bgpar[p][1], m_bgpar[p][2], 8, -1.0, 1.0, m_injpar[p][0], m_injpar[p][1],
179
180 prep.prepareSample(tree, outfile, sfx, m_bgcurve, m_bgsigma, p, m_ismakePlots);
181 }
182 outfile->Close();
183
184}
185
186void CDCDedxHadBGAlgorithm::SigmaFits(std::vector< std::string > particles, const std::string& sfx, const std::string& svar)
187{
188 // only the muon samples are used for the sigma fits
189 HadronCalibration hadcal;
190
191 std::string filename = Form("widget_%s_1D_%s.root", svar.data(), sfx.data());
192
193 TFile* outfile = new TFile(filename.data(), "RECREATE");
194 outfile->cd();
195
196 for (int ip = 0; ip < int(particles.size()); ++ip) {
197
198 std::string particle = particles[ip];
199 auto hadron = getObjectPtr<TTree>(Form("%s", particle.data()));
200
201 HadronBgPrep prep(m_bgpar[particle][0], m_bgpar[particle][1], m_bgpar[particle][2], m_cospar[particle], m_cosMin, m_cosMax,
202 m_injpar[particle][0],
203 m_injpar[particle][1], m_injpar[particle][2], m_nhitBins, m_nhitMin, m_nhitMax, m_cut);
204
205 double mass = prep.getParticleMass(particle);
206 if (mass == 0.0) B2FATAL("Mass of particle " << particle.data() << " is zero");
207 // --------------------------------------------------
208 // INITIALIZE CONTAINERS
209 // --------------------------------------------------
210 double dedxnosat; // dE/dx without hadron saturation correction
211 double p; // track momentum
212 double costh; // cosine of track polar angle
213 double timereso;
214 int nhits; // number of hits on this track
215
216 hadron->SetBranchAddress("dedxnosat", &dedxnosat);
217 hadron->SetBranchAddress("p", &p);
218 hadron->SetBranchAddress("costh", &costh);
219 hadron->SetBranchAddress("timereso", &timereso);
220 hadron->SetBranchAddress("nhits", &nhits);
221
222 int nbins = m_nhitBins;
223 double lower = m_nhitMin;
224 double upper = m_nhitMax;
225 double nstep = (upper - lower + 1) / nbins;
226
227 if (svar == "costh") {
228 nbins = m_cospar[particle];
229 lower = m_cosMin, upper = m_cosMax;
230 nstep = (upper - lower) / nbins;
231 }
232
233 // Create the histograms to be fit
234 std::vector<TH1F*> hdedx_var;
235
236 //define histograms
237 prep.defineHisto(hdedx_var, "chi", svar, particle.data());
238
239 // Create some containers to calculate averages
240 std::vector<double> sumvar(nbins);
241 std::vector<int> sumsize(nbins);
242 for (int i = 0; i < nbins; ++i) {
243 sumvar[i] = 0;
244 sumsize[i] = 0;
245 }
246
247 // get the hadron saturation parameters
248 CDCDedxMeanPred mgpar;
249 CDCDedxSigmaPred sgpar;
250
251 mgpar.setParameters(m_bgcurve.data());
252 sgpar.setParameters(m_bgsigma.data());
253
254 CDCDedxHadSat had;
255 had.setParameters("sat-pars.fit.txt");
256 // --------------------------------------------------
257 // LOOP OVER EVENTS AND FILL CONTAINERS
258 // --------------------------------------------------
259 // Fill the histograms to be fitted
260
261 for (unsigned int index = 0; index < hadron->GetEntries(); ++index) {
262
263 hadron->GetEvent(index);
264 double bg; // track beta-gamma
265 bg = fabs(p) / mass;
266
267 if (fabs(p) > 8.0)continue; //unphysical tracks
268
269 // clean up bad events and restrict the momentum range
270 if (svar == "nhit") {if (nhits < lower || nhits > upper) continue;}
271 else if (svar == "costh") {if (costh > upper || costh < lower)continue;}
272
273 if (dedxnosat <= 0)continue;
274 if (costh != costh)continue;
275
276 if (particle == "proton") {if ((dedxnosat - 0.45)*abs(p)*abs(p) < m_cut) continue;}
277
278 if (particle == "electron" || particle == "muon") {if (fabs(p) > 2.0) continue;}
279
280 double dedx_new = had.D2I(costh, had.I2D(costh, 1.0) * dedxnosat);
281
282 double dedx_cur = mgpar.getMean(bg);
283
284 if (svar == "nhit") {
285 double res_cor = sgpar.cosPrediction(costh) * sgpar.ionzPrediction(dedx_cur) * timereso;
286 int nhitBin = (int)((fabs(nhits) - lower) / nstep);
287 if (res_cor != 0) hdedx_var[nhitBin]->Fill((dedx_new - dedx_cur) / res_cor);
288 sumvar[nhitBin] += nhits;
289 sumsize[nhitBin] += 1;
290 } else if (svar == "costh") {
291
292 double res_cor = sgpar.nhitPrediction(nhits) * sgpar.ionzPrediction(dedx_cur) * timereso;
293 int cosBin = (int)((costh - lower) / (upper - lower) * nbins);
294
295 if (res_cor != 0) hdedx_var[cosBin]->Fill((dedx_new - dedx_cur) / res_cor);
296
297 sumvar[cosBin] += costh;
298 sumsize[cosBin] += 1;
299 }
300 }// end of event loop
301
302 // --------------------------------------------------
303 // FIT IN BINS OF NHIT
304 // --------------------------------------------------
305 // fit the histograms with Gaussian functions
306 // and extract the means and errors
307
308
309 TTree* tTree = new TTree(Form("%s_%s", particle.data(), svar.data()), "chi m_means and m_errors");
310 double avg, mean, mean_err, sigma, sigma_err;
311
312 tTree->Branch("avg", &avg, "avg/D");
313 tTree->Branch("chimean", &mean, "chimean/D");
314 tTree->Branch("chimean_err", &mean_err, "chimean_err/D");
315 tTree->Branch("chisigma", &sigma, "chisigma/D");
316 tTree->Branch("chisigma_err", &sigma_err, "chisigma_err/D");
317
318 double avg_sigma = 0.0;
319 std::vector<double> var(nbins), varres(nbins), varreserr(nbins);
320
321 int count_bins = 0;
322 for (int i = 0; i < nbins; ++i) {
323
324 varres[i] = 0.0;
325 varreserr[i] = 0.0;
326 var[i] = sumvar[i] / sumsize[i];
327
328 // fit the dE/dx distribution in bins of injection time'
329 if (hdedx_var[i]->Integral() > 100) {
330 prep.fit(hdedx_var[i], particle.data());
331 varres[i] = hdedx_var[i]->GetFunction("gaus")->GetParameter(2);;
332 varreserr[i] = hdedx_var[i]->GetFunction("gaus")->GetParError(2);
333 count_bins++;
334 avg_sigma += varres[i];
335
336 }
337 }
338 if (count_bins > 0) avg_sigma = avg_sigma / count_bins;
339 for (int i = 0; i < nbins; ++i) {
340
341 if (avg_sigma > 0) {
342 sigma = varres[i] = varres[i] / avg_sigma;
343 sigma_err = varreserr[i] = varreserr[i] / avg_sigma;
344 }
345 mean = hdedx_var[i]->GetFunction("gaus")->GetParameter(1);
346 mean_err = hdedx_var[i]->GetFunction("gaus")->GetParError(1);
347 avg = var[i];
348 tTree->Fill();
349 }
350
351 tTree->Write();
352
353 prep.plotDist(hdedx_var, Form("fits_chi_%s_%s_%s", svar.data(), sfx.data(), particle.data()), nbins);
354
355 prep.deleteHistos(hdedx_var);
356 }
357 outfile->Close();
358
359 if (svar == "costh") hadcal.fitSigmaVsCos(particles, filename, m_bgsigma, sfx);
360 else hadcal.fitSigmaVsNHit(particles, filename, m_bgsigma, sfx);
361
362}
363
364
void SigmaFits(std::vector< std::string > particles, const std::string &sfx, const std::string &svar)
function to do the sigma vs nhit or cos fits and store parameters
DBObjPtr< CDCDedxMeanPars > m_DBMeanPars
db object for dE/dx mean parameters
std::map< std::string, std::array< double, 3 > > m_bgpar
bg bins, min, max for different particles
void getExpRunInfo()
function to get exp/run information (payload object, plotting)
double m_cosMax
max range of cosine
std::map< std::string, double > m_cospar
cos bins for different particles
std::string m_bgcurve
string for mean parameter file names
bool m_ismakePlots
produce plots for monitoring
int m_iter
set number of iteration
std::string m_suffix
string suffix for object names
CDCDedxHadBGAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
double m_nhitMax
max range of nhits
DBObjPtr< CDCDedxSigmaPars > m_DBSigmaPars
db object for dE/dx resolution parameters
std::string m_bgsigma
string for sigma parameter file names
double m_cosMin
min range of cosine
double m_cut
cut to clean protons
virtual EResult calibrate() override
CDC dE/dx Beta Gamma curve and resolution algorithm.
double m_nhitMin
min range of nhits
std::map< std::string, std::array< double, 3 > > m_injpar
injection time bins, min, max for different particles
void createPayload()
function to store payloads after full calibration
void prepareSample(std::vector< std::string > particles, const std::string &filename, const std::string &sfx)
function to prepare sample for bgcurve fitting, sigma vs ionzation fitting and monitoring plots
Class to hold the hadron saturation functions.
Definition: CDCDedxHadSat.h:31
double I2D(double cosTheta, double I) const
hadron saturation parameterization part 2
double D2I(double cosTheta, double D) const
hadron saturation parameterization part 1
void setParameters()
set the parameters
dE/dx mean (curve versus beta-gamma) parameterization constants
Class to hold the prediction of mean as a function of beta-gamma (bg)
void printParameters(std::string infile)
write the parameters in file
double getMean(double bg)
Return the predicted mean value as a function of beta-gamma (bg)
void setParameters(std::string infile)
set the parameters from file
dE/dx sigma (versus beta-gamma) parameterization constants
Class to hold the prediction of resolution depending dE/dx, nhit, and cos(theta)
double ionzPrediction(double dedx)
Return sigma from the ionization parameterization.
double cosPrediction(double cos)
Return sigma from the cos parameterization.
double nhitPrediction(double nhit)
Return sigma from the nhit parameterization.
void printParameters(std::string infile)
write the parameters in file
void setParameters(std::string infile)
set the parameters from file
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class to prepare sample for fitting in beta gamma bins.
Definition: HadronBgPrep.h:43
void defineHisto(std::vector< TH1F * > &htemp, const std::string &svar, const std::string &stype, const std::string &pdg)
function to define histograms
double getParticleMass(const std::string &particle)
function to get the particle mass
Definition: HadronBgPrep.h:160
void deleteHistos(std::vector< TH1F * > &htemp)
function to delete the histograms
Definition: HadronBgPrep.h:152
void fit(TH1F *&hist, const std::string &pdg)
function to fit the histograms
void plotDist(std::map< int, std::vector< TH1F * > > &hist, const std::string &suffix, int bins)
function to plot the map of histograms
void prepareSample(std::shared_ptr< TTree > hadron, TFile *&outfile, const std::string &suffix, const std::string &bgcurvefile, const std::string &bgsigmafile, const std::string &pdg, bool ismakePlots)
function to prepare sample for monitoring plots, bg curve fitting and sigma vs ionz fitting
Definition: HadronBgPrep.cc:46
Class to perform the fitting in beta gamma bins.
void fitSigmaVsCos(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffx)
fit sigma vs.
void fitSigmaVsNHit(std::vector< std::string > particles, const std::string &filename, const std::string &paramsigma, const std::string &suffx)
fit sigma vs.
void fitBGCurve(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffx)
fit the beta-gamma curve
void plotBGMonitoring(std::vector< std::string > particles, const std::string &filename, const std::string &suffix)
plots mean and width after fitting
void fitSigmavsIonz(std::vector< std::string > particles, const std::string &filename, const std::string &paramfile, const std::string &suffix)
fit sigma vs.
Abstract base class for different kinds of events.