29#include "Math/GenVector/VectorUtil.h"
30#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) {
262 previousDecisionIDs[1] = &muons[itrk2].decisionIDs;
266 auto charge2 = trk2->
charge();
268 double mass = (p1 + p2).M();
270 ATH_MSG_DEBUG(
"muon 1: " << p1.Pt()<<
" / " << p1.Eta() <<
" / " << p1.Phi() <<
" / " << trk1->
charge() );
271 ATH_MSG_DEBUG(
"muon 2: " << p2.Pt()<<
" / " << p2.Eta() <<
" / " << p2.Phi() <<
" / " << trk2->
charge() );
275 ATH_MSG_DEBUG(
"muon pair is rejected by opposite charge check" );
280 ATH_MSG_DEBUG(
"muon pair did not pass passDimuonTrigger() check" );
285 ATH_MSG_DEBUG(
"muon pair is out of the requested mass range" );
290 auto vertex =
fit(state.
context(), trackParticleLinks);
291 if (!vertex)
continue;
296 ATH_MSG_ERROR(
"xAOD::Vertex could not be converted to xAOD::TrigBphys object: please enable MakeExtendedVertex option in vertex fitter " <<
m_vertexFitter->name() );
297 return StatusCode::FAILURE;
309 return StatusCode::SUCCESS;
315 std::vector<int> nSelectedTrk;
321 for (
size_t dimuonIndex = 0; dimuonIndex < state.
dimuons.
size(); ++dimuonIndex) {
332 mon_nTrk = state.
tracks.size();
335 return StatusCode::SUCCESS;
344 selectedTracks.clear();
345 selectedTrackZ0.clear();
349 std::vector<const xAOD::Muon*> muons(2,
nullptr);
351 for (
size_t i = 0; i < 2; ++i) {
352 const auto& muon = state.
muons.at(muonIndices[i]);
353 muons[i] = *muon.link;
362 for (
const auto& trackEL : state.
tracks) {
366 if (perigee && std::abs(perigee->parameters()[
Trk::z0]) <
m_trkZ0) {
367 selectedTracks.push_back(trackEL);
368 selectedTrackZ0[*trackEL] = perigee->parameters()[
Trk::z0];
372 selectedTracks.push_back(trackEL);
373 selectedTrackZ0[*trackEL] = -1000.;
378 if (selectedTracks.size() < 2) {
379 ATH_MSG_DEBUG(
"Found no tracks consistent with dimuon vertex " << dimuonIndex );
380 selectedTracks.clear();
381 selectedTrackZ0.clear();
382 return StatusCode::SUCCESS;
384 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()); });
386 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()); });
388 std::sort(selectedTracks.begin(), selectedTracks.end(), [](
const auto& lhs,
const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
390 ATH_MSG_DEBUG(
"Found " << selectedTracks.size() <<
" tracks consistent with dimuon vertex " << dimuonIndex );
392 return StatusCode::SUCCESS;
403 ATH_CHECK( dimuonTriggerObjectEL.isValid() );
406 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx1(dimuon->
trackParticleLinks());
407 trackParticleLinks_vtx1.emplace_back();
410 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx2(trackParticleLinks_vtx1);
411 trackParticleLinks_vtx2.emplace_back();
414 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx3(3);
420 size_t iterations = 0;
422 bool isOverWarningThreshold =
false;
424 for (
size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
427 trackParticleLinks_vtx1[2] = selectedTracks[itrk1];
429 auto charge1 = trk1->
charge();
431 std::unique_ptr<xAOD::Vertex> vtx1;
432 bool makeFit_vtx1 = !makeCombinations;
433 bool passFastFit_vtx1 = (!makeCombinations && !state.
isBadCombination(itrk1));
443 makeFit_vtx1 =
false;
461 makeFit_vtx1 =
false;
472 for (
size_t itrk2 = itrk1 + 1; itrk2 < selectedTracks.size(); ++itrk2) {
475 trackParticleLinks_vtx2[2] = selectedTracks[itrk1];
476 trackParticleLinks_vtx2[3] = selectedTracks[itrk2];
478 auto charge2 = trk2->
charge();
480 std::unique_ptr<xAOD::Vertex> vtx2;
481 bool makeFit_vtx2 = !makeCombinations;
498 makeFit_vtx2 =
false;
521 makeFit_vtx2 =
false;
543 makeFit_vtx2 =
false;
567 makeFit_vtx2 =
false;
590 makeFit_vtx2 =
false;
600 for (
size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
602 if (itrk3 == itrk1 || itrk3 == itrk2)
continue;
604 trackParticleLinks_vtx3[0] = selectedTracks[itrk1];
605 trackParticleLinks_vtx3[1] = selectedTracks[itrk2];
606 trackParticleLinks_vtx3[2] = selectedTracks[itrk3];
610 std::unique_ptr<xAOD::Vertex> vtx3;
611 bool makeFit_vtx3 = !makeCombinations;
612 bool passFastFit_vtx3 = (!makeCombinations && !state.
isBadCombination(itrk1, itrk2, itrk3));
619 charge1 * charge2 < 0. &&
630 vtx3 =
fit(state.
context(), trackParticleLinks_vtx3,
kDs, dimuon);
631 makeFit_vtx3 =
false;
645 charge1 * charge2 > 0. && charge1 *
charge3 < 0. &&
656 makeFit_vtx3 =
false;
671 isOverWarningThreshold =
true;
674 ATH_MSG_WARNING(
"Dimuon + tracks: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
682 isOverWarningThreshold =
false;
685 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_D0(2);
687 for (
size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
690 trackParticleLinks_D0[0] = selectedTracks[itrk1];
693 auto charge1 = trk1->
charge();
695 for (
size_t itrk2 = 0; itrk2 < selectedTracks.size(); ++itrk2) {
696 if (itrk2 == itrk1)
continue;
699 trackParticleLinks_D0[1] = selectedTracks[itrk2];
702 auto charge2 = trk2->
charge();
704 std::unique_ptr<xAOD::Vertex> D0;
705 if (charge1 * charge2 < 0. &&
710 D0 =
fit(state.
context(), trackParticleLinks_D0,
kD0, dimuon);
713 bool isValidD0 =
false;
716 ATH_MSG_DEBUG(
"Partially reconstructed B_c+(-> mu+ mu- D0 X) candidate has been created" );
724 for (
size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
726 if (itrk3 == itrk1 || itrk3 == itrk2)
continue;
729 trackParticleLinks_vtx1[2] = selectedTracks[itrk3];
740 ATH_MSG_DEBUG(
"Decay vertex(mu+ mu- D*+.pi+) for B_c+ candidate has been created" );
744 ATH_CHECK( triggerObjectEL_vtx1.isValid() );
747 auto Bc_vtx2 =
fit(state.
context(), trackParticleLinks_D0,
kD0, Bc_vtx1.get());
750 ATH_MSG_DEBUG(
"Fully reconstructed B_c+(-> mu+ mu- D*+) candidate has been created" );
763 isOverWarningThreshold =
true;
766 ATH_MSG_WARNING(
"B_c+ -> mu+ mu- D*+: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
774 return StatusCode::SUCCESS;
785 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2mu1trk(dimuon->
trackParticleLinks());
786 trackParticleLinks_2mu1trk.emplace_back();
789 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2trk(2);
792 size_t iterations = 0;
794 if (item.second < 5)
continue;
796 size_t key = item.first;
814 return StatusCode::SUCCESS;
824 ATH_MSG_DEBUG(
"Found xAOD::TrigBphys object: mass = " << triggerObject->mass() );
831 if (!dimuonTriggerObject) {
832 ATH_MSG_ERROR(
"Failed to found a valid link for preceding dimuon trigger object" );
833 return StatusCode::FAILURE;
839 auto dimuonIndex = dimuonTriggerObject->index();
842 ATH_MSG_ERROR(
"Failed to find original muons the dimuon vertex had been built from" );
843 return StatusCode::FAILURE;
849 std::vector<const DecisionIDContainer*> previousDecisionIDs;
851 const auto& muon = state.
muons.at(i);
855 previousDecisionIDs.push_back(&muon.decisionIDs);
863 ATH_CHECK( tool->decideOnSingleObject(decision, previousDecisionIDs) );
867 return StatusCode::SUCCESS;
872 const EventContext& context,
879 if (trackParticleLinks.size() < 2) {
880 ATH_MSG_WARNING(
"At least two tracks should be given to the vertex fitter" );
884 std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(),
nullptr);
885 std::transform(trackParticleLinks.begin(), trackParticleLinks.end(), tracklist.begin(),
894 ATH_MSG_WARNING(
"Already fitted dimuon vertex should be provided for B -> mu1 mu2 trk1 .. trkN decay as a starting point for fitter" );
898 const Trk::Perigee& perigee1 = tracklist[0]->perigeeParameters();
899 const Trk::Perigee& perigee2 = tracklist[1]->perigeeParameters();
900 startingPoint =
m_vertexPointEstimator->getCirclesIntersectionPoint(&perigee1, &perigee2, flag, errorcode);
901 if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
903 ATH_MSG_VERBOSE(
"Starting point: (" << startingPoint(0) <<
", " << startingPoint(1) <<
", " << startingPoint(2) <<
")" );
914 std::unique_ptr<xAOD::Vertex> vertex(
m_vertexFitter->fit(tracklist, startingPoint, *fitterState));
920 ATH_MSG_VERBOSE(
"Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() <<
")" );
927 vertex->clearTracks();
928 vertex->setTrackParticleLinks(trackParticleLinks);
938 const std::vector<double>& trkMass,
946 std::vector<xAOD::TrackParticle::GenVecFourMom_t> momenta;
947 if (!vertex.vxTrackAtVertexAvailable())
return nullptr;
948 for (
size_t i = 0; i < vertex.vxTrackAtVertex().
size(); ++i) {
950 if (!perigee)
return nullptr;
952 momenta.emplace_back(p.x(), p.y(), p.z(), trkMass[i]);
955 if (isCascadeDecay) {
956 momentum += ROOT::Math::PtEtaPhiMVector(dimuon->
pt(), dimuon->
eta(), dimuon->
phi(), dimuon->
mass());
960 result->makePrivateStore();
964 mass +=
PDG::mD0 - (momenta[0] + momenta[1]).M();
967 mass +=
PDG::mJpsi - (isCascadeDecay ? dimuon->
mass() : (momenta[0] + momenta[1]).M());
973 result->setFitx(vertex.x());
974 result->setFity(vertex.y());
975 result->setFitz(vertex.z());
976 result->setFitchi2(vertex.chiSquared());
977 result->setFitndof(vertex.numberDoF());
980 result->setLxy(
Lxy(productionVertex, vertex));
983 result->setTrackParticleLinks(vertex.trackParticleLinks());
987 result->setLowerChainLink(dimuonLink);
991 "TrigBphys object:\n\t " <<
992 "roiId: " << result->roiId() <<
"\n\t " <<
993 "particleType: " << result->particleType() <<
"\n\t " <<
994 "level: " << result->level() <<
"\n\t " <<
995 "eta: " << result->eta() <<
"\n\t " <<
996 "phi: " << result->phi() <<
"\n\t " <<
997 "mass: " << result->mass() <<
"\n\t " <<
998 "fitmass: " << result->fitmass() <<
"\n\t " <<
999 "chi2/NDF: " << result->fitchi2() <<
" / " << result->fitndof() <<
"\n\t " <<
1000 "vertex: (" << result->fitx() <<
", " << result->fity() <<
", " << result->fitz() <<
")" <<
"\n\t " <<
1001 "Lxy: " << result->lxy() );
1017 rhs->
trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle));
1023 auto p_mu = muon->genvecP4();
1024 auto p_trk = track->genvecP4();
1025 return (ROOT::Math::VectorUtil::DeltaPhi(p_mu, p_trk) <
m_roiPhiWidth && std::abs(p_mu.eta() - p_trk.eta()) <
m_roiEtaWidth);
1031 XYVector R(decayVertex.
x() - productionVertex.x(), decayVertex.
y() - productionVertex.y());
1036 for (
const auto& track : tracks) {
1038 if (!perigee)
return -100.;
1042 return R.Dot(pT.unit());
1049 for (
size_t i = 0; i < vertex.vxTrackAtVertex().
size(); ++i) {
1060 if (previousDecisionIDs.size() != 2) {
1061 ATH_MSG_WARNING(
"TrigBmumuxComboHypo::passDimuonTrigger() expects exactly two containers with previous decision IDs" );
1066 const std::vector<HLT::Identifier>& legDecisionIDs = tool->legDecisionIds();
1067 if (legDecisionIDs.size() == 1 && tool->legMultiplicity().at(0) >= 2) {
1069 const DecisionID id = legDecisionIDs[0].numeric();
1072 else if (legDecisionIDs.size() == 2) {
1075 bool inverse =
true;
1076 for (
size_t i = 0; i < 2; ++i) {
1080 if (direct || inverse)
return true;
1083 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_VERBOSE(x)
#define ATH_MSG_WARNING(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 NULL) 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 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