LDMX Software
CommonUtils.h
1// This file is part of the Acts project.
2//
3// Copyright (C) 2019-2021 CERN for the benefit of the Acts project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11#include <functional>
12#include <limits>
13
14#include <TColor.h>
15#include <TDirectory.h>
16#include <TH1F.h>
17#include <TString.h>
18
26template <typename hist_t>
27void setHistStyle(hist_t* hist, short color = 1) {
28 hist->GetXaxis()->SetTitleSize(0.04);
29 hist->GetYaxis()->SetTitleSize(0.04);
30 hist->GetXaxis()->SetLabelSize(0.04);
31 hist->GetYaxis()->SetLabelSize(0.04);
32 hist->GetXaxis()->SetTitleOffset(1.0);
33 hist->GetYaxis()->SetTitleOffset(1.0);
34 hist->GetXaxis()->SetNdivisions(505);
35 hist->SetMarkerStyle(20);
36 hist->SetMarkerSize(0.8);
37 hist->SetLineWidth(2);
38 hist->SetTitle("");
39 hist->SetLineColor(color);
40 hist->SetMarkerColor(color);
41}
42
50template <typename eff_t>
51void setEffStyle(eff_t* eff, short color = 1) {
52 eff->SetMarkerStyle(20);
53 eff->SetMarkerSize(0.8);
54 eff->SetLineWidth(2);
55 eff->SetLineColor(color);
56 eff->SetMarkerColor(color);
57}
58
69template <typename hist_t>
70void adaptColorPalette(hist_t* h, float rmin, float rmax, float rgood,
71 float rwindow, int n) {
72 // min - max is the range of the axis
73 float rel_good = (rgood - rmin) / (rmax - rmin);
74 float rel_window = rwindow / (rmax - rmin);
75
76 // Stops are
77 const int number = 5;
78 double red[number] = {0., 0., 0., 1., 1.};
79 double green[number] = {0., 1., 1., 1., 0.};
80 double blue[number] = {1., 1., 0., 0., 0.};
81 double stops[number] = {0., rel_good - rel_window, rel_good,
82 rel_good + rel_window, 1.};
83 h->SetContour(n);
84
85 TColor::CreateGradientColorTable(number, stops, red, green, blue, n);
86}
87
97template <typename eff_t>
98void adaptEffRange(eff_t* eff, float minScale = 1, float maxScale = 1.1) {
99 gPad->Update();
100 auto ymin = gPad->GetUymin();
101 auto ymax = gPad->GetUymax();
102 auto graph = eff->GetPaintedGraph();
103 graph->SetMinimum(ymin * minScale);
104 graph->SetMaximum(ymax * maxScale);
105 gPad->Modified();
106 gPad->Update();
107}
108
117 std::string tag = "";
118
120 std::string residualStr = "";
121 std::string residualUnit = "";
122
124 std::string errorStr = "";
125
127 std::string rangeDrawStr = "";
128 std::string rangeMaxStr = "";
129 std::string rangeCutStr = "";
130
132 std::array<float, 2> range = {0., 0.};
133
136 std::function<float(ULong64_t)> value;
137
139 std::function<float(ULong64_t)> error;
140
142 std::function<bool(ULong64_t)> accept;
143
144 TH1F* rangeHist = nullptr;
145
146 TH1F* residualHist = nullptr;
147
148 TH1F* pullHist = nullptr;
149
150 ULong64_t accepted = 0;
151
155 void fill(unsigned int entry) {
156 if (accept(entry)) {
157 // Access the value, error
158 float v = value(entry);
159 residualHist->Fill(v);
160 pullHist->Fill(v / error(entry));
161 // Count the accessor
162 ++accepted;
163 }
164 };
165};
166
170 std::string tag = "";
171
173 std::string label = "";
174
175 // Range draw string
176 std::string rangeDrawStr = "";
177
179 unsigned int bins = 1;
180
182 std::array<float, 2> range = {0., 0.};
183
186 std::function<float(ULong64_t)> value;
187
189 std::function<bool(ULong64_t)> accept;
190
191 TH1F* hist = nullptr;
192
196 void fill(unsigned int entry) {
197 if (accept(entry)) {
198 // Access the value, error
199 float v = value(entry);
200 hist->Fill(v);
201 }
202 }
203};
204
209 std::function<bool(ULong64_t)> one;
210
211 std::function<bool(ULong64_t)> two;
212
215 bool operator()(ULong64_t entry) { return (one(entry) && two(entry)); }
216};
217
219struct AcceptAll {
220 // Call operator always returns true
221 bool operator()(ULong64_t /*event*/) { return true; }
222};
223
227 std::vector<float>* value = nullptr;
228
229 std::array<float, 2> range = {0., 0.};
230
233 bool operator()(ULong64_t entry) {
234 if (value != nullptr) {
235 float v = value->at(entry);
236 return (range[0] <= v && range[1] > v);
237 }
238 return false;
239 }
240};
241
246template <typename primitive_t>
248 std::vector<primitive_t>* value = nullptr;
249
253 primitive_t operator()(ULong64_t entry) {
254 if (value) {
255 primitive_t v = value->at(entry);
256 return v;
257 }
258 return std::numeric_limits<primitive_t>::max();
259 }
260};
261
262// Division accessor
263template <typename primitive_one_t, typename primitive_two_t>
265 std::vector<primitive_one_t>* one = nullptr;
266
267 std::vector<primitive_two_t>* two = nullptr;
268
272 primitive_one_t operator()(ULong64_t entry) {
273 if (one && two) {
274 primitive_one_t vo = one->at(entry);
275 primitive_two_t vt = two->at(entry);
276 return vo / vt;
277 }
278 return std::numeric_limits<primitive_one_t>::max();
279 }
280};
281
282// This is a residual type accessor
284 std::vector<float>* value = nullptr;
285
286 std::vector<float>* reference = nullptr;
287
291 float operator()(ULong64_t entry) {
292 if (value != nullptr && reference != nullptr) {
293 float v = value->at(entry);
294 float r = reference->at(entry);
295 return (v - r);
296 }
297 return std::numeric_limits<float>::infinity();
298 }
299};
300
301// This is a dedicated qop residual accessor
303 std::vector<float>* qop_value = nullptr;
304
305 std::vector<int>* reference_charge = nullptr;
306
307 std::vector<float>* reference_p = nullptr;
308
312 float operator()(ULong64_t entry) {
313 if (qop_value != nullptr && reference_charge != nullptr &&
314 reference_p != nullptr) {
315 float v = qop_value->at(entry);
316 float q_true = reference_charge->at(entry);
317 float p_true = reference_p->at(entry);
318 return (v - q_true / p_true);
319 }
320 return std::numeric_limits<float>::infinity();
321 }
322};
323
326 std::vector<float>* qop_value = nullptr;
327
328 std::vector<float>* theta_value = nullptr;
329
330 std::vector<float>* reference_pt = nullptr;
331
335 float operator()(ULong64_t entry) {
336 if (qop_value != nullptr && theta_value != nullptr &&
337 reference_pt != nullptr) {
338 float p = 1. / std::abs(qop_value->at(entry));
339 float theta = theta_value->at(entry);
340 float pt_true = reference_pt->at(entry);
341 return (p * sin(theta) - pt_true);
342 }
343 return std::numeric_limits<float>::infinity();
344 }
345};
346
347// This is a dedicated pT error accessor
349 std::vector<float>* qop_value = nullptr;
350 std::vector<float>* qop_error = nullptr;
351
352 std::vector<float>* theta_value = nullptr;
353 std::vector<float>* theta_error = nullptr;
354
358 float operator()(ULong64_t entry) {
359 if (qop_value != nullptr && qop_error != nullptr &&
360 theta_value != nullptr && theta_error != nullptr) {
361 float qop_v = qop_value->at(entry);
362 float qop_e = qop_error->at(entry);
363 float theta_v = theta_value->at(entry);
364 float theta_e = theta_error->at(entry);
365 return std::cos(theta_v) / qop_v * theta_e -
366 std::sin(theta_v) / (qop_v * qop_v) * qop_e;
367 }
368 return std::numeric_limits<float>::infinity();
369 }
370};
371
382template <typename dir_t, typename tree_t>
383void estimateResiudalRange(ResidualPullHandle& handle, dir_t& directory,
384 tree_t& tree, unsigned long peakEntries,
385 unsigned int hBarcode) {
386 // Change into the Directory
387 directory.cd();
388 TString rangeHist = handle.rangeDrawStr;
389 rangeHist += ">>";
390 // Hist name snipped
391 TString rangeHN = "hrg_";
392 rangeHN += hBarcode;
393 // Full histogram
394 rangeHist += rangeHN;
395 rangeHist += handle.rangeMaxStr;
396
397 // Do the drawing
398 tree.Draw(rangeHist.Data(), handle.rangeCutStr.c_str(), "", peakEntries);
399 handle.rangeHist = dynamic_cast<TH1F*>(gDirectory->Get(rangeHN.Data()));
400 if (handle.rangeHist != nullptr) {
401 float rms = handle.rangeHist->GetRMS();
402 handle.range = {-rms, rms};
403 }
404}
405
416template <typename dir_t, typename tree_t>
417void estimateIntegerRange(SingleHandle& handle, dir_t& directory, tree_t& tree,
418 unsigned long peakEntries, unsigned int startBins,
419 unsigned int addBins, unsigned int hBarcode) {
420 // Change into the Directory
421 directory.cd();
422 TString rangeHist = handle.rangeDrawStr;
423 rangeHist += ">>";
424 // Hist name snipped
425 TString rangeHN = "hrg_";
426 rangeHN += hBarcode;
427 // Full histogram
428 rangeHist += rangeHN;
429 rangeHist += "(";
430 rangeHist += startBins;
431 rangeHist += ",-0.5,";
432 rangeHist += static_cast<float>(startBins - 0.5);
433 rangeHist += ")";
434
435 unsigned int nBins = startBins;
436 // Do the drawing
437 tree.Draw(rangeHist.Data(), "", "", peakEntries);
438 auto rhist = dynamic_cast<TH1F*>(gDirectory->Get(rangeHN.Data()));
439 if (rhist != nullptr) {
440 for (unsigned int ib = 1; ib <= startBins; ++ib) {
441 if (rhist->GetBinContent(ib) > 0.) {
442 nBins = ib;
443 }
444 }
445 handle.bins = (nBins + addBins);
446 handle.range = {-0.5, static_cast<float>(handle.bins - 0.5)};
447 return;
448 }
449 handle.bins = (startBins);
450 handle.range = {-0.5, static_cast<float>(handle.bins - 0.5)};
451}
452
459void bookHistograms(ResidualPullHandle& handle, float pullRange,
460 unsigned int hBins, unsigned int hBarcode) {
461 // Residual histogram
462 TString rName = std::string("res_") + handle.tag;
463 rName += hBarcode;
464 handle.residualHist =
465 new TH1F(rName.Data(), handle.tag.c_str(), hBins,
466 pullRange * handle.range[0], pullRange * handle.range[1]);
467 std::string xAxisTitle =
468 handle.residualStr + std::string(" ") + handle.residualUnit;
469 handle.residualHist->GetXaxis()->SetTitle(xAxisTitle.c_str());
470 handle.residualHist->GetYaxis()->SetTitle("Entries");
471
472 // Pull histogram
473 TString pName = std::string("pull_") + handle.tag;
474 pName += hBarcode;
475 handle.pullHist =
476 new TH1F(pName.Data(), (std::string("pull ") + handle.tag).c_str(), hBins,
477 -pullRange, pullRange);
478 xAxisTitle = std::string("(") + handle.residualStr + std::string(")/") +
479 handle.errorStr;
480 handle.pullHist->GetXaxis()->SetTitle(xAxisTitle.c_str());
481 handle.pullHist->GetYaxis()->SetTitle("Entries");
482}
483
492template <typename tree_t>
493unsigned long estimateEntries(const tree_t& tree,
494 unsigned long configuredEntries) {
495 unsigned long entries = static_cast<unsigned long>(tree.GetEntries());
496 if (configuredEntries > 0 && configuredEntries < entries) {
497 entries = configuredEntries;
498 }
499 return entries;
500}
This Struct is to accept all values - a placeholder.
This is a combined accept struct.
bool operator()(ULong64_t entry)
returns true if value is within range
This Struct is to accept a certain range from a TTree accessible value.
bool operator()(ULong64_t entry)
returns true if value is within range
This is a direct type accessor.
primitive_t operator()(ULong64_t entry)
Gives direct access to the underlying parameter.
primitive_one_t operator()(ULong64_t entry)
Gives direct access to the underlying parameter.
float operator()(ULong64_t entry)
This the dedicted pT residual accessor.
float operator()(ULong64_t entry)
float operator()(ULong64_t entry)
float operator()(ULong64_t entry)
A Parameter handle struct to deal with residuals and pulls.
std::function< bool(ULong64_t)> accept
The acceptance.
std::string residualStr
Title and names: residual.
std::function< float(ULong64_t)> error
The associated error accessor.
std::string rangeDrawStr
The rangeDrawStr draw string.
std::array< float, 2 > range
The range array.
std::string errorStr
Title and names: error.
std::function< float(ULong64_t)> value
Value function that allows to create combined parameters.
std::string tag
A tag name.
void fill(unsigned int entry)
Fill the entry.
This is a s.
std::function< float(ULong64_t)> value
Value function that allows to create combined parameters.
std::string label
A label name.
std::array< float, 2 > range
The range array.
std::string tag
A tag name.
void fill(unsigned int entry)
Fill the entry.
std::function< bool(ULong64_t)> accept
The acceptance.
unsigned int bins
The number of bins for the booking.