ATLAS Offline Software
Loading...
Searching...
No Matches
TElectronLikelihoodTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
6#include "TFile.h" // for TFile
7#include "TH1.h" // for TH1F
8#include "TROOT.h"
9#include "TString.h" // for TString
10#include "TSystem.h"
11#include <algorithm> // for min
12#include <cmath>
13#include <format>
14
16
21
22//=============================================================================
23// Constructor
24//=============================================================================
25
26//----------------------------------------------------------------------------------------
56
57StatusCode
59{
60 ATH_MSG_DEBUG("TElectronLikelihoodTool initialize.");
61
62 // use an int as a StatusCode
63 StatusCode sc(StatusCode::SUCCESS);
64
65 // Check that all needed variables are setup
66 if (m_pdfFileName.empty()) {
67 ATH_MSG_WARNING("You need to specify the input PDF file name before you "
68 "call initialize() with "
69 "setPDFFileName('your/file/name.root') ");
70 sc = StatusCode::FAILURE;
71 }
72
73 unsigned int number_of_expected_bin_combinedLH;
75 number_of_expected_bin_combinedLH = s_fnDiscEtBinsOneExtra * s_fnEtaBins;
76 else
77 number_of_expected_bin_combinedLH = s_fnDiscEtBins * s_fnEtaBins;
78 unsigned int number_of_expected_bin_combinedOther =
80
81 if (m_cutLikelihood.size() != number_of_expected_bin_combinedLH) {
82 ATH_MSG_ERROR("Configuration issue : cutLikelihood expected size "
83 << number_of_expected_bin_combinedLH << " input size "
84 << m_cutLikelihood.size());
85 sc = StatusCode::FAILURE;
86 }
87
90 number_of_expected_bin_combinedLH) {
92 "Configuration issue : DiscHardCutForPileupTransform expected size "
93 << number_of_expected_bin_combinedLH << " input size "
95 sc = StatusCode::FAILURE;
96 }
97 }
100 number_of_expected_bin_combinedLH) {
101 ATH_MSG_ERROR("Configuration issue : "
102 "DiscHardCutSlopeForPileupTransform expected size "
103 << number_of_expected_bin_combinedLH << " input size "
105 sc = StatusCode::FAILURE;
106 }
107 }
108 if (!m_discLooseForPileupTransform.empty()) {
110 number_of_expected_bin_combinedLH) {
112 "Configuration issue : DiscLooseForPileupTransform expected size "
113 << number_of_expected_bin_combinedLH << " input size "
115 sc = StatusCode::FAILURE;
116 }
117 }
118
119 // d0 cut
120 if (!m_cutA0.empty()) {
121 if (m_cutA0.size() != number_of_expected_bin_combinedOther) {
122 ATH_MSG_ERROR("Configuration issue : CutA0 expected size "
123 << number_of_expected_bin_combinedOther << " input size "
124 << m_cutA0.size());
125 sc = StatusCode::FAILURE;
126 }
127 }
128
129 // deltaEta cut
130 if (!m_cutDeltaEta.empty()) {
131 if (m_cutDeltaEta.size() != number_of_expected_bin_combinedOther) {
132 ATH_MSG_ERROR("Configuration issue : CutDeltaEta expected size "
133 << number_of_expected_bin_combinedOther << " input size "
134 << m_cutDeltaEta.size());
135 sc = StatusCode::FAILURE;
136 }
137 }
138
139 // deltaPhiRes cut
140 if (!m_cutDeltaPhiRes.empty()) {
141 if (m_cutDeltaPhiRes.size() != number_of_expected_bin_combinedOther) {
142 ATH_MSG_ERROR("Configuration issue : CutDeltaPhiRes expected size "
143 << number_of_expected_bin_combinedOther << " input size "
144 << m_cutDeltaPhiRes.size());
145 sc = StatusCode::FAILURE;
146 }
147 }
148 if (sc == StatusCode::FAILURE) {
150 "Could NOT initialize! Please fix the errors mentioned above...");
151 return sc;
152 }
153
154 // --------------------------------------------------------------------------
155 // Register the cuts and check that the registration worked:
156 // NOTE: THE ORDER IS IMPORTANT!!! Cut0 corresponds to bit 0, Cut1 to bit
157 // 1,... Cut position for the kineatic pre-selection
158 m_cutPosition_kinematic = m_acceptInfo.addCut("kinematic", "pass kinematic");
159 if (m_cutPosition_kinematic < 0) {
160 sc = StatusCode::FAILURE;
161 }
162
163 // NSilicon
164 m_cutPosition_NSilicon = m_acceptInfo.addCut("NSilicon", "pass NSilicon");
165 if (m_cutPosition_NSilicon < 0) {
166 sc = StatusCode::FAILURE;
167 }
168
169 // NPixel
170 m_cutPosition_NPixel = m_acceptInfo.addCut("NPixel", "pass NPixel");
171 if (m_cutPosition_NPixel < 0) {
172 sc = StatusCode::FAILURE;
173 }
174
175 // NBlayer
176 m_cutPosition_NBlayer = m_acceptInfo.addCut("NBlayer", "pass NBlayer");
177 if (m_cutPosition_NBlayer < 0) {
178 sc = StatusCode::FAILURE;
179 }
180
181 // Ambiguity
182 m_cutPosition_ambiguity = m_acceptInfo.addCut("ambiguity", "pass ambiguity");
183 if (m_cutPosition_ambiguity < 0) {
184 sc = StatusCode::FAILURE;
185 }
186
187 // Cut position for the likelihood selection - DO NOT CHANGE ORDER!
188 m_cutPosition_LH = m_acceptInfo.addCut("passLH", "pass Likelihood");
189 if (m_cutPosition_LH < 0) {
190 sc = StatusCode::FAILURE;
191 }
192
193 // D0
195 m_acceptInfo.addCut("TrackA0", "A0 (aka d0) wrt beam spot < Cut");
196 if (m_cutPositionTrackA0 < 0) {
197 sc = StatusCode::FAILURE;
198 }
199
200 // deltaeta
202 "TrackMatchEta", "Track match deta in 1st sampling < Cut");
204 sc = StatusCode::FAILURE;
205 }
206
207 // deltaphi
209 "TrackMatchPhiRes", "Track match dphi in 2nd sampling, rescaled < Cut");
211 sc = StatusCode::FAILURE;
212 }
213
214 // Wstot
216 "WstotAtHighET", "Above HighETBinThreshold, Wstot < Cut");
218 sc = StatusCode::FAILURE;
219 }
220
221 // EoverP
223 "EoverPAtHighET", "Above HighETBinThreshold, EoverP < Cut");
225 sc = StatusCode::FAILURE;
226 }
227
228 // Check that we got everything OK
229 if (sc == StatusCode::FAILURE) {
231 "! Something went wrong with the setup of the decision objects...");
232 return sc;
233 }
234
235 // ----------------------------------
236 // Get the correct bit mask for the current likelihood operating point
238
239 //----------File/Histo operation------------------------------------
240 // Load the ROOT file containing the PDFs
241 TString tmpString(m_pdfFileName);
242 gSystem->ExpandPathName(tmpString);
243 std::string fname(tmpString.Data());
244 auto pdfFile = std::unique_ptr<TFile>(TFile::Open(fname.c_str(), "READ"));
245 // Check that we could load the ROOT file
246 if (!pdfFile) {
247 ATH_MSG_ERROR(" No ROOT file found here: " << m_pdfFileName);
248 return StatusCode::FAILURE;
249 }
250
251 // Load the histograms
252 for (unsigned int varIndex = 0; varIndex < s_fnVariables; varIndex++) {
253 const std::string& vstr = s_fVariables[varIndex];
254 // Skip the loading of PDFs for variables we don't care about for this
255 // operating point. If the string is empty (which is true in the default
256 // 2012 case), load all of them.
257 if (m_variableNames.find(vstr) == std::string::npos &&
258 !m_variableNames.empty()) {
259 continue;
260 }
261 loadVarHistograms(vstr, pdfFile.get(), varIndex);
262 }
263
264 // TFile close does not free the memory
265 pdfFile->Close();
266 //----------End File/Histo operation------------------------------------
267
268 ATH_MSG_DEBUG("Initialization complete for a LH tool with these specs:"
269 << "\n - pdfFileName : "
271 << "\n - Variable bitmask : "
273
274 ATH_MSG_DEBUG("\n - VariableNames : "
276 << "\n - (bool)CutBL (yes/no) : "
277 << (!m_cutBL.empty() ? "yes" : "no")
278 << "\n - (bool)CutPi (yes/no) : "
279 << (!m_cutPi.empty() ? "yes" : "no")
280 << "\n - (bool)CutSi (yes/no) : "
281 << (!m_cutSi.empty() ? "yes" : "no")
282 << "\n - (bool)CutAmbiguity (yes/no) : "
283 << (!m_cutAmbiguity.empty() ? "yes" : "no")
284 << "\n - (bool)doRemoveF3AtHighEt (yes/no) : "
285 << (m_doRemoveF3AtHighEt ? "yes" : "no")
286 << "\n - (bool)doRemoveTRTPIDAtHighEt (yes/no) : "
287 << (m_doRemoveTRTPIDAtHighEt ? "yes" : "no")
288 << "\n - (bool)doSmoothBinInterpolation (yes/no) : "
289 << (m_doSmoothBinInterpolation ? "yes" : "no")
290 << "\n - (bool)useOneExtraHighETLHBin(yes/no) : "
291 << (m_useOneExtraHighETLHBin ? "yes" : "no")
292 << "\n - (double)HighETBinThreshold : "
294 << "\n - (bool)doPileupTransform (yes/no) : "
295 << (m_doPileupTransform ? "yes" : "no")
296 << "\n - (bool)doCentralityTransform (yes/no) : "
297 << (m_doCentralityTransform ? "yes" : "no")
298 << "\n - (bool)CutLikelihood (yes/no) : "
299 << (!m_cutLikelihood.empty() ? "yes" : "no")
300 << "\n - (bool)CutLikelihoodPileupCorrection (yes/no) : "
301 << (!m_cutLikelihoodPileupCorrection.empty() ? "yes" : "no")
302 << "\n - (bool)CutA0 (yes/no) : "
303 << (!m_cutA0.empty() ? "yes" : "no")
304 << "\n - (bool)CutDeltaEta (yes/no) : "
305 << (!m_cutDeltaEta.empty() ? "yes" : "no")
306 << "\n - (bool)CutDeltaPhiRes (yes/no) : "
307 << (!m_cutDeltaPhiRes.empty() ? "yes" : "no")
308 << "\n - (bool)CutWstotAtHighET (yes/no) : "
309 << (!m_cutWstotAtHighET.empty() ? "yes" : "no")
310 << "\n - (bool)CutEoverPAtHighET (yes/no) : "
311 << (!m_cutEoverPAtHighET.empty() ? "yes" : "no"));
312 return sc;
313}
314
315int
317 TFile* pdfFile,
318 unsigned int varIndex)
319{
320 for (unsigned int s_or_b = 0; s_or_b < 2; ++s_or_b) {
321 for (unsigned int ip = 0; ip < IP_BINS; ++ip) {
322 for (unsigned int et = 0; et < s_fnEtBinsHist; ++et) {
323 for (unsigned int eta = 0; eta < s_fnEtaBins; ++eta) {
324
325 std::string sig_bkg = (s_or_b == 0) ? "sig" : "bkg";
326 // Because eta bins in the root file don't match up exactly with cut
327 // menu definitions, the second eta bin is an exact copy of the first,
328 // and all subsequent eta bins are pushed back by one.
329 unsigned int eta_tmp = (eta > 0) ? eta - 1 : eta;
330 // The 7-10 GeV, crack bin uses the 10-15 Gev pdfs. WE DO NOT DO THIS
331 // ANYMORE! unsigned int et_tmp = (eta == 5 && et == 1) ? 1 : et;
332 unsigned int et_tmp = et;
333 std::string binname = getBinName(et_tmp, eta_tmp, ip, m_ipBinning);
334
335 if (((std::string(binname).find("2.37") != std::string::npos)) &&
336 (vstr.find("el_f3") != std::string::npos)) {
337 continue;
338 }
339
340 if (((std::string(binname).find("2.01") != std::string::npos) ||
341 (std::string(binname).find("2.37") != std::string::npos)) &&
342 (vstr.find("TRT") != std::string::npos)) {
343 continue;
344 }
345
346 const std::string pdfdir = std::format("{}/{}", vstr, sig_bkg);
347
348 std::string pdf = std::format("{}_{}_smoothed_hist_from_KDE_{}",
349 vstr, sig_bkg, binname);
350
351 std::string pdf_newname = std::format("{}_{}_{}_LHtool_copy_{}",
352 m_name, vstr, sig_bkg, binname);
353
354 if (!pdfFile->GetListOfKeys()->Contains(vstr.c_str())) {
355 ATH_MSG_INFO("Warning: skipping variable "
356 << vstr << " because the folder does not exist.");
357 return 1;
358 }
359 if (!((TDirectory*)pdfFile->Get(vstr.c_str()))
360 ->GetListOfKeys()
361 ->Contains(sig_bkg.c_str())) {
362 ATH_MSG_INFO("Warning: skipping variable "
363 << vstr << " because the folder does not exist.");
364 return 1;
365 }
366
367 // If the 0th et bin (4-7 GeV) histogram does not exist in the root
368 // file, then just use the 7-10 GeV bin histogram. This should
369 // preserve backward compatibility
370 if (et == 0 && !((TDirectory*)pdfFile->Get(pdfdir.c_str()))
371 ->GetListOfKeys()
372 ->Contains(pdf.c_str())) {
373 binname = getBinName(et_tmp + 1, eta_tmp, ip, m_ipBinning);
374
375 pdf = std::format("{}_{}_smoothed_hist_from_KDE_{}",
376 vstr, sig_bkg, binname);
377
378 pdf_newname = std::format("{}_{}_{}_LHtool_copy4GeV_{}",
379 m_name, vstr, sig_bkg, binname);
380 }
381 if (((TDirectory*)pdfFile->Get(pdfdir.c_str()))
382 ->GetListOfKeys()
383 ->Contains(pdf.c_str())) {
384 TH1F* hist = (TH1F*)(((TDirectory*)pdfFile->Get(pdfdir.c_str()))->Get(pdf.c_str()));
385 m_fPDFbins[s_or_b][ip][et][eta][varIndex] =
386 std::make_unique<EGSelectors::SafeTH1>(hist);
387 } else {
388 ATH_MSG_INFO("Warning: Object " << pdf << " does not exist.");
389 ATH_MSG_INFO("Skipping all other histograms with this variable.");
390 return 1;
391 }
392 }
393 }
394 }
395 }
396 return 1;
397}
398
401 double eta,
402 double eT,
403 int nSiHitsPlusDeadSensors,
404 int nPixHitsPlusDeadSensors,
405 bool passBLayerRequirement,
406 uint8_t ambiguityBit,
407 double d0,
408 double deltaEta,
409 double deltaphires,
410 double wstot,
411 double EoverP,
412 double ip) const
413{
415 vars.likelihood = likelihood;
416 vars.eta = eta;
417 vars.eT = eT;
418 vars.nSiHitsPlusDeadSensors = nSiHitsPlusDeadSensors;
419 vars.nPixHitsPlusDeadSensors = nPixHitsPlusDeadSensors;
420 vars.passBLayerRequirement = passBLayerRequirement;
421 vars.ambiguityBit = ambiguityBit;
422 vars.d0 = d0;
423 vars.deltaEta = deltaEta;
424 vars.deltaphires = deltaphires;
425 vars.wstot = wstot;
426 vars.EoverP = EoverP;
427 vars.ip = ip;
428
429 return accept(vars);
430}
431
432// This method calculates if the current electron passes the requested
433// likelihood cut
436 LikeEnum::LHAcceptVars_t& vars_struct) const
437{
438 // Setup return accept with AcceptInfo
439 asg::AcceptData acceptData(&m_acceptInfo);
440
441 // Set up the individual cuts
442 bool passKine(true);
443 bool passNSilicon(true);
444 bool passNPixel(true);
445 bool passNBlayer(true);
446 bool passAmbiguity(true);
447 bool passLH(true);
448 bool passTrackA0(true);
449 bool passDeltaEta(true);
450 bool passDeltaPhiRes(true);
451 bool passWstotAtHighET(true);
452 bool passEoverPAtHighET(true);
453
454 if (std::abs(vars_struct.eta) > 2.47) {
455 ATH_MSG_DEBUG("This electron is std::abs(eta)>2.47 Returning False.");
456 passKine = false;
457 }
458
459 unsigned int etbinLH = getLikelihoodEtDiscBin(vars_struct.eT, true);
460 unsigned int etbinOther = getLikelihoodEtDiscBin(vars_struct.eT, false);
461 unsigned int etabin = getLikelihoodEtaBin(vars_struct.eta);
462
463 // sanity
464 if (etbinLH >= s_fnDiscEtBinsOneExtra) {
465 ATH_MSG_WARNING("Cannot evaluate likelihood for Et "
466 << vars_struct.eT << ". Returning false..");
467 passKine = false;
468 }
469 // sanity
470 if (etbinOther >= s_fnDiscEtBins) {
471 ATH_MSG_WARNING("Cannot evaluate likelihood for Et "
472 << vars_struct.eT << ". Returning false..");
473 passKine = false;
474 }
475
476 // Return if the kinematic requirements are not fulfilled
477 acceptData.setCutResult(m_cutPosition_kinematic, passKine);
478 if (!passKine) {
479 return acceptData;
480 }
481
482 // ambiguity bit
483 if (!m_cutAmbiguity.empty()) {
486 m_cutAmbiguity[etabin])) {
487 ATH_MSG_DEBUG("Likelihood macro: ambiguity Bit Failed.");
488 passAmbiguity = false;
489 }
490 }
491
492 // blayer cut
493 if (!m_cutBL.empty()) {
494 if (m_cutBL[etabin] == 1 && !vars_struct.passBLayerRequirement) {
495 ATH_MSG_DEBUG("Likelihood macro: Blayer cut failed.");
496 passNBlayer = false;
497 }
498 }
499 // pixel cut
500 if (!m_cutPi.empty()) {
501 if (vars_struct.nPixHitsPlusDeadSensors < m_cutPi[etabin]) {
502 ATH_MSG_DEBUG("Likelihood macro: Pixels Failed.");
503 passNPixel = false;
504 }
505 }
506 // silicon cut
507 if (!m_cutSi.empty()) {
508 if (vars_struct.nSiHitsPlusDeadSensors < m_cutSi[etabin]) {
509 ATH_MSG_DEBUG("Likelihood macro: Silicon Failed.");
510 passNSilicon = false;
511 }
512 }
513
514 double cutDiscriminant;
515 unsigned int ibin_combinedLH =
516 etbinLH * s_fnEtaBins + etabin; // Must change if number of eta bins
517 // changes!. Also starts from 7-10 GeV bin.
518 unsigned int ibin_combinedOther =
519 etbinOther * s_fnEtaBins +
520 etabin; // Must change if number of eta bins changes!. Also
521 // starts from 7-10 GeV bin.
522
523 if (!m_cutLikelihood.empty()) {
524 // To protect against a binning mismatch, which should never happen
525 if (ibin_combinedLH >= m_cutLikelihood.size()) {
526 ATH_MSG_ERROR("The desired eta/pt bin "
527 << ibin_combinedLH
528 << " is outside of the range specified by the input"
529 << m_cutLikelihood.size() << "This should never happen!");
530 return acceptData;
531 }
532
534 cutDiscriminant = InterpolateCuts(
535 m_cutLikelihood, m_cutLikelihood4GeV, vars_struct.eT, vars_struct.eta);
538 cutDiscriminant +=
541 vars_struct.eT,
542 vars_struct.eta);
543 } else {
544 if (vars_struct.eT > 7000. || m_cutLikelihood4GeV.empty()) {
545 cutDiscriminant = m_cutLikelihood[ibin_combinedLH];
546 // If doPileupTransform, then correct the discriminant itself instead of
547 // the cut value
549 cutDiscriminant +=
550 vars_struct.ip * m_cutLikelihoodPileupCorrection[ibin_combinedLH];
551 }
552 } else {
553 cutDiscriminant = m_cutLikelihood4GeV[etabin];
554 if (!m_doPileupTransform &&
556 cutDiscriminant +=
557 vars_struct.ip * m_cutLikelihoodPileupCorrection4GeV[etabin];
558 }
559 }
560
561 // Determine if the calculated likelihood value passes the cut
562 ATH_MSG_DEBUG("Likelihood macro: Discriminant: ");
563 if (vars_struct.likelihood < cutDiscriminant) {
564 ATH_MSG_DEBUG("Likelihood macro: Disciminant Cut Failed.");
565 passLH = false;
566 }
567 }
568
569 // d0 cut
570 if (!m_cutA0.empty()) {
571 if (std::abs(vars_struct.d0) > m_cutA0[ibin_combinedOther]) {
572 ATH_MSG_DEBUG("Likelihood macro: D0 Failed.");
573 passTrackA0 = false;
574 }
575 }
576
577 // deltaEta cut
578 if (!m_cutDeltaEta.empty()) {
579 if (std::abs(vars_struct.deltaEta) > m_cutDeltaEta[ibin_combinedOther]) {
580 ATH_MSG_DEBUG("Likelihood macro: deltaEta Failed.");
581 passDeltaEta = false;
582 }
583 }
584
585 // deltaPhiRes cut
586 if (!m_cutDeltaPhiRes.empty()) {
587 if (std::abs(vars_struct.deltaphires) >
588 m_cutDeltaPhiRes[ibin_combinedOther]) {
589 ATH_MSG_DEBUG("Likelihood macro: deltaphires Failed.");
590 passDeltaPhiRes = false;
591 }
592 }
593
594 // Only do this above HighETBinThreshold [in GeV]
595 if (vars_struct.eT > m_highETBinThreshold * 1000) {
596 // wstot cut
597 if (!m_cutWstotAtHighET.empty()) {
598 if (std::abs(vars_struct.wstot) > m_cutWstotAtHighET[etabin]) {
599 ATH_MSG_DEBUG("Likelihood macro: wstot Failed.");
600 passWstotAtHighET = false;
601 }
602 }
603
604 // EoverP cut
605 if (!m_cutEoverPAtHighET.empty()) {
606 if (std::abs(vars_struct.EoverP) > m_cutEoverPAtHighET[etabin]) {
607 ATH_MSG_DEBUG("Likelihood macro: EoverP Failed.");
608 passEoverPAtHighET = false;
609 }
610 }
611 }
612
613 // Set the individual cut bits in the return object
614 acceptData.setCutResult(m_cutPosition_NSilicon, passNSilicon);
615 acceptData.setCutResult(m_cutPosition_NPixel, passNPixel);
616 acceptData.setCutResult(m_cutPosition_NBlayer, passNBlayer);
617 acceptData.setCutResult(m_cutPosition_ambiguity, passAmbiguity);
618 acceptData.setCutResult(m_cutPosition_LH, passLH);
619 acceptData.setCutResult(m_cutPositionTrackA0, passTrackA0);
620 acceptData.setCutResult(m_cutPositionTrackMatchEta, passDeltaEta);
621 acceptData.setCutResult(m_cutPositionTrackMatchPhiRes, passDeltaPhiRes);
622 acceptData.setCutResult(m_cutPositionWstotAtHighET, passWstotAtHighET);
623 acceptData.setCutResult(m_cutPositionEoverPAtHighET, passEoverPAtHighET);
624 return acceptData;
625}
626
627double
629 double eT,
630 double f3,
631 double rHad,
632 double rHad1,
633 double Reta,
634 double w2,
635 double f1,
636 double eratio,
637 double deltaEta,
638 double d0,
639 double d0sigma,
640 double rphi,
641 double deltaPoverP,
642 double deltaphires,
643 double TRT_PID,
644 double ip) const
645{
646
648
649 vars.eta = eta;
650 vars.eT = eT;
651 vars.f3 = f3;
652 vars.rHad = rHad;
653 vars.rHad1 = rHad1;
654 vars.Reta = Reta;
655 vars.w2 = w2;
656 vars.f1 = f1;
657 vars.eratio = eratio;
658 vars.deltaEta = deltaEta;
659 vars.d0 = d0;
660 vars.d0sigma = d0sigma;
661 vars.rphi = rphi;
662 vars.deltaPoverP = deltaPoverP;
663 vars.deltaphires = deltaphires;
664 vars.TRT_PID = TRT_PID;
665 vars.ip = ip;
666
667 return calculate(vars);
668}
669
670// The main public method to actually calculate the likelihood value
671double
673 LikeEnum::LHCalcVars_t& vars_struct) const
674{
675 // Reset the results to defaul values
676 double result = -999;
677
678 unsigned int etabin = getLikelihoodEtaBin(vars_struct.eta);
679 double rhad_corr;
680 if (etabin == 3 || etabin == 4) {
681 rhad_corr = vars_struct.rHad;
682 } else {
683 rhad_corr = vars_struct.rHad1;
684 }
685 double d0significance = vars_struct.d0sigma == 0
686 ? 0.
687 : std::abs(vars_struct.d0) / vars_struct.d0sigma;
688
689 std::vector<double> vec = {
690 d0significance, vars_struct.eratio, vars_struct.deltaEta,
691 vars_struct.f1, vars_struct.f3, vars_struct.Reta,
692 rhad_corr, vars_struct.rphi, vars_struct.d0,
693 vars_struct.w2, vars_struct.deltaPoverP, vars_struct.deltaphires,
694 vars_struct.TRT_PID
695 };
696 // Calculate the actual likelihood value and fill the return object
697 result = this->evaluateLikelihood(
698 vec, vars_struct.eT, vars_struct.eta, vars_struct.ip);
699
700 return result;
701}
702
703double
705 const std::vector<float>& varVector,
706 double et,
707 double eta,
708 double ip) const
709{
710 std::vector<double> vec;
711 vec.reserve(s_fnVariables);
712for (unsigned int var = 0; var < s_fnVariables; var++) {
713 vec.push_back(varVector[var]);
714 }
715 return evaluateLikelihood(vec, et, eta, ip);
716}
717
718double
720 const std::vector<double>& varVector,
721 double et,
722 double eta,
723 double ip) const
724{
725
726 const double GeV = 1000;
727 unsigned int etbin = getLikelihoodEtHistBin(et); // hist binning
728 unsigned int etabin = getLikelihoodEtaBin(eta);
729 unsigned int ipbin = getIpBin(ip);
730
731 ATH_MSG_DEBUG("et: " << et << " eta: " << eta << " etbin: " << etbin
732 << " etabin: " << etabin);
733
734 if (etbin >= s_fnEtBinsHist) {
735 ATH_MSG_WARNING("skipping etbin " << etbin << ", et " << et);
736 return -999.;
737 }
738 if (etabin >= s_fnEtaBins) {
739 ATH_MSG_WARNING("skipping etabin " << etabin << ", eta " << eta);
740 return -999.;
741 }
742
743 if (varVector.size() != s_fnVariables) {
744 ATH_MSG_WARNING("Error! Variable vector size mismatch! Check your vector!");
745 }
746
747 double SigmaS = 1.;
748 double SigmaB = 1.;
749
750 // define some string constants
751 const std::string TRT_string = "TRT";
752 const std::string el_f3_string = "el_f3";
753 const std::string el_TRT_PID_string = "el_TRT_PID";
754
755 for (unsigned int var = 0; var < s_fnVariables; var++) {
756
757 const std::string& varstr = s_fVariables[var];
758
759 // Skip variables that are masked off (not used) in the likelihood
760 if (!(m_variableBitMask & (0x1 << var))) {
761 continue;
762 }
763 // Don't use TRT for outer eta bins (2.01,2.37)
764 if (((etabin == 8) || (etabin == 9)) &&
765 (varstr.find(TRT_string) != std::string::npos)) {
766 continue;
767 }
768 // Don't use f3 for outer eta bin (2.37)
769 if ((etabin == 9) && (varstr.find(el_f3_string) != std::string::npos)) {
770 continue;
771 }
772 // Don't use f3 for high et (>80 GeV)
773 if (m_doRemoveF3AtHighEt && (et > 80 * GeV) &&
774 (varstr.find(el_f3_string) != std::string::npos)) {
775 continue;
776 }
777 // Don't use TRTPID for high et (>80 GeV)
778 if (m_doRemoveTRTPIDAtHighEt && (et > 80 * GeV) &&
779 (varstr.find(el_TRT_PID_string) != std::string::npos)) {
780 continue;
781 }
782 for (unsigned int s_or_b = 0; s_or_b < 2; s_or_b++) {
783
784 int bin =
785 m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->FindBin(varVector[var]);
786
787 double prob = 0;
789 prob = InterpolatePdfs(s_or_b, ipbin, et, eta, bin, var);
790 } else {
791 double integral =
792 double(m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->Integral());
793 if (integral == 0) {
794 ATH_MSG_WARNING("Error! PDF integral == 0!");
795 return -1.35;
796 }
797
798 prob =
799 double(
800 m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->GetBinContent(bin)) /
801 integral;
802 }
803
804 if (s_or_b == 0) {
805 SigmaS *= prob;
806 } else if (s_or_b == 1) {
807 SigmaB *= prob;
808 }
809 }
810 }
811
812 return TransformLikelihoodOutput(SigmaS, SigmaB, ip, et, eta);
813}
814
815// --------------------------------------------
816double
818 double pb,
819 double ip,
820 double et,
821 double eta) const
822{
823 // returns transformed or non-transformed output
824 // (Taken mostly from TMVA likelihood code)
825 double fEpsilon = 1e-99;
826 // If both signal and bkg are 0, we want it to fail.
827 if (ps < fEpsilon)
828 ps = 0;
829 if (pb < fEpsilon)
830 pb = fEpsilon;
831 double disc = ps / double(ps + pb);
832
833 if (disc >= 1.0) {
834 disc = 1. - 1.e-15;
835 } else if (disc <= 0.0) {
836 disc = fEpsilon;
837 }
838
839 double tau = 15.0;
840 disc = -std::log(1.0 / disc - 1.0) * (1. / double(tau));
841
842 // Linearly transform the discriminant as a function of pileup, rather than
843 // the old scheme of changing the cut value based on pileup. This is simpler
844 // for the tuning, as well as ensuring subsets / making discriminants more
845 // transparent. In the HI case, a quadratic centrality transform is applied
846 // instead.
848
849 // The variables used by the transform:
850 //
851 // - hard_cut_ref = extremely tight discriminant cut as reference to ensure
852 // pileup correction for looser menus is less than for tighter menus.
853 // - loose_ref = a loose menu with no pileup correction. Any tighter
854 // menu with same inputs will necessarily have pileup dependence built in
855 // - disc_max = max disc value for which pileup correction is desired.
856 // - pileup_max = max nvtx or mu for calculating the transform. Any larger
857 // pileup values will use this maximum value in the transform.
858
863 "Vectors needed for pileup-dependent transform not correctly filled! "
864 "Skipping the transform.");
865 return disc;
866 }
867
870 ATH_MSG_WARNING("Vectors needed for centrality-dependent transform not "
871 "correctly filled! "
872 "Skipping the transform.");
873 return disc;
874 }
875
876 unsigned int etabin = getLikelihoodEtaBin(eta);
877
878 double disc_hard_cut_ref = 0;
879 double disc_hard_cut_ref_slope = 0;
880 double disc_hard_cut_ref_quad =
881 0; // only used for heavy ion implementation of the LH
882 double disc_loose_ref = 0;
883 double disc_max = m_discMaxForPileupTransform;
884 double pileup_max = m_pileupMaxForPileupTransform;
885
889 et,
890 eta);
891 disc_hard_cut_ref_slope =
894 et,
895 eta);
897 disc_hard_cut_ref_quad =
900 et,
901 eta);
904 et,
905 eta);
906 } else {
907 // default situation, in the case where 4-7 GeV bin is not defined
908 if (et > 7000. || m_discHardCutForPileupTransform4GeV.empty()) {
909 unsigned int etfinebinLH = getLikelihoodEtDiscBin(et, true);
910 unsigned int ibin_combined = etfinebinLH * s_fnEtaBins + etabin;
911 disc_hard_cut_ref = m_discHardCutForPileupTransform[ibin_combined];
912 disc_hard_cut_ref_slope =
915 disc_hard_cut_ref_quad =
917 disc_loose_ref = m_discLooseForPileupTransform[ibin_combined];
918 } else {
922 ATH_MSG_WARNING("Vectors needed for pileup-dependent transform not "
923 "correctly filled for 4-7 GeV "
924 "bin! Skipping the transform.");
925 return disc;
926 }
929 ATH_MSG_WARNING("Vectors needed for centrality-dependent transform "
930 "not correctly filled for 4-7 "
931 "GeV bin! Skipping the transform.");
932 return disc;
933 }
934 disc_hard_cut_ref = m_discHardCutForPileupTransform4GeV[etabin];
935 disc_hard_cut_ref_slope =
938 disc_hard_cut_ref_quad =
940 disc_loose_ref = m_discLooseForPileupTransform4GeV[etabin];
941 }
942 }
943
944 double ip_for_corr =
945 std::min(ip, pileup_max); // turn off correction for values > pileup_max
946 double disc_hard_cut_ref_prime =
947 disc_hard_cut_ref + disc_hard_cut_ref_slope * ip_for_corr +
948 disc_hard_cut_ref_quad * ip_for_corr * ip_for_corr;
949
950 if (disc <= disc_loose_ref) {
951 // Below threshold for applying pileup correction
952 } else if (disc <= disc_hard_cut_ref_prime) {
953 // Between the loose and hard cut reference points for pileup correction
954 double denom = double(disc_hard_cut_ref_prime - disc_loose_ref);
955 if (denom < 0.001)
956 denom = 0.001;
957 disc = disc_loose_ref + (disc - disc_loose_ref) *
958 (disc_hard_cut_ref - disc_loose_ref) / denom;
959 } else if (disc_hard_cut_ref_prime < disc && disc <= disc_max) {
960 // Between the hard cut and max reference points for pileup correction
961 double denom = double(disc_max - disc_hard_cut_ref_prime);
962 if (denom < 0.001)
963 denom = 0.001;
964 disc = disc_hard_cut_ref + (disc - disc_hard_cut_ref_prime) *
965 (disc_max - disc_hard_cut_ref) / denom;
966 }
967 }
968
969 ATH_MSG_DEBUG("disc is " << disc);
970 return disc;
971}
972
973//---------------------------------------------------------------------------------------
974// Gets the IP bin
975unsigned int
977{
978 for (unsigned int ipBin = 0; ipBin < IP_BINS; ++ipBin) {
979 if (ip < s_fIpBounds[ipBin + 1])
980 return ipBin;
981 }
982 return 0;
983}
984
985//---------------------------------------------------------------------------------------
986// Gets the Eta bin [0-9] given the eta
987unsigned int
989{
990 const unsigned int nEtaBins = s_fnEtaBins;
991 const double etaBins[nEtaBins] = { 0.1, 0.6, 0.8, 1.15, 1.37,
992 1.52, 1.81, 2.01, 2.37, 2.47 };
993
994 for (unsigned int etaBin = 0; etaBin < nEtaBins; ++etaBin) {
995 if (std::abs(eta) < etaBins[etaBin])
996 return etaBin;
997 }
998
999 return 9;
1000}
1001//---------------------------------------------------------------------------------------
1002// Gets the histogram Et bin given the et (MeV) -- corrresponds to fnEtBinsHist
1003unsigned int
1005{
1006 const double GeV = 1000;
1007
1008 const unsigned int nEtBins = s_fnEtBinsHist;
1009 const double eTBins[nEtBins] = { 7 * GeV, 10 * GeV, 15 * GeV, 20 * GeV,
1010 30 * GeV, 40 * GeV, 50 * GeV };
1011
1012 for (unsigned int eTBin = 0; eTBin < nEtBins; ++eTBin) {
1013 if (eT < eTBins[eTBin]) {
1014 return eTBin;
1015 }
1016 }
1017
1018 return nEtBins - 1; // Return the last bin if > the last bin.
1019}
1020
1021//---------------------------------------------------------------------------------------
1022// Gets the Et bin [0-10] given the et (MeV)
1023unsigned int
1025 double eT,
1026 const bool isLHbinning) const
1027{
1028 const double GeV = 1000;
1029
1030 if (m_useOneExtraHighETLHBin && isLHbinning) {
1031 const unsigned int nEtBins = s_fnDiscEtBinsOneExtra;
1032 const double eTBins[nEtBins] = {
1033 10 * GeV, 15 * GeV, 20 * GeV,
1034 25 * GeV, 30 * GeV, 35 * GeV,
1035 40 * GeV, 45 * GeV, m_highETBinThreshold * GeV,
1036 6000 * GeV
1037 };
1038
1039 for (unsigned int eTBin = 0; eTBin < nEtBins; ++eTBin) {
1040 if (eT < eTBins[eTBin])
1041 return eTBin;
1042 }
1043
1044 return nEtBins - 1; // Return the last bin if > the last bin.
1045 }
1046
1047 const unsigned int nEtBins = s_fnDiscEtBins;
1048 const double eTBins[nEtBins] = { 10 * GeV, 15 * GeV, 20 * GeV,
1049 25 * GeV, 30 * GeV, 35 * GeV,
1050 40 * GeV, 45 * GeV, 50 * GeV };
1051
1052 for (unsigned int eTBin = 0; eTBin < nEtBins; ++eTBin) {
1053 if (eT < eTBins[eTBin])
1054 return eTBin;
1055 }
1056
1057 return nEtBins - 1; // Return the last bin if > the last bin.
1058}
1059
1060//---------------------------------------------------------------------------------------
1061// Gets the bin name. Given the HISTOGRAM binning (fnEtBinsHist)
1062std::string
1064 int etabin,
1065 int ipbin,
1066 const std::string& iptype)
1067{
1068 const double eta_bounds[9] = { 0.0, 0.6, 0.8, 1.15, 1.37, 1.52, 1.81, 2.01, 2.37 };
1069 const int et_bounds[s_fnEtBinsHist] = { 4, 7, 10, 15, 20, 30, 40 };
1070 if (!iptype.empty()) {
1071 return std::format("{}{}et{:02}eta{:.2f}",
1072 iptype, int(s_fIpBounds[ipbin]),
1073 et_bounds[etbin], eta_bounds[etabin]);
1074 } else {
1075 return std::format("et{}eta{:.2f}",
1076 et_bounds[etbin], eta_bounds[etabin]);
1077 }
1078}
1079//----------------------------------------------------------------------------------------
1080unsigned int
1082 const std::string& vars) const
1083{
1084 unsigned int mask = 0x0;
1085 ATH_MSG_DEBUG("Variables to be used: ");
1086 for (unsigned int var = 0; var < s_fnVariables; var++) {
1087 if (vars.find(s_fVariables[var]) != std::string::npos) {
1089 mask = mask | 0x1 << var;
1090 }
1091 }
1092 ATH_MSG_DEBUG("mask: " << mask);
1093 return mask;
1094}
1095
1096//----------------------------------------------------------------------------------------
1097// Note that this will only perform the cut interpolation up to ~45 GeV, so
1098// no smoothing is done above this for the high ET LH binning yet
1099double
1101 const std::vector<double>& cuts,
1102 const std::vector<double>& cuts_4gev,
1103 double et,
1104 double eta) const
1105{
1106
1107
1108 //get the value of the cut
1109 unsigned int etbinLH = getLikelihoodEtDiscBin(et, true);
1110 unsigned int etabin = getLikelihoodEtaBin(eta);
1111 unsigned int ibin_combinedLH = etbinLH * s_fnEtaBins + etabin;
1112 double cut = cuts.at(ibin_combinedLH);
1113
1114 //Special low pt cuts
1115 if (!cuts_4gev.empty()) {
1116 if (et < 7000.) {
1117 cut = cuts_4gev.at(etabin);
1118 }
1119 // Below 6 GeV we do not interpolate
1120 if (et < 6000) {
1121 return cut;
1122 }
1123 } else {// No special low Et cuts
1124 // and below 8500 we do not interpolate
1125 if (et < 8500.) {
1126 return cut;
1127 }
1128 }
1129 // We interpolate until 47500 (last bin)
1130 // size of array is s_fnDiscEtBins
1131 if (et > 47500. || !(etbinLH < s_fnDiscEtBins)) {
1132 return cut;
1133 }
1134 // Interpolate
1135 double bin_width = 5000.;
1136 if (7000. < et && et < 10000.) {
1137 bin_width = 3000.;
1138 }
1139 if (et < 7000.) {
1140 bin_width = 2000.;
1141 }
1142 const double GeV = 1000;
1143 const double eTBins[s_fnDiscEtBins] = { 8.5 * GeV, 12.5 * GeV, 17.5 * GeV,
1144 22.5 * GeV, 27.5 * GeV, 32.5 * GeV,
1145 37.5 * GeV, 42.5 * GeV, 47.5 * GeV };
1146 double bin_center = eTBins[etbinLH];
1147 if (et > bin_center) {
1148 double cut_next = cut;
1149 if (etbinLH + 1 <= 8)
1150 cut_next = cuts.at((etbinLH + 1) * s_fnEtaBins + etabin);
1151 return cut + (cut_next - cut) * (et - bin_center) / (bin_width);
1152 }
1153 // or else if et < bin_center :
1154 double cut_before = cut;
1155 if (etbinLH >= 1) {
1156 cut_before = cuts.at((etbinLH - 1) * s_fnEtaBins + etabin);
1157 } else if (etbinLH == 0 && !cuts_4gev.empty()) {
1158 cut_before = cuts_4gev.at(etabin);
1159 }
1160
1161 return cut - (cut - cut_before) * (bin_center - et) / (bin_width);
1162}
1163
1164//----------------------------------------------------------------------------------------
1165// Note that this will only perform the PDF interpolation up to ~45 GeV, so
1166// no smoothing is done above this for the high ET LH binning yet
1167double
1169 unsigned int ipbin,
1170 double et,
1171 double eta,
1172 int bin,
1173 unsigned int var) const
1174{
1175 // histograms exist for the following bins: 4, 7, 10, 15, 20, 30, 40.
1176 // Interpolation between histograms must follow fairly closely the
1177 // interpolation scheme between cuts - so be careful!
1178 int etbin = getLikelihoodEtHistBin(et); // hist binning
1179 int etabin = getLikelihoodEtaBin(eta);
1180 double integral =
1181 double(m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->Integral());
1182 double prob =
1183 double(m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->GetBinContent(bin)) /
1184 integral;
1185
1186 int Nbins = m_fPDFbins[s_or_b][ipbin][etbin][etabin][var]->GetNbinsX();
1187 if (et > 42500.) {
1188 return prob; // interpolation stops here.
1189 }
1190 if (et < 6000.) {
1191 return prob; // interpolation stops here.
1192 }
1193 if (22500. < et && et < 27500.) {
1194 return prob; // region of non-interpolation for pdfs
1195 }
1196 if (32500. < et && et < 37500.) {
1197 return prob; // region of non-interpolation for pdfs
1198 }
1199 double bin_width = 5000.;
1200 if (7000. < et && et < 10000.) {
1201 bin_width = 3000.;
1202 }
1203 if (et < 7000.) {
1204 bin_width = 2000.;
1205 }
1206 const double GeV = 1000;
1207 const double eTHistBins[s_fnEtBinsHist] = { 6. * GeV, 8.5 * GeV,
1208 12.5 * GeV, 17.5 * GeV,
1209 22.5 * GeV, 32.5 * GeV,
1210 42.5 * GeV };
1211 double bin_center = eTHistBins[etbin];
1212 if (etbin == 4 && et >= 27500.) {
1213 bin_center = 27500.; // special: interpolate starting from 27.5 here
1214 }
1215 if (etbin == 5 && et >= 37500.) {
1216 bin_center = 37500.; // special: interpolate starting from 37.5 here
1217 }
1218 if (et > bin_center) {
1219 double prob_next = prob;
1220 if (etbin + 1 <= 6) {
1221 // account for potential histogram bin inequalities
1222 int NbinsPlus =
1223 m_fPDFbins[s_or_b][ipbin][etbin + 1][etabin][var]->GetNbinsX();
1224 int binplus = bin;
1225 if (Nbins < NbinsPlus) {
1226 binplus = int(round(bin * (Nbins / NbinsPlus)));
1227 } else if (Nbins > NbinsPlus) {
1228 binplus = int(round(bin * (NbinsPlus / Nbins)));
1229 }
1230 // do interpolation
1231 double integral_next =
1232 double(m_fPDFbins[s_or_b][ipbin][etbin + 1][etabin][var]->Integral());
1233 prob_next =
1234 double(m_fPDFbins[s_or_b][ipbin][etbin + 1][etabin][var]->GetBinContent(
1235 binplus)) /
1236 integral_next;
1237 return prob + (prob_next - prob) * (et - bin_center) / (bin_width);
1238 }
1239 }
1240 // or else if et < bin_center :
1241 double prob_before = prob;
1242 if (etbin - 1 >= 0) {
1243 // account for potential histogram bin inequalities
1244 int NbinsMinus =
1245 m_fPDFbins[s_or_b][ipbin][etbin - 1][etabin][var]->GetNbinsX();
1246 int binminus = bin;
1247 if (Nbins < NbinsMinus) {
1248 binminus = int(round(bin * (Nbins / NbinsMinus)));
1249 } else if (Nbins > NbinsMinus) {
1250 binminus = int(round(bin * (NbinsMinus / Nbins)));
1251 }
1252 double integral_before =
1253 double(m_fPDFbins[s_or_b][ipbin][etbin - 1][etabin][var]->Integral());
1254 prob_before =
1255 double(m_fPDFbins[s_or_b][ipbin][etbin - 1][etabin][var]->GetBinContent(
1256 binminus)) /
1257 integral_before;
1258 }
1259 return prob - (prob - prob_before) * (bin_center - et) / (bin_width);
1260}
1261
1262//----------------------------------------------------------------------------------------
1263
1264// These are the variables availalble in the likelihood.
1265const std::string Root::TElectronLikelihoodTool::s_fVariables[s_fnVariables] = {
1266 "el_d0significance",
1267 "el_eratio",
1268 "el_deltaeta1",
1269 "el_f1",
1270 "el_f3",
1271 "el_reta",
1272 "el_rhad",
1273 "el_rphi",
1274 "el_trackd0pvunbiased",
1275 "el_weta2",
1276 "el_DeltaPoverP",
1277 "el_deltaphiRescaled",
1278 "el_TRT_PID"
1279};
Scalar eta() const
pseudorapidity method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
static Double_t sc
int m_cutPosition_NPixel
The position of the NPixel cut bit in the AcceptInfo return object.
int m_cutPositionTrackMatchEta
The position of the deltaeta cut bit in the AcceptInfo return object.
std::vector< double > m_discHardCutForPileupTransform
reference disc for very hard cut; used by pileup transform
std::unique_ptr< EGSelectors::SafeTH1 > m_fPDFbins[2][IP_BINS][s_fnEtBinsHist][s_fnEtaBins][s_fnVariables]
static constexpr unsigned int s_fnEtBinsHist
std::vector< double > m_discHardCutQuadForPileupTransform
reference quadratic apr on disc for very hard cut; used by centrality transform
static constexpr unsigned int s_fnDiscEtBinsOneExtra
static constexpr unsigned int s_fnDiscEtBins
static const std::string s_fVariables[s_fnVariables]
std::vector< double > m_discLooseForPileupTransform4GeV
reference disc for a pileup independent loose menu; used by pileup transform - 4-7 GeV
std::vector< double > m_discHardCutSlopeForPileupTransform
reference slope on disc for very hard cut; used by pileup transform
static unsigned int getIpBin(double ip)
std::vector< int > m_cutSi
cut min on precision hits
bool m_useOneExtraHighETLHBin
use one extra bin for high ET LH
double evaluateLikelihood(const std::vector< double > &varVector, double et, double eta, double ip=0) const
double m_highETBinThreshold
ET threshold for using high ET cuts and bin.
double InterpolateCuts(const std::vector< double > &cuts, const std::vector< double > &cuts_4gev, double et, double eta) const
std::vector< int > m_cutBL
cut min on b-layer hits
static constexpr double s_fIpBounds[IP_BINS+1]
asg::AcceptInfo m_acceptInfo
Accept info.
std::vector< int > m_cutAmbiguity
do cut on ambiguity bit
std::vector< int > m_cutPi
cut min on pixel hits
std::vector< double > m_discHardCutQuadForPileupTransform4GeV
reference quadratic par on disc for very hard cut; used by centrality transform - 4-7 GeV
int m_cutPosition_ambiguity
The position of the ambiguity cut bit in the AcceptInfo return object.
int m_cutPositionTrackA0
The position of the d0 cut bit in the AcceptInfo return object.
std::vector< double > m_cutLikelihoodPileupCorrection4GeV
pileup correction factor for cut on likelihood output, 4 GeV bin
std::vector< double > m_discLooseForPileupTransform
reference disc for a pileup independent loose menu; used by pileup transform
std::vector< double > m_cutA0
cut max on track d0 bit
asg::AcceptData accept(LikeEnum::LHAcceptVars_t &vars_struct) const
The main accept method: the actual cuts are applied here.
std::vector< double > m_discHardCutForPileupTransform4GeV
reference disc for very hard cut; used by pileup transform - 4-7 GeV
asg::AcceptData accept() const
Return dummy accept with only info.
double calculate(LikeEnum::LHCalcVars_t &vars_struct) const
int m_cutPosition_NBlayer
The position of the NBlayer cut bit in the AcceptInfo return object.
std::vector< double > m_cutEoverPAtHighET
do cut on EoverP above HighETBinThreshold bit
std::string m_variableNames
variables to use in the LH
static unsigned int getLikelihoodEtHistBin(double eT)
Coarse Et binning. Used for the likelihood pdfs.
bool m_doRemoveTRTPIDAtHighEt
do remove TRTPID variable from likelihood at high Et (>80 GeV)
std::vector< double > m_cutLikelihood4GeV
cut on likelihood output, 4 GeV bin
int m_cutPosition_kinematic
The position of the kinematic cut bit in the AcceptInfo return object.
std::vector< double > m_cutWstotAtHighET
do cut on wstot above HighETBinThreshold bit
std::string m_pdfFileName
Name of the pdf file.
int loadVarHistograms(const std::string &vstr, TFile *pdfFile, unsigned int varIndex)
Load the variable histograms from the pdf file.
static constexpr unsigned int s_fnVariables
static unsigned int getLikelihoodEtaBin(double eta)
Eta binning for pdfs and discriminant cuts.
double m_discMaxForPileupTransform
max discriminant for which pileup transform is to be used
int m_cutPosition_LH
The position of the likelihood cut bit in the AcceptInfo return object.
StatusCode initialize()
Initialize this class.
int m_cutPositionWstotAtHighET
The position of the high ET wstot cut bit in the AcceptInfo return object.
std::vector< double > m_cutDeltaPhiRes
do cut on delta phi bit
bool m_doRemoveF3AtHighEt
do remove f3 variable from likelihood at high Et (>80 GeV)
int m_cutPositionEoverPAtHighET
The position of the high ET EoverP cut bit in the AcceptInfo return object.
unsigned int m_variableBitMask
The bitmask corresponding to the variables in the likelihood.
bool m_doCentralityTransform
do centrality-dependent transform on discriminant value
std::vector< double > m_discHardCutSlopeForPileupTransform4GeV
reference slope on disc for very hard cut; used by pileup transform
std::vector< double > m_cutLikelihoodPileupCorrection
pileup correction factor for cut on likelihood output
double m_pileupMaxForPileupTransform
max nvtx or mu to be used in pileup transform
int m_cutPosition_NSilicon
The position of the NSilicon cut bit in the AcceptInfo return object.
double InterpolatePdfs(unsigned int s_or_b, unsigned int ipbin, double et, double eta, int bin, unsigned int var) const
static std::string getBinName(int etbin, int etabin, int ipbin, const std::string &iptype)
TElectronLikelihoodTool(const char *name="TElectronLikelihoodTool")
Standard constructor.
unsigned int getLikelihoodBitmask(const std::string &vars) const
double TransformLikelihoodOutput(double ps, double pb, double ip, double et, double eta) const
Apply a transform to zoom into the LH output peaks.
std::vector< double > m_cutLikelihood
cut on likelihood output
unsigned int getLikelihoodEtDiscBin(double eT, const bool isLHbinning) const
Fine Et binning. Used for the likelihood discriminant cuts.
static constexpr unsigned int s_fnEtaBins
int m_cutPositionTrackMatchPhiRes
The position of the deltaphi cut bit in the AcceptInfo return object.
bool m_doPileupTransform
do pileup-dependent transform on discriminant value
bool m_doSmoothBinInterpolation
do smooth interpolation between bins
std::vector< double > m_cutDeltaEta
do cut on delta eta bit
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer).
Definition AcceptData.h:135
AsgMessaging(const std::string &name)
Constructor with a name.
STL class.
double integral(TH1 *h)
Definition computils.cxx:59
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
bool passAmbiguity(xAOD::AmbiguityTool::AmbiguityType type, const uint16_t criterion)
return true if the ambiguity type is one of several that are stored in a bitmask
STL namespace.
Extra patterns decribing particle interation process.