39#include "Math/GenVector/VectorUtil.h"
40#include "Math/Vector2D.h"
47using ROOT::Math::XYVector;
58bool prev_perm (std::vector<char>& v)
60 return std::ranges::prev_permutation(v).found;;
80 ATH_MSG_INFO(
"totalCharge value is not specified, no charge selection for track combinations will be used" );
85 ATH_MSG_INFO(
"trackMasses value is not specified, muon/electron mass will be used" );
86 for (
const auto& n :
m_nTrk) {
91 ATH_MSG_INFO(
"trackPtThresholds value is not specified" );
92 for (
const auto& n :
m_nTrk) {
93 m_trkPt.value().emplace_back(std::vector<double>(n, -100.));
97 for (
size_t i = 0; i <
m_trkPt.size(); ++i) {
104 for (
size_t i = 0; i <
m_nTrk.size(); ++i) {
116 for (
size_t i = 0; i <
m_nTrk.size(); ++i) {
118 for (
size_t j = 0; j <
m_nTrk[i]; ++j) {
122 msg() << MSG::DEBUG <<
" mass range: {";
124 msg() << MSG::DEBUG <<
" { " << range.first <<
", " << range.second <<
" }";
126 msg() << MSG::DEBUG <<
" }" << std::endl;
130 ATH_MSG_DEBUG(
"Configured to run in a streamer mode: no trigger objects will be created" );
133 ATH_MSG_ERROR(
"Could not create trigger objects from tracks or L2 CB muons, use the streamer mode for L2 step" );
134 return StatusCode::FAILURE;
148 return StatusCode::FAILURE;
162 if (item.second.size() > 1) {
163 for (
size_t i = 0; i < item.second.size(); i++) {
177 bool isMergedElectronChain =
false;
180 isMergedElectronChain =
true;
203 ATH_MSG_DEBUG(
"No GenericMonitoringTool configured: no monitoring histograms will be available" );
206 return StatusCode::SUCCESS;
216 CHECK( previousDecisionsHandle.isValid() );
217 ATH_MSG_DEBUG(
"Running with "<< previousDecisionsHandle->size() <<
" previous decisions" );
225 beamSpotData = *beamSpotHandle;
228 std::unique_ptr<TrigMultiTrkState<xAOD::MuonContainer>> muonState;
229 std::unique_ptr<TrigMultiTrkState<xAOD::ElectronContainer>> electronState;
232 electronState = std::make_unique<TrigMultiTrkState<xAOD::ElectronContainer>>(context, *previousDecisionsHandle, *outputDecisionsHandle,
nullptr, beamSpotData);
233 commonState = electronState.get();
236 muonState = std::make_unique<TrigMultiTrkState<xAOD::MuonContainer>>(context, *previousDecisionsHandle, *outputDecisionsHandle,
nullptr, beamSpotData);
237 commonState = muonState.get();
255 ATH_CHECK( trigBphysHandle.record(std::make_unique<xAOD::TrigBphysContainer>(),
256 std::make_unique<xAOD::TrigBphysAuxContainer>()) );
274 ATH_MSG_DEBUG(
"TrigMultiTrkHypo::execute() terminates with StatusCode::SUCCESS" );
275 return StatusCode::SUCCESS;
282 auto& leptons = state.
leptons();
286 std::map<const Decision*, int> decisionToInputCollectionIndexMap;
287 for (
const auto& decision : previousDecisions) decisionToInputCollectionIndexMap.emplace(decision, 0);
291 CHECK( previousDecisionsHandle.isValid() );
293 for (
const Decision* decision : *previousDecisionsHandle) {
294 previousDecisions.push_back(decision);
295 decisionToInputCollectionIndexMap.emplace(decision,
static_cast<int>(k));
301 for (
const Decision* decision : previousDecisions) {
311 leptonEL = leptonLinkInfo.link;
314 const auto lepton = *leptonEL;
315 if constexpr(std::is_same<T, xAOD::MuonContainer>::value) {
316 if (!lepton->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle))
continue;
317 if (!lepton->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle))
continue;
319 else if constexpr(std::is_same<T, xAOD::ElectronContainer>::value) {
320 if (!lepton->trackParticle())
continue;
323 ATH_MSG_ERROR(
"mergeLeptonsFromDecisions(): no scenario for the provided CONTAINER is specified" );
324 return StatusCode::FAILURE;
328 auto itr = leptons.end();
330 itr = std::find_if(leptons.begin(), leptons.end(),
331 [
this, lepton = lepton](
const auto&
x){ return this->isIdenticalTracks(lepton, *x.link); });
333 if (itr == leptons.end()) {
334 leptons.push_back({leptonEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL),
DecisionIDContainer()});
337 (*itr).decisionLinks.push_back(decisionEL);
343 std::sort(leptons.begin(), leptons.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs.link)->pt() > (*rhs.link)->pt()); });
347 for (
auto& item : leptons) {
350 auto decisionIndex = decisionToInputCollectionIndexMap[*decisionEL];
355 if (legToInputCollectionIndexMap.at(chain).at(legIndex) == decisionIndex) item.decisionIDs.insert(
id);
365 ATH_MSG_DEBUG(
"Dump found leptons before vertex fit: " << leptons.size() <<
" candidates" );
366 for (
const auto& item : leptons) {
367 const auto lepton = *item.link;
369 if constexpr(std::is_same<T, xAOD::MuonContainer>::value) {
370 track = lepton->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
373 track = lepton->trackParticle();
375 ATH_MSG_DEBUG(
" -- lepton InDetTrackParticle pt/eta/phi/q: " << track->pt() <<
" / " << track->eta() <<
" / " << track->phi() <<
" / " << track->charge() );
376 ATH_MSG_DEBUG(
" lepton pt (muon: CombinedTrackParticle): " << lepton->pt() <<
" / " << lepton->eta() <<
" / " << lepton->phi() <<
" / " << lepton->charge() );
378 for (
const DecisionID&
id : item.decisionIDs) {
384 return StatusCode::SUCCESS;
390 auto& tracks = state.
tracks();
393 std::set<const SG::View*> views;
399 const SG::View* view = *viewLinkInfo.link;
400 if (views.find(view) != views.end())
continue;
406 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
407 tracksFromView.reserve(tracksHandle->size());
408 for (
size_t idx = 0; idx < tracksHandle->size(); ++idx) {
412 for (
const auto& trackEL : tracksFromView) {
414 if (track->definingParametersCovMatrixVec().empty() || track->pt() <
m_trkPtMin)
continue;
417 std::find_if(tracks.begin(), tracks.end(),
418 [
this, track](
const auto&
x){ return isIdenticalTracks(track, *x); }) == tracks.end()) {
419 tracks.emplace_back(trackEL);
424 std::sort(tracks.begin(), tracks.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
427 ATH_MSG_DEBUG(
"Dump found tracks before vertex fit: " << tracks.size() <<
" candidates" );
428 for (
const auto& trackEL : tracks) {
430 ATH_MSG_DEBUG(
" -- track pt/eta/phi/q: " << track->pt() <<
" / " << track->eta() <<
" / " << track->phi() <<
" / " << track->charge() );
434 return StatusCode::SUCCESS;
438template<
typename CONTAINER>
441 auto& tracks = state.
tracks();
450 const auto lepton = *leptonEL;
453 if constexpr(std::is_same<CONTAINER, xAOD::MuonContainer>::value) {
454 if (!lepton->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle))
continue;
455 if (!lepton->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle))
continue;
456 trackEL = lepton->inDetTrackParticleLink();
458 else if constexpr(std::is_same<CONTAINER, xAOD::L2CombinedMuonContainer>::value) {
459 if (!lepton->idTrack())
continue;
460 trackEL = lepton->idTrackLink();
462 else if constexpr(std::is_same<CONTAINER, xAOD::ElectronContainer>::value) {
463 if (!lepton->trackParticle())
continue;
464 trackEL = lepton->trackParticleLink();
467 ATH_MSG_ERROR(
"mergeTracksFromDecisions(): no scenario for the provided CONTAINER is specified" );
468 return StatusCode::FAILURE;
471 if (!trackEL.
isValid())
continue;
473 std::find_if(tracks.begin(), tracks.end(),
474 [
this, track = *trackEL](
const auto&
x){ return this->isIdenticalTracks(track, *x); }) == tracks.end()) {
475 tracks.emplace_back(trackEL);
478 std::sort(tracks.begin(), tracks.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
481 ATH_MSG_DEBUG(
"Dump found tracks before vertex fit: " << tracks.size() <<
" candidates" );
482 for (
const auto& trackEL : tracks) {
484 ATH_MSG_DEBUG(
" -- track pt/eta/phi/q: " << track->pt() <<
" / " << track->eta() <<
" / " << track->phi() <<
" / " << track->charge() );
488 return StatusCode::SUCCESS;
494 const auto& tracks = state.
tracks();
504 mon_nAcceptedTrk, mon_nVertexFitterCalls, mon_isEventAccepted,
507 for (
size_t iTrk = 0; iTrk <
m_nTrk.size(); ++iTrk) {
509 size_t nTrk =
m_nTrk[iTrk];
511 if (tracks.size() < nTrk) {
512 ATH_MSG_DEBUG(
"Could not build a subset of " << nTrk <<
" tracks from collection which contains only " << tracks.size() <<
" objects" );
515 ATH_MSG_DEBUG(
"Consider combinations of " << nTrk <<
" tracks from collection which contains " << tracks.size() <<
" objects until find a good one" );
517 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracklist(nTrk);
518 std::vector<xAOD::TrackParticle::GenVecFourMom_t> p(nTrk);
522 std::vector<char> idx(tracks.size(), 0);
523 std::fill(idx.begin(), idx.begin() + nTrk, 1);
526 bool isValidCombination =
true;
529 for (
size_t i = 0; i < idx.size(); ++i) {
530 if (!idx[i])
continue;
531 const auto& trackEL = tracks[i];
532 tracklist[j] = trackEL;
533 const auto track = *trackEL;
534 p[j] = track->genvecP4();
536 totalCharge +=
static_cast<int>(track->charge());
537 if (p[j].Pt() <
m_trkPt[iTrk][j]) {
538 isValidCombination =
false;
546 ATH_MSG_DEBUG(
"Dump found tracks before vertex fit: pT / eta / phi / charge" );
547 for (
size_t i = 0; i < tracklist.size(); ++i) {
548 const auto track = *tracklist[i];
549 ATH_MSG_DEBUG(
"track " << i + 1 <<
": " << p[i].Pt() <<
" / " << p[i].
Eta() <<
" / " << p[i].
Phi() <<
" / " << track->charge() );
559 auto vertex =
fit(tracklist,
m_trkMass[iTrk], *fitterState);
560 ++mon_nVertexFitterCalls;
561 if (!vertex)
continue;
563 ATH_MSG_DEBUG(
"Filter found a subset of tracks which passed the rough selection: stop looking for other combinations" );
567 }
while (prev_perm(idx));
571 ATH_MSG_DEBUG(
"Filter could not find a good subset of tracks" );
576 return StatusCode::SUCCESS;
584 const auto& leptons = state.
leptons();
592 std::vector<float> trkMassBeforeFit;
593 std::vector<float> bphysMass;
594 std::vector<float> d0track1, d0track2;
595 std::vector<float> pttrack1, pttrack2;
596 std::vector<float> etatrack1, etatrack2;
597 std::vector<int> bphysCharge;
614 mon_nAcceptedTrk, mon_nCombination, mon_nCombinationBeforeFit, mon_nBPhysObject,
615 mon_trkMassBeforeFit, mon_bphysChi2, mon_bphysLxy, mon_bphysFitMass, mon_bphysMass, mon_bphysCharge, mon_d0track1, mon_d0track2,
616 mon_timer, mon_pttrack1, mon_pttrack2, mon_etatrack1, mon_etatrack2);
618 for (
size_t iTrk = 0; iTrk <
m_nTrk.size(); ++iTrk) {
619 size_t nTrk =
m_nTrk[iTrk];
621 if (leptons.size() < nTrk) {
622 ATH_MSG_DEBUG(
"Could not build a subset of " << nTrk <<
" legs from collection which contains only " << leptons.size() <<
" objects" );
625 ATH_MSG_DEBUG(
"Consider all combinations of " << nTrk <<
" legs from collection which contains " << leptons.size() <<
" objects" );
627 std::vector<size_t> leptonIndices(nTrk);
628 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracklist(nTrk);
629 std::vector<xAOD::TrackParticle::GenVecFourMom_t> p(nTrk);
631 std::vector<char> combination(leptons.size(), 0);
632 std::fill(combination.begin(), combination.begin() + nTrk, 1);
635 bool isValidCombination =
true;
638 for (
size_t i = 0; i < combination.size(); ++i) {
639 if (!combination[i])
continue;
640 leptonIndices[j] = i;
641 auto leg = *leptons[i].link;
642 charge +=
static_cast<int>(lround(leg->charge()));
644 if constexpr(std::is_same<T, xAOD::MuonContainer>::value) {
645 trackEL = leg->inDetTrackParticleLink();
648 trackEL = leg->trackParticleLink();
650 tracklist[j] = trackEL;
652 p[j] = leg->genvecP4();
656 p[j] = (*trackEL)->genvecP4();
659 if (p[j].Pt() <
m_trkPt[iTrk][j]) {
660 isValidCombination =
false;
668 ATH_MSG_DEBUG(
"Dump found leptons before vertex fit: pT / eta / phi / charge" );
669 for (
size_t i = 0; i < tracklist.size(); ++i) {
670 const auto track = *tracklist[i];
671 ATH_MSG_DEBUG(
"legs " << i + 1 <<
": " << p[i].Pt() <<
" / " << p[i].
Eta() <<
" / " << p[i].
Phi() <<
" / " << track->charge() );
679 trkMassBeforeFit.push_back(mass * 0.001);
682 mon_nCombinationBeforeFit++;
684 auto vertex =
fit(tracklist,
m_trkMass[iTrk], *fitterState);
685 if (!vertex)
continue;
691 bphysMass.push_back(mass * 0.001);
692 bphysCharge.push_back(
charge);
693 d0track1.push_back((*tracklist[0])->d0());
694 d0track2.push_back((*tracklist[1])->d0());
695 pttrack1.push_back((*tracklist[0])->pt() * 0.001);
696 pttrack2.push_back((*tracklist[1])->pt() * 0.001);
697 etatrack1.push_back((*tracklist[0])->
eta());
698 etatrack2.push_back((*tracklist[1])->
eta());
700 }
while (prev_perm(combination));
702 return StatusCode::SUCCESS;
708 ATH_MSG_DEBUG(
"Try to find electrons originating from the same EM cluster" );
711 auto& leptons = state.
leptons();
714 ATH_MSG_DEBUG(
"no chains similar to BPH-0DR3-EM7J15 have been requested, should not look for close-by electrons" );
715 return StatusCode::SUCCESS;
726 const auto electron = *electronEL;
727 if (!electron->trackParticle())
continue;
736 leptons.push_back({electronEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL),
decisionIDs});
741 auto initialRoI = *roiInfo.link;
744 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracklist(2);
745 tracklist[0] = electron->trackParticleLink();
748 if (electronFromView == electron)
continue;
749 if (!electronFromView->trackParticle())
continue;
751 tracklist[1] = electronFromView->trackParticleLink();
754 auto vertex =
fit(tracklist, particleMasses, *fitterState);
755 if (!vertex)
continue;
757 trigBphys->
setRoiId(initialRoI->roiWord());
762 return StatusCode::SUCCESS;
768 ATH_MSG_DEBUG(
"Try to find muon + track combinations from the same SG::View" );
773 const std::vector<double> particleMasses(2,
PDG::mMuon);
781 const auto muon = *muonEL;
782 if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle))
continue;
783 if (!muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle))
continue;
784 const auto muonInDetTrack = muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
785 auto muonMomentum = muonInDetTrack->genvecP4();
791 muons.push_back({muonEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL),
decisionIDs});
793 ATH_MSG_DEBUG(
"Found muon (CombinedTrackParticle): " << muon->pt() <<
" / " << muon->eta() <<
" / " << muon->phi() <<
" / " << muon->charge() );
797 auto view = *viewLinkInfo.link;
804 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracklist(2);
805 tracklist[0] = muon->inDetTrackParticleLink();
806 for (
size_t idx = 0; idx < tracksHandle->size(); ++idx) {
810 auto trackMomentum = track->genvecP4();
812 if (!
isInMassRange((muonMomentum + trackMomentum).M(), 0))
continue;
813 if (
m_nTrkCharge[0] >= 0 && muonInDetTrack->charge() * track->charge() > 0.)
continue;
817 ATH_MSG_DEBUG(
"Dump found muon+track pair before vertex fit: pT / eta / phi / charge" <<
endmsg <<
818 " muon: " << muonMomentum.Pt() <<
" / " << muonMomentum.Eta() <<
" / " << muonMomentum.Phi() <<
" / " << muon->charge() <<
endmsg <<
819 " track: " << trackMomentum.Pt() <<
" / " << trackMomentum.Eta() <<
" / " << trackMomentum.Phi() <<
" / " << track->charge() );
822 auto vertex =
fit(tracklist, particleMasses, *fitterState);
823 if (!vertex)
continue;
830 return StatusCode::SUCCESS;
844 std::set_intersection(previousDecisionIDs.begin(), previousDecisionIDs.end(),
m_allowedIDs.begin(),
m_allowedIDs.end(),
855 return StatusCode::SUCCESS;
863 ATH_MSG_DEBUG(
"Found xAOD::TrigBphys: mass / chi2 = " << triggerObject->mass() <<
" / " << triggerObject->fitchi2() );
871 std::vector<const DecisionIDContainer*> previousDecisionIDs;
882 decision->
setDetail<int32_t>(
"noCombo", 1);
894 return StatusCode::SUCCESS;
905 CHECK( previousDecisionsHandle.isValid() );
906 ATH_MSG_DEBUG(
"Running with "<< previousDecisionsHandle->size() <<
" previous decisions" );
908 for (
const Decision* previousDecision : *previousDecisionsHandle) {
914 std::set_intersection(previousDecisionIDs.begin(), previousDecisionIDs.end(),
m_allowedIDs.begin(),
m_allowedIDs.end(),
923 return StatusCode::SUCCESS;
929 const std::vector<double>& particleMasses,
933 std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(),
nullptr);
934 std::transform(trackParticleLinks.begin(), trackParticleLinks.end(), tracklist.begin(),
937 const Trk::Perigee& perigee1 = tracklist[0]->perigeeParameters();
938 const Trk::Perigee& perigee2 = tracklist[1]->perigeeParameters();
942 if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
943 ATH_MSG_DEBUG(
"Starting point: (" << startingPoint(0) <<
", " << startingPoint(1) <<
", " << startingPoint(2) <<
")" );
945 m_vertexFitter->setMassInputParticles(particleMasses, fitterState);
946 std::unique_ptr<xAOD::Vertex> vertex(
m_vertexFitter->fit(tracklist, startingPoint, fitterState));
951 if (vertex->chiSquared() >
m_chi2) {
952 ATH_MSG_DEBUG(
"Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() <<
" > " <<
m_chi2.value() <<
")" );
957 vertex->clearTracks();
958 vertex->setTrackParticleLinks(trackParticleLinks);
965 const std::vector<double>& particleMasses,
969 double invariantMass = 0.;
970 double invariantMassError = 0.;
971 if (!
m_vertexFitter->VKalGetMassError(invariantMass, invariantMassError, fitterState).isSuccess()) {
972 ATH_MSG_DEBUG(
"Warning from TrkVKalVrtFitter: can not calculate uncertainties" );
973 invariantMass = -9999.;
977 for (
size_t i = 0; i < vertex.nTrackParticles(); ++i) {
978 auto p = vertex.trackParticle(i)->genvecP4();
979 p.SetM(particleMasses[i]);
984 result->makePrivateStore();
988 result->setFitmass(invariantMass);
989 result->setFitchi2(vertex.chiSquared());
990 result->setFitndof(vertex.numberDoF());
991 result->setFitx(vertex.x());
992 result->setFity(vertex.y());
993 result->setFitz(vertex.z());
994 result->setTrackParticleLinks(vertex.trackParticleLinks());
995 result->setLxy(
m_v0Tools->lxy(&vertex, &beamSpot));
996 result->setLxyError(
m_v0Tools->lxyError(&vertex, &beamSpot));
999 "TrigBphys objects:\n\t " <<
1000 "roiId: " << result->roiId() <<
"\n\t " <<
1001 "particleType: " << result->particleType() <<
"\n\t " <<
1002 "level: " << result->level() <<
"\n\t " <<
1003 "eta: " << result->eta() <<
"\n\t " <<
1004 "phi: " << result->phi() <<
"\n\t " <<
1005 "mass: " << result->mass() <<
"\n\t " <<
1006 "fitmass: " << result->fitmass() <<
"\n\t " <<
1007 "chi2/NDF: " << result->fitchi2() <<
" / " << result->fitndof() <<
"\n\t " <<
1008 "vertex: (" << result->fitx() <<
", " << result->fity() <<
", " << result->fitz() <<
")\n\t " <<
1009 "Lxy/LxyError: " << result->lxy() <<
" / " << result->lxyError() );
1036 return (mass > range.first && mass < range.second);
1042 if (
m_deltaRMax == std::numeric_limits<float>::max() &&
m_deltaRMin == std::numeric_limits<float>::lowest()) {
1045 for (
size_t i = 0; i < p.size(); ++i) {
1046 for (
size_t j = i + 1; j < p.size(); ++j) {
1047 double deltaR = ROOT::Math::VectorUtil::DeltaR(p[i], p[j]);
Scalar eta() const
pseudorapidity method
Scalar deltaR(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
double charge(const T &p)
#define CHECK(...)
Evaluate an expression and check for errors.
void decisionIDs(const Decision *d, DecisionIDContainer &id)
Extracts DecisionIDs stored in the Decision object.
xAOD::ElectronContainer * electronContainer
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
bool msgLvl(const MSG::Level lvl) const
ComboHypo(const std::string &name, ISvcLocator *pSvcLocator)
const SG::WriteHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsOutput() const
const Combo::MultiplicityReqMap & triggerMultiplicityMap() const
ToolHandleArray< ComboHypoToolBase > & hypoTools()
const Combo::LegMap & legToInputCollectionMap() const
const SG::ReadHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsInput() const
virtual StatusCode initialize() override
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
ElementLink implementation for ROOT usage.
bool isValid() const
Test to see if the link can be dereferenced.
std::string name() const
reports human redable name
TrigCompositeUtils::DecisionContainer & decisions()
void setTrigBphysCollection(xAOD::TrigBphysContainer *trigBphysCollection)
const TrigCompositeUtils::DecisionContainer & previousDecisions() const
const xAOD::Vertex & beamSpot() const
xAOD::TrigBphysContainer & trigBphysCollection()
const EventContext & context() const
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
A "view" of the event store (IProxyDict).
pointer_type ptr()
Dereference the pointer.
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
StatusCode mergeLeptonsFromDecisions(TrigMultiTrkState< CONTAINER > &) const
Go through state.previousDecisions(), fetch xAOD::Muons/xAODElectron objects attached to decisions an...
Gaudi::Property< bool > m_combineInputDecisionCollections
ToolHandle< GenericMonitoringTool > m_monTool
Gaudi::Property< bool > m_checkMultiplicity
SG::WriteHandleKey< xAOD::TrigBphysContainer > m_trigBphysContainerKey
virtual StatusCode initialize() override
TrigCompositeUtils::DecisionIDContainer m_mergedElectronIDs
Gaudi::Property< float > m_deltaR
xAOD::TrigBphys * makeTrigBPhys(const xAOD::Vertex &vertex, const std::vector< double > &particleMasses, const xAOD::Vertex &beamSpot, const Trk::IVKalState &fitterState) const
Construct the trigger object that may be stored for debugging or matching.
virtual StatusCode execute(const EventContext &context) const override
Gaudi::Property< float > m_chi2
StatusCode findMuTrkCandidates(TrigMultiTrkState< xAOD::MuonContainer > &) const
Build J/psi candidates from muon from SG::View and tracks from the same SG::View, to be used for Tag-...
Gaudi::Property< bool > m_useLeptonMomentum
std::unique_ptr< xAOD::Vertex > fit(const std::vector< ElementLink< xAOD::TrackParticleContainer > > &trackParticleLinks, const std::vector< double > &particleMasses, Trk::IVKalState &fitterState) const
Perform a vertex fit on selected tracks.
bool isInMassRange(double mass, size_t idx) const
Gaudi::Property< std::vector< std::vector< double > > > m_trkMass
Gaudi::Property< std::vector< int > > m_nTrkCharge
ToolHandle< Trk::V0Tools > m_v0Tools
StatusCode filterTrackCombinations(TrigMultiTrkStateBase &) const
Make all possible combinations from state.tracks(), fit tracks to the common vertex and set state....
ToolHandle< InDet::VertexPointEstimator > m_vertexPointEstimator
Gaudi::Property< std::vector< std::vector< double > > > m_trkPt
StatusCode copyAdditionalDecisionObjects(TrigMultiTrkStateBase &) const
For chains from CombinedSlice (similar to 'HLT_e9_lhvloose_e5_lhvloose_bBeeM6000_mu4_L1BPH-0M9-EM7-EM...
Gaudi::Property< std::vector< std::string > > m_mergedElectronChains
TrigCompositeUtils::DecisionIDContainer m_allowedIDs
Gaudi::Property< std::vector< unsigned int > > m_nTrk
Gaudi::Property< bool > m_applyOverlapRemoval
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
bool isIdenticalTracks(const xAOD::TrackParticle *lhs, const xAOD::TrackParticle *rhs) const
Attempts to identify identical tracks by selection on DeltaR.
bool passedDeltaRcut(const std::vector< xAOD::TrackParticle::GenVecFourMom_t > &momenta) const
Gaudi::Property< bool > m_isStreamer
Gaudi::Property< float > m_deltaRMin
ToolHandle< Trk::TrkVKalVrtFitter > m_vertexFitter
Gaudi::Property< float > m_deltaRMax
Gaudi::Property< std::vector< std::pair< double, double > > > m_massRange
Gaudi::Property< bool > m_doElectrons
StatusCode findMultiLeptonCandidates(TrigMultiTrkState< CONTAINER > &) const
Make all possible combinations from state.leptons(), fit tracks to the common vertex,...
StatusCode copyDecisionObjects(TrigMultiTrkStateBase &) const
All appropriate decisions from state.previousDecisions() will be copied to state.decisions() if flag ...
StatusCode processMergedElectrons(TrigMultiTrkState< xAOD::ElectronContainer > &) const
Make all possible combinations from electrons originating from the same BPH-0DR3-EM7J15 cluster,...
Gaudi::Property< double > m_caloClusterEtThreshold
Gaudi::Property< std::string > m_trigLevel
Gaudi::Property< bool > m_isMuTrkMode
TrigMultiTrkComboHypo()=delete
StatusCode mergeTracksFromViews(TrigMultiTrkStateBase &) const
Go through state.previousDecisions() and fetch xAOD::TrackParticle objects associated with the neares...
StatusCode createDecisionObjects(TrigMultiTrkStateBase &) const
Create a decision for each xAOD::TrigBphys object from state.trigBphysCollection() and save it to sta...
TrigCompositeUtils::DecisionIDContainer m_resolvedElectronIDs
StatusCode mergeTracksFromDecisions(TrigMultiTrkStateBase &) const
Go through state.previousDecisions(), fetch xAOD::Muons/xAODElectron objects attached to decisions an...
virtual bool checkMultiplicity(const std::vector< int > &legMultiplicity, const std::vector< HLT::Identifier > &legDecisionIDs) const =0
std::vector< std::vector< size_t > > & trigBphysLegIndices()
std::vector< ElementLink< xAOD::TrackParticleContainer > > & tracks()
int isEventAccepted() const
std::vector< size_t > & getTrigBphysLegIndices(size_t idx)
virtual TrigCompositeUtils::DecisionIDContainer & getDecisionIDs(size_t)=0
virtual std::vector< ElementLink< TrigCompositeUtils::DecisionContainer > > & getDecisionLinks(size_t)=0
void setEventAccepted(bool flag=true)
State class for TrigMultiTrkComboHypo algorithm.
std::vector< LEPTON > & leptons()
virtual void addTrigBphysObject(xAOD::TrigBphys *trigBphysObject, const std::vector< size_t > &legIndices) override final
const ElementLink< TrackParticleContainer > & trackParticleLink(size_t index=0) const
ElementLink to the xAOD::TrackParticle/s that match the electron candidate.
const ElementLink< TrackParticleContainer > & inDetTrackParticleLink() const
Returns an ElementLink to the InnerDetector TrackParticle used in identification of this muon.
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D< double > > GenVecFourMom_t
Base 4 Momentum type for TrackParticle.
GenVecFourMom_t genvecP4() const
The full 4-momentum of the particle : GenVector form.
float charge() const
Returns the charge.
void setRoiId(uint32_t id)
set method: roiId
float fitchi2() const
accessor method: chi2 from vertex fit
float lxy() const
accessor method: lxy
void setMass(float)
Set the mass of the object.
bool setObjectLink(const std::string &name, const ElementLink< CONTAINER > &link)
Set the link to an object.
bool setDetail(const std::string &name, const TYPE &value)
Set an TYPE detail on the object.
bool addObjectCollectionLinks(const std::string &collectionName, const std::vector< ElementLink< CONTAINER > > &links)
Add links to multiple objects within a collection. Performs de-duplication.
Eigen::Matrix< double, 3, 1 > Vector3D
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
const std::string & viewString()
xAOD::TrigComposite Decision
void insertDecisionIDs(const Decision *src, Decision *dest)
Appends the decision IDs of src to the dest decision object.
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name)
Helper method to create a Decision object, place it in the container and return a pointer to it.
const std::string & featureString()
int32_t getIndexFromLeg(const HLT::Identifier &legIdentifier)
Extract the numeric index of a leg identifier.
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
const std::string & comboHypoAlgNodeName()
std::set< DecisionID > DecisionIDContainer
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
void linkToPrevious(Decision *d, const std::string &previousCollectionKey, size_t previousIndex)
Links to the previous object, location of previous 'seed' decision supplied by hand.
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
const std::string & initialRoIString()
const std::string & seedString()
xAOD::TrigCompositeContainer DecisionContainer
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
bool isAnyIDPassing(const Decision *d, const DecisionIDContainer &required)
Checks if any of the DecisionIDs passed in arg required is availble in Decision object.
ElementLink< DecisionContainer > decisionToElementLink(const Decision *d, const EventContext &ctx)
Takes a raw pointer to a Decision and returns an ElementLink to the Decision.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ElementLink< T > makeLink(const SG::View *view, const SG::ReadHandle< T > &handle, size_t index)
Create EL to a collection in view.
auto makeHandle(const SG::View *view, const KEY &key, const EventContext &ctx)
Create a view handle from a handle key.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
TrigBphysContainer_v1 TrigBphysContainer
Electron_v1 Electron
Definition of the current "egamma version".
static constexpr CLID ID()
static constexpr double mElectron
static constexpr double mMuon