20#include "Acts/Definitions/Units.hpp"
21#include "Acts/Surfaces/PlaneSurface.hpp"
22#include "Acts/Utilities/Helpers.hpp"
30using namespace Acts::UnitLiterals;
34 constexpr double toDeg(
const double rad) {
35 return rad / 1._degree;
41 const EventContext& ctx) {
43 if(!
SG::get(muTagCont, key, ctx).isSuccess()){
50 if (muTag->idTrack() == &idTrack){
57 bool isOnCaloExit(
const Acts::Surface& surf) {
61 bool isOnCaloExit(
const Acts::BoundTrackParameters& pars) {
62 return isOnCaloExit(pars.referenceSurface());
71 if (matchedSegs.empty() ||
toLayerIndex(matchedSegs.front()->chamberIndex()) ==
toLayerIndex(matchedSegs.back()->chamberIndex())) {
84 const auto [barrelLength, barrelTheta] =
calcSeedLength(tgContext, barrelSeed);
85 const auto [endcapLength, endcapTheta] =
calcSeedLength(tgContext, endcapSeed);
86 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Constructed new seed from truth muon wih pT:"
87 <<(truthMuon.pt()/ Gaudi::Units::GeV)<<
" [GeV], eta: "<<truthMuon.eta()
88 <<
", phi: "<<toDeg(truthMuon.phi())<<
", q: "<<truthMuon.charge()
89 <<
", matchedSeg: "<<matchedSegs.size()<<
" barrel (L/theta): "<<barrelLength
90 <<
"/"<<barrelTheta<<
" - endcap (L/theta): "
91 <<endcapLength<<
"/"<<endcapTheta<<
"\n"<<barrelSeed);
92 if (barrelLength < 0 && endcapLength < 0) {
96 return barrelLength < 0 || std::abs(endcapLength) < barrelLength
97 ? endcapSeed : barrelSeed;
102 double maxL{-1.*Gaudi::Units::km}, minL{1.*Gaudi::Units::km},
103 maxTheta{-181.}, minTheta{181};
106 if (!
m_seedingTool->withinBounds(projPos, seed.location())) {
109 const double projected = projPos[seed.location()==Location::Barrel];
110 const double theta = seg->direction().theta();
111 minL = std::min(minL, projected);
112 maxL = std::max(maxL, projected);
113 minTheta = std::min(minTheta, toDeg(
theta));
114 maxTheta = std::max(maxTheta, toDeg(
theta));
116 return std::make_pair(maxL - minL, maxTheta - minTheta);
147 return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
152 return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
163 const unsigned linkIdx = truthS ?
m_truthSegs->push_back(*truthS) : -1;
183 unsigned short linkIdx =
m_truthTrks->find(truthP);
186 for (
auto loc : {Location::Barrel, Location::Endcap}) {
188 std::format(
"TruthSegments_has{}Proj", loc), [loc,
this](
const SG::AuxElement* aux) ->
unsigned short {
191 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(Gaudi::Hive::currentContext());
206 std::vector<unsigned short>>>(
m_tree,
208 std::vector<unsigned short> idx{};
218 return getTruthSegments(p).size();
224 std::vector<const xAOD::MuonSimHit*> allHits{};
227 allHits.insert(allHits.end(), hits.begin(), hits.end());
229 if (allHits.empty()) {
233 return a->kineticEnergy() < b->kineticEnergy();
235 return (
min->kineticEnergy() -
max->kineticEnergy()) / Gaudi::Units::GeV;
238 auto cone = std::make_shared<VectorBranch<float>>(m_tree,
239 std::format(
"{}_seedThetaCone", m_truthTrks->name()));
240 auto qTimesP = std::make_shared<VectorBranch<float>>(m_tree,
241 std::format(
"{}_qTimesP", m_truthTrks->name()));
243 m_tree.addBranch(cone);
244 m_tree.addBranch(qTimesP);
247 std::format(
"{:}_seedLength", m_truthTrks->name()), [cone, qTimesP,
this] (
const xAOD::TruthParticle& p) ->
float {
249 const EventContext& ctx{Gaudi::Hive::currentContext()};
250 const Acts::GeometryContext tgContext = m_ctxProvider.getGeometryContext(ctx);
251 const Acts::MagneticFieldContext mfContext = m_ctxProvider.getMagneticFieldContext(ctx);
253 mfContext.get<
const AtlasFieldCacheCondObj*>()->getInitializedCache(magField);
254 auto truthSeed = makeSeedFromTruth(tgContext, p);
257 qTimesP->push_back(0);
260 auto [
length,
theta] = calcSeedLength(tgContext, *truthSeed);
261 cone->push_back(
theta);
262 qTimesP->push_back(m_seedingTool->estimateQtimesP(tgContext, *truthSeed, magField) / Gaudi::Units::GeV);
266 m_tree.addBranch(m_truthTrks);
267 m_trkTruthLinks.emplace_back(m_truthSegmentKey,
"truthParticleLink");
268 m_trkTruthLinks.emplace_back(m_truthKey,
"truthSegmentLinks");
269 m_trkTruthLinks.emplace_back(m_recoSegmentKey,
"truthSegmentLink");
270 m_trkTruthLinks.emplace_back(m_muonKey,
"truthParticleLink");
273 m_tree.addBranch(m_recoSegs);
274 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, evOpts));
276 static const std::vector<std::string> trackSummaries{
278 "innerSmallHits",
"innerLargeHits",
"innerSmallHoles",
"innerLargeHoles",
279 "innerClosePrecisionHits",
281 "middleSmallHits",
"middleLargeHits",
"middleSmallHoles",
282 "middleLargeHoles",
"middleClosePrecisionHits",
284 "outerSmallHits",
"outerLargeHits",
"outerSmallHoles",
"outerLargeHoles",
285 "outerClosePrecisionHits",
287 "extendedSmallHits",
"extendedLargeHits",
"extendedSmallHoles",
288 "extendedLargeHoles",
"extendedClosePrecisionHits",
289 "innerTriggerEtaHits",
"innerTriggerPhiHits",
290 "middleTriggerEtaHits",
"middleTriggerPhiHits",
291 "outerTriggerEtaHits",
"outerTriggerPhiHits",
293 "innerTriggerEtaHoles",
"innerTriggerPhiHoles",
294 "middleTriggerEtaHoles",
"middleTriggerPhiHoles",
295 "outerTriggerEtaHoles",
"outerTriggerPhiHoles",
297 if(!m_legacyTrackKey.empty()) {
298 m_legacyTrks = std::make_unique<IParticleFourMomBranch>(m_tree,
"LegacyMSTrks");
299 m_legacyTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_legacyTrks));
304 },
"truth",
"LegacyMS");
306 for (
const auto& summary : trackSummaries) {
309 m_tree.addBranch(m_legacyTrks);
310 m_legacyRecoSegs = std::make_unique<SegmentVariables>(m_tree, m_legacySegmentKey.key(),
"LegacyRecoSegments", msgLevel());
311 m_tree.addBranch(m_legacyRecoSegs);
314 m_seedSummary = std::make_shared<TrackSummaryModule>(m_tree,
"TrkSeed", m_summaryTool.get());
315 m_muonTrks = std::make_shared<IParticleFourMomBranch>(m_tree,
"ActsMuons");
316 m_muonTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_muonTrks));
317 m_muonTrks->addVariable<
float>(4.5,
"segmentDeltaEta");
318 m_muonTrks->addVariable<
float>(std::numbers::pi,
"segmentDeltaPhi");
319 m_muonTrks->addVariable<
float>(-1.,
"segmentChi2OverDoF");
321 using TrkType = xAOD::Muon::TrackParticleType;
322 auto dumpTrack = [&](
const std::string& trkName, TrkType
type) {
323 auto trkColl = std::make_shared<IParticleFourMomBranch>(m_tree, trkName);
324 trkColl->addVariable(std::make_unique<TrackChi2Branch>(*trkColl));
325 if (
type != TrkType::InnerDetectorTrackParticle) {
326 trkColl->addVariable(std::make_unique<TrackFitIterBranch>(*trkColl));
328 trkColl->addVariable(std::make_unique<MaterialRecorderBranch>(*trkColl));
329 trkColl->addVariable(std::make_unique<EnergyLossBranch>(*trkColl));
331 trkColl->addVariable<
float>(
"d0");
332 trkColl->addVariable<
float>(
"z0");
333 if (
type != TrkType::InnerDetectorTrackParticle) {
334 for (
const auto& summary : trackSummaries) {
350 auto msTracks = dumpTrack(
"MsTrk", TrkType::MuonSpectrometerTrackParticle);
351 dumpTrack(
"MeTrk", TrkType::ExtrapolatedMuonSpectrometerTrackParticle);
352 m_idTracks = dumpTrack(
"IdTrk", TrkType::InnerDetectorTrackParticle);
356 auto&
l0{
m_tree.newVector<
float>(std::format(
"{:}_caloExitLoc0", m_idTracks->name()))};
357 auto&
l1{
m_tree.newVector<
float>(std::format(
"{:}_caloExitLoc1", m_idTracks->name()))};
358 auto&
theta{
m_tree.newVector<
float>(std::format(
"{:}_caloExitTheta", m_idTracks->name()))};
359 auto&
phi{
m_tree.newVector<
float>(std::format(
"{:}_caloExitPhi", m_idTracks->name()))};
360 auto&
mom{
m_tree.newVector<
float>(std::format(
"{:}_caloExitMom", m_idTracks->name()))};
363 std::format(
"{:}_isCandidate", m_idTracks->name()),
365 const MuonR4::MuonTag* tag = findBaseIdTag(idTrack, Gaudi::Hive::currentContext());
366 std::optional<Acts::BoundTrackParameters> trkPars = tag ? tag->extrapolatedParsID(Acts::hashString(
"@CaloExit"))
368 const std::size_t idx = l0.size();
369 using namespace MuonCombinedR4;
370 l0[idx] = trkPars ? longitudinalParam(*trkPars, logger()) : 1._km;
371 l1[idx] = trkPars ? toDeg(localPolarAngle(*trkPars, logger())) : 360.;
373 theta[idx] = trkPars ? toDeg(trkPars->get<Acts::eBoundTheta>()) : 360.;
374 phi[idx] = trkPars ? toDeg(trkPars->get<Acts::eBoundPhi>()) : 360.;
375 mom[idx] = trkPars ? trkPars->absoluteMomentum() : -1._GeV;
376 return trkPars != std::nullopt;
380 auto& dX0{
m_tree.newMatrix<
float>(std::format(
"{:}_segTagDx0", m_idTracks->name()))};
381 auto& dY0{
m_tree.newMatrix<
float>(std::format(
"{:}_segTagDy0", m_idTracks->name()))};
382 auto&
dTheta{
m_tree.newMatrix<
float>(std::format(
"{:}_segTagDtheta", m_idTracks->name()))};
383 auto&
dPhi{
m_tree.newMatrix<
float>(std::format(
"{:}_segTagDphi", m_idTracks->name()))};
384 auto& segments{
m_tree.newMatrix<std::uint8_t>(std::format(
"{:}_segTagSegments", m_idTracks->name()))};
385 auto& goodExtp{
m_tree.newMatrix<std::uint8_t>(std::format(
"{:}_segTagExtpGood",m_idTracks->name()))};
386 auto& taggedSeg{
m_tree.newMatrix<std::uint8_t>(std::format(
"{:}_segTagOnTag", m_idTracks->name()))};
387 m_idTracks->addVariable(
389 std::format(
"{:}_segTagScore", m_idTracks->name()),
390 [&dX0, &dY0, &dTheta, &dPhi, &segments,
392 auto result = calcSegTagVariables(idTrack, Gaudi::Hive::currentContext());
394 segments.push_back(std::move(result.recoSegs));
395 dX0.push_back(std::move(result.deltaX0));
396 dY0.push_back(std::move(result.deltaY0));
397 dTheta.push_back(std::move(result.deltaTheta));
398 dPhi.push_back(std::move(result.deltaPhi));
399 goodExtp.push_back(std::move(result.goodExtp));
400 taggedSeg.push_back(std::move(result.taggedSeg));
401 return std::move(result.matchScores);
407 return truthTreeParticle(*trk, Gaudi::Hive::currentContext());
408 },
"truth",
"IdTrack");
412 m_muonTrks->addVariable<
uint16_t>(
"allAuthors");
413 m_muonTrks->addVariable<
uint16_t>(
"author");
416 std::vector<unsigned short>>>(m_tree,
417 std::format(
"{:}_segmentLinks", m_muonTrks->name()), [&] (
const xAOD::Muon& p){
418 std::vector<unsigned short> idx{};
419 for (
unsigned seg = 0 ; seg <
p.nMuonSegments(); ++seg) {
420 idx.push_back(m_recoSegs->push_back(*
p.muonSegment(seg)));
426 std::format(
"{:}_seedLink", msTracks->name()), [&] (
const xAOD::TrackParticle& p) ->
unsigned short {
427 auto actsTrk = ActsTrk::getActsTrack(p);
429 THROW_EXCEPTION(
"Cannot find the associated ms track from the primary track");
431 return actsTrk->component<std::size_t>(
"parentSeed");
438 THROW_EXCEPTION(
"Cannot find the associated ms track from the primary track");
440 auto refPars = actsTrk->createParametersAtReference();
442 : refPars.
get<
Acts::eBoundLoc0>();
448 THROW_EXCEPTION(
"Cannot find the associated ms track from the primary track");
450 auto refPars = actsTrk->createParametersAtReference();
452 : refPars.
get<
Acts::eBoundLoc0>();
458 THROW_EXCEPTION(
"Cannot find the associated ms track from the primary track");
460 return isOnCaloExit(actsTrk->referenceSurface());
466 },
"truth",
"ActsMuon");
469 for (
const auto& summary : trackSummaries) {
472 m_tree.addBranch(m_muonTrks);
474 m_tree.addBranch(m_seedSummary);
478 return StatusCode::SUCCESS;
482 const EventContext& ctx)
const {
496 const EventContext& ctx)
const {
497 return findTagMatchingToId(idTrack,
m_idTagKey, ctx);
500 const EventContext& ctx)
const {
501 return findTagMatchingToId(idTrack,
m_segTagKey, ctx);
504 std::vector<const xAOD::MuonSegment*>
506 const EventContext& ctx)
const {
507 std::vector<const xAOD::MuonSegment*> compatibleSegs{};
509 std::vector<const xAOD::MuonSegment*> truthSegs =
getTruthSegments(*truthPart);
512 std::copy_if(recoSegs->
begin(), recoSegs->
end(), std::back_inserter(compatibleSegs),
514 return Acts::rangeContainsValue(truthSegs, getMatchedTruthSegment(*recoSeg));
516 if (!compatibleSegs.empty()) {
517 return compatibleSegs;
524 if (muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle) == &idTrack) {
525 for (std::size_t s = 0; s < muon->nMuonSegments() ; ++s) {
526 compatibleSegs.push_back(muon->muonSegment(s));
531 return compatibleSegs;
540 const EventContext& ctx) {
545 if (compatibleSegs.empty()) {
553 std::optional<Acts::BoundTrackParameters> startPars = caloExt->
lastParameters();
560 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
565 const Acts::Surface& target{msSector->
surface()};
566 if (target.geometryId() == startPars->referenceSurface().geometryId()) {
570 auto surfPars = muTag->
extrapolatedParsID(Acts::toUnderlying(segment.chamberIndex()));
572 startPars = surfPars;
573 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Recycle cached parameters from muTag\n"
577 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Extrapolation to "<<
printID(segment)<<
" failed somehow");
581 if (!extpPars.ok()) {
582 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Extrapolation keeps failing");
585 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Updated parameters to \n"<<(*extpPars));
586 startPars = *extpPars;
591 float bestMatchScore{std::numeric_limits<float>::max()};
592 Acts::BoundVector bestPars{Acts::BoundVector::Zero()};
594 auto dumpBestSeg = [&]() {
598 result.recoSegs.push_back(
m_recoSegs->push_back(*bestSeg));
599 result.matchScores.push_back(bestMatchScore);
600 result.deltaPhi.push_back(toDeg(bestPars[Acts::eBoundPhi]));
601 result.deltaTheta.push_back(toDeg(bestPars[Acts::eBoundTheta]));
602 result.deltaY0.push_back(bestPars[Acts::eBoundLoc1]);
603 result.deltaX0.push_back(bestPars[Acts::eBoundLoc0]);
604 result.goodExtp.push_back(1);
605 result.taggedSeg.push_back(muTag && Acts::rangeContainsValue(muTag->
segments(), bestSeg));
607 bestMatchScore = std::numeric_limits<float>::max();
608 bestPars = Acts::BoundVector::Zero();
611 for (
auto segItr = compatibleSegs.begin(); segItr != compatibleSegs.end(); ) {
614 if (!nextParameters(*testMe)) {
615 result.recoSegs.push_back(
m_recoSegs->push_back(*testMe));
616 result.matchScores.push_back(-1.f);
617 result.deltaX0.push_back(1._m);
618 result.deltaY0.push_back(1._m);
619 result.deltaTheta.push_back(180.);
620 result.deltaPhi.push_back(180.);
621 result.goodExtp.push_back(0);
622 result.taggedSeg.push_back(0);
623 segItr = std::find_if(std::next(segItr),compatibleSegs.end(), [&](
const xAOD::MuonSegment* assocSeg){
624 return getEnvelope(*testMe) != getEnvelope(*assocSeg);
634 Acts::BoundVector dPars = segmentPars.parameters() - startPars->parameters();
637 dPars[Acts::eBoundPhi] = dPars[Acts::eBoundLoc0] = 0.;
642 dPars[Acts::eBoundQOverP] = dPars[Acts::eBoundTime] = 0.;
643 Acts::BoundMatrix covariance{Acts::BoundMatrix::Identity()};
644 covariance(Acts::eBoundLoc0, Acts::eBoundLoc0) = Acts::square(
m_toleranceX0.value());
645 covariance(Acts::eBoundLoc1, Acts::eBoundLoc1) = Acts::square(
m_toleranceY0.value());
646 covariance(Acts::eBoundTheta, Acts::eBoundTheta) = Acts::square(
m_toleranceTheta.value());
647 covariance(Acts::eBoundPhi, Acts::eBoundPhi) = Acts::square(
m_tolerancePhi.value());
648 if (startPars->covariance()) {
649 covariance += (*startPars->covariance());
651 if (segmentPars.covariance()) {
652 covariance += (*segmentPars.covariance());
654 const float chi2 = dPars.dot(covariance.inverse()*dPars);
655 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Difference: "<<Acts::toString(dPars)
656 <<
", covariance: \n"<<Acts::toString(covariance)<<
",\nchi2: "<<
chi2);
657 if (
chi2 < bestMatchScore) {
658 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Best parameters on surface thus far");
659 bestMatchScore =
chi2;
661 bestPars = std::move(dPars);
676 return StatusCode::SUCCESS;
680 ATH_MSG_VERBOSE(
"iMuon " << muon->index() <<
" pT: "<<(muon->pt() *MeVtoGeV)<<
" [GeV], eta: "
681 <<muon->eta() <<
", phi: "<<toDeg(muon->phi())<<
", q: "<<muon->charge()
682 <<
", nSegments: "<<muon->nMuonSegments());
683 const xAOD::TrackParticle* track = muon->trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle);
690 for (
size_t s = 0; s < muon->nMuonSegments(); ++s) {
693 ATH_MSG_VERBOSE(std::format(
"Legacy muon-segment link: segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
704 if (legacyRecoSegs->
size()) {
720 return StatusCode::SUCCESS;
724 return StatusCode::SUCCESS;
732 Amg::toString(seg->position())<<
", eta: "<<seg->direction().eta()
733 <<
", phi: "<<toDeg(seg->direction().phi()));
736 if (truthSegs->
size()) {
743 const std::size_t nT = truthMuons->
size() - 1;
744 if (!truthMuons->
empty()) {
752 <<
", eta: "<<truth->eta()<<
", phi: "<<toDeg(truth->phi())<<
", q: "<<truth->charge()
757 return StatusCode::SUCCESS;
775 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
776 const Acts::MagneticFieldContext mfContext =
m_ctxProvider.getMagneticFieldContext(ctx);
782 std::vector<unsigned>> truthToSeedMatchCounter{};
784 if (!trkSeeds->empty()) {
791 m_seedType+= Acts::toUnderlying(seed.location());
795 auto startPars =
m_seedingTool->estimateStartParameters(ctx, seed);
796 if (startPars.ok()) {
806 truthSeg !=
nullptr) {
808 if (seedIdx >= matchCounter.size()) {
809 matchCounter.resize(seedIdx +1);
811 ++matchCounter[seedIdx];
821 for (
auto& [truthMuon, matches] : truthToSeedMatchCounter) {
822 const unsigned tIndex =
m_truthTrks->find(truthMuon);
827 while (std::count_if(matches.begin(), matches.end(),
828 [](
const unsigned nMatched){
831 auto bestMatch = std::ranges::max_element(matches);
832 const std::size_t seedIdx = std::distance(matches.begin(), bestMatch);
854 return xAOD::TruthHelpers::getTruthParticle(*idTrk) ==
855 xAOD::TruthHelpers::getTruthParticle(*p);
865 if (idTag->extrapolatedParsID(Acts::hashString(
"@CaloExit"))){
870 return StatusCode::SUCCESS;
878 return StatusCode::SUCCESS;
882 return StatusCode::SUCCESS;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
Handle class for reading from StoreGate.
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
The CaloExtension holds the ID extrapolation states through the calorimeter and the associated CaloCl...
std::optional< Acts::BoundTrackParameters > lastParameters() const
Returns the outermost parameters known to the extension.
const ServiceHandle< StoreGateSvc > & detStore() const
StatusCode addVariable(const std::string &name, T *&ptr, std::string_view docstring="")
Add a variable to the tuple.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
const Acts::PlaneSurface & surface() const
Returns the associated surface.
void addSegment(const xAOD::MuonSegment *seg)
Append a segment to the seed.
Location
Enum defining whether the seed is made in the endcap / barrel.
void setPosition(Amg::Vector3D &&pos)
set the seed's position
Baseline EDM object to gather all relevant information about a reconstructed muon candidate which can...
std::optional< Acts::BoundTrackParameters > extrapolatedParsID(const Acts::HashedString &parName) const
Returns the cached extrapolated ID track parameters.
const std::vector< const xAOD::MuonSegment * > & segments() const
Returns the segments associated with the tag.
ToolHandle< MuonR4::ITrackSeedingDiagnosticsTool > m_seedingTool
The track seeding tool to construct the seed candidates and to estimate the initial parameters.
const MuonGMR4::MuonDetectorManager * m_detMgr
The detector manager to fetch the segment surfaces.
MuonVal::ScalarBranch< std::uint16_t > & m_nIdTags
The number of selected ID tracks in the event.
ToolHandle< MuonR4::ITrackSummaryTool > m_summaryTool
Hit summary tool.
StatusCode dumpLegacyTracks(const EventContext &ctx)
Dumps the legacy containers to the TTree.
SegmentKey_t m_legacySegmentKey
Legacy segment container.
const MuonR4::MuonTag * findBaseIdTag(const xAOD::TrackParticle &idTrack, const EventContext &ctx) const
Searches the Id track in the basline collection of all ID tracks selected for the combined muon recon...
const MuonGMR4::SpectrometerSector * getEnvelope(const xAOD::MuonSegment &segment) const
MuonTagKey_t m_idTagKey
The collection of all ID tracks that are selected for combined reconstruction.
TrackKey_t m_idTrackKey
The collection of ID tracks associated with the truth particle.
MuonVal::VectorBranch< unsigned short > & m_legacySegToTrkLinks
Link of the legacy track to the legacy segment.
ParticleBranchPtr_t m_truthTrks
MuonVal::VectorBranch< int > & m_seedSector
Sector of the seed, even center, odd overlap regions, for details see:
MuonVal::VectorBranch< float > & m_seedThetaCone
Maximum angular difference between the segments part of the seed.
ParticleBranchPtr_t m_legacyTrks
Output branches of the legacy MS tracks.
SegmentBranchPtr_t m_truthSegs
SegmentBranchPtr_t m_legacyRecoSegs
MuonVal::ScalarBranch< std::uint16_t > & m_nIdTracks
The number of ID tracks in the event.
MuonVal::MatrixBranch< unsigned short > & m_truthMuRecoSegLinks
Links from the truth muon to the segments.
std::unique_ptr< const Acts::Logger > m_logger
Instance to the Acts logger.
MuonVal::MatrixBranch< unsigned short > & m_truthMuToSeedIdx
Links to all MsTrkSeeds that could be matched to the truthMuon, i.e.
TrackKey_t m_legacyTrackKey
Legacy track reconstruction chain.
std::pair< double, double > calcSeedLength(const Acts::GeometryContext &tgContext, const MuonR4::MsTrackSeed &seed) const
Calculate the length of the seed and the theta deflection angle The length is defined as the spread o...
StatusCode execute(const EventContext &ctx) override final
Execute method.
SegmentTagVariables calcSegTagVariables(const xAOD::TrackParticle &idTrack, const EventContext &ctx)
MuonTagKey_t m_segTagKey
The collection of the original segment tags.
MuonVal::VectorBranch< char > & m_seedType
Is the seed in the encap or in the barrel chambers.
StatusCode dumpRecoContent(const EventContext &ctx)
Dump the reconstructed information.
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthKey
Key to the truth particle collection.
Gaudi::Property< double > m_toleranceTheta
Extra tolerance applied on the bending direction when calculating the matching score.
Gaudi::Property< bool > m_isMC
Toggle whether the job runs on MC or not.
ParticleBranchPtr_t m_muonTrks
Stored muon information from the Acts muon reco chain.
MuonVal::MatrixBranch< unsigned short > & m_truthSegToRecoLink
Link of the truth segments to the matchin reco segments.
Gaudi::Property< double > m_toleranceX0
Extra tolerance applied on the non-bending intercept when calculating the matching score.
SegmentBranchPtr_t m_recoSegs
StatusCode dumpTruthContent(const EventContext &ctx)
Dump truth information.
SG::ReadHandleKey< MuonR4::MsTrackSeedContainer > m_msTrkSeedKey
Temporary container write handle to push the seeds to store gate for later efficiency analysis.
Gaudi::Property< bool > m_storeID
Toggle whether to process ID tracks or not.
ToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
Track extrapolation tool.
const xAOD::TruthParticle * truthTreeParticle(const xAOD::IParticle &part, const EventContext &ctx) const
Returns the matched truth particle that is dumped in the tree.
const MuonR4::MuonTag * findMuTagIMO(const xAOD::TrackParticle &idTrack, const EventContext &ctx) const
ParticleBranchPtr_t m_idTracks
Stored ID track information.
StatusCode initialize() override final
MuonVal::MatrixBranch< unsigned short > & m_seedRecoSegMatch
Link of the track seed to the building segment.
MuonVal::VectorBranch< float > & m_seedQP
Estimated momentum times charge from the track seed.
MuonVal::MatrixBranch< unsigned short > & m_truthMuToSeedCounter
Number of matched segments in the seed.
MuonVal::ThreeVectorBranch m_seedPos
Simple seed information.
Gaudi::Property< double > m_tolerancePhi
Extra tolerance applied on the bending direction when calculating the matching score.
MuonKey_t m_legacyMuonKey
Legacy muons.
MuonVal::VectorBranch< float > & m_seedLength
Maximum separation between the segments on the reference plane.
MuonVal::UnitThreeVectorBranch m_seedDir
Seed direction vector.
ToolHandle< MuonR4::ISegmentSelectionTool > m_segSelector
Selection tool to quantify the segment candidate quality.
SegmentKey_t m_recoSegmentKey
Primary segment container.
MuonVal::MuonTesterTree m_tree
The output tree object.
std::vector< const xAOD::MuonSegment * > getAssociatedSegments(const xAOD::TrackParticle &idTrack, const EventContext &ctx) const
Returns the collection of reconstructed segments that can be associated to the id track If the track ...
ActsTrk::ContextUtility m_ctxProvider
Context provider for geometry, magnetic field and calibration contexts.
SegmentKey_t m_truthSegmentKey
Segment from the truth hits.
MuonVal::VectorBranch< char > & m_seedGood
Does the seeding tool construct valid parameters from the seed.
std::optional< MuonR4::MsTrackSeed > makeSeedFromTruth(const Acts::GeometryContext &tgContext, const xAOD::TruthParticle &truthMuon) const
Construct MS track seed from the truth associated segments.
StatusCode finalize() override final
std::shared_ptr< TrackSummaryModule > m_seedSummary
Hit summary on the track seed.
Gaudi::Property< double > m_toleranceY0
Extra tolerance applied on the bending intercept when calculating the matching score.
MuonVal::VectorBranch< unsigned short > & m_seedTruthLink
Link to the truth muon.
MuonKey_t m_muonKey
Dependency on the R4 muon container.
static bool connectCollections(ParticleBranch_ptr primColl, ParticleBranch_ptr secondColl, Linker_t fromPrimToSec, const std::string &altPrimName="", const std::string &altSecName="")
@ isMC
Flag determining whether the branch is simulation.
Generic branch object where the information is evaluated by a std::function instead reading it from t...
Property holding a SG store/key/clid from which a ReadHandle is made.
Class providing the definition of the 4-vector interface.
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
::Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index.
Amg::Vector3D position() const
Returns the position as Amg::Vector.
int etaIndex() const
Returns the eta index, which corresponds to stationEta in the offline identifiers (and the ).
std::uint8_t nPhiLayers() const
Returns the number of trigger phi hits.
double chi2(TH1 *h0, TH1 *h1)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
static Root::TMsgLogger logger("iLumiCalc")
constexpr std::size_t s_caloEnvelopeID
Volume Ids ofthe Calorimeter.
const CaloExtension * getCaloExtension(const xAOD::TrackParticle &track)
Retrieve a pointer to the CaloExtension linked with the passed TrackParticle.
std::optional< ActsTrk::TrackContainer::ConstTrackProxy > getActsTrack(const xAOD::TrackParticle &trkPart)
Return the proxy to the Acts track from which the track particle was made frome.
This class is not to needed in AthSimulation.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 2, 1 > Vector2D
ID3PD * m_tree
Pointer to the ID3PD object used.
for(size_t i=0;i< m_blockFillers.size();i++)
Fill one block.
double localPolarAngle(const Acts::BoundTrackParameters &pars, const Acts::Logger &logger)
Returns the local angular polar angle of the track parameter.
double longitudinalParam(const Acts::BoundTrackParameters &pars, const Acts::Logger &logger)
Returns the longitudinal local track parameter which is defined as.
Acts::BoundTrackParameters boundSegmentPars(const ActsTrk::GeometryContext &gctx, const MuonGMR4::MuonDetectorManager &detMgr, const xAOD::MuonSegment &segment, const Acts::ParticleHypothesis hypot=Acts::ParticleHypothesis::muon())
Returns the segment parameters as boundTrackParameters.
This header ties the generic definitions in this package.
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
std::vector< MsTrackSeed > MsTrackSeedContainer
std::string printID(const xAOD::MuonSegment &seg)
Print the chamber ID of a segment, e.g.
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
std::vector< const xAOD::MuonSegment * > getTruthSegments(const xAOD::TruthParticle &truthMuon)
Returns the segments associated to the truth muon.
DataVector< MuonTag > MuonTagContainer
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Class to store array like branches into the n-tuples.
LayerIndex toLayerIndex(ChIndex index)
convert ChIndex into LayerIndex
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
bool dPhi(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
const xAOD::TruthParticle * getTruthParticle(const xAOD::IParticle &p)
Return the truthParticle associated to the given IParticle (if any).
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
MuonSegment_v1 MuonSegment
Reference the current persistent version:
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Searched the MuTagIMO tag.
#define THROW_EXCEPTION(MESSAGE)