File indexing completed on 2026-09-12 08:21:35
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <functional>
0012 #include <limits>
0013
0014 #include <TColor.h>
0015 #include <TDirectory.h>
0016 #include <TH1F.h>
0017 #include <TString.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026 template <typename hist_t>
0027 void setHistStyle(hist_t* hist, short color = 1) {
0028 if (hist == nullptr) {
0029 return;
0030 }
0031 hist->GetXaxis()->SetTitleSize(0.04);
0032 hist->GetYaxis()->SetTitleSize(0.04);
0033 hist->GetXaxis()->SetLabelSize(0.04);
0034 hist->GetYaxis()->SetLabelSize(0.04);
0035 hist->GetXaxis()->SetTitleOffset(1.0);
0036 hist->GetYaxis()->SetTitleOffset(1.0);
0037 hist->GetXaxis()->SetNdivisions(505);
0038 hist->SetMarkerStyle(20);
0039 hist->SetMarkerSize(0.8);
0040 hist->SetLineWidth(2);
0041 hist->SetTitle("");
0042 hist->SetLineColor(color);
0043 hist->SetMarkerColor(color);
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053 template <typename eff_t>
0054 void setEffStyle(eff_t* eff, short color = 1) {
0055 eff->SetMarkerStyle(20);
0056 eff->SetMarkerSize(0.8);
0057 eff->SetLineWidth(2);
0058 eff->SetLineColor(color);
0059 eff->SetMarkerColor(color);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 template <typename hist_t>
0073 void adaptColorPalette(hist_t* h, float rmin, float rmax, float rgood,
0074 float rwindow, int n) {
0075
0076 float rel_good = (rgood - rmin) / (rmax - rmin);
0077 float rel_window = rwindow / (rmax - rmin);
0078
0079
0080 const int number = 5;
0081 double red[number] = {0., 0., 0., 1., 1.};
0082 double green[number] = {0., 1., 1., 1., 0.};
0083 double blue[number] = {1., 1., 0., 0., 0.};
0084 double stops[number] = {0., rel_good - rel_window, rel_good,
0085 rel_good + rel_window, 1.};
0086 h->SetContour(n);
0087
0088 TColor::CreateGradientColorTable(number, stops, red, green, blue, n);
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 template <typename eff_t>
0101 void adaptEffRange(eff_t* eff, float minScale = 1, float maxScale = 1.1) {
0102 gPad->Update();
0103 auto ymin = gPad->GetUymin();
0104 auto ymax = gPad->GetUymax();
0105 auto graph = eff->GetPaintedGraph();
0106 graph->SetMinimum(ymin * minScale);
0107 graph->SetMaximum(ymax * maxScale);
0108 gPad->Modified();
0109 gPad->Update();
0110 }
0111
0112
0113
0114
0115
0116
0117
0118 struct ResidualPullHandle {
0119
0120 std::string tag = "";
0121
0122
0123 std::string residualStr = "";
0124 std::string residualUnit = "";
0125
0126
0127 std::string errorStr = "";
0128
0129
0130 std::string rangeDrawStr = "";
0131 std::string rangeMaxStr = "";
0132 std::string rangeCutStr = "";
0133
0134
0135 std::array<float, 2> range = {0., 0.};
0136
0137
0138
0139 std::function<float(ULong64_t)> value;
0140
0141
0142 std::function<float(ULong64_t)> error;
0143
0144
0145 std::function<bool(ULong64_t)> accept;
0146
0147 TH1F* rangeHist = nullptr;
0148
0149 TH1F* residualHist = nullptr;
0150
0151 TH1F* pullHist = nullptr;
0152
0153 ULong64_t accepted = 0;
0154
0155
0156
0157
0158 void fill(unsigned int entry) {
0159 if (accept(entry)) {
0160
0161 float v = value(entry);
0162 residualHist->Fill(v);
0163 pullHist->Fill(v / error(entry));
0164
0165 ++accepted;
0166 }
0167 };
0168 };
0169
0170
0171 struct SingleHandle {
0172
0173 std::string tag = "";
0174
0175
0176 std::string label = "";
0177
0178
0179 std::string rangeDrawStr = "";
0180
0181
0182 unsigned int bins = 1;
0183
0184
0185 std::array<float, 2> range = {0., 0.};
0186
0187
0188
0189 std::function<float(ULong64_t)> value;
0190
0191
0192 std::function<bool(ULong64_t)> accept;
0193
0194 TH1F* hist = nullptr;
0195
0196
0197
0198
0199 void fill(unsigned int entry) {
0200 if (accept(entry)) {
0201
0202 float v = value(entry);
0203 hist->Fill(v);
0204 }
0205 }
0206 };
0207
0208
0209
0210
0211 struct AcceptCombination {
0212 std::function<bool(ULong64_t)> one;
0213
0214 std::function<bool(ULong64_t)> two;
0215
0216
0217
0218 bool operator()(ULong64_t entry) { return (one(entry) && two(entry)); }
0219 };
0220
0221
0222 struct AcceptAll {
0223
0224 bool operator()(ULong64_t ) { return true; }
0225 };
0226
0227
0228
0229 struct AcceptRange {
0230 std::vector<float>* value = nullptr;
0231
0232 std::array<float, 2> range = {0., 0.};
0233
0234
0235
0236 bool operator()(ULong64_t entry) {
0237 if (value != nullptr) {
0238 float v = value->at(entry);
0239 return (range[0] <= v && range[1] > v);
0240 }
0241 return false;
0242 }
0243 };
0244
0245
0246
0247
0248
0249 template <typename primitive_t>
0250 struct DirectAccessor {
0251 std::vector<primitive_t>* value = nullptr;
0252
0253
0254
0255
0256 primitive_t operator()(ULong64_t entry) {
0257 if (value) {
0258 primitive_t v = value->at(entry);
0259 return v;
0260 }
0261 return std::numeric_limits<primitive_t>::max();
0262 }
0263 };
0264
0265
0266 template <typename primitive_one_t, typename primitive_two_t>
0267 struct DivisionAccessor {
0268 std::vector<primitive_one_t>* one = nullptr;
0269
0270 std::vector<primitive_two_t>* two = nullptr;
0271
0272
0273
0274
0275 primitive_one_t operator()(ULong64_t entry) {
0276 if (one && two) {
0277 primitive_one_t vo = one->at(entry);
0278 primitive_two_t vt = two->at(entry);
0279 return vo / vt;
0280 }
0281 return std::numeric_limits<primitive_one_t>::max();
0282 }
0283 };
0284
0285
0286 struct ResidualAccessor {
0287 std::vector<float>* value = nullptr;
0288
0289 std::vector<float>* reference = nullptr;
0290
0291
0292
0293
0294 float operator()(ULong64_t entry) {
0295 if (value != nullptr && reference != nullptr) {
0296 float v = value->at(entry);
0297 float r = reference->at(entry);
0298 return (v - r);
0299 }
0300 return std::numeric_limits<float>::infinity();
0301 }
0302 };
0303
0304
0305 struct QopResidualAccessor {
0306 std::vector<float>* qop_value = nullptr;
0307
0308 std::vector<int>* reference_charge = nullptr;
0309
0310 std::vector<float>* reference_p = nullptr;
0311
0312
0313
0314
0315 float operator()(ULong64_t entry) {
0316 if (qop_value != nullptr && reference_charge != nullptr &&
0317 reference_p != nullptr) {
0318 float v = qop_value->at(entry);
0319 float q_true = reference_charge->at(entry);
0320 float p_true = reference_p->at(entry);
0321 return (v - q_true / p_true);
0322 }
0323 return std::numeric_limits<float>::infinity();
0324 }
0325 };
0326
0327
0328 struct PtResidualAccessor {
0329 std::vector<float>* qop_value = nullptr;
0330
0331 std::vector<float>* theta_value = nullptr;
0332
0333 std::vector<float>* reference_pt = nullptr;
0334
0335
0336
0337
0338 float operator()(ULong64_t entry) {
0339 if (qop_value != nullptr && theta_value != nullptr &&
0340 reference_pt != nullptr) {
0341 float p = 1. / std::abs(qop_value->at(entry));
0342 float theta = theta_value->at(entry);
0343 float pt_true = reference_pt->at(entry);
0344 return (p * std::sin(theta) - pt_true);
0345 }
0346 return std::numeric_limits<float>::infinity();
0347 }
0348 };
0349
0350
0351 struct PtErrorAccessor {
0352 std::vector<float>* qop_value = nullptr;
0353 std::vector<float>* qop_error = nullptr;
0354
0355 std::vector<float>* theta_value = nullptr;
0356 std::vector<float>* theta_error = nullptr;
0357
0358
0359
0360
0361 float operator()(ULong64_t entry) {
0362 if (qop_value != nullptr && qop_error != nullptr &&
0363 theta_value != nullptr && theta_error != nullptr) {
0364 float qop_v = qop_value->at(entry);
0365 float qop_e = qop_error->at(entry);
0366 float theta_v = theta_value->at(entry);
0367 float theta_e = theta_error->at(entry);
0368 return std::cos(theta_v) / qop_v * theta_e -
0369 std::sin(theta_v) / (qop_v * qop_v) * qop_e;
0370 }
0371 return std::numeric_limits<float>::infinity();
0372 }
0373 };
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 template <typename dir_t, typename tree_t>
0386 void estimateResiudalRange(ResidualPullHandle& handle, dir_t& directory,
0387 tree_t& tree, unsigned long peakEntries,
0388 unsigned int hBarcode) {
0389
0390 directory.cd();
0391 TString rangeHist = handle.rangeDrawStr;
0392 rangeHist += ">>";
0393
0394 TString rangeHN = "hrg_";
0395 rangeHN += hBarcode;
0396
0397 rangeHist += rangeHN;
0398 rangeHist += handle.rangeMaxStr;
0399
0400
0401 tree.Draw(rangeHist.Data(), handle.rangeCutStr.c_str(), "", peakEntries);
0402 handle.rangeHist = dynamic_cast<TH1F*>(gDirectory->Get(rangeHN.Data()));
0403 if (handle.rangeHist != nullptr) {
0404 float rms = handle.rangeHist->GetRMS();
0405 handle.range = {-rms, rms};
0406 }
0407 }
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 template <typename dir_t, typename tree_t>
0420 void estimateIntegerRange(SingleHandle& handle, dir_t& directory, tree_t& tree,
0421 unsigned long peakEntries, unsigned int startBins,
0422 unsigned int addBins, unsigned int hBarcode) {
0423
0424 directory.cd();
0425 TString rangeHist = handle.rangeDrawStr;
0426 rangeHist += ">>";
0427
0428 TString rangeHN = "hrg_";
0429 rangeHN += hBarcode;
0430
0431 rangeHist += rangeHN;
0432 rangeHist += "(";
0433 rangeHist += startBins;
0434 rangeHist += ",-0.5,";
0435 rangeHist += static_cast<float>(startBins - 0.5);
0436 rangeHist += ")";
0437
0438 unsigned int nBins = startBins;
0439
0440 tree.Draw(rangeHist.Data(), "", "", peakEntries);
0441 auto rhist = dynamic_cast<TH1F*>(gDirectory->Get(rangeHN.Data()));
0442 if (rhist != nullptr) {
0443 for (unsigned int ib = 1; ib <= startBins; ++ib) {
0444 if (rhist->GetBinContent(ib) > 0.) {
0445 nBins = ib;
0446 }
0447 }
0448 handle.bins = (nBins + addBins);
0449 handle.range = {-0.5, static_cast<float>(handle.bins - 0.5)};
0450 return;
0451 }
0452 handle.bins = (startBins);
0453 handle.range = {-0.5, static_cast<float>(handle.bins - 0.5)};
0454 }
0455
0456
0457
0458
0459
0460
0461
0462 void bookHistograms(ResidualPullHandle& handle, float pullRange,
0463 unsigned int hBins, unsigned int hBarcode) {
0464
0465 TString rName = std::string("res_") + handle.tag;
0466 rName += hBarcode;
0467 handle.residualHist =
0468 new TH1F(rName.Data(), handle.tag.c_str(), hBins,
0469 pullRange * handle.range[0], pullRange * handle.range[1]);
0470 std::string xAxisTitle =
0471 handle.residualStr + std::string(" ") + handle.residualUnit;
0472 handle.residualHist->GetXaxis()->SetTitle(xAxisTitle.c_str());
0473 handle.residualHist->GetYaxis()->SetTitle("Entries");
0474
0475
0476 TString pName = std::string("pull_") + handle.tag;
0477 pName += hBarcode;
0478 handle.pullHist =
0479 new TH1F(pName.Data(), (std::string("pull ") + handle.tag).c_str(), hBins,
0480 -pullRange, pullRange);
0481 xAxisTitle = std::string("(") + handle.residualStr + std::string(")/") +
0482 handle.errorStr;
0483 handle.pullHist->GetXaxis()->SetTitle(xAxisTitle.c_str());
0484 handle.pullHist->GetYaxis()->SetTitle("Entries");
0485 }
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 template <typename tree_t>
0496 unsigned long estimateEntries(const tree_t& tree,
0497 unsigned long configuredEntries) {
0498 unsigned long entries = static_cast<unsigned long>(tree.GetEntries());
0499 if (configuredEntries > 0 && configuredEntries < entries) {
0500 entries = configuredEntries;
0501 }
0502 return entries;
0503 }