ATLAS Offline Software
Loading...
Searching...
No Matches
TrigBhhComboHypo.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <algorithm>
6#include <numeric>
7#include <iterator>
8
9#include "TrigBhhComboHypo.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
36using ROOT::Math::XYVector;
37
38
39TrigBhhComboHypo::TrigBhhComboHypo(const std::string& name, ISvcLocator* pSvcLocator)
40 : ::ComboHypo(name, pSvcLocator) {}
41
42
44 ATH_MSG_DEBUG( "TrigBhhComboHypo::initialize()" );
45
47
50 ATH_CHECK( m_trigBphysContainerKey.initialize() );
51 ATH_CHECK( m_beamSpotKey.initialize() );
52
53 ATH_CHECK( m_vertexFitter.retrieve() );
55
56 // allowed IDs to filter out incoming decisions at L2 level
57 for (const auto& item : triggerMultiplicityMap()) {
58 const HLT::Identifier id = HLT::Identifier(item.first);
59 m_allowedIDs.insert(id.numeric());
60 if (item.second.size() > 1) {
61 for (size_t i = 0; i < item.second.size(); i++) {
62 m_allowedIDs.insert(TrigCompositeUtils::createLegName(id, i).numeric());
63 }
64 }
65 }
66 if (msgLvl(MSG::DEBUG)) {
67 ATH_MSG_DEBUG( "Allowed decisions:" );
68 for (const DecisionID& id : m_allowedIDs) {
69 ATH_MSG_DEBUG( " +++ " << HLT::Identifier(id) );
70 }
71 }
72
73 if (!m_monTool.empty()) {
74 ATH_CHECK( m_monTool.retrieve() );
75 ATH_MSG_DEBUG( "GenericMonitoringTool name:" << m_monTool );
76 }
77 else {
78 ATH_MSG_DEBUG( "No GenericMonitoringTool configured: no monitoring histograms will be available" );
79 }
80
81 return StatusCode::SUCCESS;
82}
83
84
85StatusCode TrigBhhComboHypo::execute(const EventContext& context) const {
86
87 ATH_MSG_DEBUG( "TrigBhhComboHypo::execute() starts" );
88
89 ATH_MSG_DEBUG( "decision input key: " << decisionsInput().at(0).key() );
90 auto previousDecisionsHandle = SG::makeHandle(decisionsInput().at(0), context);
91 ATH_CHECK( previousDecisionsHandle.isValid() );
92 ATH_MSG_DEBUG( "Running with " << previousDecisionsHandle->size() << " previous decisions" );
93
95
96 auto trigBphysHandle = SG::makeHandle(m_trigBphysContainerKey, context);
97 ATH_CHECK( trigBphysHandle.record(std::make_unique<xAOD::TrigBphysContainer>(), std::make_unique<xAOD::TrigBphysAuxContainer>()) );
98
100 ATH_CHECK( beamSpotHandle.isValid() );
101
102 auto state = std::make_unique<TrigBhhState>(context, *previousDecisionsHandle, *outputDecisionsHandle, trigBphysHandle.ptr(), *beamSpotHandle);
103
106 ATH_CHECK( findBhhCandidates(*state) );
108
109 ATH_MSG_DEBUG( "TrigBhhComboHypo::execute() terminates with StatusCode::SUCCESS" );
110 return StatusCode::SUCCESS;
111}
112
113
115
116 auto& muons = state.muons;
117 muons.clear();
118
119 // all muons from views are already connected with previous decisions by TrigMuonEFHypoAlg
120 for (const Decision* decision : state.previousDecisions()) {
121 if (!TrigCompositeUtils::isAnyIDPassing(decision, m_allowedIDs)) continue;
122
124 auto muonEL = decision->objectLink<xAOD::MuonContainer>(TrigCompositeUtils::featureString());
125 const xAOD::Muon* muon = *muonEL;
126 if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) continue;
127
128 auto decisionEL = TrigCompositeUtils::decisionToElementLink(decision, state.context());
129 auto itr = std::find_if(muons.begin(), muons.end(), [this, muon](const auto& x){ return isIdenticalTracks(muon, *x.link); });
130 if (itr == muons.end()) {
131 muons.push_back({muonEL, std::vector<ElementLink<DecisionContainer>>(1, decisionEL), DecisionIDContainer()});
132 }
133 else {
134 (*itr).decisionLinks.push_back(decisionEL);
135 }
136 }
137
138 // muon->pt() is equal to muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)->pt()
139 // and the later is used by TrigMuonEFHypoTool for classification of muEFCB candidates
140 std::sort(muons.begin(), muons.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs.link)->pt() > (*rhs.link)->pt()); });
141
142 // for each muon we extract DecisionIDs stored in the associated Decision objects and copy them at muon.decisionIDs
143 for (auto& item : muons) {
144 for (const ElementLink<xAOD::TrigCompositeContainer>& decisionEL : item.decisionLinks) {
145 TrigCompositeUtils::decisionIDs(*decisionEL, item.decisionIDs);
146 }
147 }
148
149 if (msgLvl(MSG::DEBUG)) {
150 ATH_MSG_DEBUG( "Dump found muons before vertex fit: " << muons.size() << " candidates" );
151 for (const auto& item : muons) {
152 const xAOD::Muon* muon = *item.link;
153 const xAOD::TrackParticle* track = *muon->inDetTrackParticleLink();
154 ATH_MSG_DEBUG( " -- muon InDetTrackParticle pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
155 ATH_MSG_DEBUG( " muon CombinedTrackParticle pt: " << muon->pt() );
156 ATH_MSG_DEBUG( " allowed decisions:" );
157 for (const DecisionID& id : item.decisionIDs) {
158 ATH_MSG_DEBUG( " +++ " << HLT::Identifier(id) );
159 }
160 }
161 }
162
163 return StatusCode::SUCCESS;
164}
165
166
168
169 const auto& muons = state.muons;
170 auto& tracks = state.tracks;
171 tracks.clear();
172
173 size_t viewCounter = 0;
174 for (const Decision* decision : state.previousDecisions()) {
175 if (!TrigCompositeUtils::isAnyIDPassing(decision, m_allowedIDs)) continue;
176
178 ATH_CHECK( viewLinkInfo.isValid() );
179 auto view = *viewLinkInfo.link;
180
182 ATH_CHECK( roiLinkInfo.isValid() );
183 const auto roi = *roiLinkInfo.link;
184
185 auto tracksHandle = ViewHelper::makeHandle(view, m_trackParticleContainerKey, state.context());
186 ATH_CHECK( tracksHandle.isValid() );
187 ATH_MSG_DEBUG( "tracks handle " << m_trackParticleContainerKey << " size: " << tracksHandle->size() );
188
189 std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
190 tracksFromView.reserve(tracksHandle->size());
191 for (size_t idx = 0; idx < tracksHandle->size(); ++idx) {
192 tracksFromView.emplace_back(ViewHelper::makeLink<xAOD::TrackParticleContainer>(view, tracksHandle, idx));
193 }
194
195 for (const auto& trackEL : tracksFromView) {
196 const xAOD::TrackParticle* track = *trackEL;
197 if (track->definingParametersCovMatrixVec().empty()) continue;
198
199 if (viewCounter == 0 ||
200 std::find_if(tracks.begin(), tracks.end(),
201 [this, track](const auto& x){ return isIdenticalTracks(track, *x); }) == tracks.end()) {
202 tracks.emplace_back(trackEL);
203 }
204 }
205 viewCounter++;
206 if (roi->composite()) {
207 break;
208 }
209 }
210
211 if (msgLvl(MSG::DEBUG)) {
212 std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
213 ATH_MSG_DEBUG( "Found " << tracks.size() << " tracks" );
214 for (const auto& trackEL : tracks) {
215 const xAOD::TrackParticle* track = *trackEL;
216 ATH_MSG_DEBUG( " -- track pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
217 }
218 }
219
220 if (tracks.size() < 2) {
221 tracks.clear();
222 return StatusCode::SUCCESS;
223 }
224
225 // remove muon duplicates
226 if (m_applyMuonRemoval) {
227 for (size_t i = 0; i < muons.size(); ++i) {
228 const xAOD::Muon* muon = *muons[i].link;
229 const xAOD::TrackParticle* track = *muon->inDetTrackParticleLink();
230 std::sort(tracks.begin(), tracks.end(), [p_mu=track->genvecP4()](const auto& lhs, const auto& rhs){ return ROOT::Math::VectorUtil::DeltaR(p_mu, (*lhs)->genvecP4()) > ROOT::Math::VectorUtil::DeltaR(p_mu, (*rhs)->genvecP4()); });
231 if (isIdenticalTracks(track, *tracks.back())) tracks.pop_back();
232 }
233 std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
234
235 if (msgLvl(MSG::DEBUG)) {
236 ATH_MSG_DEBUG( "Found " << tracks.size() << " tracks after muon removal" );
237 for (const auto& trackEL : tracks) {
238 const xAOD::TrackParticle* track = *trackEL;
239 ATH_MSG_DEBUG( " -- track pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
240 }
241 }
242 }
243
244 // apply pT threshold cut
245 std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
246 tracks.erase(std::upper_bound(tracks.begin(), tracks.end(), m_trkPt, [](double trkPt, const auto& trackEL){ return trkPt > (*trackEL)->pt(); }), tracks.end());
247
248 if (msgLvl(MSG::DEBUG)) {
249 ATH_MSG_DEBUG( "Found " << tracks.size() << " tracks after pT threshold cut" );
250 for (const auto& trackEL : tracks) {
251 const xAOD::TrackParticle* track = *trackEL;
252 ATH_MSG_DEBUG( " -- track pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
253 }
254 }
255 return StatusCode::SUCCESS;
256}
257
258
260
261 // monitored variables
262 auto mon_nMuon = Monitored::Scalar<int>("nMuon", 0);
263 auto mon_nTrk = Monitored::Scalar<int>("nTrk", 0);
264 auto mon_nBPhysObject = Monitored::Scalar<int>("nBPhysObject", 0);
265
266 auto group = Monitored::Group(m_monTool,
267 mon_nMuon, mon_nTrk, mon_nBPhysObject);
268
269 const auto& tracks = state.tracks;
270
271 size_t iterations = 0;
272 bool isOverWarningThreshold = false;
273
274 std::vector<ElementLink<xAOD::TrackParticleContainer>> trackParticleLinks(2);
275 for (size_t itrk1 = 0; itrk1 < tracks.size(); ++itrk1) {
276 trackParticleLinks[0] = tracks[itrk1];
277 const xAOD::TrackParticle* trk1 = *trackParticleLinks[0];
278 auto p_trk1 = trk1->genvecP4();
279 auto charge1 = trk1->charge();
280
281 for (size_t itrk2 = itrk1 + 1; itrk2 < tracks.size(); ++itrk2) {
282 trackParticleLinks[1] = tracks[itrk2];
283 const xAOD::TrackParticle* trk2 = *trackParticleLinks[1];
284 auto p_trk2 = trk2->genvecP4();
285 auto charge2 = trk2->charge();
286
287 auto mKK = (p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mKaon)).M();
288 auto mPiPi = (p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mPion)).M();
289
290 if (charge1 * charge2 > 0. || mKK < m_massRange.value().first || mPiPi > m_massRange.value().second) continue;
291
292 // fit tracks to the common vertex
293 auto vertex = fit(state.context(), trackParticleLinks);
294 iterations++;
295 if (!vertex) continue;
296
298 xAOD::TrigBphys* triggerObject = state.trigBphysCollection().back();
299
300 ATH_CHECK( fillTriggerObject(*triggerObject, *vertex, state.beamSpotPosition()) );
301 triggerObject->setMass(mKK);
302
303 ATH_MSG_DEBUG( "Found B -> h+ h- candidate: M(K+,K-) = " << mKK << " M(pi+,pi-) = " << mPiPi );
304
305 if (iterations > m_fitAttemptsWarningThreshold && !isOverWarningThreshold) {
306 ATH_MSG_WARNING( "B -> hh: " << state.trigBphysCollection().size() << " vertices created after " << iterations << " vertex fitter calls" );
307 isOverWarningThreshold = true;
308 }
309 if (iterations > m_fitAttemptsBreakThreshold) {
310 ATH_MSG_WARNING( "b -> hh: the number of fit attempts has exceeded the limit, breaking the loop at this point" );
311 itrk1 = tracks.size();
312 break;
313 }
314
315 }
316 }
317
318 mon_nMuon = state.muons.size();
319 mon_nTrk = tracks.size();
320 mon_nBPhysObject = state.trigBphysCollection().size();
321
322 return StatusCode::SUCCESS;
323}
324
325
327
328 // state.muons() are common seeds for all B -> hh candidates
329 std::vector<ElementLink<TrigCompositeUtils::DecisionContainer>> previousDecisionLinks;
331 std::vector<const DecisionIDContainer*> previousDecisionIDs = { &decisionIDs };
332
333 for (const Decision* previousDecision : state.previousDecisions()) {
334 if (!TrigCompositeUtils::isAnyIDPassing(previousDecision, m_allowedIDs)) continue;
335
336 previousDecisionLinks.emplace_back(TrigCompositeUtils::decisionToElementLink(previousDecision, state.context()));
338 }
339
340 for (const xAOD::TrigBphys* triggerObject : state.trigBphysCollection()) {
341 ATH_MSG_DEBUG( "Found xAOD::TrigBphys object: fitMass = " << triggerObject->fitmass() << ", chi2 = " << triggerObject->fitchi2() );
342
343 auto triggerObjectEL = ElementLink<xAOD::TrigBphysContainer>(state.trigBphysCollection(), triggerObject->index());
344 ATH_CHECK( triggerObjectEL.isValid() );
345
346 // create a new output Decision object, backed by the 'decisions' container.
348
349 // attach all previous decisions, no need to use TrigCompositeUtils::linkToPrevious()
350 decision->addObjectCollectionLinks(TrigCompositeUtils::seedString(), previousDecisionLinks);
351
352 // set mandatory link to the trigger object
354
355 for (const auto& tool : hypoTools()) {
356 ATH_MSG_DEBUG( "Go to " << tool );
357 ATH_CHECK( tool->decideOnSingleObject(decision, previousDecisionIDs) );
358 }
359 }
360
361 return StatusCode::SUCCESS;
362}
363
364
365std::unique_ptr<xAOD::Vertex> TrigBhhComboHypo::fit(
366 const EventContext& context,
367 const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks,
368 const std::vector<double>& trkMass) const {
369
370 ATH_MSG_DEBUG( "Perform vertex fit" );
371
372 if (trackParticleLinks.size() != 2) {
373 ATH_MSG_WARNING( "Exactly two tracks should be given to the vertex fitter" );
374 return std::unique_ptr<xAOD::Vertex>(nullptr);
375 }
376
377 std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(), nullptr);
378 std::transform(trackParticleLinks.begin(), trackParticleLinks.end(), tracklist.begin(),
379 [](const ElementLink<xAOD::TrackParticleContainer>& link){ return *link; });
380
381 Amg::Vector3D startingPoint = Amg::Vector3D::Zero(3);
382 int flag = 0;
383 int errorcode = 0;
384 const Trk::Perigee& perigee1 = tracklist[0]->perigeeParameters();
385 const Trk::Perigee& perigee2 = tracklist[1]->perigeeParameters();
386 startingPoint = m_vertexPointEstimator->getCirclesIntersectionPoint(&perigee1, &perigee2, flag, errorcode);
387 if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
388 ATH_MSG_DEBUG( "Starting point: (" << startingPoint(0) << ", " << startingPoint(1) << ", " << startingPoint(2) << ")" );
389
390 auto fitterState = m_vertexFitter->makeState(context);
391 m_vertexFitter->setMassInputParticles(trkMass, *fitterState);
392
393 std::unique_ptr<xAOD::Vertex> vertex(m_vertexFitter->fit(tracklist, startingPoint, *fitterState));
394 if (!vertex) {
395 ATH_MSG_DEBUG( "Vertex fit fails" );
396 return vertex;
397 }
398 if (vertex->chiSquared() > m_chi2) {
399 ATH_MSG_DEBUG( "Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() << ")" );
400 vertex.reset();
401 return vertex;
402 }
403 ATH_MSG_DEBUG( "Fit is successful" );
404
405 // update trackParticleLinks()
406 vertex->clearTracks();
407 vertex->setTrackParticleLinks(trackParticleLinks);
408
409 return vertex;
410}
411
412
414 xAOD::TrigBphys& triggerObject,
415 const xAOD::Vertex& vertex,
416 const Amg::Vector3D& productionVertex,
417 const std::vector<double>& trkMass) const {
418
419 // refitted track momentum as a 4-vector for mass hypothesis defined by the given decay value
421 std::vector<xAOD::TrackParticle::GenVecFourMom_t> momenta;
422 ATH_CHECK( vertex.vxTrackAtVertexAvailable() );
423 ATH_CHECK( vertex.vxTrackAtVertex().size() == trkMass.size() );
424 for (size_t i = 0; i < vertex.vxTrackAtVertex().size(); ++i) {
425 const Trk::TrackParameters* perigee = vertex.vxTrackAtVertex()[i].perigeeAtVertex();
426 ATH_CHECK( perigee != nullptr );
427 const Amg::Vector3D& p = perigee->momentum();
428 momenta.emplace_back(p.x(), p.y(), p.z(), trkMass[i]);
429 momentum += momenta.back();
430 }
431
432 triggerObject.initialise(0, momentum.Eta(), momentum.Phi(), momentum.Pt(), xAOD::TrigBphys::BHH, momentum.M(), xAOD::TrigBphys::EF);
433
434 triggerObject.setFitmass(momentum.M());
435 triggerObject.setFitx(vertex.x());
436 triggerObject.setFity(vertex.y());
437 triggerObject.setFitz(vertex.z());
438 triggerObject.setFitchi2(vertex.chiSquared());
439 triggerObject.setFitndof(vertex.numberDoF());
440 triggerObject.setLxy(Lxy(productionVertex, vertex.position(), momenta));
441
442 // set all the particles associated with the decay
443 triggerObject.setTrackParticleLinks(vertex.trackParticleLinks());
444
446 "TrigBphys object:\n\t " <<
447 "roiId: " << triggerObject.roiId() << "\n\t " <<
448 "particleType: " << triggerObject.particleType() << "\n\t " <<
449 "level: " << triggerObject.level() << "\n\t " <<
450 "eta: " << triggerObject.eta() << "\n\t " <<
451 "phi: " << triggerObject.phi() << "\n\t " <<
452 "mass: " << triggerObject.mass() << "\n\t " <<
453 "fitmass: " << triggerObject.fitmass() << "\n\t " <<
454 "chi2/NDF: " << triggerObject.fitchi2() << " / " << triggerObject.fitndof() << "\n\t " <<
455 "vertex: (" << triggerObject.fitx() << ", " << triggerObject.fity() << ", " << triggerObject.fitz() << ")" );
456
457 return StatusCode::SUCCESS;
458}
459
460
462
463 if (lhs->charge() * rhs->charge() < 0.) return false;
464 return (ROOT::Math::VectorUtil::DeltaR(lhs->genvecP4(), rhs->genvecP4()) < m_deltaR);
465}
466
467
468bool TrigBhhComboHypo::isIdenticalTracks(const xAOD::Muon* lhs, const xAOD::Muon* rhs) const {
469
471}
472
473
474double TrigBhhComboHypo::Lxy(const Amg::Vector3D& productionVertex, const Amg::Vector3D& decayVertex, const std::vector<xAOD::TrackParticle::GenVecFourMom_t>& momenta) const {
475
476 XYVector R(decayVertex.x() - productionVertex.x(), decayVertex.y() - productionVertex.y());
477 XYVector pT;
478 for (const auto& p : momenta) {
479 pT += XYVector(p.x(), p.y());
480 }
481 return R.Dot(pT.unit());
482}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Base class for elements of a container that can have aux data.
void decisionIDs(const Decision *d, DecisionIDContainer &id)
Extracts DecisionIDs stored in the Decision object.
#define x
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)
Definition ComboHypo.cxx:13
const SG::WriteHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsOutput() const
Definition ComboHypo.h:42
const Combo::MultiplicityReqMap & triggerMultiplicityMap() const
Definition ComboHypo.h:43
ToolHandleArray< ComboHypoToolBase > & hypoTools()
Definition ComboHypo.h:45
const SG::ReadHandleKeyArray< TrigCompositeUtils::DecisionContainer > & decisionsInput() const
Definition ComboHypo.h:41
virtual StatusCode initialize() override
Definition ComboHypo.cxx:22
const T * back() const
Access the last element in the collection 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.
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.
ToolHandle< InDet::VertexPointEstimator > m_vertexPointEstimator
StatusCode fillTriggerObject(xAOD::TrigBphys &triggerObject, const xAOD::Vertex &vertex, const Amg::Vector3D &productionVertex, const std::vector< double > &trkMass={PDG::mKaon, PDG::mKaon}) const
Fill the trigger object that may be stored for debugging or matching.
Gaudi::Property< double > m_chi2
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleContainerKey
TrigBhhComboHypo()=delete
StatusCode mergeMuonsFromDecisions(TrigBhhState &) const
Go through state.previousDecisions(), fetch xAOD::Muons objects attached to decisions and save links ...
ToolHandle< Trk::TrkVKalVrtFitter > m_vertexFitter
Gaudi::Property< double > m_trkPt
virtual StatusCode execute(const EventContext &context) const override
bool isIdenticalTracks(const xAOD::TrackParticle *lhs, const xAOD::TrackParticle *rhs) const
Returns false for the tracks with opposite charges.
Gaudi::Property< std::pair< double, double > > m_massRange
SG::WriteHandleKey< xAOD::TrigBphysContainer > m_trigBphysContainerKey
ToolHandle< GenericMonitoringTool > m_monTool
TrigCompositeUtils::DecisionIDContainer m_allowedIDs
Gaudi::Property< double > m_deltaR
Gaudi::Property< size_t > m_fitAttemptsBreakThreshold
virtual StatusCode initialize() override
std::unique_ptr< xAOD::Vertex > fit(const EventContext &context, const std::vector< ElementLink< xAOD::TrackParticleContainer > > &trackParticleLinks, const std::vector< double > &trkMass={PDG::mKaon, PDG::mKaon}) const
Perform a vertex fit on selected tracks.
Gaudi::Property< bool > m_applyMuonRemoval
double Lxy(const Amg::Vector3D &productionVertex, const Amg::Vector3D &decayVertex, const std::vector< xAOD::TrackParticle::GenVecFourMom_t > &momenta) const
Returns the transverse decay length of a particle Lxy in [mm].
Gaudi::Property< size_t > m_fitAttemptsWarningThreshold
StatusCode findBhhCandidates(TrigBhhState &) const
Make all possible combinations from state.tracks(), fit tracks to the common vertex,...
StatusCode mergeTracksFromViews(TrigBhhState &) const
Go through state.previousDecisions() and fetch xAOD::TrackParticle objects associated with the neares...
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
StatusCode createDecisionObjects(TrigBhhState &) const
Create a decision for each xAOD::TrigBphys object from state.trigBphysCollection() and use hypoTools(...
State class for TrigBhhComboHypo algorithm.
std::vector< ElementLink< xAOD::TrackParticleContainer > > tracks
std::vector< Muon > muons
const Amg::Vector3D & momentum() const
Access method for the momentum.
const ElementLink< TrackParticleContainer > & inDetTrackParticleLink() const
Returns an ElementLink to the InnerDetector TrackParticle used in identification of this muon.
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzM4D< double > > GenVecFourMom_t
Base 4 Momentum type for TrackParticle.
GenVecFourMom_t genvecP4() const
The full 4-momentum of the particle : GenVector form.
float charge() const
Returns the charge.
int fitndof() const
accessor method: ndof from vertex fit
void setFitchi2(float FitChi2)
set method: chi2 from vertex fit
void setFitx(float FitX)
set method: x position of vertex
uint32_t roiId() const
accessor method: ID of L1 RoI
void setFity(float FitY)
set method: y position of vertex
float eta() const
accessor method: eta
pType particleType() const
accessor method: particle Type
float phi() const
accessor method: phi
float fitchi2() const
accessor method: chi2 from vertex fit
void setFitndof(int FitNdof)
set method: ndof from vertex fit
void setFitz(float FitZ)
set method: z position of vertex
float fitx() const
accessor method: x position of vertex
void setLxy(float v)
set method: lxy
void setFitmass(float FitMass)
set method: mass from vertex fit
float fitz() const
accessor method: z position of vertex
float fitmass() const
accessor method: mass from vertex fit
float mass() const
accessor method: mass
void setMass(float)
Set the mass of the object.
float fity() const
accessor method: y position of vertex
levelType level() const
accessor method: level Type
void setTrackParticleLinks(const std::vector< ElementLink< TrackParticleContainer > > &links)
Set the track particle links on the object.
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.
Eigen::Matrix< double, 3, 1 > Vector3D
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.
unsigned int DecisionID
const std::string & viewString()
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()
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()
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
bool isAnyIDPassing(const Decision *d, const DecisionIDContainer &required)
Checks if any of the DecisionIDs passed in arg required is availble in Decision object.
ElementLink< DecisionContainer > decisionToElementLink(const Decision *d, const EventContext &ctx)
Takes a raw pointer to a Decision and returns an ElementLink to the Decision.
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.
Definition ViewHelper.h:309
auto makeHandle(const SG::View *view, const KEY &key, const EventContext &ctx)
Create a view handle from a handle key.
Definition ViewHelper.h:273
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TrigBphys_v1 TrigBphys
Definition TrigBphys.h:18
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