ATLAS Offline Software
TrigBmumuxComboHypo.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <algorithm>
6 #include <numeric>
7 #include <iterator>
8 
9 #include "TrigBmumuxComboHypo.h"
10 
11 #include "xAODMuon/Muon.h"
13 #include "xAODTracking/Vertex.h"
20 
23 
24 #include "AthViews/View.h"
25 #include "AthViews/ViewHelper.h"
27 
28 #include "Math/GenVector/VectorUtil.h"
29 #include "Math/Vector2D.h"
30 
31 
36 using ROOT::Math::XYVector;
37 
38 
39 const std::vector<std::vector<double>> TrigBmumuxComboHypo::s_trkMass{
40  {PDG::mMuon, PDG::mMuon}, // {Psi.mu1, Psi.mu2}
41  {PDG::mMuon, PDG::mMuon, PDG::mKaon}, // {Psi.mu1, Psi.mu2, trk1}
42  {PDG::mMuon, PDG::mMuon, PDG::mKaon, PDG::mKaon}, // {Psi.mu1, Psi.mu2, trk1, trk2}
43  {PDG::mKaon, PDG::mKaon, PDG::mPion}, // {D_s+.K+, D_s+.K-, D_s+.pi+}
44  {PDG::mPion, PDG::mPion, PDG::mKaon}, // {D+.pi+, D+.pi+, D+.K-}
45  {PDG::mKaon, PDG::mPion}, // {D0.K-, D0.pi+}
46  {PDG::mMuon, PDG::mMuon, PDG::mPion}, // {Psi.mu1, Psi.mu2, D*+.pi+}
47  {PDG::mPion, PDG::mPion}, // {trk1, trk2}
48  {PDG::mMuon, PDG::mMuon, PDG::mPion} // {mu1, mu2, trk1}
49 };
50 
51 TrigBmumuxComboHypo::TrigBmumuxComboHypo(const std::string& name, ISvcLocator* pSvcLocator)
52  : ::ComboHypo(name, pSvcLocator) {}
53 
54 
56  ATH_MSG_DEBUG( "TrigBmumuxComboHypo::initialize()" );
57 
59 
60  ATH_CHECK( m_muonContainerKey.initialize() );
64  ATH_CHECK( m_trigBphysContainerKey.initialize() );
66 
67  ATH_CHECK( m_vertexFitter.retrieve() );
68  ATH_CHECK( m_vertexPointEstimator.retrieve() );
69  ATH_CHECK( m_trackToVertexTool.retrieve() );
70 
71  // allowed IDs to filter out incoming decisions at L2 level
72  for (const auto& item : triggerMultiplicityMap()) {
73  const HLT::Identifier id = HLT::Identifier(item.first);
74  m_allowedIDs.insert(id.numeric());
75  if (item.second.size() > 1) {
76  for (size_t i = 0; i < item.second.size(); i++) {
77  m_allowedIDs.insert(TrigCompositeUtils::createLegName(id, i).numeric());
78  }
79  }
80  }
81  if (msgLvl(MSG::DEBUG)) {
82  ATH_MSG_DEBUG( "Allowed decisions:" );
83  for (const DecisionID& id : m_allowedIDs) {
84  ATH_MSG_DEBUG( " +++ " << HLT::Identifier(id) );
85  }
86  }
87 
88  if (!m_monTool.empty()) {
89  ATH_CHECK( m_monTool.retrieve() );
90  ATH_MSG_DEBUG( "GenericMonitoringTool name:" << m_monTool );
91  }
92  else {
93  ATH_MSG_DEBUG( "No GenericMonitoringTool configured: no monitoring histograms will be available" );
94  }
95 
96  return StatusCode::SUCCESS;
97 }
98 
99 
100 StatusCode TrigBmumuxComboHypo::execute(const EventContext& context) const {
101 
102  ATH_MSG_DEBUG( "TrigBmumuxComboHypo::execute() starts" );
103 
104  ATH_MSG_DEBUG( "decision input key: " << decisionsInput().at(0).key() );
105  auto previousDecisionsHandle = SG::makeHandle(decisionsInput().at(0), context);
106  ATH_CHECK( previousDecisionsHandle.isValid() );
107  ATH_MSG_DEBUG( "Running with " << previousDecisionsHandle->size() << " previous decisions" );
108 
110 
111  auto trigBphysHandle = SG::makeHandle(m_trigBphysContainerKey, context);
112  ATH_CHECK( trigBphysHandle.record(std::make_unique<xAOD::TrigBphysContainer>(),
113  std::make_unique<xAOD::TrigBphysAuxContainer>()) );
114 
115  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle {m_beamSpotKey, context};
116  ATH_CHECK( beamSpotHandle.isValid() );
117 
118  auto state = std::make_unique<TrigBmumuxState>(context, *previousDecisionsHandle, *outputDecisionsHandle, trigBphysHandle.ptr(), *beamSpotHandle);
119 
121  ATH_CHECK( findDimuonCandidates(*state) );
122 
123  if (!state->dimuons.empty()) {
124  ATH_CHECK( mergeTracksFromViews(*state) );
125  ATH_CHECK( findBmumuxCandidates(*state) );
126  ATH_CHECK( createDecisionObjects(*state) );
127  }
128 
129  ATH_MSG_DEBUG( "TrigBmumuxComboHypo::execute() terminates with StatusCode::SUCCESS" );
130  return StatusCode::SUCCESS;
131 }
132 
133 
135 
136  auto& muons = state.muons;
137  muons.clear();
138 
139  // all muons from views are already connected with previous decisions by TrigMuonEFHypoAlg
140  for (const Decision* decision : state.previousDecisions()) {
142  auto muonEL = decision->objectLink<xAOD::MuonContainer>(TrigCompositeUtils::featureString());
143  const xAOD::Muon* muon = *muonEL;
144  if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) continue;
145 
146  auto decisionEL = TrigCompositeUtils::decisionToElementLink(decision, state.context());
147  auto itr = std::find_if(muons.begin(), muons.end(), [this, muon](const auto& x){ return isIdenticalTracks(muon, *x.link); });
148  if (itr == muons.end()) {
149  muons.push_back({muonEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL), DecisionIDContainer()});
150  }
151  else {
152  (*itr).decisionLinks.push_back(decisionEL);
153  }
154  }
155 
156  // muon->pt() is equal to muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)->pt()
157  // and the later is used by TrigMuonEFHypoTool for classification of muEFCB candidates
158  std::sort(muons.begin(), muons.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs.link)->pt() > (*rhs.link)->pt()); });
159 
160  // for each muon we extract DecisionIDs stored in the associated Decision objects and copy them at muon.decisionIDs
161  for (auto& item : muons) {
162  for (const ElementLink<xAOD::TrigCompositeContainer>& decisionEL : item.decisionLinks) {
163  TrigCompositeUtils::decisionIDs(*decisionEL, item.decisionIDs);
164  }
165  }
166 
167  if (msgLvl(MSG::DEBUG)) {
168  ATH_MSG_DEBUG( "Dump found muons before vertex fit: " << muons.size() << " candidates" );
169  for (const auto& item : muons) {
170  const xAOD::Muon* muon = *item.link;
171  const xAOD::TrackParticle* track = *muon->inDetTrackParticleLink();
172  ATH_MSG_DEBUG( " -- muon InDetTrackParticle pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
173  ATH_MSG_DEBUG( " muon CombinedTrackParticle pt: " << muon->pt() );
174  ATH_MSG_DEBUG( " allowed decisions:" );
175  for (const DecisionID& id : item.decisionIDs) {
176  ATH_MSG_DEBUG( " +++ " << HLT::Identifier(id) );
177  }
178  }
179  }
180 
181  return StatusCode::SUCCESS;
182 }
183 
184 
186 
187  auto& tracks = state.tracks;
188  tracks.clear();
189 
190  size_t viewCounter = 0;
191  for (const Decision* decision : state.previousDecisions()) {
192  auto viewLinkInfo = TrigCompositeUtils::findLink<ViewContainer>(decision, TrigCompositeUtils::viewString(), true);
193  ATH_CHECK( viewLinkInfo.isValid() );
194  auto view = *viewLinkInfo.link;
195 
196  auto roiLinkInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>(decision, TrigCompositeUtils::roiString(), true);
197  ATH_CHECK( roiLinkInfo.isValid() );
198  const auto roi = *roiLinkInfo.link;
199 
200  auto tracksHandle = ViewHelper::makeHandle(view, m_trackParticleContainerKey, state.context());
201  ATH_CHECK( tracksHandle.isValid() );
202  ATH_MSG_DEBUG( "tracks handle " << m_trackParticleContainerKey << " size: " << tracksHandle->size() );
203 
204  std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
205  tracksFromView.reserve(tracksHandle->size());
206  for (size_t idx = 0; idx < tracksHandle->size(); ++idx) {
207  tracksFromView.emplace_back(ViewHelper::makeLink<xAOD::TrackParticleContainer>(view, tracksHandle, idx));
208  }
209 
210  for (const auto& trackEL : tracksFromView) {
211  const xAOD::TrackParticle* track = *trackEL;
212  if (track->definingParametersCovMatrixVec().empty()) continue;
213 
214  if (viewCounter == 0 ||
215  std::find_if(tracks.begin(), tracks.end(),
216  [this, track](const auto& x){ return isIdenticalTracks(track, *x); }) == tracks.end()) {
217  tracks.emplace_back(trackEL);
218  }
219  }
220  viewCounter++;
221  if (roi->composite()) {
222  state.isCompositeRoI = true;
223  break;
224  }
225  }
226  std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
227 
228  if (msgLvl(MSG::DEBUG)) {
229  ATH_MSG_DEBUG( "Dump found tracks before vertex fit: " << tracks.size() << " candidates" );
230  for (const auto& trackEL : tracks) {
231  const xAOD::TrackParticle* track = *trackEL;
232  ATH_MSG_DEBUG( " -- track pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
233  }
234  }
235  return StatusCode::SUCCESS;
236 }
237 
238 
240 
241  auto mon_nDimuon = Monitored::Scalar<int>("nDimuon", 0);
242  auto group = Monitored::Group(m_monTool, mon_nDimuon);
243 
244  const auto& muons = state.muons;
245  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks(2);
246  std::vector<const DecisionIDContainer*> previousDecisionIDs(2, nullptr);
247 
248  for (size_t itrk1 = 0; itrk1 < muons.size(); ++itrk1) {
249  const xAOD::Muon* mu1 = *muons[itrk1].link;
251  previousDecisionIDs[0] = &muons[itrk1].decisionIDs;
252  const xAOD::TrackParticle* trk1 = *trackParticleLinks[0];
253  auto p1 = trk1->genvecP4();
254  p1.SetM(PDG::mMuon);
255  auto charge1 = trk1->charge();
256 
257  for (size_t itrk2 = itrk1 + 1; itrk2 < muons.size(); ++itrk2) {
258  const xAOD::Muon* mu2 = *muons[itrk2].link;
260  previousDecisionIDs[1] = &muons[itrk2].decisionIDs;
261  const xAOD::TrackParticle* trk2 = *trackParticleLinks[1];
262  auto p2 = trk2->genvecP4();
263  p2.SetM(PDG::mMuon);
264  auto charge2 = trk2->charge();
265 
266  double mass = (p1 + p2).M();
267 
268  ATH_MSG_DEBUG( "muon 1: " << p1.Pt()<< " / " << p1.Eta() << " / " << p1.Phi() << " / " << trk1->charge() );
269  ATH_MSG_DEBUG( "muon 2: " << p2.Pt()<< " / " << p2.Eta() << " / " << p2.Phi() << " / " << trk2->charge() );
270  ATH_MSG_DEBUG( "track pair mass: " << mass );
271 
272  if (m_dimuon_rejectSameChargeTracks && charge1 * charge2 > 0.) {
273  ATH_MSG_DEBUG( "muon pair is rejected by opposite charge check" );
274  continue;
275  }
276 
277  if (!passDimuonTrigger(previousDecisionIDs)) {
278  ATH_MSG_DEBUG( "muon pair did not pass passDimuonTrigger() check" );
279  continue;
280  }
281 
283  ATH_MSG_DEBUG( "muon pair is out of the requested mass range" );
284  continue;
285  }
286 
287  // fit muons to the common vertex and pass this vertex to the dimuons collection which also takes the ownership of the created object
288  auto vertex = fit(state.context(), trackParticleLinks);
289  if (!vertex) continue;
290 
291  // convert vertex to trigger object and add it to the output xAOD::TrigBphysContainer
292  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vertex);
293  if (!trigBphys) {
294  ATH_MSG_ERROR( "xAOD::Vertex could not be converted to xAOD::TrigBphys object: please enable MakeExtendedVertex option in vertex fitter " << m_vertexFitter->name() );
295  return StatusCode::FAILURE;
296  }
297 
298  // the dimuon vertex in the xAOD::TrigBphysContainer is used as a reference for the upcoming B-candidates and to fire bBmumux_idperf chain
299  state.dimuons.push_back(vertex.release());
300  state.trigBphysMuonIndices.emplace_back(std::array<size_t, 2>{itrk1, itrk2});
301  state.trigBphysCollection().push_back(trigBphys);
302  }
303  }
304  mon_nDimuon = state.dimuons.size();
305  ATH_MSG_DEBUG( "Found " << state.dimuons.size() << " dimuon candidates" );
306 
307  return StatusCode::SUCCESS;
308 }
309 
310 
312 
313  std::vector<int> nSelectedTrk;
314  auto mon_nTrk = Monitored::Scalar<int>("nTrk", 0);
315  auto mon_nSelectedTrk = Monitored::Collection("nSelectedTrk", nSelectedTrk);
316  auto mon_nBPhysObject = Monitored::Scalar<int>("nBPhysObject", 0);
317  auto group = Monitored::Group(m_monTool, mon_nTrk, mon_nSelectedTrk, mon_nBPhysObject);
318 
319  for (size_t dimuonIndex = 0; dimuonIndex < state.dimuons.size(); ++dimuonIndex) {
320 
321  ATH_CHECK( findBmumuxCandidates_selectTracks(state, dimuonIndex) );
322  if (state.selectedTracks.empty()) continue;
323  nSelectedTrk.push_back(state.selectedTracks.size());
324 
325  ATH_CHECK( findBmumuxCandidates_fit(state, dimuonIndex, true) );
326  ATH_CHECK( findBmumuxCandidates_fastFit(state, dimuonIndex) );
327  ATH_CHECK( findBmumuxCandidates_fit(state, dimuonIndex) );
328  }
329 
330  mon_nTrk = state.tracks.size();
331  mon_nBPhysObject = state.trigBphysCollection().size() - state.dimuons.size();
332 
333  return StatusCode::SUCCESS;
334 }
335 
336 
338 
339  auto& selectedTracks = state.selectedTracks;
340  auto& selectedTrackZ0 = state.selectedTrackZ0;
341 
342  selectedTracks.clear();
343  selectedTrackZ0.clear();
344 
345  const xAOD::Vertex* dimuon = state.dimuons.get(dimuonIndex);
346 
347  std::vector<const xAOD::Muon*> muons(2, nullptr);
348  const auto& muonIndices = state.trigBphysMuonIndices.at(dimuonIndex);
349  for (size_t i = 0; i < 2; ++i) {
350  const auto& muon = state.muons.at(muonIndices[i]);
351  muons[i] = *muon.link;
352  }
353 
354  const xAOD::TrackParticle* mu1 = dimuon->trackParticle(0);
355  const xAOD::TrackParticle* mu2 = dimuon->trackParticle(1);
356 
357  // check impact parameter of the track with respect to the fitted dimuon vertex
358  // we can safely omit tracks with large z0
359  state.selectedTracks.reserve(state.tracks.size());
360  for (const auto& trackEL : state.tracks) {
361  if (state.isCompositeRoI && !isInSameRoI(muons[0], *trackEL) && !isInSameRoI(muons[1], *trackEL)) continue;
362  if (m_trkZ0 > 0.) {
363  std::unique_ptr<const Trk::Perigee> perigee(m_trackToVertexTool->perigeeAtVertex(state.context(), **trackEL, dimuon->position()));
364  if (perigee && std::abs(perigee->parameters()[Trk::z0]) < m_trkZ0) {
365  selectedTracks.push_back(trackEL);
366  selectedTrackZ0[*trackEL] = perigee->parameters()[Trk::z0];
367  }
368  }
369  else {
370  selectedTracks.push_back(trackEL);
371  selectedTrackZ0[*trackEL] = -1000.;
372  }
373  }
374 
375  // remove muon duplicates
376  if (selectedTracks.size() < 2) {
377  ATH_MSG_DEBUG( "Found no tracks consistent with dimuon vertex " << dimuonIndex );
378  selectedTracks.clear();
379  selectedTrackZ0.clear();
380  return StatusCode::SUCCESS;
381  }
382  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()); });
383  if (isIdenticalTracks(mu1, *selectedTracks.back())) selectedTracks.pop_back();
384  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()); });
385  if (isIdenticalTracks(mu2, *selectedTracks.back())) selectedTracks.pop_back();
386  std::sort(selectedTracks.begin(), selectedTracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
387 
388  ATH_MSG_DEBUG( "Found " << selectedTracks.size() << " tracks consistent with dimuon vertex " << dimuonIndex );
389 
390  return StatusCode::SUCCESS;
391 }
392 
393 
394 StatusCode TrigBmumuxComboHypo::findBmumuxCandidates_fit(TrigBmumuxState& state, size_t dimuonIndex, bool makeCombinations) const {
395 
396  const auto& selectedTracks = state.selectedTracks;
397  if (makeCombinations) state.trackCombinations.clear();
398 
399  const xAOD::Vertex* dimuon = state.dimuons.get(dimuonIndex);
400  auto dimuonTriggerObjectEL = ElementLink<xAOD::TrigBphysContainer>(state.trigBphysCollection(), dimuonIndex);
401  ATH_CHECK( dimuonTriggerObjectEL.isValid() );
402 
403  // vtx1 = {mu1, mu2, trk1}
404  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx1(dimuon->trackParticleLinks());
405  trackParticleLinks_vtx1.emplace_back();
406 
407  // vtx2 = {mu1, mu2, trk1, trk2}
408  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx2(trackParticleLinks_vtx1);
409  trackParticleLinks_vtx2.emplace_back();
410 
411  // vtx3 = {trk1, trk2, trk3}
412  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_vtx3(3);
413 
414  const xAOD::TrackParticle* mu1 = *trackParticleLinks_vtx1[0];
415  const xAOD::TrackParticle* mu2 = *trackParticleLinks_vtx1[1];
416  auto p_dimuon = mu1->genvecP4().SetM(PDG::mMuon) + mu2->genvecP4().SetM(PDG::mMuon);
417 
418  size_t iterations = 0;
419  size_t nTrigBphysObjects = state.trigBphysCollection().size();
420  bool isOverWarningThreshold = false;
421  // dimuon + 1 track
422  for (size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
423  const xAOD::TrackParticle* trk1 = *selectedTracks[itrk1];
424 
425  trackParticleLinks_vtx1[2] = selectedTracks[itrk1];
426  auto p_trk1 = trk1->genvecP4();
427  auto charge1 = trk1->charge();
428 
429  std::unique_ptr<xAOD::Vertex> vtx1;
430  bool makeFit_vtx1 = !makeCombinations;
431  bool passFastFit_vtx1 = (!makeCombinations && !state.isBadCombination(itrk1));
432 
433  // B+ -> mu+ mu- K+
434  if (m_BplusToMuMuKaon &&
435  p_trk1.Pt() > m_BplusToMuMuKaon_minKaonPt &&
436  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon)).M(), m_BplusToMuMuKaon_massRange)) {
437 
438  if (makeCombinations && m_BplusToMuMuKaon_useFastFit) state.addTrackCombination(itrk1);
439  if (!vtx1 && makeFit_vtx1 && (passFastFit_vtx1 || !m_BplusToMuMuKaon_useFastFit)) {
440  vtx1 = fit(state.context(), trackParticleLinks_vtx1, kB_2mu1trk, dimuon);
441  makeFit_vtx1 = false;
442  ++iterations;
443  }
444  if (vtx1 && vtx1->chiSquared() < m_BplusToMuMuKaon_chi2) {
445  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx1, xAOD::TrigBphys::BKMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon}, dimuonTriggerObjectEL);
446  ATH_CHECK( state.addTriggerObject(trigBphys) );
447  }
448  }
449 
450  // B_c+ -> J/psi(-> mu+ mu-) pi+
451  if (m_BcToMuMuPion &&
452  p_trk1.Pt() > m_BcToMuMuPion_minPionPt &&
454  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mPion)).M() - p_dimuon.M() + PDG::mJpsi, m_BcToMuMuPion_massRange)) {
455 
456  if (makeCombinations && m_BcToMuMuPion_useFastFit) state.addTrackCombination(itrk1);
457  if (!vtx1 && makeFit_vtx1 && (passFastFit_vtx1 || !m_BcToMuMuPion_useFastFit)) {
458  vtx1 = fit(state.context(), trackParticleLinks_vtx1, kB_2mu1trk, dimuon);
459  makeFit_vtx1 = false;
460  ++iterations;
461  }
462  if (vtx1 && vtx1->chiSquared() < m_BcToMuMuPion_chi2) {
463  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx1, xAOD::TrigBphys::BCPIMUMU, {PDG::mMuon, PDG::mMuon, PDG::mPion}, dimuonTriggerObjectEL);
464  ATH_CHECK( state.addTriggerObject(trigBphys) );
465  }
466  }
467  vtx1.reset();
468 
469  // dimuon + 2 tracks
470  for (size_t itrk2 = itrk1 + 1; itrk2 < selectedTracks.size(); ++itrk2) {
471  const xAOD::TrackParticle* trk2 = *selectedTracks[itrk2];
472 
473  trackParticleLinks_vtx2[2] = selectedTracks[itrk1];
474  trackParticleLinks_vtx2[3] = selectedTracks[itrk2];
475  auto p_trk2 = trk2->genvecP4();
476  auto charge2 = trk2->charge();
477 
478  std::unique_ptr<xAOD::Vertex> vtx2;
479  bool makeFit_vtx2 = !makeCombinations;
480  bool passFastFit_vtx2 = (!makeCombinations && !state.isBadCombination(itrk1) && !state.isBadCombination(itrk2));
481 
482  // B_s0 -> mu+ mu- phi(-> K+ K-)
483  if (m_BsToMuMuPhi1020 &&
484  (!m_BsToMuMuPhi1020_rejectSameChargeTracks || charge1 * charge2 < 0.) &&
485  p_trk1.Pt() > m_BsToMuMuPhi1020_minKaonPt &&
486  p_trk2.Pt() > m_BsToMuMuPhi1020_minKaonPt &&
487  isInMassRange((p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mKaon)).M(), m_BsToMuMuPhi1020_phiMassRange) &&
488  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mKaon)).M(), m_BsToMuMuPhi1020_massRange)) {
489 
490  if (makeCombinations && m_BsToMuMuPhi1020_useFastFit) {
491  state.addTrackCombination(itrk1);
492  state.addTrackCombination(itrk2);
493  }
494  if (!vtx2 && makeFit_vtx2 && (passFastFit_vtx2 || !m_BsToMuMuPhi1020_useFastFit)) {
495  vtx2 = fit(state.context(), trackParticleLinks_vtx2, kB_2mu2trk, dimuon);
496  makeFit_vtx2 = false;
497  ++iterations;
498  }
499  if (vtx2 && vtx2->chiSquared() < m_BsToMuMuPhi1020_chi2) {
500  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx2, xAOD::TrigBphys::BSPHIMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon, PDG::mKaon}, dimuonTriggerObjectEL);
501  ATH_CHECK( state.addTriggerObject(trigBphys) );
502  }
503  }
504 
505  // B0 -> mu+ mu- K*0(-> K+ pi-)
506  if (m_BdToMuMuKstar0 &&
507  (!m_BdToMuMuKstar0_rejectSameChargeTracks || charge1 * charge2 < 0.) &&
508  p_trk1.Pt() > m_BdToMuMuKstar0_minKaonPt &&
509  p_trk2.Pt() > m_BdToMuMuKstar0_minPionPt &&
510  isInMassRange((p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M(), m_BdToMuMuKstar0_KstarMassRange) &&
511  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M(), m_BdToMuMuKstar0_massRange)) {
512 
513  if (makeCombinations && m_BdToMuMuKstar0_useFastFit) {
514  state.addTrackCombination(itrk1);
515  state.addTrackCombination(itrk2);
516  }
517  if (!vtx2 && makeFit_vtx2 && (passFastFit_vtx2 || !m_BdToMuMuKstar0_useFastFit)) {
518  vtx2 = fit(state.context(), trackParticleLinks_vtx2, kB_2mu2trk, dimuon);
519  makeFit_vtx2 = false;
520  ++iterations;
521  }
522  if (vtx2 && vtx2->chiSquared() < m_BdToMuMuKstar0_chi2) {
523  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx2, xAOD::TrigBphys::BDKSTMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon, PDG::mPion}, dimuonTriggerObjectEL);
524  ATH_CHECK( state.addTriggerObject(trigBphys) );
525  }
526  }
527  // anti-B0 -> mu+ mu- anti-K*0(-> K- pi+)
528  if (m_BdToMuMuKstar0 &&
529  (!m_BdToMuMuKstar0_rejectSameChargeTracks || charge1 * charge2 < 0.) &&
530  p_trk1.Pt() > m_BdToMuMuKstar0_minPionPt &&
531  p_trk2.Pt() > m_BdToMuMuKstar0_minKaonPt &&
532  isInMassRange((p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M(), m_BdToMuMuKstar0_KstarMassRange) &&
533  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M(), m_BdToMuMuKstar0_massRange)) {
534 
535  if (makeCombinations && m_BdToMuMuKstar0_useFastFit) {
536  state.addTrackCombination(itrk1);
537  state.addTrackCombination(itrk2);
538  }
539  if (!vtx2 && makeFit_vtx2 && (passFastFit_vtx2 || !m_BdToMuMuKstar0_useFastFit)) {
540  vtx2 = fit(state.context(), trackParticleLinks_vtx2, kB_2mu2trk, dimuon);
541  makeFit_vtx2 = false;
542  ++iterations;
543  }
544  if (vtx2 && vtx2->chiSquared() < m_BdToMuMuKstar0_chi2) {
545  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx2, xAOD::TrigBphys::BDKSTMUMU, {PDG::mMuon, PDG::mMuon, PDG::mPion, PDG::mKaon}, dimuonTriggerObjectEL);
546  ATH_CHECK( state.addTriggerObject(trigBphys) );
547  }
548  }
549 
550  // Lambda_b0 -> J/psi(-> mu+ mu-) p K-
553  p_trk2.Pt() > m_LambdaBToMuMuProtonKaon_minKaonPt &&
554  (p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M() > m_LambdaBToMuMuProtonKaon_minKstarMass &&
555  (p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M() > m_LambdaBToMuMuProtonKaon_minKstarMass &&
557  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mProton) + p_trk2.SetM(PDG::mKaon)).M() - p_dimuon.M() + PDG::mJpsi, m_LambdaBToMuMuProtonKaon_massRange)) {
558 
559  if (makeCombinations && m_LambdaBToMuMuProtonKaon_useFastFit) {
560  state.addTrackCombination(itrk1);
561  state.addTrackCombination(itrk2);
562  }
563  if (!vtx2 && makeFit_vtx2 && (passFastFit_vtx2 || !m_LambdaBToMuMuProtonKaon_useFastFit)) {
564  vtx2 = fit(state.context(), trackParticleLinks_vtx2, kB_2mu2trk, dimuon);
565  makeFit_vtx2 = false;
566  ++iterations;
567  }
568  if (vtx2 && vtx2->chiSquared() < m_LambdaBToMuMuProtonKaon_chi2 && Lxy(state.beamSpotPosition(), *vtx2) > 0.) {
569  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx2, xAOD::TrigBphys::LBPQMUMU, {PDG::mMuon, PDG::mMuon, PDG::mProton, PDG::mKaon}, dimuonTriggerObjectEL);
570  ATH_CHECK( state.addTriggerObject(trigBphys) );
571  }
572  }
573  // anti-Lambda_b0 -> J/psi(-> mu+ mu-) anti-p K+
575  p_trk1.Pt() > m_LambdaBToMuMuProtonKaon_minKaonPt &&
577  (p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M() > m_LambdaBToMuMuProtonKaon_minKstarMass &&
578  (p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M() > m_LambdaBToMuMuProtonKaon_minKstarMass &&
580  isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mProton)).M() - p_dimuon.M() + PDG::mJpsi, m_LambdaBToMuMuProtonKaon_massRange)) {
581 
582  if (makeCombinations && m_LambdaBToMuMuProtonKaon_useFastFit) {
583  state.addTrackCombination(itrk1);
584  state.addTrackCombination(itrk2);
585  }
586  if (!vtx2 && makeFit_vtx2 && (passFastFit_vtx2 || !m_LambdaBToMuMuProtonKaon_useFastFit)) {
587  vtx2 = fit(state.context(), trackParticleLinks_vtx2, kB_2mu2trk, dimuon);
588  makeFit_vtx2 = false;
589  ++iterations;
590  }
591  if (vtx2 && vtx2->chiSquared() < m_LambdaBToMuMuProtonKaon_chi2 && Lxy(state.beamSpotPosition(), *vtx2) > 0.) {
592  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx2, xAOD::TrigBphys::LBPQMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon, PDG::mProton}, dimuonTriggerObjectEL);
593  ATH_CHECK( state.addTriggerObject(trigBphys) );
594  }
595  }
596  vtx2.reset();
597 
598  for (size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
599  const xAOD::TrackParticle* trk3 = *selectedTracks[itrk3];
600  if (itrk3 == itrk1 || itrk3 == itrk2) continue;
601 
602  trackParticleLinks_vtx3[0] = selectedTracks[itrk1];
603  trackParticleLinks_vtx3[1] = selectedTracks[itrk2];
604  trackParticleLinks_vtx3[2] = selectedTracks[itrk3];
605  auto p_trk3 = trk3->genvecP4();
606  auto charge3 = trk3->charge();
607 
608  std::unique_ptr<xAOD::Vertex> vtx3;
609  bool makeFit_vtx3 = !makeCombinations;
610  bool passFastFit_vtx3 = (!makeCombinations && !state.isBadCombination(itrk1, itrk2, itrk3));
611 
612  // B_c+ -> J/psi(-> mu+ mu-) D_s+(->phi(-> K+ K-) pi+)
613  p_trk1.SetM(PDG::mKaon); // D_s+.phi.K+
614  p_trk2.SetM(PDG::mKaon); // D_s+.phi.K-
615  p_trk3.SetM(PDG::mPion); // D_s+.pi+
616  if (m_BcToDsMuMu &&
617  charge1 * charge2 < 0. &&
618  p_trk1.Pt() > m_BcToDsMuMu_minKaonPt &&
619  p_trk2.Pt() > m_BcToDsMuMu_minKaonPt &&
620  p_trk3.Pt() > m_BcToDsMuMu_minPionPt &&
622  isInMassRange((p_trk1 + p_trk2).M(), m_BcToDsMuMu_phiMassRange) &&
623  isInMassRange((p_trk1 + p_trk2 + p_trk3).M(), m_BcToDsMuMu_DsMassRange) &&
624  isInMassRange((p_dimuon + p_trk1 + p_trk2 + p_trk3).M() - p_dimuon.M() + PDG::mJpsi, m_BcToDsMuMu_massRange)) {
625 
626  if (makeCombinations && m_BcToDsMuMu_useFastFit) state.addTrackCombination(itrk1, itrk2, itrk3);
627  if (!vtx3 && makeFit_vtx3 && (passFastFit_vtx3 || !m_BcToDsMuMu_useFastFit)) {
628  vtx3 = fit(state.context(), trackParticleLinks_vtx3, kDs, dimuon);
629  makeFit_vtx3 = false;
630  ++iterations;
631  }
632  if (vtx3 && vtx3->chiSquared() < m_BcToDsMuMu_chi2) {
633  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx3, xAOD::TrigBphys::BCDSMUMU, {PDG::mKaon, PDG::mKaon, PDG::mPion}, dimuonTriggerObjectEL);
634  ATH_CHECK( state.addTriggerObject(trigBphys) );
635  }
636  }
637 
638  // B_c+ -> J/psi(-> mu+ mu-) D+(-> K- pi+ pi+)
639  p_trk1.SetM(PDG::mPion); // D+.pi+
640  p_trk2.SetM(PDG::mPion); // D+.pi+
641  p_trk3.SetM(PDG::mKaon); // D+.K-
642  if (m_BcToDplusMuMu &&
643  charge1 * charge2 > 0. && charge1 * charge3 < 0. &&
644  p_trk1.Pt() > m_BcToDplusMuMu_minPionPt &&
645  p_trk2.Pt() > m_BcToDplusMuMu_minPionPt &&
646  p_trk3.Pt() > m_BcToDplusMuMu_minKaonPt &&
648  isInMassRange((p_trk1 + p_trk2 + p_trk3).M(), m_BcToDplusMuMu_DplusMassRange) &&
649  isInMassRange((p_dimuon + p_trk1 + p_trk2 + p_trk3).M() - p_dimuon.M() + PDG::mJpsi, m_BcToDplusMuMu_massRange)) {
650 
651  if (makeCombinations && m_BcToDplusMuMu_useFastFit) state.addTrackCombination(itrk1, itrk2, itrk3);
652  if (!vtx3 && makeFit_vtx3 && (passFastFit_vtx3 || !m_BcToDplusMuMu_useFastFit)) {
653  vtx3 = fit(state.context(), trackParticleLinks_vtx3, kDplus, dimuon);
654  makeFit_vtx3 = false;
655  ++iterations;
656  }
657  if (vtx3 && vtx3->chiSquared() < m_BcToDplusMuMu_chi2 && Lxy(dimuon->position(), *vtx3) > 0.) {
658  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *vtx3, xAOD::TrigBphys::BCDPMUMU, {PDG::mPion, PDG::mPion, PDG::mKaon}, dimuonTriggerObjectEL);
659  ATH_CHECK( state.addTriggerObject(trigBphys) );
660  }
661  }
662  vtx3.reset();
663 
664  }
665  }
666 
667  if (iterations > m_fitAttemptsWarningThreshold && !isOverWarningThreshold) {
668  ATH_MSG_WARNING( "Dimuon + tracks: " << state.trigBphysCollection().size() - nTrigBphysObjects << " vertices created after " << iterations << " vertex fitter calls" );
669  isOverWarningThreshold = true;
670  }
671  if (iterations > m_fitAttemptsBreakThreshold) {
672  ATH_MSG_WARNING( "Dimuon + tracks: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
673  break;
674  }
675  }
676  ATH_MSG_DEBUG( "Dimuon + tracks: " << state.trigBphysCollection().size() - nTrigBphysObjects << " vertices created after " << iterations << " vertex fitter calls" );
677 
678  iterations = 0;
679  nTrigBphysObjects = state.trigBphysCollection().size();
680  isOverWarningThreshold = false;
681  // B_c+ -> J/psi(-> mu+ mu-) D*+(-> D0(-> K- pi+) pi+)
682  if (!makeCombinations && m_BcToDstarMuMu && isInMassRange(p_dimuon.M(), m_BcToDstarMuMu_dimuonMassRange)) {
683  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_D0(2); // {K-, pi+}
684 
685  for (size_t itrk1 = 0; itrk1 < selectedTracks.size(); ++itrk1) {
686  const xAOD::TrackParticle* trk1 = *selectedTracks[itrk1];
687 
688  trackParticleLinks_D0[0] = selectedTracks[itrk1];
689  auto p_trk1 = trk1->genvecP4();
690  p_trk1.SetM(PDG::mKaon);
691  auto charge1 = trk1->charge();
692 
693  for (size_t itrk2 = 0; itrk2 < selectedTracks.size(); ++itrk2) {
694  if (itrk2 == itrk1) continue;
695  const xAOD::TrackParticle* trk2 = *selectedTracks[itrk2];
696 
697  trackParticleLinks_D0[1] = selectedTracks[itrk2];
698  auto p_trk2 = trk2->genvecP4();
699  p_trk2.SetM(PDG::mPion);
700  auto charge2 = trk2->charge();
701 
702  std::unique_ptr<xAOD::Vertex> D0;
703  if (charge1 * charge2 < 0. &&
704  p_trk1.Pt() > m_BcToDstarMuMu_minD0KaonPt &&
705  p_trk2.Pt() > m_BcToDstarMuMu_minD0PionPt &&
706  isInMassRange((p_trk1 + p_trk2).M(), m_BcToDstarMuMu_D0MassRange) &&
707  isInMassRange((p_dimuon + p_trk1 + p_trk2).M() - p_dimuon.M() + PDG::mJpsi, m_BcToDstarMuMu_massRange)) {
708  D0 = fit(state.context(), trackParticleLinks_D0, kD0, dimuon);
709  ++iterations;
710  }
711  bool isValidD0 = false;
712  if (D0 && D0->chiSquared() < m_BcToDstarMuMu_chi2 && Lxy(dimuon->position(), *D0) > 0.) {
713  isValidD0 = true;
714  ATH_MSG_DEBUG( "Partially reconstructed B_c+(-> mu+ mu- D0 X) candidate has been created" );
715  xAOD::TrigBphys* trigBphys = makeTriggerObject(state, *D0, xAOD::TrigBphys::DZKPI, s_trkMass[kD0], dimuonTriggerObjectEL);
716  ATH_CHECK( state.addTriggerObject(trigBphys) );
717  }
718 
719  if (m_BcToDstarMuMu_makeDstar && isValidD0) { // full B_c+ reconstruction
721 
722  for (size_t itrk3 = 0; itrk3 < selectedTracks.size(); ++itrk3) {
723  const xAOD::TrackParticle* trk3 = *selectedTracks[itrk3];
724  if (itrk3 == itrk1 || itrk3 == itrk2) continue;
725 
726  // J/psi + pion from D*+
727  trackParticleLinks_vtx1[2] = selectedTracks[itrk3];
728  auto p_trk3 = trk3->genvecP4();
729  p_trk3.SetM(PDG::mPion);
730 
731  if (p_trk3.Pt() > m_BcToDstarMuMu_minDstarPionPt &&
733  isInMassRange((p_D0 + p_trk3).M() - p_D0.M() + PDG::mD0, m_BcToDstarMuMu_DstarMassRange)) {
734  auto Bc_vtx1 = fit(state.context(), trackParticleLinks_vtx1, kB_PsiPi);
735  ++iterations;
736 
737  if (Bc_vtx1 && Bc_vtx1->chiSquared() < m_BcToDstarMuMu_chi2) {
738  ATH_MSG_DEBUG( "Decay vertex(mu+ mu- D*+.pi+) for B_c+ candidate has been created" );
739  xAOD::TrigBphys* triggerObject_vtx1 = makeTriggerObject(state, *Bc_vtx1, xAOD::TrigBphys::DSTDZPI, s_trkMass[kB_PsiPi], dimuonTriggerObjectEL);
740  auto triggerObjectEL_vtx1 = ElementLink<xAOD::TrigBphysContainer>(state.trigBphysCollection(), state.trigBphysCollection().size());
741  ATH_CHECK( state.addTriggerObject(triggerObject_vtx1) );
742  ATH_CHECK( triggerObjectEL_vtx1.isValid() );
743 
744  // refit D0 vertex
745  auto Bc_vtx2 = fit(state.context(), trackParticleLinks_D0, kD0, Bc_vtx1.get());
746  ++iterations;
747  if (Bc_vtx2 && Bc_vtx2->chiSquared() < m_BcToDstarMuMu_chi2) {
748  ATH_MSG_DEBUG( "Fully reconstructed B_c+(-> mu+ mu- D*+) candidate has been created" );
749  xAOD::TrigBphys* triggerObject_vtx2 = makeTriggerObject(state, *Bc_vtx2, xAOD::TrigBphys::BCDSTMUMU, s_trkMass[kD0], triggerObjectEL_vtx1);
750  ATH_CHECK( state.addTriggerObject(triggerObject_vtx2) );
751  }
752  }
753  }
754  }
755  } // end of full B_c+ reconstruction
756 
757  }
758 
759  if (iterations > m_fitAttemptsWarningThreshold && !isOverWarningThreshold) {
760  ATH_MSG_WARNING( "B_c+ -> mu+ mu- D*+: " << state.trigBphysCollection().size() - nTrigBphysObjects << " vertices created after " << iterations << " vertex fitter calls" );
761  isOverWarningThreshold = true;
762  }
763  if (iterations > m_fitAttemptsBreakThreshold) {
764  ATH_MSG_WARNING( "B_c+ -> mu+ mu- D*+: the number of fit attempts has exceeded the limit; breaking the loop at this point" );
765  break;
766  }
767  }
768  ATH_MSG_DEBUG( "B_c+ -> mu+ mu- D*+: " << state.trigBphysCollection().size() - nTrigBphysObjects << " vertices created after " << iterations << " vertex fitter calls" );
769 
770  } // end of B_c+ -> J/psi D*+ topology
771 
772  return StatusCode::SUCCESS;
773 }
774 
775 
777 
778  state.badTrackCombinations.clear();
779 
780  const xAOD::Vertex* dimuon = state.dimuons.get(dimuonIndex);
781 
782  // {mu1, mu2, trk1}
783  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2mu1trk(dimuon->trackParticleLinks());
784  trackParticleLinks_2mu1trk.emplace_back();
785 
786  // {trk1, trk2}
787  std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks_2trk(2);
788 
789  size_t n = state.selectedTracks.size();
790  size_t iterations = 0;
791  for (const auto& item : state.trackCombinations) {
792  if (item.second < 5) continue;
793 
794  size_t key = item.first;
795  if (key < n) { // dimuon + track
796  trackParticleLinks_2mu1trk[2] = state.selectedTracks[key];
797  auto vertex = fit(state.context(), trackParticleLinks_2mu1trk, kFastFit_2mu1trk, dimuon);
798  iterations++;
799  if (!vertex || vertex->chiSquared() > m_fastFit_2mu1trk_chi2) state.badTrackCombinations.push_back(key);
800  }
801  else { // track + track
802  trackParticleLinks_2trk[0] = state.selectedTracks[key % n];
803  trackParticleLinks_2trk[1] = state.selectedTracks[key / n];
804  auto vertex = fit(state.context(), trackParticleLinks_2trk, kFastFit_2trk);
805  iterations++;
806  if (!vertex || vertex->chiSquared() > m_fastFit_2trk_chi2) state.badTrackCombinations.push_back(key);
807  }
808  }
809  std::sort(state.badTrackCombinations.begin(), state.badTrackCombinations.end());
810  ATH_MSG_DEBUG( "Fast fit found " << state.badTrackCombinations.size() << " bad combinations after " << iterations << " iterations" );
811 
812  return StatusCode::SUCCESS;
813 }
814 
815 
817 
818  for (const xAOD::TrigBphys* triggerObject : state.trigBphysCollection()) {
819  // skip the first vertex of the cascade decay B_c+(-> mu+ mu- D*+), it is already linked to the xAOD::TrigBphys::BCDSTMUMU trigger object via lowerChainLink()
820  if (triggerObject->particleType() == xAOD::TrigBphys::DSTDZPI) continue;
821 
822  ATH_MSG_DEBUG( "Found xAOD::TrigBphys object: mass = " << triggerObject->mass() );
823 
824  auto triggerObjectEL = ElementLink<xAOD::TrigBphysContainer>(state.trigBphysCollection(), triggerObject->index());
825  ATH_CHECK( triggerObjectEL.isValid() );
826 
827  const xAOD::TrigBphys* dimuonTriggerObject = (triggerObject->particleType() == xAOD::TrigBphys::MULTIMU ? triggerObject : triggerObject->lowerChain());
828  if (triggerObject->particleType() == xAOD::TrigBphys::BCDSTMUMU && dimuonTriggerObject) dimuonTriggerObject = dimuonTriggerObject->lowerChain();
829  if (!dimuonTriggerObject) {
830  ATH_MSG_ERROR( "Failed to found a valid link for preceding dimuon trigger object" );
831  return StatusCode::FAILURE;
832  }
833 
834  // need to get the references to the original muon objects used to build the dimuon vertex
835  // the position of this vertex in state.dimuons container is the same as for dimuonTriggerObject in trigBphysCollection
836  // dimuon vertex has already been decorated with muon indices
837  auto dimuonIndex = dimuonTriggerObject->index();
838  const xAOD::Vertex* dimuon = state.dimuons.get(dimuonIndex);
839  if ( !dimuon || dimuonIndex >= state.trigBphysMuonIndices.size() ) {
840  ATH_MSG_ERROR( "Failed to find original muons the dimuon vertex had been built from" );
841  return StatusCode::FAILURE;
842  }
843 
844  // create a new output Decision object, backed by the 'decisions' container.
846 
847  std::vector<const DecisionIDContainer*> previousDecisionIDs;
848  for (const size_t& i : state.trigBphysMuonIndices.at(dimuonIndex)) {
849  const auto& muon = state.muons.at(i);
850  // attach all previous decisions: if the same previous decision is called twice, that's fine - internally takes care of that
851  // we already have an array of links to the previous decisions, so there is no need to use TrigCompositeUtils::linkToPrevious()
852  decision->addObjectCollectionLinks(TrigCompositeUtils::seedString(), muon.decisionLinks);
853  previousDecisionIDs.push_back(&muon.decisionIDs);
854  }
855 
856  // set mandatory link to the trigger object
857  decision->setObjectLink<xAOD::TrigBphysContainer>(TrigCompositeUtils::featureString(), triggerObjectEL);
858 
859  for (const auto& tool : hypoTools()) {
860  ATH_MSG_DEBUG( "Go to " << tool );
861  ATH_CHECK( tool->decideOnSingleObject(decision, previousDecisionIDs) );
862  }
863  }
864 
865  return StatusCode::SUCCESS;
866 }
867 
868 
869 std::unique_ptr<xAOD::Vertex> TrigBmumuxComboHypo::fit(
870  const EventContext& context,
872  Decay decay,
873  const xAOD::Vertex* dimuon) const {
874 
875  ATH_MSG_VERBOSE( "Perform vertex fit" );
876 
877  if (trackParticleLinks.size() < 2) {
878  ATH_MSG_WARNING( "At least two tracks should be given to the vertex fitter" );
879  return nullptr;
880  }
881 
882  std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(), nullptr);
883  std::transform(trackParticleLinks.begin(), trackParticleLinks.end(), tracklist.begin(),
884  [](const ElementLink<xAOD::TrackParticleContainer>& link){ return *link; });
885 
886  Amg::Vector3D startingPoint = Amg::Vector3D::Zero(3);
887  if (dimuon) {
888  startingPoint = Amg::Vector3D(dimuon->x(), dimuon->y(), dimuon->z());
889  }
890  else {
891  if (decay != Decay::kPsi_2mu && decay != Decay::kB_PsiPi && decay != Decay::kFastFit_2trk) {
892  ATH_MSG_WARNING( "Already fitted dimuon vertex should be provided for B -> mu1 mu2 trk1 .. trkN decay as a starting point for fitter" );
893  }
894  int flag = 0;
895  int errorcode = 0;
896  const Trk::Perigee& perigee1 = tracklist[0]->perigeeParameters();
897  const Trk::Perigee& perigee2 = tracklist[1]->perigeeParameters();
898  startingPoint = m_vertexPointEstimator->getCirclesIntersectionPoint(&perigee1, &perigee2, flag, errorcode);
899  if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
900  }
901  ATH_MSG_VERBOSE( "Starting point: (" << startingPoint(0) << ", " << startingPoint(1) << ", " << startingPoint(2) << ")" );
902 
903  auto fitterState = m_vertexFitter->makeState(context);
904  m_vertexFitter->setMassInputParticles(s_trkMass[static_cast<size_t>(decay)], *fitterState);
905 
906  // the combined momentum of D+/D_s+ candidate is constrained to point to the dimuon vertex
907  if (decay == Decay::kDs || decay == Decay::kDplus || decay == Decay::kD0) {
908  m_vertexFitter->setVertexForConstraint(*dimuon, *fitterState);
909  m_vertexFitter->setCnstType(8, *fitterState);
910  }
911 
912  std::unique_ptr<xAOD::Vertex> vertex(m_vertexFitter->fit(tracklist, startingPoint, *fitterState));
913  if (!vertex) {
914  ATH_MSG_VERBOSE( "Vertex fit fails" );
915  return vertex;
916  }
917  if (vertex->chiSquared() > 150. || (decay == Decay::kPsi_2mu && vertex->chiSquared() > m_dimuon_chi2)) {
918  ATH_MSG_VERBOSE( "Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() << ")" );
919  vertex.reset();
920  return vertex;
921  }
922  ATH_MSG_VERBOSE( "Fit is successful" );
923 
924  // update trackParticleLinks()
925  vertex->clearTracks();
926  vertex->setTrackParticleLinks(trackParticleLinks);
927 
928  return vertex;
929 }
930 
931 
933  TrigBmumuxState& state,
934  const xAOD::Vertex& vertex,
936  const std::vector<double>& trkMass,
937  const ElementLink<xAOD::TrigBphysContainer>& dimuonLink) const {
938 
939  const xAOD::TrigBphys* dimuon = (type != xAOD::TrigBphys::MULTIMU ? *dimuonLink : nullptr);
941 
942  // refitted track momentum as a 4-vector for mass hypothesis defined by the given decay value
944  std::vector<xAOD::TrackParticle::GenVecFourMom_t> momenta;
945  if (!vertex.vxTrackAtVertexAvailable()) return nullptr;
946  for (size_t i = 0; i < vertex.vxTrackAtVertex().size(); ++i) {
947  const Trk::TrackParameters* perigee = vertex.vxTrackAtVertex()[i].perigeeAtVertex();
948  if (!perigee) return nullptr;
949  const Amg::Vector3D& p = perigee->momentum();
950  momenta.emplace_back(p.x(), p.y(), p.z(), trkMass[i]);
951  momentum += momenta.back();
952  }
953  if (isCascadeDecay) {
954  momentum += ROOT::Math::PtEtaPhiMVector(dimuon->pt(), dimuon->eta(), dimuon->phi(), dimuon->mass());
955  }
956 
957  auto result = new xAOD::TrigBphys();
958  result->makePrivateStore();
959 
960  float mass = momentum.M();
962  mass += PDG::mD0 - (momenta[0] + momenta[1]).M();
963  }
964  else if (type != xAOD::TrigBphys::MULTIMU) {
965  mass += PDG::mJpsi - (isCascadeDecay ? dimuon->mass() : (momenta[0] + momenta[1]).M());
966  }
967 
968  result->initialise(0, momentum.Eta(), momentum.Phi(), momentum.Pt(), type, mass, xAOD::TrigBphys::EF);
969 
970  result->setFitmass(momentum.M());
971  result->setFitx(vertex.x());
972  result->setFity(vertex.y());
973  result->setFitz(vertex.z());
974  result->setFitchi2(vertex.chiSquared());
975  result->setFitndof(vertex.numberDoF());
976 
977  Amg::Vector3D productionVertex = (isCascadeDecay ? Amg::Vector3D(dimuon->fitx(), dimuon->fity(), dimuon->fitz()) : state.beamSpotPosition());
978  result->setLxy(Lxy(productionVertex, vertex));
979 
980  // set all the particles associated with the decay
981  result->setTrackParticleLinks(vertex.trackParticleLinks());
982 
983  // use lowerChainLink() as a link to the preceding dimuon trigger object
985  result->setLowerChainLink(dimuonLink);
986  }
987 
989  "TrigBphys object:\n\t " <<
990  "roiId: " << result->roiId() << "\n\t " <<
991  "particleType: " << result->particleType() << "\n\t " <<
992  "level: " << result->level() << "\n\t " <<
993  "eta: " << result->eta() << "\n\t " <<
994  "phi: " << result->phi() << "\n\t " <<
995  "mass: " << result->mass() << "\n\t " <<
996  "fitmass: " << result->fitmass() << "\n\t " <<
997  "chi2/NDF: " << result->fitchi2() << " / " << result->fitndof() << "\n\t " <<
998  "vertex: (" << result->fitx() << ", " << result->fity() << ", " << result->fitz() << ")" << "\n\t " <<
999  "Lxy: " << result->lxy() );
1000 
1001  return result;
1002 }
1003 
1004 
1006 
1007  if (lhs->charge() * rhs->charge() < 0.) return false;
1008  return (ROOT::Math::VectorUtil::DeltaR(lhs->genvecP4(), rhs->genvecP4()) < m_deltaR);
1009 }
1010 
1011 
1013 
1015 }
1016 
1017 
1019 
1020  auto p_mu = muon->genvecP4();
1021  auto p_trk = track->genvecP4();
1022  return (ROOT::Math::VectorUtil::DeltaPhi(p_mu, p_trk) < m_roiPhiWidth && std::abs(p_mu.eta() - p_trk.eta()) < m_roiEtaWidth);
1023 }
1024 
1025 
1026 double TrigBmumuxComboHypo::Lxy(const Amg::Vector3D& productionVertex, const xAOD::Vertex& decayVertex) const {
1027 
1028  XYVector R(decayVertex.x() - productionVertex.x(), decayVertex.y() - productionVertex.y());
1029  XYVector pT;
1030 
1031  if (!decayVertex.vxTrackAtVertexAvailable()) return -100.;
1032  const auto& tracks = decayVertex.vxTrackAtVertex();
1033  for (const auto& track : tracks) {
1034  const Trk::TrackParameters* perigee = track.perigeeAtVertex();
1035  if (!perigee) return -100.;
1036  const Amg::Vector3D& momentum = perigee->momentum();
1037  pT += XYVector(momentum.x(), momentum.y());
1038  }
1039  return R.Dot(pT.unit());
1040 }
1041 
1042 
1044 
1046  for (size_t i = 0; i < vertex.vxTrackAtVertex().size(); ++i) {
1047  const Trk::TrackParameters* perigee = vertex.vxTrackAtVertex()[i].perigeeAtVertex();
1048  const Amg::Vector3D& p = perigee->momentum();
1050  }
1051  return momentum;
1052 }
1053 
1054 
1055 bool TrigBmumuxComboHypo::passDimuonTrigger(const std::vector<const DecisionIDContainer*>& previousDecisionIDs) const {
1056 
1057  if (previousDecisionIDs.size() != 2) {
1058  ATH_MSG_WARNING( "TrigBmumuxComboHypo::passDimuonTrigger() expects exactly two containers with previous decision IDs" );
1059  return false;
1060  }
1061 
1062  for (const auto& tool : hypoTools()) {
1063  const std::vector<HLT::Identifier>& legDecisionIDs = tool->legDecisionIds();
1064  if (legDecisionIDs.size() == 1 && tool->legMultiplicity().at(0) >= 2) {
1065  // trigger with symmetric legs like HLT_2mu4_bBmumux_BsmumuPhi_L12MU4
1066  const DecisionID id = legDecisionIDs[0].numeric();
1067  if (TrigCompositeUtils::passed(id, *previousDecisionIDs[0]) && TrigCompositeUtils::passed(id, *previousDecisionIDs[1])) return true;
1068  }
1069  else if (legDecisionIDs.size() == 2) {
1070  // trigger with asymmetric legs like HLT_mu6_mu4_bBmumux_BsmumuPhi_L1MU6_2MU4
1071  bool direct = true;
1072  bool inverse = true;
1073  for (size_t i = 0; i < 2; ++i) {
1074  if (direct && !TrigCompositeUtils::passed(legDecisionIDs[i].numeric(), *previousDecisionIDs[i])) direct = false;
1075  if (inverse && !TrigCompositeUtils::passed(legDecisionIDs[i].numeric(), *previousDecisionIDs[1-i])) inverse = false;
1076  }
1077  if (direct || inverse) return true;
1078  }
1079  else {
1080  ATH_MSG_WARNING( "TrigBmumuxComboHypo can not check decisions for " << tool->name() );
1081  }
1082  }
1083  return false;
1084 }
TrigBmumuxComboHypo::m_fastFit_2trk_chi2
Gaudi::Property< double > m_fastFit_2trk_chi2
Definition: TrigBmumuxComboHypo.h:267
TrigBmumuxComboHypo::m_BcToDsMuMu_phiMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_phiMassRange
Definition: TrigBmumuxComboHypo.h:371
xAOD::TrackParticle_v1::GenVecFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D< double > > GenVecFourMom_t
Base 4 Momentum type for TrackParticle.
Definition: TrackParticle_v1.h:78
TrigBmumuxComboHypo::m_BcToDplusMuMu_massRange
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_massRange
Definition: TrigBmumuxComboHypo.h:387
TrigBmumuxComboHypo::m_BcToDstarMuMu_minDstarPionPt
Gaudi::Property< double > m_BcToDstarMuMu_minDstarPionPt
Definition: TrigBmumuxComboHypo.h:407
TrigBmumuxState::addTriggerObject
StatusCode addTriggerObject(xAOD::TrigBphys *triggerObject)
Definition: TrigBmumuxComboHypo.h:92
TrigBmumuxComboHypo::s_trkMass
static const std::vector< std::vector< double > > s_trkMass
Definition: TrigBmumuxComboHypo.h:434
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_useFastFit
Gaudi::Property< bool > m_BsToMuMuPhi1020_useFastFit
Definition: TrigBmumuxComboHypo.h:319
xAOD::Vertex_v1::x
float x() const
Returns the x position.
CalculateHighPtTerm.pT
pT
Definition: ICHEP2016/CalculateHighPtTerm.py:57
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
DeMoSetup.direct
string direct
Definition: DeMoSetup.py:111
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_chi2
Gaudi::Property< float > m_BsToMuMuPhi1020_chi2
Definition: TrigBmumuxComboHypo.h:317
TrigBmumuxComboHypo.h
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
TrigBmumuxComboHypo::m_BcToDstarMuMu
Gaudi::Property< bool > m_BcToDstarMuMu
Definition: TrigBmumuxComboHypo.h:399
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrigBmumuxComboHypo::m_BcToDsMuMu_minKaonPt
Gaudi::Property< double > m_BcToDsMuMu_minKaonPt
Definition: TrigBmumuxComboHypo.h:363
TrigCompositeUtils::DecisionID
unsigned int DecisionID
Definition: TrigComposite_v1.h:27
ComboHypo::decisionsOutput
const SG::WriteHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsOutput() const
Definition: ComboHypo.h:41
TrigCompositeUtils::DecisionContainer
xAOD::TrigCompositeContainer DecisionContainer
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigCompositeContainer.h:21
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
xAOD::TrigBphys_v1::BDKSTMUMU
@ BDKSTMUMU
Definition: TrigBphys_v1.h:57
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
IDTPM::R
float R(const U &p)
Definition: TrackParametersHelper.h:101
TrigCompositeUtils.h
xAOD::TrigBphys_v1::BSPHIMUMU
@ BSPHIMUMU
Definition: TrigBphys_v1.h:58
TrigBmumuxComboHypo::m_roiPhiWidth
Gaudi::Property< double > m_roiPhiWidth
Definition: TrigBmumuxComboHypo.h:261
TrigBmumuxComboHypo::m_BcToDstarMuMu_minD0KaonPt
Gaudi::Property< double > m_BcToDstarMuMu_minD0KaonPt
Definition: TrigBmumuxComboHypo.h:403
xAOD::TrigBphys_v1::LBPQMUMU
@ LBPQMUMU
Definition: TrigBphys_v1.h:72
xAOD::TrackParticle_v1::charge
float charge() const
Returns the charge.
Definition: TrackParticle_v1.cxx:150
Muon.h
TrigCompositeUtils::newDecisionIn
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.
Definition: TrigCompositeUtilsRoot.cxx:46
TrigBmumuxComboHypo::m_BcToMuMuPion_minPionPt
Gaudi::Property< double > m_BcToMuMuPion_minPionPt
Definition: TrigBmumuxComboHypo.h:295
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon
Gaudi::Property< bool > m_LambdaBToMuMuProtonKaon
Definition: TrigBmumuxComboHypo.h:341
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
TrigBmumuxComboHypo::m_fitAttemptsBreakThreshold
Gaudi::Property< size_t > m_fitAttemptsBreakThreshold
Definition: TrigBmumuxComboHypo.h:265
TrigBmumuxComboHypo::m_BdToMuMuKstar0_rejectSameChargeTracks
Gaudi::Property< bool > m_BdToMuMuKstar0_rejectSameChargeTracks
Definition: TrigBmumuxComboHypo.h:325
xAOD::Vertex_v1::trackParticleLinks
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
TrigBmumuxComboHypo::m_BcToDplusMuMu_minPionPt
Gaudi::Property< double > m_BcToDplusMuMu_minPionPt
Definition: TrigBmumuxComboHypo.h:385
met::DeltaR
@ DeltaR
Definition: METRecoCommon.h:11
xAOD::TrigBphys_v1::DSTDZPI
@ DSTDZPI
Definition: TrigBphys_v1.h:67
TrigBmumuxComboHypo::findBmumuxCandidates_fit
StatusCode findBmumuxCandidates_fit(TrigBmumuxState &, size_t dimuonIndex, bool makeCombinations=false) const
Perform fit of B decays for the topologies described above if makeCombinations = false.
Definition: TrigBmumuxComboHypo.cxx:394
ViewHelper::makeHandle
SG::ReadHandle< T > makeHandle(const SG::View *view, const SG::ReadHandleKey< T > &rhKey, const EventContext &context)
navigate from the TrigComposite to nearest view and fetch object from it
Definition: ViewHelper.h:258
PDG20::mMuon
static constexpr double mMuon
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:12
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounce
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)
Definition: AthCommonDataStore.h:380
xAOD::TrigBphys_v1::fitx
float fitx() const
accessor method: x position of vertex
TrigBmumuxComboHypo::m_BplusToMuMuKaon_chi2
Gaudi::Property< float > m_BplusToMuMuKaon_chi2
Definition: TrigBmumuxComboHypo.h:287
TrigBmumuxComboHypo::m_BcToDstarMuMu_minD0PionPt
Gaudi::Property< double > m_BcToDstarMuMu_minD0PionPt
Definition: TrigBmumuxComboHypo.h:405
TrigBmumuxState::trigBphysMuonIndices
std::vector< std::array< size_t, 2 > > trigBphysMuonIndices
Definition: TrigBmumuxComboHypo.h:73
TrigBmumuxComboHypo::isInSameRoI
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 ...
Definition: TrigBmumuxComboHypo.cxx:1018
TrigBmumuxComboHypo::isIdenticalTracks
bool isIdenticalTracks(const xAOD::TrackParticle *lhs, const xAOD::TrackParticle *rhs) const
Attempts to identify identical tracks by selection on DeltaR.
Definition: TrigBmumuxComboHypo.cxx:1005
TrigBmumuxComboHypo::m_BplusToMuMuKaon
Gaudi::Property< bool > m_BplusToMuMuKaon
Definition: TrigBmumuxComboHypo.h:281
TrigBmumuxComboHypo::kDplus
@ kDplus
Definition: TrigBmumuxComboHypo.h:128
DataVector::get
const T * get(size_type n) const
Access an element, as an rvalue.
Trk::z0
@ z0
Definition: ParamDefs.h:70
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
TrigBmumuxComboHypo::kFastFit_2mu1trk
@ kFastFit_2mu1trk
Definition: TrigBmumuxComboHypo.h:132
TrigBmumuxState::dimuons
xAOD::VertexContainer dimuons
Definition: TrigBmumuxComboHypo.h:71
TrigBmumuxState::selectedTracks
std::vector< ElementLink< xAOD::TrackParticleContainer > > selectedTracks
Definition: TrigBmumuxComboHypo.h:76
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_minKaonPt
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minKaonPt
Definition: TrigBmumuxComboHypo.h:347
TrigCompositeUtils::comboHypoAlgNodeName
const std::string & comboHypoAlgNodeName()
Definition: TrigCompositeUtilsRoot.cxx:910
TrigCompositeUtils::createAndStore
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
Definition: TrigCompositeUtilsRoot.cxx:30
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_phiMassRange
Gaudi::Property< std::pair< double, double > > m_BsToMuMuPhi1020_phiMassRange
Definition: TrigBmumuxComboHypo.h:315
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
xAOD::TrigBphys_v1::mass
float mass() const
accessor method: mass
TrigBmumuxComboHypo::m_BcToDplusMuMu_minKaonPt
Gaudi::Property< double > m_BcToDplusMuMu_minKaonPt
Definition: TrigBmumuxComboHypo.h:383
TrigBmumuxComboHypo::m_BcToMuMuPion_chi2
Gaudi::Property< float > m_BcToMuMuPion_chi2
Definition: TrigBmumuxComboHypo.h:301
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ITrigBphysState::beamSpotPosition
Amg::Vector3D beamSpotPosition() const
Definition: ITrigBphysState.h:47
TrigBphysAuxContainer.h
TrigBmumuxComboHypo::kD0
@ kD0
Definition: TrigBmumuxComboHypo.h:129
ViewHelper.h
x
#define x
xAOD::TrigBphys_v1::BKMUMU
@ BKMUMU
Definition: TrigBphys_v1.h:56
TrigBmumuxComboHypo::m_BcToDsMuMu_massRange
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_massRange
Definition: TrigBmumuxComboHypo.h:367
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
xAOD::TrigBphys_v1::pt
float pt() const
accessor method: pt
Definition: TrigBphys_v1.cxx:362
TrigBmumuxComboHypo::fit
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.
Definition: TrigBmumuxComboHypo.cxx:869
ComboHypo
Definition: ComboHypo.h:30
TrigBmumuxComboHypo::m_beamSpotKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Definition: TrigBmumuxComboHypo.h:252
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
TrigBmumuxComboHypo::kDs
@ kDs
Definition: TrigBmumuxComboHypo.h:127
TrigBmumuxComboHypo::m_BcToDplusMuMu_DplusMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_DplusMassRange
Definition: TrigBmumuxComboHypo.h:391
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:269
TrigBmumuxComboHypo::m_BcToDsMuMu_minPionPt
Gaudi::Property< double > m_BcToDsMuMu_minPionPt
Definition: TrigBmumuxComboHypo.h:365
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
xAOD::TrigBphys_v1::BCDSTMUMU
@ BCDSTMUMU
Definition: TrigBphys_v1.h:64
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_massRange
Gaudi::Property< std::pair< double, double > > m_BsToMuMuPhi1020_massRange
Definition: TrigBmumuxComboHypo.h:313
TrigBmumuxComboHypo::m_BdToMuMuKstar0_massRange
Gaudi::Property< std::pair< double, double > > m_BdToMuMuKstar0_massRange
Definition: TrigBmumuxComboHypo.h:331
TrigBmumuxComboHypo::m_BsToMuMuPhi1020
Gaudi::Property< bool > m_BsToMuMuPhi1020
Definition: TrigBmumuxComboHypo.h:307
TrigBmumuxComboHypo::m_BcToDstarMuMu_maxDstarPionZ0
Gaudi::Property< double > m_BcToDstarMuMu_maxDstarPionZ0
Definition: TrigBmumuxComboHypo.h:409
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_minKaonPt
Gaudi::Property< double > m_BsToMuMuPhi1020_minKaonPt
Definition: TrigBmumuxComboHypo.h:311
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigBmumuxComboHypo::m_trigBphysContainerKey
SG::WriteHandleKey< xAOD::TrigBphysContainer > m_trigBphysContainerKey
Definition: TrigBmumuxComboHypo.h:249
TrigBmumuxState::muons
std::vector< Muon > muons
Definition: TrigBmumuxComboHypo.h:64
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_dimuonMassRange
Gaudi::Property< std::pair< double, double > > m_LambdaBToMuMuProtonKaon_dimuonMassRange
Definition: TrigBmumuxComboHypo.h:351
TrigBmumuxComboHypo::m_BdToMuMuKstar0_chi2
Gaudi::Property< float > m_BdToMuMuKstar0_chi2
Definition: TrigBmumuxComboHypo.h:335
TrigBmumuxComboHypo::findBmumuxCandidates_fastFit
StatusCode findBmumuxCandidates_fastFit(TrigBmumuxState &, size_t dimuonIndex) const
Go through (dimuon+track) and (track+track) combinations found by findBmumuxCandidates_fit(makeCombin...
Definition: TrigBmumuxComboHypo.cxx:776
lumiFormat.i
int i
Definition: lumiFormat.py:92
ComboHypo::hypoTools
ToolHandleArray< ComboHypoToolBase > & hypoTools()
Definition: ComboHypo.h:44
TrigBmumuxComboHypo::m_BcToDstarMuMu_dimuonMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_dimuonMassRange
Definition: TrigBmumuxComboHypo.h:413
ITrigBphysState::context
const EventContext & context() const
Definition: ITrigBphysState.h:42
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TrigBphys.h
TrigBmumuxComboHypo::createDecisionObjects
StatusCode createDecisionObjects(TrigBmumuxState &) const
Create a decision for each xAOD::TrigBphys object from state.trigBphysCollection() and save it to sta...
Definition: TrigBmumuxComboHypo.cxx:816
TrigBmumuxComboHypo::m_vertexPointEstimator
ToolHandle< InDet::VertexPointEstimator > m_vertexPointEstimator
Definition: TrigBmumuxComboHypo.h:423
TrigBmumuxComboHypo::m_BplusToMuMuKaon_minKaonPt
Gaudi::Property< double > m_BplusToMuMuKaon_minKaonPt
Definition: TrigBmumuxComboHypo.h:283
master.flag
bool flag
Definition: master.py:29
TrigBmumuxComboHypo::m_fitAttemptsWarningThreshold
Gaudi::Property< size_t > m_fitAttemptsWarningThreshold
Definition: TrigBmumuxComboHypo.h:263
ClassID_traits
Default, invalid implementation of ClassID_traits.
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:40
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
TrigBmumuxComboHypo::m_BdToMuMuKstar0_minKaonPt
Gaudi::Property< double > m_BdToMuMuKstar0_minKaonPt
Definition: TrigBmumuxComboHypo.h:327
TrigBmumuxComboHypo::mergeTracksFromViews
StatusCode mergeTracksFromViews(TrigBmumuxState &) const
Go through state.previousDecisions() and fetch xAOD::TrackParticle objects associated with the neares...
Definition: TrigBmumuxComboHypo.cxx:185
TrigBmumuxComboHypo::kB_PsiPi
@ kB_PsiPi
Definition: TrigBmumuxComboHypo.h:130
TrigCompositeUtils::decisionToElementLink
ElementLink< DecisionContainer > decisionToElementLink(const Decision *d, const EventContext &ctx)
Takes a raw pointer to a Decision and returns an ElementLink to the Decision.
Definition: TrigCompositeUtilsRoot.cxx:122
TrigBmumuxComboHypo::TrigBmumuxComboHypo
TrigBmumuxComboHypo()=delete
xAOD::TauHelpers::trackParticleLinks
std::vector< ElementLink< xAOD::TrackParticleContainer > > trackParticleLinks(const xAOD::TauJet *tau, xAOD::TauJetParameters::TauTrackFlag flag=xAOD::TauJetParameters::TauTrackFlag::classifiedCharged)
Definition: TauxAODHelpers.cxx:22
TrigBmumuxComboHypo::m_BdToMuMuKstar0_KstarMassRange
Gaudi::Property< std::pair< double, double > > m_BdToMuMuKstar0_KstarMassRange
Definition: TrigBmumuxComboHypo.h:333
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrigBmumuxComboHypo::m_BcToDstarMuMu_D0MassRange
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_D0MassRange
Definition: TrigBmumuxComboHypo.h:415
TrigBmumuxComboHypo::kB_2mu2trk
@ kB_2mu2trk
Definition: TrigBmumuxComboHypo.h:126
ComboHypo::triggerMultiplicityMap
const Combo::MultiplicityReqMap & triggerMultiplicityMap() const
Definition: ComboHypo.h:42
TrigBmumuxComboHypo::findBmumuxCandidates
StatusCode findBmumuxCandidates(TrigBmumuxState &) const
Find B decays by appling next three subprocedures to each found dimuon candidate.
Definition: TrigBmumuxComboHypo.cxx:311
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
xAOD::TrackParticle_v1::genvecP4
GenVecFourMom_t genvecP4() const
The full 4-momentum of the particle : GenVector form.
Definition: TrackParticle_v1.cxx:116
TrigBmumuxComboHypo::m_dimuon_rejectSameChargeTracks
Gaudi::Property< bool > m_dimuon_rejectSameChargeTracks
Definition: TrigBmumuxComboHypo.h:273
Trk::ParametersBase
Definition: ParametersBase.h:55
xAOD::Vertex_v1::z
float z() const
Returns the z position.
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
TrigBmumuxComboHypo::m_muonContainerKey
SG::ReadHandleKey< xAOD::MuonContainer > m_muonContainerKey
Definition: TrigBmumuxComboHypo.h:247
xAOD::TrigBphys_v1::fitz
float fitz() const
accessor method: z position of vertex
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
TrigBmumuxComboHypo::m_BplusToMuMuKaon_useFastFit
Gaudi::Property< bool > m_BplusToMuMuKaon_useFastFit
Definition: TrigBmumuxComboHypo.h:289
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Vertex.h
HLT::Identifier
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:20
TrigBmumuxComboHypo::m_roiEtaWidth
Gaudi::Property< double > m_roiEtaWidth
Definition: TrigBmumuxComboHypo.h:259
PDG20::mProton
static constexpr double mProton
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:19
TrigBmumuxState::addTrackCombination
void addTrackCombination(size_t i1)
Definition: TrigBmumuxComboHypo.h:86
TrigBmumuxComboHypo::kFastFit_2trk
@ kFastFit_2trk
Definition: TrigBmumuxComboHypo.h:131
TrigBmumuxComboHypo::m_BdToMuMuKstar0_useFastFit
Gaudi::Property< bool > m_BdToMuMuKstar0_useFastFit
Definition: TrigBmumuxComboHypo.h:337
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_chi2
Gaudi::Property< float > m_LambdaBToMuMuProtonKaon_chi2
Definition: TrigBmumuxComboHypo.h:355
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtilsRoot.cxx:886
ComboHypo::initialize
virtual StatusCode initialize() override
Definition: ComboHypo.cxx:23
TrigBmumuxComboHypo::execute
virtual StatusCode execute(const EventContext &context) const override
Definition: TrigBmumuxComboHypo.cxx:100
TrigBmumuxComboHypo::m_BcToDsMuMu_chi2
Gaudi::Property< float > m_BcToDsMuMu_chi2
Definition: TrigBmumuxComboHypo.h:375
TrigBmumuxComboHypo::m_BcToDstarMuMu_massRange
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_massRange
Definition: TrigBmumuxComboHypo.h:411
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_minKstarMass
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minKstarMass
Definition: TrigBmumuxComboHypo.h:349
TrigBmumuxComboHypo::m_BcToMuMuPion_useFastFit
Gaudi::Property< bool > m_BcToMuMuPion_useFastFit
Definition: TrigBmumuxComboHypo.h:303
TrigBmumuxComboHypo::m_BsToMuMuPhi1020_rejectSameChargeTracks
Gaudi::Property< bool > m_BsToMuMuPhi1020_rejectSameChargeTracks
Definition: TrigBmumuxComboHypo.h:309
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
TrigBmumuxComboHypo::findBmumuxCandidates_selectTracks
StatusCode findBmumuxCandidates_selectTracks(TrigBmumuxState &, size_t dimuonIndex) const
Select tracks in vicinity of given dimuon vertex.
Definition: TrigBmumuxComboHypo.cxx:337
xAOD::TrigBphys_v1::EF
@ EF
Definition: TrigBphys_v1.h:85
TrigBmumuxComboHypo::m_BcToDsMuMu
Gaudi::Property< bool > m_BcToDsMuMu
Definition: TrigBmumuxComboHypo.h:361
Trk::trkMass
@ trkMass
Extended perigee: mass.
Definition: ParamDefs.h:87
TrigBmumuxComboHypo::momentum
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.
Definition: TrigBmumuxComboHypo.cxx:1043
TrigCompositeUtils::Decision
xAOD::TrigComposite Decision
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:20
TrigBmumuxComboHypo::mergeMuonsFromDecisions
StatusCode mergeMuonsFromDecisions(TrigBmumuxState &) const
Go through state.previousDecisions(), fetch xAOD::Muons objects attached to decisions and save links ...
Definition: TrigBmumuxComboHypo.cxx:134
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
item
Definition: ItemListSvc.h:43
xAOD::TrigBphys_v1::BCDSMUMU
@ BCDSMUMU
Definition: TrigBphys_v1.h:60
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
xAOD::TrigBphys_v1::phi
float phi() const
accessor method: phi
TrigBmumuxComboHypo::m_BcToDstarMuMu_chi2
Gaudi::Property< float > m_BcToDstarMuMu_chi2
Definition: TrigBmumuxComboHypo.h:419
ITrigBphysState::previousDecisions
const TrigCompositeUtils::DecisionContainer & previousDecisions() const
Definition: ITrigBphysState.h:43
TrigCompositeUtils::createLegName
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
Definition: TrigCompositeUtilsRoot.cxx:166
xAOD::TrigBphys_v1::BCPIMUMU
@ BCPIMUMU
Definition: TrigBphys_v1.h:71
TrigBmumuxComboHypo::isInMassRange
bool isInMassRange(double mass, const std::pair< double, double > &range) const
Checks that the given mass value falls into the specified range.
Definition: TrigBmumuxComboHypo.h:229
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_minProtonPt
Gaudi::Property< double > m_LambdaBToMuMuProtonKaon_minProtonPt
Definition: TrigBmumuxComboHypo.h:345
TrigBmumuxComboHypo::m_BcToDsMuMu_DsMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_DsMassRange
Definition: TrigBmumuxComboHypo.h:373
TrigBmumuxComboHypo::m_trackToVertexTool
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
Definition: TrigBmumuxComboHypo.h:427
xAOD::TrigBphys_v1::BCDPMUMU
@ BCDPMUMU
Definition: TrigBphys_v1.h:63
TrigBmumuxComboHypo::m_BcToDstarMuMu_makeDstar
Gaudi::Property< bool > m_BcToDstarMuMu_makeDstar
Definition: TrigBmumuxComboHypo.h:401
TrackParticle.h
TrigBmumuxComboHypo::m_BcToMuMuPion
Gaudi::Property< bool > m_BcToMuMuPion
Definition: TrigBmumuxComboHypo.h:293
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
xAOD::Muon_v1::inDetTrackParticleLink
const ElementLink< TrackParticleContainer > & inDetTrackParticleLink() const
Returns an ElementLink to the InnerDetector TrackParticle used in identification of this muon.
TrigCompositeUtils::seedString
const std::string & seedString()
Definition: TrigCompositeUtilsRoot.cxx:890
TrigBmumuxComboHypo::m_dimuon_chi2
Gaudi::Property< double > m_dimuon_chi2
Definition: TrigBmumuxComboHypo.h:277
TrigBmumuxComboHypo::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: TrigBmumuxComboHypo.h:429
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
TrigBmumuxComboHypo::m_BdToMuMuKstar0
Gaudi::Property< bool > m_BdToMuMuKstar0
Definition: TrigBmumuxComboHypo.h:323
VertexContainer.h
TrigCompositeUtils::DecisionIDContainer
std::set< DecisionID > DecisionIDContainer
Definition: TrigComposite_v1.h:28
TrigBmumuxState
State class for TrigBmumuxComboHypo algorithm.
Definition: TrigBmumuxComboHypo.h:45
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
xAOD::Vertex_v1::chiSquared
float chiSquared() const
Returns the of the vertex fit as float.
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
TrigBmumuxComboHypo::m_BcToDplusMuMu_useFastFit
Gaudi::Property< bool > m_BcToDplusMuMu_useFastFit
Definition: TrigBmumuxComboHypo.h:395
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_massRange
Gaudi::Property< std::pair< double, double > > m_LambdaBToMuMuProtonKaon_massRange
Definition: TrigBmumuxComboHypo.h:353
TrigBmumuxComboHypo::initialize
virtual StatusCode initialize() override
Definition: TrigBmumuxComboHypo.cxx:55
xAOD::TrigBphys_v1::lowerChain
const TrigBphys_v1 * lowerChain() const
accessor method: lowerChain decay particle
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DEBUG
#define DEBUG
Definition: page_access.h:11
ITrigBphysState::decisions
TrigCompositeUtils::DecisionContainer & decisions()
Definition: ITrigBphysState.h:44
HLTIdentifier.h
xAOD::Vertex_v1::y
float y() const
Returns the y position.
TrigBmumuxState::selectedTrackZ0
std::map< const xAOD::TrackParticle *, double > selectedTrackZ0
Definition: TrigBmumuxComboHypo.h:77
PDG20::mPion
static constexpr double mPion
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:13
TrigBmumuxComboHypo::m_dimuon_massRange
Gaudi::Property< std::pair< double, double > > m_dimuon_massRange
Definition: TrigBmumuxComboHypo.h:275
TrigCompositeUtils::decisionIDs
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Definition: TrigCompositeUtilsRoot.cxx:67
charge3
int charge3(const T &p)
Definition: AtlasPID.h:493
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
TrigBmumuxComboHypo::m_BcToDstarMuMu_DstarMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDstarMuMu_DstarMassRange
Definition: TrigBmumuxComboHypo.h:417
TrigBmumuxComboHypo::m_BcToMuMuPion_massRange
Gaudi::Property< std::pair< double, double > > m_BcToMuMuPion_massRange
Definition: TrigBmumuxComboHypo.h:299
ComboHypo::decisionsInput
const SG::ReadHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsInput() const
Definition: ComboHypo.h:40
TrigCompositeUtils::roiString
const std::string & roiString()
Definition: TrigCompositeUtilsRoot.cxx:878
TrigBmumuxComboHypo::m_BcToDplusMuMu_chi2
Gaudi::Property< float > m_BcToDplusMuMu_chi2
Definition: TrigBmumuxComboHypo.h:393
TrigBmumuxComboHypo::m_BplusToMuMuKaon_massRange
Gaudi::Property< std::pair< double, double > > m_BplusToMuMuKaon_massRange
Definition: TrigBmumuxComboHypo.h:285
TrigBmumuxComboHypo::kB_2mu1trk
@ kB_2mu1trk
Definition: TrigBmumuxComboHypo.h:125
TrigBmumuxState::isCompositeRoI
bool isCompositeRoI
Definition: TrigBmumuxComboHypo.h:68
TrigBmumuxComboHypo::m_deltaR
Gaudi::Property< double > m_deltaR
Definition: TrigBmumuxComboHypo.h:255
TrigBmumuxComboHypo::m_allowedIDs
TrigCompositeUtils::DecisionIDContainer m_allowedIDs
Definition: TrigBmumuxComboHypo.h:432
TrigBmumuxComboHypo::m_trackParticleContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
Definition: TrigBmumuxComboHypo.h:245
TrigBmumuxComboHypo::Lxy
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...
Definition: TrigBmumuxComboHypo.cxx:1026
xAOD::TrigBphys
TrigBphys_v1 TrigBphys
Definition: TrigBphys.h:18
PDG20::mKaon
static constexpr double mKaon
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:15
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
TrigBmumuxComboHypo::Decay
Decay
Definition: TrigBmumuxComboHypo.h:123
xAOD::TrigBphys_v1::fity
float fity() const
accessor method: y position of vertex
View.h
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
xAOD::Vertex_v1::vxTrackAtVertex
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
Definition: Vertex_v1.cxx:181
PDG20::mJpsi
static constexpr double mJpsi
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:21
TrigBmumuxComboHypo::m_BcToDsMuMu_dimuonMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDsMuMu_dimuonMassRange
Definition: TrigBmumuxComboHypo.h:369
TrigBmumuxComboHypo::findDimuonCandidates
StatusCode findDimuonCandidates(TrigBmumuxState &) const
Make all possible dimuon combinations from state.muons(), fit muon InDet tracks to the common vertex,...
Definition: TrigBmumuxComboHypo.cxx:239
TrigBmumuxState::badTrackCombinations
std::vector< size_t > badTrackCombinations
Definition: TrigBmumuxComboHypo.h:83
xAOD::TrigBphys_v1::eta
float eta() const
accessor method: eta
TrigBphysContainer.h
xAOD::TrigBphys_v1::DZKPI
@ DZKPI
Definition: TrigBphys_v1.h:69
xAOD::TrigBphys_v1::MULTIMU
@ MULTIMU
Definition: TrigBphys_v1.h:55
TrigBmumuxState::isBadCombination
bool isBadCombination(size_t i1) const
Definition: TrigBmumuxComboHypo.h:89
PDG20::mD0
static constexpr double mD0
Definition: Trigger/TrigHypothesis/TrigBphysHypo/src/Constants.h:18
TrigBmumuxComboHypo::m_fastFit_2mu1trk_chi2
Gaudi::Property< double > m_fastFit_2mu1trk_chi2
Definition: TrigBmumuxComboHypo.h:269
TrigBmumuxComboHypo::passDimuonTrigger
bool passDimuonTrigger(const std::vector< const TrigCompositeUtils::DecisionIDContainer * > &previousDecisionIDs) const
Definition: TrigBmumuxComboHypo.cxx:1055
TrigBmumuxComboHypo::makeTriggerObject
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.
Definition: TrigBmumuxComboHypo.cxx:932
xAOD::Vertex_v1::vxTrackAtVertexAvailable
bool vxTrackAtVertexAvailable() const
Check if VxTrackAtVertices are attached to the object.
Definition: Vertex_v1.cxx:209
TrigComposite.h
TrigBmumuxComboHypo::m_BcToDplusMuMu
Gaudi::Property< bool > m_BcToDplusMuMu
Definition: TrigBmumuxComboHypo.h:381
TrigBmumuxState::tracks
std::vector< ElementLink< xAOD::TrackParticleContainer > > tracks
Definition: TrigBmumuxComboHypo.h:67
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TrigCompositeUtils::viewString
const std::string & viewString()
Definition: TrigCompositeUtilsRoot.cxx:882
TrigBmumuxComboHypo::m_BcToDplusMuMu_dimuonMassRange
Gaudi::Property< std::pair< double, double > > m_BcToDplusMuMu_dimuonMassRange
Definition: TrigBmumuxComboHypo.h:389
TrigBmumuxComboHypo::m_trkZ0
Gaudi::Property< double > m_trkZ0
Definition: TrigBmumuxComboHypo.h:257
xAOD::TrigBphys_v1
Class describing a Bphysics online composite object.
Definition: TrigBphys_v1.h:44
xAOD::TrigBphys_v1::pType
pType
enum for different particle types
Definition: TrigBphys_v1.h:48
AuxElement.h
Base class for elements of a container that can have aux data.
TrigBmumuxState::trackCombinations
std::map< size_t, size_t > trackCombinations
Definition: TrigBmumuxComboHypo.h:80
VertexAuxContainer.h
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
ITrigBphysState::trigBphysCollection
xAOD::TrigBphysContainer & trigBphysCollection()
Definition: ITrigBphysState.h:45
TrigBmumuxComboHypo::m_vertexFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_vertexFitter
Definition: TrigBmumuxComboHypo.h:425
TrigBmumuxComboHypo::m_BcToMuMuPion_dimuonMassRange
Gaudi::Property< std::pair< double, double > > m_BcToMuMuPion_dimuonMassRange
Definition: TrigBmumuxComboHypo.h:297
TrigBmumuxComboHypo::m_LambdaBToMuMuProtonKaon_useFastFit
Gaudi::Property< bool > m_LambdaBToMuMuProtonKaon_useFastFit
Definition: TrigBmumuxComboHypo.h:357
drawFromPickle.view
view
Definition: drawFromPickle.py:294
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
TrigBmumuxComboHypo::m_BcToDsMuMu_useFastFit
Gaudi::Property< bool > m_BcToDsMuMu_useFastFit
Definition: TrigBmumuxComboHypo.h:377
TrigBmumuxComboHypo::m_BdToMuMuKstar0_minPionPt
Gaudi::Property< double > m_BdToMuMuKstar0_minPionPt
Definition: TrigBmumuxComboHypo.h:329