31#include "TObjString.h"
46AsgElectronChargeIDSelectorTool::AsgElectronChargeIDSelectorTool(
47 const std::string& myname)
51 declareProperty(
"WorkingPoint", m_WorkingPoint =
"",
"The Working Point");
54 "usePVContainer", m_usePVCont =
true,
"Whether to use the PV container");
56 "nPVdefault", m_nPVdefault = 0,
"The default number of PVs if not counted");
60 declareProperty(
"TrainingFile",
62 "The input ROOT file name holding training");
63 declareProperty(
"CutOnBDT", m_cutOnBDT = 0,
"Cut on BDT discriminant");
64 m_pid_name = myname.data();
84 std::string op_name =
"loose";
85 bool op_isUserSpecified =
false;
97 op_isUserSpecified =
true;
101 std::string display =
102 op_isUserSpecified ?
"user specified" :
"97% signal-eff";
104 <<
", which corresponds to " << display
105 <<
" working point.");
107 std::string TrainingFile;
112 if (TrainingFile.empty()) {
114 return StatusCode::FAILURE;
116 ATH_MSG_INFO(
"trainingfile loaded from: " << TrainingFile);
121 return StatusCode::FAILURE;
125 std::unique_ptr<TFile> bdtfile(TFile::Open(TrainingFile.data(),
"READ"));
127 ATH_MSG_ERROR(
"Input file found to be empty!! " << TrainingFile);
128 return StatusCode::FAILURE;
130 TIter next(bdtfile->GetListOfKeys());
132 while ((key = (TKey*)next())) {
133 TClass* clas = gROOT->GetClass(key->GetClassName());
134 if (!clas->InheritsFrom(
"TDirectoryFile"))
136 TDirectory* td = (TDirectoryFile*)key->ReadObj();
137 std::string dirName = td->GetName();
138 if (dirName.find(
m_pid_name) != std::string::npos) {
139 std::string foldconf = dirName.substr(dirName.rfind(
'_') + 1);
140 std::string s_nfold = foldconf.substr(foldconf.find(
'o') + 1);
141 nfold = atoi(s_nfold.data());
149 const TString toaPath = Form(
"ECIDS_%s_0o%d/variables",
m_pid_name.Data(),nfold);
150 const TObjArray* toa = bdtfile->Get<TObjArray>(toaPath);
152 const TObjString* tos =
dynamic_cast<const TObjString*
>(toa->At(0));
154 std::istringstream commaSepVars(tos->GetString().Data());
155 ATH_MSG_INFO(
"Variables for ECIDS " << commaSepVars.str());
157 while (std::getline(commaSepVars,inVar,
',')) {
165 << bdtfile->GetName() <<
" " << toaPath);
168 for (
unsigned i_fold = 0; i_fold < nfold; i_fold++) {
182 return StatusCode::SUCCESS;
236 "\t AsgElectronChargeIDSelectorTool::calculate( &ctx, *eg, mu= "
237 << (&ctx) <<
", " << eg <<
", " << mu <<
" )");
250 const double energy = cluster->
e();
251 const float eta = cluster->
etaBE(2);
252 if (fabs(
eta) > 300.0) {
258 if (eg->trackParticle())
259 et = (cosh(eg->trackParticle()->eta()) != 0.)
260 ? energy / cosh(eg->trackParticle()->eta())
263 et = (cosh(
eta) != 0.) ? energy / cosh(
eta) : 0.;
267 float trackqoverp(0.0);
268 float trackqoverpsig(0.0);
271 float trackchi2(0.0);
272 float avgCharge_SCTw(0.0);
282 float deltaPhi1 = 0, deltaPhi2 = 0;
283 float deltaPhiFromLM = 0;
284 float deltaPhiRescaled2 = 0;
290 bool allFound =
true;
294 trackqoverp = t->qOverP();
306 trackchi2 = t->chiSquared();
308 phi0 = t->phi() + (d0 >= 0 ?
M_PI / 2 : -
M_PI / 2);
309 TVector2 d0_direction;
310 d0_direction.SetMagPhi(fabs(d0), phi0);
311 float inner_product =
312 el_cluster.X() * d0_direction.X() + el_cluster.Y() * d0_direction.Y();
313 lifeSign = inner_product >= 0 ? 1 : -1;
315 EoverP = energy * fabs(t->qOverP());
320 float vard0 = t->definingParametersCovMatrix()(0, 0);
322 d0sigma = sqrtf(vard0);
328 for (
unsigned TPit = 0; TPit < eg->nTrackParticles(); TPit++) {
329 uint8_t temp_NSCTHits;
330 if (eg->trackParticle(TPit)) {
331 eg->trackParticle(TPit)->summaryValue(temp_NSCTHits,
334 SCT += temp_NSCTHits;
335 charge += temp_NSCTHits * eg->trackParticle(TPit)->charge();
338 "Assigning #SCT-hits= 0!!! ");
340 avgCharge_SCTw =
SCT != 0 ? eg->charge() *
charge /
SCT : 0;
342 const std::vector<float>& cov = t->definingParametersCovMatrixVec();
343 trackqoverpsig = cov[14];
350 double fEpsilon = 1.0e-30;
351 double pid_tmp = TRT_PID;
353 pid_tmp = 1.0 - 1.0e-15;
354 else if (pid_tmp <= fEpsilon)
362 double refittedTrack_LMqoverp =
363 t->charge() / sqrt(std::pow(t->parameterPX(
index), 2) +
364 std::pow(t->parameterPY(
index), 2) +
365 std::pow(t->parameterPZ(
index), 2));
367 dpOverp = 1 - trackqoverp / (refittedTrack_LMqoverp);
386 allFound = allFound &&
387 eg->trackCaloMatchValue(deltaPhiRescaled2,
393 allFound = allFound && eg->trackCaloMatchValue(
402 allFound = allFound && eg->trackCaloMatchValue(
410 eg->trackCaloMatchValue(
421 ATH_MSG_FATAL(
"Missing input variable for ECIDS BDT calculation");
424 if (
evtStore()->retrieve(eventInfo,
"EventInfo").isFailure())
432 std::vector<float> v_inputs;
435 v_inputs.push_back(
et);
437 v_inputs.push_back(
eta);
438 if (var ==
"abs_eta")
439 v_inputs.push_back(fabs(
eta));
440 if (var ==
"avgCharge_SCTw")
441 v_inputs.push_back(avgCharge_SCTw);
443 v_inputs.push_back(d0);
445 v_inputs.push_back(lifeSign * d0);
447 v_inputs.push_back(
charge * d0);
449 v_inputs.push_back(EoverP);
450 if (var ==
"deltaphi1")
451 v_inputs.push_back(deltaPhi1);
452 if (var ==
"deltaphiRes")
453 v_inputs.push_back(deltaPhiRescaled2);
455 v_inputs.push_back(Rphi);
456 if (var ==
"qoverpSig")
457 v_inputs.push_back(trackqoverpsig);
458 if (var ==
"nSctHits")
459 v_inputs.push_back(nSCT);
460 if (var ==
"z0sinTheta")
461 v_inputs.push_back(z0 * sin(
theta));
463 v_inputs.push_back(d0sigma);
465 v_inputs.push_back(d0 / d0sigma);
466 if (var ==
"deltaphi2")
467 v_inputs.push_back(deltaPhi2);
468 if (var ==
"chi2oftrackfit")
469 v_inputs.push_back(trackchi2);
470 if (var ==
"deltaPoverP")
471 v_inputs.push_back(dpOverp);
472 if (var ==
"deltaDeltaPhiFirstAndLM")
473 v_inputs.push_back(deltaPhi2 - deltaPhiFromLM);
479 <<
"xAOD variables: pt = " <<
et
480 <<
",\t isRequested= "
484 <<
"\t\t xAOD variables: eta = " <<
eta
485 <<
",\t isRequested= "
489 <<
"\t\t xAOD variables: abs_eta = " << fabs(
eta)
490 <<
",\t isRequested= "
494 <<
"\t\t xAOD variables: avgCharge_SCTw = " << avgCharge_SCTw
495 <<
",\t isRequested= "
499 <<
"\t\t xAOD variables: d0 = " << d0
500 <<
",\t isRequested= "
504 <<
"\t\t xAOD variables: ld0 = " << lifeSign * d0
505 <<
",\t isRequested= "
509 <<
"\t\t xAOD variables: cd0 = " <<
charge * d0
510 <<
",\t isRequested= "
514 <<
"\t\t xAOD variables: EoverP = " << EoverP
515 <<
",\t isRequested= "
519 <<
"\t\t xAOD variables: deltaphi1 = " << deltaPhi1
520 <<
",\t isRequested= "
524 <<
"\t\t xAOD variables: deltaphiRes = " << deltaPhiRescaled2
525 <<
",\t isRequested= "
529 <<
"\t\t xAOD variables: Rphi = " << Rphi
530 <<
",\t isRequested= "
534 <<
"\t\t xAOD variables: qoverpSig = " << trackqoverpsig
535 <<
",\t isRequested= "
539 <<
"\t\t xAOD variables: nSctHits = " <<
unsigned(nSCT)
540 <<
",\t isRequested= "
544 <<
"\t\t xAOD variables: z0sinTheta = " << z0 * sin(
theta)
545 <<
",\t isRequested= "
549 <<
"\t\t xAOD variables: d0Err = " << d0sigma
550 <<
",\t isRequested= "
554 <<
"\t\t xAOD variables: d0Sig = " << d0 / d0sigma
555 <<
",\t isRequested= "
559 <<
"\t\t xAOD variables: deltaphi2 = " << deltaPhi2
560 <<
",\t isRequested= "
564 <<
"\t\t xAOD variables: chi2oftrackfit = " << trackchi2
565 <<
",\t isRequested= "
569 <<
"\t\t xAOD variables: deltaPoverP = " << dpOverp
570 <<
",\t isRequested= "
574 <<
"\t\t xAOD variables: deltaDeltaPhiFirstandLM = "
575 << deltaPhi2 - deltaPhiFromLM <<
",\t isRequested= "
580 <<
"\t\t xAOD variables: AllFound = " << allFound);
592 double bdt_output =
m_v_bdts.at(bdt_index)->GetGradBoostMVA(v_inputs);
617 return accept(Gaudi::Hive::currentContext(), part);
650 unsigned int nVtx(0);
654 <<
" container, returning default nVtx");
657 for (
const auto *vxcand : *vtxCont) {
658 if (vxcand->nTrackParticles() >= 2)
Scalar eta() const
pseudorapidity method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
static const Attributes_t empty
ServiceHandle< StoreGateSvc > & evtStore()
Simplified Boosted Regression Tree, support TMVA, lgbm, and xgboost.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer)
void clear()
Clear all bits.
float phiBE(const unsigned layer) const
Get the phi in one layer of the EM Calo.
virtual double e() const
The total energy of the particle.
float energyBE(const unsigned layer) const
Get the energy in one layer of the EM Calo.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
uint64_t eventNumber() const
The current event's event number.
Class providing the definition of the 4-vector interface.
static std::string treename
@ Electron
The object is an electron.
@ deltaPhiFromLastMeasurement
difference between the cluster phi (sampling 2) and the eta of the track extrapolated from the last m...
@ deltaPhi1
difference between the cluster eta (1st sampling) and the eta of the track extrapolated to the 1st sa...
@ deltaPhiRescaled2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
@ deltaPhi2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
EventInfo_v1 EventInfo
Definition of the latest event info version.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Egamma_v1 Egamma
Definition of the current "egamma version".
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".
@ LastMeasurement
Parameter defined at the position of the last measurement.
Extra patterns decribing particle interation process.