27#include "Math/GenVector/VectorUtil.h"
28#include "Math/Vector2D.h"
37using ROOT::Math::XYVector;
77 if (item.second.size() > 1) {
78 for (
size_t i = 0; i < item.second.size(); i++) {
95 ATH_MSG_DEBUG(
"No GenericMonitoringTool configured: no monitoring histograms will be available" );
98 return StatusCode::SUCCESS;
108 ATH_CHECK( previousDecisionsHandle.isValid() );
109 ATH_MSG_DEBUG(
"Running with " << previousDecisionsHandle->size() <<
" previous decisions" );
114 ATH_CHECK( trigBphysHandle.record(std::make_unique<xAOD::TrigBphysContainer>(),
115 std::make_unique<xAOD::TrigBphysAuxContainer>()) );
120 auto state = std::make_unique<TrigBmumuxState>(context, *previousDecisionsHandle, *outputDecisionsHandle, trigBphysHandle.
ptr(), *beamSpotHandle);
125 if (!state->dimuons.empty()) {
131 ATH_MSG_DEBUG(
"TrigBmumuxComboHypo::execute() terminates with StatusCode::SUCCESS" );
132 return StatusCode::SUCCESS;
138 auto& muons = state.
muons;
146 if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle))
continue;
149 auto itr = std::find_if(muons.begin(), muons.end(), [
this, muon](
const auto&
x){ return isIdenticalTracks(muon, *x.link); });
150 if (itr == muons.end()) {
151 muons.push_back({muonEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL),
DecisionIDContainer()});
154 (*itr).decisionLinks.push_back(decisionEL);
160 std::sort(muons.begin(), muons.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs.link)->pt() > (*rhs.link)->pt()); });
163 for (
auto& item : muons) {
170 ATH_MSG_DEBUG(
"Dump found muons before vertex fit: " << muons.size() <<
" candidates" );
171 for (
const auto& item : muons) {
173 const xAOD::TrackParticle* track = muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
174 ATH_MSG_DEBUG(
" -- muon InDetTrackParticle pt/eta/phi/q: " << track->pt() <<
" / " << track->eta() <<
" / " << track->phi() <<
" / " << track->charge() );
175 ATH_MSG_DEBUG(
" muon CombinedTrackParticle pt: " << muon->pt() );
177 for (
const DecisionID&
id : item.decisionIDs) {
183 return StatusCode::SUCCESS;
189 auto& tracks = state.
tracks;
192 size_t viewCounter = 0;
196 auto view = *viewLinkInfo.link;
200 const auto roi = *roiLinkInfo.link;
206 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
207 tracksFromView.reserve(tracksHandle->size());
208 for (
size_t idx = 0; idx < tracksHandle->size(); ++idx) {
212 for (
const auto& trackEL : tracksFromView) {
214 if (track->definingParametersCovMatrixVec().empty())
continue;
216 if (viewCounter == 0 ||
217 std::find_if(tracks.begin(), tracks.end(),
218 [
this, track](
const auto&
x){ return isIdenticalTracks(track, *x); }) == tracks.end()) {
219 tracks.emplace_back(trackEL);
223 if (roi->composite()) {
228 std::sort(tracks.begin(), tracks.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
231 ATH_MSG_DEBUG(
"Dump found tracks before vertex fit: " << tracks.size() <<
" candidates" );
232 for (
const auto& trackEL : tracks) {
234 ATH_MSG_DEBUG(
" -- track pt/eta/phi/q: " << track->pt() <<
" / " << track->eta() <<
" / " << track->phi() <<
" / " << track->charge() );
237 return StatusCode::SUCCESS;
246 const auto& muons = state.
muons;
247 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks(2);
248 std::vector<const DecisionIDContainer*> previousDecisionIDs(2,
nullptr);
250 for (
size_t itrk1 = 0; itrk1 < muons.size(); ++itrk1) {
253 previousDecisionIDs[0] = &muons[itrk1].decisionIDs;
257 auto charge1 = trk1->
charge();
259 for (
size_t itrk2 = itrk1 + 1; itrk2 < muons.size(); ++itrk2) {
263 previousDecisionIDs[1] = &muons[itrk2].decisionIDs;
267 auto charge2 = trk2->
charge();
269 double mass = (p1 + p2).M();
271 ATH_MSG_DEBUG(
"muon 1: " << p1.Pt()<<
" / " << p1.Eta() <<
" / " << p1.Phi() <<
" / " << trk1->
charge() );
272 ATH_MSG_DEBUG(
"muon 2: " << p2.Pt()<<
" / " << p2.Eta() <<
" / " << p2.Phi() <<
" / " << trk2->
charge() );
276 ATH_MSG_DEBUG(
"muon pair is rejected by opposite charge check" );
281 ATH_MSG_DEBUG(
"muon pair did not pass passDimuonTrigger() check" );
286 ATH_MSG_DEBUG(
"muon pair is out of the requested mass range" );
291 auto vertex =
fit(state.
context(), trackParticleLinks);
292 if (!vertex)
continue;
297 ATH_MSG_ERROR(
"xAOD::Vertex could not be converted to xAOD::TrigBphys object: please enable MakeExtendedVertex option in vertex fitter " <<
m_vertexFitter->name() );
298 return StatusCode::FAILURE;
310 return StatusCode::SUCCESS;
316 std::vector<int> nSelectedTrk;
322 for (
size_t dimuonIndex = 0; dimuonIndex < state.
dimuons.
size(); ++dimuonIndex) {
333 mon_nTrk = state.
tracks.size();
336 return StatusCode::SUCCESS;
345 selectedTracks.clear();
346 selectedTrackZ0.clear();
350 std::vector<const xAOD::Muon*> muons(2,
nullptr);
352 for (
size_t i = 0; i < 2; ++i) {
353 const auto& muon = state.
muons.at(muonIndices[i]);
354 muons[i] = *muon.link;
363 for (
const auto& trackEL : state.
tracks) {
367 if (perigee && std::abs(perigee->parameters()[
Trk::z0]) <
m_trkZ0) {
368 selectedTracks.push_back(trackEL);
369 selectedTrackZ0[*trackEL] = perigee->parameters()[
Trk::z0];
373 selectedTracks.push_back(trackEL);
374 selectedTrackZ0[*trackEL] = -1000.;
379 if (selectedTracks.size() < 2) {
380 ATH_MSG_DEBUG(
"Found no tracks consistent with dimuon vertex " << dimuonIndex );
381 selectedTracks.clear();
382 selectedTrackZ0.clear();
383 return StatusCode::SUCCESS;
385 std::sort(selectedTracks.begin(), selectedTracks.end(), [p_mu=mu1->
genvecP4()](
const auto& lhs,
const auto& rhs){ return ROOT::Math::VectorUtil::DeltaR(p_mu, (*lhs)->genvecP4()) > ROOT::Math::VectorUtil::DeltaR(p_mu, (*rhs)->genvecP4()); });
387 std::sort(selectedTracks.begin(), selectedTracks.end(), [p_mu=mu2->
genvecP4()](
const auto& lhs,
const auto& rhs){ return ROOT::Math::VectorUtil::DeltaR(p_mu, (*lhs)->genvecP4()) > ROOT::Math::VectorUtil::DeltaR(p_mu, (*rhs)->genvecP4()); });
389 std::sort(selectedTracks.begin(), selectedTracks.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
391 ATH_MSG_DEBUG(
"Found " << selectedTracks.size() <<
" tracks consistent with dimuon vertex " << dimuonIndex );
393 return StatusCode::SUCCESS;
404 ATH_CHECK( dimuonTriggerObjectEL.isValid() );
407 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx1(dimuon->
trackParticleLinks());
408 trackParticleLinks_vtx1.emplace_back();
411 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx2(trackParticleLinks_vtx1);
412 trackParticleLinks_vtx2.emplace_back();
415 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx3(3);
421 size_t iterations = 0;
423 bool isOverWarningThreshold =
false;
425 for (
size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
428 trackParticleLinks_vtx1[2] = selectedTracks[itrk1];
430 auto charge1 = trk1->
charge();
432 std::unique_ptr<xAOD::Vertex> vtx1;
433 bool makeFit_vtx1 = !makeCombinations;
434 bool passFastFit_vtx1 = (!makeCombinations && !state.
isBadCombination(itrk1));
444 makeFit_vtx1 =
false;
462 makeFit_vtx1 =
false;
473 for (
size_t itrk2 = itrk1 + 1; itrk2 < selectedTracks.size(); ++itrk2) {
476 trackParticleLinks_vtx2[2] = selectedTracks[itrk1];
477 trackParticleLinks_vtx2[3] = selectedTracks[itrk2];
479 auto charge2 = trk2->
charge();
481 std::unique_ptr<xAOD::Vertex> vtx2;
482 bool makeFit_vtx2 = !makeCombinations;
499 makeFit_vtx2 =
false;
522 makeFit_vtx2 =
false;
544 makeFit_vtx2 =
false;
568 makeFit_vtx2 =
false;
591 makeFit_vtx2 =
false;
601 for (
size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
603 if (itrk3 == itrk1 || itrk3 == itrk2)
continue;
605 trackParticleLinks_vtx3[0] = selectedTracks[itrk1];
606 trackParticleLinks_vtx3[1] = selectedTracks[itrk2];
607 trackParticleLinks_vtx3[2] = selectedTracks[itrk3];
611 std::unique_ptr<xAOD::Vertex> vtx3;
612 bool makeFit_vtx3 = !makeCombinations;
613 bool passFastFit_vtx3 = (!makeCombinations && !state.
isBadCombination(itrk1, itrk2, itrk3));
620 charge1 * charge2 < 0. &&
631 vtx3 =
fit(state.
context(), trackParticleLinks_vtx3,
kDs, dimuon);
632 makeFit_vtx3 =
false;
646 charge1 * charge2 > 0. && charge1 *
charge3 < 0. &&
657 makeFit_vtx3 =
false;
672 isOverWarningThreshold =
true;
675 ATH_MSG_WARNING(
"Dimuon + tracks: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
683 isOverWarningThreshold =
false;
686 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_D0(2);
688 for (
size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
691 trackParticleLinks_D0[0] = selectedTracks[itrk1];
694 auto charge1 = trk1->
charge();
696 for (
size_t itrk2 = 0; itrk2 < selectedTracks.size(); ++itrk2) {
697 if (itrk2 == itrk1)
continue;
700 trackParticleLinks_D0[1] = selectedTracks[itrk2];
703 auto charge2 = trk2->
charge();
705 std::unique_ptr<xAOD::Vertex> D0;
706 if (charge1 * charge2 < 0. &&
711 D0 =
fit(state.
context(), trackParticleLinks_D0,
kD0, dimuon);
714 bool isValidD0 =
false;
717 ATH_MSG_DEBUG(
"Partially reconstructed B_c+(-> mu+ mu- D0 X) candidate has been created" );
725 for (
size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
727 if (itrk3 == itrk1 || itrk3 == itrk2)
continue;
730 trackParticleLinks_vtx1[2] = selectedTracks[itrk3];
741 ATH_MSG_DEBUG(
"Decay vertex(mu+ mu- D*+.pi+) for B_c+ candidate has been created" );
745 ATH_CHECK( triggerObjectEL_vtx1.isValid() );
748 auto Bc_vtx2 =
fit(state.
context(), trackParticleLinks_D0,
kD0, Bc_vtx1.get());
751 ATH_MSG_DEBUG(
"Fully reconstructed B_c+(-> mu+ mu- D*+) candidate has been created" );
764 isOverWarningThreshold =
true;
767 ATH_MSG_WARNING(
"B_c+ -> mu+ mu- D*+: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
775 return StatusCode::SUCCESS;
786 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2mu1trk(dimuon->
trackParticleLinks());
787 trackParticleLinks_2mu1trk.emplace_back();
790 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2trk(2);
793 size_t iterations = 0;
795 if (item.second < 5)
continue;
797 size_t key = item.first;
815 return StatusCode::SUCCESS;
825 ATH_MSG_DEBUG(
"Found xAOD::TrigBphys object: mass = " << triggerObject->mass() );
832 if (!dimuonTriggerObject) {
833 ATH_MSG_ERROR(
"Failed to found a valid link for preceding dimuon trigger object" );
834 return StatusCode::FAILURE;
840 auto dimuonIndex = dimuonTriggerObject->index();
843 ATH_MSG_ERROR(
"Failed to find original muons the dimuon vertex had been built from" );
844 return StatusCode::FAILURE;
850 std::vector<const DecisionIDContainer*> previousDecisionIDs;
852 const auto& muon = state.
muons.at(i);
856 previousDecisionIDs.push_back(&muon.decisionIDs);
864 ATH_CHECK( tool->decideOnSingleObject(decision, previousDecisionIDs) );
868 return StatusCode::SUCCESS;
873 const EventContext& context,
880 if (trackParticleLinks.size() < 2) {
881 ATH_MSG_WARNING(
"At least two tracks should be given to the vertex fitter" );
885 std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(),
nullptr);
886 std::transform(trackParticleLinks.begin(), trackParticleLinks.end(), tracklist.begin(),
895 ATH_MSG_WARNING(
"Already fitted dimuon vertex should be provided for B -> mu1 mu2 trk1 .. trkN decay as a starting point for fitter" );
899 const Trk::Perigee& perigee1 = tracklist[0]->perigeeParameters();
900 const Trk::Perigee& perigee2 = tracklist[1]->perigeeParameters();
901 startingPoint =
m_vertexPointEstimator->getCirclesIntersectionPoint(&perigee1, &perigee2, flag, errorcode);
902 if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
904 ATH_MSG_VERBOSE(
"Starting point: (" << startingPoint(0) <<
", " << startingPoint(1) <<
", " << startingPoint(2) <<
")" );
915 std::unique_ptr<xAOD::Vertex> vertex(
m_vertexFitter->fit(tracklist, startingPoint, *fitterState));
921 ATH_MSG_VERBOSE(
"Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() <<
")" );
928 vertex->clearTracks();
929 vertex->setTrackParticleLinks(trackParticleLinks);
939 const std::vector<double>& trkMass,
947 std::vector<xAOD::TrackParticle::GenVecFourMom_t> momenta;
948 if (!vertex.vxTrackAtVertexAvailable())
return nullptr;
949 for (
size_t i = 0; i < vertex.vxTrackAtVertex().
size(); ++i) {
951 if (!perigee)
return nullptr;
953 momenta.emplace_back(p.x(), p.y(), p.z(), trkMass[i]);
956 if (isCascadeDecay) {
957 momentum += ROOT::Math::PtEtaPhiMVector(dimuon->
pt(), dimuon->
eta(), dimuon->
phi(), dimuon->
mass());
961 result->makePrivateStore();
965 mass +=
PDG::mD0 - (momenta[0] + momenta[1]).M();
968 mass +=
PDG::mJpsi - (isCascadeDecay ? dimuon->
mass() : (momenta[0] + momenta[1]).M());
974 result->setFitx(vertex.x());
975 result->setFity(vertex.y());
976 result->setFitz(vertex.z());
977 result->setFitchi2(vertex.chiSquared());
978 result->setFitndof(vertex.numberDoF());
981 result->setLxy(
Lxy(productionVertex, vertex));
984 result->setTrackParticleLinks(vertex.trackParticleLinks());
988 result->setLowerChainLink(dimuonLink);
992 "TrigBphys object:\n\t " <<
993 "roiId: " << result->roiId() <<
"\n\t " <<
994 "particleType: " << result->particleType() <<
"\n\t " <<
995 "level: " << result->level() <<
"\n\t " <<
996 "eta: " << result->eta() <<
"\n\t " <<
997 "phi: " << result->phi() <<
"\n\t " <<
998 "mass: " << result->mass() <<
"\n\t " <<
999 "fitmass: " << result->fitmass() <<
"\n\t " <<
1000 "chi2/NDF: " << result->fitchi2() <<
" / " << result->fitndof() <<
"\n\t " <<
1001 "vertex: (" << result->fitx() <<
", " << result->fity() <<
", " << result->fitz() <<
")" <<
"\n\t " <<
1002 "Lxy: " << result->lxy() );
1018 rhs->
trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle));
1024 auto p_mu = muon->genvecP4();
1025 auto p_trk = track->genvecP4();
1026 return (ROOT::Math::VectorUtil::DeltaPhi(p_mu, p_trk) <
m_roiPhiWidth && std::abs(p_mu.eta() - p_trk.eta()) <
m_roiEtaWidth);
1032 XYVector R(decayVertex.
x() - productionVertex.x(), decayVertex.
y() - productionVertex.y());
1037 for (
const auto& track : tracks) {
1039 if (!perigee)
return -100.;
1043 return R.Dot(pT.unit());
1050 for (
size_t i = 0; i < vertex.vxTrackAtVertex().
size(); ++i) {
1061 if (previousDecisionIDs.size() != 2) {
1062 ATH_MSG_WARNING(
"TrigBmumuxComboHypo::passDimuonTrigger() expects exactly two containers with previous decision IDs" );
1067 const std::vector<HLT::Identifier>& legDecisionIDs = tool->legDecisionIds();
1068 if (legDecisionIDs.size() == 1 && tool->legMultiplicity().at(0) >= 2) {
1070 const DecisionID id = legDecisionIDs[0].numeric();
1073 else if (legDecisionIDs.size() == 2) {
1076 bool inverse =
true;
1077 for (
size_t i = 0; i < 2; ++i) {
1081 if (direct || inverse)
return true;
1084 ATH_MSG_WARNING(
"TrigBmumuxComboHypo can not check decisions for " << tool->name() );
#define ATH_CHECK
Evaluate an expression and check for errors.
ElementLink()
Default constructor.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
Base class for elements of a container that can have aux data.
ElementLink< xAOD::TrackParticleContainer > linkTrack(const xAOD::TrackParticle *trk)
size_t size() const
Number of registered mappings.
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 SG::ReadHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsInput() const
virtual StatusCode initialize() override
const T * get(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
TrigCompositeUtils::DecisionContainer & decisions()
const TrigCompositeUtils::DecisionContainer & previousDecisions() const
xAOD::TrigBphysContainer & trigBphysCollection()
Amg::Vector3D beamSpotPosition() const
const EventContext & context() const
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
pointer_type ptr()
Dereference the pointer.
Gaudi::Property< bool > m_dimuon_rejectSameChargeTracks
Gaudi::Property< bool > m_BcToDplusMuMu_useFastFit
StatusCode findBmumuxCandidates_fit(TrigBmumuxState &, size_t dimuonIndex, bool makeCombinations=false) const
Perform fit of B decays for the topologies described above if makeCombinations = false.
Gaudi::Property< std::pair< double, double > > m_BcToMuMuPion_massRange
Gaudi::Property< float > m_BdToMuMuKstar0_chi2
ToolHandle< Trk::TrkVKalVrtFitter > m_vertexFitter
Gaudi::Property< bool > m_BdToMuMuKstar0_rejectSameChargeTracks
Gaudi::Property< bool > m_BdToMuMuKstar0_useFastFit
Gaudi::Property< double > m_BdToMuMuKstar0_minPionPt
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_massRange
std::unique_ptr< xAOD::Vertex > fit(const EventContext &context, const std::vector< ElementLink< xAOD::TrackParticleContainer > > &trackParticleLinks, Decay decay=kPsi_2mu, const xAOD::Vertex *dimuon=nullptr) const
Perform a vertex fit on selected tracks.
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_phiMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_D0MassRange
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_DplusMassRange
Gaudi::Property< bool > m_BcToDsMuMu
Gaudi::Property< double > m_fastFit_2mu1trk_chi2
Gaudi::Property< bool > m_BcToMuMuPion
Gaudi::Property< double > m_BplusToMuMuKaon_minKaonPt
Gaudi::Property< std::pair< double, double > > m_BsToMuMuPhi1020_massRange
Gaudi::Property< double > m_BcToDsMuMu_minPionPt
Gaudi::Property< std::pair< double, double > > m_BdToMuMuKstar0_massRange
TrigCompositeUtils::DecisionIDContainer m_allowedIDs
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Gaudi::Property< bool > m_LambdaBToMuMuProtonKaon
Gaudi::Property< double > m_roiPhiWidth
Gaudi::Property< double > m_BcToMuMuPion_minPionPt
SG::WriteHandleKey< xAOD::TrigBphysContainer > m_trigBphysContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
Gaudi::Property< double > m_dimuon_chi2
Gaudi::Property< float > m_BsToMuMuPhi1020_chi2
Gaudi::Property< bool > m_BcToDsMuMu_useFastFit
Gaudi::Property< double > m_BsToMuMuPhi1020_minKaonPt
ToolHandle< InDet::VertexPointEstimator > m_vertexPointEstimator
bool passDimuonTrigger(const std::vector< const TrigCompositeUtils::DecisionIDContainer * > &previousDecisionIDs) const
Gaudi::Property< std::pair< double, double > > m_BsToMuMuPhi1020_phiMassRange
Gaudi::Property< float > m_BcToDsMuMu_chi2
Gaudi::Property< std::pair< double, double > > m_BplusToMuMuKaon_massRange
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_DsMassRange
Gaudi::Property< float > m_BcToMuMuPion_chi2
Gaudi::Property< double > m_BcToDstarMuMu_minD0KaonPt
Gaudi::Property< double > m_BdToMuMuKstar0_minKaonPt
double Lxy(const Amg::Vector3D &productionVertex, const xAOD::Vertex &decayVertex) const
Calculate the Lxy (~distance between vertices) It is defined as the transverse distance between the p...
Gaudi::Property< bool > m_LambdaBToMuMuProtonKaon_useFastFit
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
Gaudi::Property< std::pair< double, double > > m_LambdaBToMuMuProtonKaon_massRange
StatusCode findBmumuxCandidates(TrigBmumuxState &) const
Find B decays by appling next three subprocedures to each found dimuon candidate.
Gaudi::Property< std::pair< double, double > > m_dimuon_massRange
StatusCode mergeMuonsFromDecisions(TrigBmumuxState &) const
Go through state.previousDecisions(), fetch xAOD::Muons objects attached to decisions and save links ...
Gaudi::Property< float > m_BplusToMuMuKaon_chi2
Gaudi::Property< bool > m_BsToMuMuPhi1020
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minKaonPt
Gaudi::Property< bool > m_BplusToMuMuKaon
Gaudi::Property< bool > m_BdToMuMuKstar0
Gaudi::Property< double > m_BcToDstarMuMu_minD0PionPt
StatusCode findBmumuxCandidates_selectTracks(TrigBmumuxState &, size_t dimuonIndex) const
Select tracks in vicinity of given dimuon vertex.
StatusCode findBmumuxCandidates_fastFit(TrigBmumuxState &, size_t dimuonIndex) const
Go through (dimuon+track) and (track+track) combinations found by findBmumuxCandidates_fit(makeCombin...
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_DstarMassRange
xAOD::TrigBphys * makeTriggerObject(TrigBmumuxState &state, const xAOD::Vertex &vertex, xAOD::TrigBphys::pType type=xAOD::TrigBphys::MULTIMU, const std::vector< double > &trkMass={PDG::mMuon, PDG::mMuon}, const ElementLink< xAOD::TrigBphysContainer > &dimuonLink=ElementLink< xAOD::TrigBphysContainer >()) const
Construct the trigger object that may be stored for debugging or matching.
Gaudi::Property< double > m_BcToDstarMuMu_minDstarPionPt
Gaudi::Property< std::pair< double, double > > m_LambdaBToMuMuProtonKaon_dimuonMassRange
Gaudi::Property< bool > m_BplusToMuMuKaon_useFastFit
Gaudi::Property< bool > m_BsToMuMuPhi1020_useFastFit
bool isInSameRoI(const xAOD::Muon *, const xAOD::TrackParticle *) const
Attempts to identify if the track is in the same RoI as the muon by comparing the angle with the RoI ...
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_dimuonMassRange
TrigBmumuxComboHypo()=delete
virtual StatusCode initialize() override
Gaudi::Property< double > m_roiEtaWidth
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_massRange
Gaudi::Property< double > m_BcToDplusMuMu_minPionPt
Gaudi::Property< bool > m_BcToDstarMuMu
Gaudi::Property< std::pair< double, double > > m_BdToMuMuKstar0_KstarMassRange
static const std::vector< std::vector< double > > s_trkMass
Gaudi::Property< bool > m_BcToDstarMuMu_makeDstar
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_massRange
SG::ReadHandleKey< xAOD::MuonContainer > m_muonContainerKey
ToolHandle< GenericMonitoringTool > m_monTool
Gaudi::Property< double > m_BcToDstarMuMu_maxDstarPionZ0
Gaudi::Property< bool > m_BcToDplusMuMu
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minProtonPt
Gaudi::Property< bool > m_BcToMuMuPion_useFastFit
Gaudi::Property< size_t > m_fitAttemptsBreakThreshold
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_dimuonMassRange
Gaudi::Property< float > m_BcToDstarMuMu_chi2
Gaudi::Property< double > m_deltaR
Gaudi::Property< size_t > m_fitAttemptsWarningThreshold
Gaudi::Property< float > m_LambdaBToMuMuProtonKaon_chi2
Gaudi::Property< std::pair< double, double > > m_BcToMuMuPion_dimuonMassRange
Gaudi::Property< double > m_fastFit_2trk_chi2
StatusCode mergeTracksFromViews(TrigBmumuxState &) const
Go through state.previousDecisions() and fetch xAOD::TrackParticle objects associated with the neares...
virtual StatusCode execute(const EventContext &context) const override
Gaudi::Property< bool > m_BsToMuMuPhi1020_rejectSameChargeTracks
StatusCode createDecisionObjects(TrigBmumuxState &) const
Create a decision for each xAOD::TrigBphys object from state.trigBphysCollection() and save it to sta...
Gaudi::Property< float > m_BcToDplusMuMu_chi2
StatusCode findDimuonCandidates(TrigBmumuxState &) const
Make all possible dimuon combinations from state.muons(), fit muon InDet tracks to the common vertex,...
bool isInMassRange(double mass, const std::pair< double, double > &range) const
Checks that the given mass value falls into the specified range.
bool isIdenticalTracks(const xAOD::TrackParticle *lhs, const xAOD::TrackParticle *rhs) const
Attempts to identify identical tracks by selection on DeltaR.
Gaudi::Property< double > m_trkZ0
Gaudi::Property< double > m_BcToDplusMuMu_minKaonPt
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minKstarMass
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_dimuonMassRange
Gaudi::Property< double > m_BcToDsMuMu_minKaonPt
xAOD::TrackParticle::GenVecFourMom_t momentum(const xAOD::Vertex &vertex, const std::vector< double > &trkMass) const
Calculate 4-momentum of the fitted vertex particle assuming the given masses.
State class for TrigBmumuxComboHypo algorithm.
std::vector< Muon > muons
std::map< const xAOD::TrackParticle *, double > selectedTrackZ0
void addTrackCombination(size_t i1)
bool isBadCombination(size_t i1) const
std::vector< ElementLink< xAOD::TrackParticleContainer > > selectedTracks
std::map< size_t, size_t > trackCombinations
StatusCode addTriggerObject(xAOD::TrigBphys *triggerObject)
std::vector< size_t > badTrackCombinations
xAOD::VertexContainer dimuons
std::vector< ElementLink< xAOD::TrackParticleContainer > > tracks
std::vector< std::array< size_t, 2 > > trigBphysMuonIndices
const Amg::Vector3D & momentum() const
Access method for the momentum.
const TrackParticle * trackParticle(TrackParticleType type) const
Returns a pointer (which can be a nullptr) to the 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.
float pt() const
accessor method: pt
float eta() const
accessor method: eta
float phi() const
accessor method: phi
const TrigBphys_v1 * lowerChain() const
accessor method: lowerChain decay particle
float fitx() const
accessor method: x position of vertex
float fitz() const
accessor method: z position of vertex
float mass() const
accessor method: mass
pType
enum for different particle types
float fity() const
accessor method: y position of vertex
bool setObjectLink(const std::string &name, const ElementLink< CONTAINER > &link)
Set the link to an object.
bool addObjectCollectionLinks(const std::string &collectionName, const std::vector< ElementLink< CONTAINER > > &links)
Add links to multiple objects within a collection. Performs de-duplication.
float z() const
Returns the z position.
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
float y() const
Returns the y position.
bool vxTrackAtVertexAvailable() const
Check if VxTrackAtVertices are attached to the object.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
const Amg::Vector3D & position() const
Returns the 3-pos.
float x() const
Returns the x position.
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
const std::string & roiString()
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()
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.
LinkInfo< T > findLink(const EventContext &ctx, 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 & seedString()
xAOD::TrigCompositeContainer DecisionContainer
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the 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.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< TrackParametersDim, Charged > TrackParameters
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.
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
static constexpr CLID ID()
static constexpr double mD0
static constexpr double mProton
static constexpr double mPion
static constexpr double mMuon
static constexpr double mJpsi
static constexpr double mKaon