21 #include "GaudiKernel/MsgStream.h"
22 #include "GaudiKernel/ITHistSvc.h"
39 ISvcLocator* pSvcLocator )
64 return StatusCode::SUCCESS;
81 if(! thisEventInfo.isValid()) {
83 return StatusCode::FAILURE;
87 auto writeTTrees =
Scalar(
"writeTTrees", isSimulation);
89 auto LB =
Scalar<int>(
"LB", thisEventInfo->lumiBlock());
93 auto avgLiveFrac =
Scalar(
"avgLiveFrac", lbAverageLivefraction(ctx));
95 auto avgIntPerXing =
Scalar(
"avgIntPerXing", lbAverageInteractionsPerCrossing(ctx));
102 auto evtWeight =
Scalar(
"evtWeight", 1.0);
104 evtWeight = thisEventInfo->mcEventWeight();
111 ATH_MSG_ERROR(
"No electron container" << m_ElectronContainerKey <<
" found in evtStore");
112 return StatusCode::FAILURE;
122 ATH_MSG_ERROR(
"evtStore() does not contain muon Collection with name "<< m_MuonContainerKey);
123 return StatusCode::FAILURE;
128 std::vector<const xAOD::Electron*> goodelectrons;
129 std::vector<const xAOD::Muon*> goodmuonsZ;
130 std::vector<const xAOD::Muon*> goodmuonsTP;
136 ATH_MSG_DEBUG(
"Collection with name " << m_VertexContainerKey <<
" with size " << vertices->
size() <<
" found in evtStore()");
137 for(
const auto vtx : * vertices) {
144 ATH_MSG_WARNING(
"No collection with name " << m_VertexContainerKey <<
" found in evtStore()");
149 std::vector<const xAOD::Electron*> allElectrons;
155 auto elegroup =
getGroup(
"electron");
157 for(
const auto electron : *elecTES) {
158 allElectrons.push_back(electron);
160 if(goodElectrons(electron, pVtx, ctx)){
163 auto ele_Et =
Scalar(
"ele_Et", electron->pt()/
GeV);
164 auto ele_Eta =
Scalar(
"ele_Eta", electron->eta());
165 auto ele_Phi =
Scalar(
"ele_Phi", electron->phi());
166 fill(elegroup, ele_Et, ele_Eta, ele_Phi, evtWeight);
167 goodelectrons.push_back(electron);
178 auto muTrk = (muon)->primaryTrackParticle();
181 ATH_MSG_WARNING(
"No muon track! " << thisEventInfo->runNumber() <<
" " << thisEventInfo->eventNumber());
204 if ((muon)->
pt() != 0.0){
208 ATH_MSG_DEBUG(
"Muon accept: " <<
static_cast<bool>(m_muonSelectionTool->accept(*muon)));
213 if (pVtx)
ATH_MSG_DEBUG(
"Muon z0sinth: " << std::abs((muTrk->z0()+muTrk->vz()-pVtx->
z())*
std::sin(muTrk->theta())) <<
" " << 0.5*
mm);
215 if (m_muonSelectionTool->accept(*muon) &&
216 ((muon)->pt() > 0.8*m_muonPtCut*
GeV) &&
218 std::abs(d0sig) < 3 &&
220 std::abs((muTrk->z0()+muTrk->vz()-pVtx->
z())*
std::sin(muTrk->theta())) < 0.5*
mm)
223 goodmuonsTP.push_back(muon);
224 if (((muon)->
pt() > m_muonPtCut*
GeV))
226 auto muon_Pt =
Scalar(
"muon_Pt", (muon)->
pt()/
GeV);
227 auto muon_Eta =
Scalar(
"muon_Eta", (muon)->eta());
228 auto muon_Phi =
Scalar(
"muon_Phi", (muon)->phi());
229 fill(muongroup, muon_Pt, muon_Eta, muon_Phi, evtWeight);
230 goodmuonsZ.push_back(muon);
237 doMuonTruthEff(goodmuonsZ, ctx);
240 for (
const auto iEle : allElectrons) {
241 Float_t
pt = iEle->pt();
243 if (!leadingAllEle ||
pt > leadingAllEle->
pt()){
244 subleadingAllEle = leadingAllEle;
245 leadingAllEle = iEle;
247 else if (!subleadingAllEle ||
pt > subleadingAllEle->
pt()){
248 subleadingAllEle = iEle;
254 doMuonLooseTP(goodmuonsTP, pVtx, ctx, isSimulation, writeTTrees, evtWeight);
255 doMuonInDetTP(goodmuonsTP, pVtx, ctx, isSimulation, writeTTrees, evtWeight);
256 doEleTP(leadingAllEle, subleadingAllEle, pVtx, ctx, writeTTrees, isSimulation, evtWeight);
257 doEleContainerTP(allElectrons, goodelectrons, ctx);
266 for (
const auto iEle : goodelectrons) {
267 Float_t
pt = iEle->pt();
269 if (! leadingEle ||
pt > leadingEle->
pt()) {
270 subleadingEle = leadingEle;
273 else if (! subleadingEle ||
pt > subleadingEle->
pt()) {
274 subleadingEle = iEle;
280 for (
const auto iMu : goodmuonsZ) {
281 Float_t
pt = iMu->pt();
282 if (! leadingMuZ ||
pt > leadingMuZ->
pt()) {
283 subleadingMuZ = leadingMuZ;
286 else if (! subleadingMuZ ||
pt > subleadingMuZ->
pt()) {
293 bool isZee = (goodelectrons.size() > 1);
294 bool isZmumu = (goodmuonsZ.size() > 1);
297 auto ZmumuGroup =
getGroup(
"Zmumu");
301 TLorentzVector Zee = (leadingEle->
p4() + subleadingEle->
p4());
304 bool passTrig =
true;
306 passTrig = trigChainsArePassed(m_Z_ee_trigger);
308 bool inMassWindow = (
mass > m_zCutLow*
GeV &&
mass < m_zCutHigh*
GeV);
311 (Zeecharge == 0) ? (osel =
true) : (ssel =
true);
313 fill(ZeeGroup, Zeecharge, evtWeight);
314 ATH_MSG_DEBUG(
"Found a Z to ee candidate! Mass = " <<
mass <<
", and charge = " << Zeecharge );
315 if(osel && passTrig){
318 auto phi1 =
Scalar(
"phi1", leadingEle->
phi());
319 auto phi2 =
Scalar(
"phi2", subleadingEle->
phi());
320 auto pT1 =
Scalar(
"pT1", leadingEle->
pt());
321 auto pT2 =
Scalar(
"pT2", subleadingEle->
pt());
322 auto isTruth =
Scalar(
"isTruth",
false);
325 isTruth = checkTruthElectron(leadingEle) && checkTruthElectron(subleadingEle);
327 fill(ZeeGroup,
mass,
eta1,
eta2, phi1, phi2, pT1, pT2, evtWeight, LB,
runNumber,
eventNumber, isTruth, writeTTrees, osel);
329 if(ssel && passTrig){
331 fill(ZeeGroup,
mass, LB, evtWeight, ssel);
335 doEleTriggerTP(leadingEle, subleadingEle, ctx, writeTTrees, evtWeight, osel, ssel);
341 TLorentzVector Zmumu = leadingMuZ->
p4() + subleadingMuZ->
p4();
343 auto Zmumucharge =
Scalar(
"Zmumucharge", leadingMuZ->
charge() + subleadingMuZ->
charge());
347 oktrig = trigChainsArePassed(m_Z_mm_trigger);
349 bool inMassWindow = (
mass > m_zCutLow*
GeV &&
mass < m_zCutHigh*
GeV);
352 (Zmumucharge == 0) ? (osmu =
true) : (ssmu =
true);
354 fill(ZmumuGroup, Zmumucharge, evtWeight);
355 ATH_MSG_DEBUG(
"Found a Z to mumu candidate! Mass = " <<
mass <<
", and charge = " << Zmumucharge);
359 auto phi1 =
Scalar(
"phi1", leadingMuZ->
phi());
360 auto phi2 =
Scalar(
"phi2", subleadingMuZ->
phi());
361 auto pT1 =
Scalar(
"pT1", leadingMuZ->
pt());
362 auto pT2 =
Scalar(
"pT2", subleadingMuZ->
pt());
363 auto isTruth =
Scalar(
"isTruth",
false);
365 isTruth = checkTruthMuon(leadingMuZ) && checkTruthMuon(subleadingMuZ);
367 fill(ZmumuGroup,
eta1,
eta2, phi1, phi2, pT1, pT2, isTruth, evtWeight, LB,
runNumber,
eventNumber,
mass, writeTTrees, osmu);
372 if(osmu && m_doTrigger){
373 doMuonTriggerTP(leadingMuZ, subleadingMuZ, ctx, isSimulation, writeTTrees, evtWeight);
377 fill(ZmumuGroup,
mass, LB, evtWeight, ssmu);
384 return StatusCode::SUCCESS;
393 auto group_EleTrigTP =
getGroup(
"EleTrigTP");
399 std::vector<const xAOD::Electron*>
electrons{el1, el2};
417 bool matched_tag =
false;
426 auto tagelp4(tagel->p4());
427 if (!matched_tag)
continue;
429 if (tagel == probeel) {
432 auto probeelp4(probeel->p4());
433 auto mass =
Scalar(
"mass", (tagelp4+probeelp4).M());
434 bool matched_probe =
false;
437 auto pT =
Scalar(
"pT", probeel->pt());
438 auto phi =
Scalar(
"phi", probeel->phi());
439 auto eta =
Scalar(
"eta", probeel->caloCluster()->etaBE(2));
442 auto LB =
Scalar(
"LB", thisEventInfo->lumiBlock());
443 auto mtype =
Scalar(
"mtype", -1000);
447 matched_probe =
true;
453 mtype = osel ? 0 : 1;
455 else if (!matched_probe) {
456 mtype = osel ? 2 : 3;
472 auto group_EleTP =
getGroup(
"EleTP");
475 if(leadingAllEle && subleadingAllEle){
483 auto Zeecharge =
Scalar(
"Zeecharge", (leadingAllEle->
charge() + subleadingAllEle->
charge()));
484 auto p1(leadingAllEle->
p4());
485 auto p2(subleadingAllEle->
p4());
489 bool subleadPassKinematics =
kinematicCuts(subleadingAllEle);
491 if(!leadingPassKinematics || !subleadPassKinematics)
return;
494 bool subleading_good =
goodElectrons(subleadingAllEle, pVtx, ctx);
500 bool leading_trig =
false;
508 bool subleading_trig =
false;
511 subleading_trig =
true;
516 bool opp_sign = (Zeecharge==0);
518 bool tag_good1 = (leadingAllEle->
passSelection(
"LHTight") && leading_trig && leading_good);
519 bool tag_good2 = (subleadingAllEle->
passSelection(
"LHTight") && subleading_trig && subleading_good);
528 auto phi =
Scalar(
"phi", -1000.0);
529 auto eta =
Scalar(
"eta", -1000.0);
533 auto LB =
Scalar(
"LB", -1000);
534 auto mtype =
Scalar(
"mtype", -1000);
538 pT = subleadingAllEle->
pt();
539 phi = subleadingAllEle->
phi();
544 LB = thisEventInfo->lumiBlock();
547 mtype = subleading_good ? 0 : 2;
548 if(subleading_antigood)
551 mtype = subleading_good ? 1 : 3;
552 if(subleading_antigood)
560 pT = leadingAllEle->
pt();
561 phi = leadingAllEle->
phi();
566 LB = thisEventInfo->lumiBlock();
592 auto group_EleContainerTP =
getGroup(
"EleContainerTP");
594 auto container_nomatch =
Scalar<bool>(
"container_nomatch",
false);
604 for (
const auto& tagEl : goodelectrons) {
614 auto tagElp4(tagEl->p4());
616 if (tagEl->passSelection(
"LHTight")){
617 for (
const auto& el2 : allElectrons){
619 auto probeElp4(el2->p4());
620 auto mass =
Scalar(
"mass", (tagElp4+probeElp4).M());
622 fill(group_EleContainerTP,
mass, pass_kine);
629 auto photonp4(photon->p4());
630 auto mass =
Scalar(
"mass", (tagElp4+photonp4).M());
635 for (
const auto& el2 : allElectrons){
637 bool passKinematics =
true;
639 passKinematics =
false;
640 if (std::abs(el2->caloCluster()->etaBE(2)) > 2.4)
641 passKinematics =
false;
642 if (std::abs(el2->caloCluster()->etaBE(2)) > 1.37 && std::abs(el2->caloCluster()->etaBE(2)) < 1.52)
643 passKinematics =
false;
646 if (!passKinematics || tagEl == el2 ||
deltaR < 0.1)
649 container_nomatch =
true;
650 fill(group_EleContainerTP,
mass, container_nomatch);
662 if(std::abs(particle->caloCluster()->etaBE(2)) > 2.4) isGood =
false;
664 if(std::abs(particle->caloCluster()->etaBE(2)) > 1.37 &&
665 std::abs(particle->caloCluster()->etaBE(2)) < 1.52) isGood =
false;
688 if ((electron_itr)->
pt() != 0.0){
693 auto elTrk = (electron_itr)->trackParticle();
715 std::abs(d0sig) < 5 &&
717 std::abs((elTrk->z0()+elTrk->vz()-pVtx->
z())*
std::sin(elTrk->theta())) < 0.5*
mm)
719 if (std::abs((electron_itr)->caloCluster()->
etaBE(2)) > 1.37 && std::abs((electron_itr)->caloCluster()->
etaBE(2)) < 1.52 ){
735 bool antiGood =
false;
746 if ((electron_itr)->
pt() != 0.0){
751 bool passIso =
false;
752 if(eleIso < 0.1) passIso =
true;
753 auto elTrk = (electron_itr)->trackParticle();
774 std::abs(d0sig) < 5 &&
776 std::abs((elTrk->z0()+elTrk->vz()-pVtx->
z())*
std::sin(elTrk->theta())) < 0.5*
mm)
778 if(std::abs((electron_itr)->caloCluster()->
etaBE(2)) > 1.37 && std::abs((electron_itr)->caloCluster()->
etaBE(2)) < 1.52){
782 if(!passID && !passIso) antiGood =
true;
799 auto group_MuonTriggerTP =
getGroup(
"MuonTriggerTP");
800 auto do_BCID =
Scalar(
"do_BCID",
false);
801 auto isOS =
Scalar(
"isOS",
false);
804 std::vector<const xAOD::Muon*> muons{mu1, mu2};
808 int truthMatching = 0;
809 for (
const auto mu: muons) {
814 if (truthMatching < 2)
return;
817 for (
const auto mu: muons) {
827 for (
const auto& tagmu : muons) {
828 bool matched_tag =
false;
835 auto tagmup4(tagmu->p4());
836 if (!matched_tag)
continue;
838 for (
const auto& probemu : muons) {
839 if (tagmu == probemu) {
842 auto probemup4(probemu->p4());
843 auto mass =
Scalar(
"mass", (tagmup4+probemup4).M());
844 bool matched_probe =
false;
847 auto pT =
Scalar(
"pT", probemu->pt());
848 auto eta =
Scalar(
"eta", probemu->eta());
849 auto phi =
Scalar(
"phi", probemu->phi());
851 auto mtype =
Scalar(
"mtype", -1000);
854 auto LB =
Scalar(
"LB", thisEventInfo->lumiBlock());
868 if (probemu->charge() != tagmu->charge()) {
878 else if (!matched_probe) {
879 if (probemu->charge() != tagmu->charge()) {
887 fill(group_MuonTriggerTP,
pT, eta, phi,
mass, isTruth,
runNumber, LB,
eventNumber, mtype,
weight);
895 auto group_MuonTruthEff =
getGroup(
"MuonTruthEff");
905 TLorentzVector truthp4(truthmu->p4());
907 for (
const auto& foundmu : goodmuonsZ) {
908 if (foundmu->p4().DeltaR(truthp4) < 0.05) {
924 auto group_MuonLooseTP =
getGroup(
"MuonLooseTP");
941 for (
const auto& tagmu : goodmuonsTP) {
957 auto tagmup4(tagmu->p4());
958 for (
const auto* trk : *idTracks) {
967 if (std::abs((trk->z0()+trk->vz()-pVtx->
z())*
std::sin(trk->theta())) > 2*
mm)
continue;
969 auto trkp4(trk->p4());
970 auto mass =
Scalar(
"mass", (tagmup4+trkp4).M());
973 auto phi =
Scalar(
"phi", trk->phi());
974 auto eta =
Scalar(
"eta", trk->eta());
978 auto mtype =
Scalar(
"mtype", -1000);
979 auto LB =
Scalar(
"LB", thisEventInfo->lumiBlock());
982 bool opp_sign = (trk->charge() != tagmu->charge());
984 for (
const auto& mu2: goodmuonsTP) {
985 if (tagmu == mu2)
continue;
986 auto dR =
Scalar(
"dR", trkp4.DeltaR(mu2->p4()));
987 auto dPT =
Scalar(
"dPT", ((mu2->p4()).Pt() - trkp4.Pt()));
989 if (std::abs(dPT) < 10000 && dR < 0.05) {
1001 mtype = (trk->charge() != tagmu->charge()) ? 0 : 1;
1009 mtype = (trk->charge() != tagmu->charge()) ? 2 : 3;
1017 fill(group_MuonLooseTP,
pT, phi, eta,
mass, isTruth,
runNumber, LB,
eventNumber, mtype,
weight);
1019 fill(group_MuonLooseTP,
mass, osmatch, ssmatch, osnomatch, ssnomatch);
1029 int truthMatched = 0;
1030 for (
const auto mu: goodmuonsZ) {
1035 if (truthMatched < 2)
return;
1038 auto group_MuonInDetTP =
getGroup(
"MuonInDetTP");
1053 ATH_MSG_FATAL(
"Unable to retrieve ID tracks to do muon T&P");
1056 ATH_MSG_FATAL(
"Unable to retrieve MS tracks to do muon T&P");
1059 for (
const auto& tagmu : goodmuonsZ) {
1069 auto tagmup4(tagmu->p4());
1074 if (std::abs((trk->z0()+trk->vz()-pVtx->
z())*
std::sin(trk->theta())) > 2*
mm)
1076 auto trkp4(trk->p4());
1077 auto mass =
Scalar(
"mass", (tagmup4+trkp4).M());
1080 if (mass < m_zCutLow*GeV || mass >
m_zCutHigh*
GeV)
continue;
1083 auto phi =
Scalar(
"phi", trk->phi());
1084 auto eta =
Scalar(
"eta", trk->eta());
1086 auto mtype =
Scalar(
"mtype", -1000);
1090 auto LB =
Scalar(
"LB", thisEventInfo->lumiBlock());
1094 auto idtrkp4(mu2->p4());
1095 auto mstrkp4(trk->p4());
1097 auto dR =
Scalar(
"dR", idtrkp4.DeltaR(mstrkp4));
1098 auto dPT =
Scalar(
"dPT", mstrkp4.Pt() - idtrkp4.Pt());
1101 if (std::abs(dPT) < 10000 && dR < 0.05){
1108 (trk->charge() != tagmu->charge()) ? osmatch =
true : ssmatch =
true;
1109 mtype = (trk->charge() != tagmu->charge()) ? 0 : 1;
1111 fill(group_MuonInDetTP,
pT, eta, phi,
mass, mtype, isTruth,
runNumber, LB,
eventNumber,
weight);
1113 fill(group_MuonInDetTP,
mass, osmatch, ssmatch);
1115 (trk->charge() != tagmu->charge()) ? osnomatch =
true : ssnomatch =
true;
1116 mtype = (trk->charge() != tagmu->charge()) ? 2 : 3;
1118 fill(group_MuonInDetTP,
pT, eta, phi,
mass, mtype, isTruth,
runNumber, LB,
eventNumber,
weight);
1120 fill(group_MuonInDetTP,
mass, osnomatch, ssnomatch);
1131 bool truthMatched =
false;
1133 std::pair<unsigned int, unsigned int>
res;
1139 unsigned int iTypeOfPart =
res.first;
1140 unsigned int iPartOrig =
res.second;
1143 truthMatched =
true;
1147 return truthMatched;
1156 bool truthMatched =
false;
1158 std::pair<unsigned int, unsigned int>
res;
1163 unsigned int iTypeOfPart =
res.first;
1164 unsigned int iPartOrig =
res.second;
1166 auto muTrk = muon->primaryTrackParticle();
1172 truthMatched =
true;
1176 return truthMatched;
1185 bool truthMatched =
false;
1187 std::pair<unsigned int, unsigned int>
res;
1192 unsigned int iTypeOfPart =
res.first;
1193 unsigned int iPartOrig =
res.second;
1199 truthMatched =
true;
1203 return truthMatched;
1215 auto group_EleTP =
getGroup(
"EleTP");
1217 auto good_os =
Scalar(
"good_os",
false);
1218 auto good_ss =
Scalar(
"good_ss",
false);
1219 auto bad_os =
Scalar(
"bad_os",
false);
1220 auto bad_ss =
Scalar(
"bad_ss",
false);
1221 auto template_os =
Scalar(
"template_os",
false);
1222 auto template_ss =
Scalar(
"template_ss",
false);
1225 if(probe_good) good_os =
true;
1227 if(probe_anti_good) template_os =
true;
1228 fill(group_EleTP,
mass, good_os, bad_os, template_os);
1230 if(probe_good) good_ss =
true;
1232 if(probe_anti_good) template_ss =
true;
1233 fill(group_EleTP,
mass, good_ss, bad_ss, template_ss);