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);
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;
495 const EventContext& ctx)
const {
496 return findTagMatchingToId(idTrack,
m_idTagKey, ctx);
499 const EventContext& ctx)
const {
500 return findTagMatchingToId(idTrack,
m_segTagKey, ctx);
503 std::vector<const xAOD::MuonSegment*>
505 const EventContext& ctx)
const {
506 std::vector<const xAOD::MuonSegment*> compatibleSegs{};
508 std::vector<const xAOD::MuonSegment*> truthSegs =
getTruthSegments(*truthPart);
511 std::copy_if(recoSegs->
begin(), recoSegs->
end(), std::back_inserter(compatibleSegs),
513 return Acts::rangeContainsValue(truthSegs, getMatchedTruthSegment(*recoSeg));
515 if (!compatibleSegs.empty()) {
516 return compatibleSegs;
523 if (muon->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle) == &idTrack) {
524 for (std::size_t s = 0; s < muon->nMuonSegments() ; ++s) {
525 compatibleSegs.push_back(muon->muonSegment(s));
530 return compatibleSegs;
539 const EventContext& ctx) {
544 if (compatibleSegs.empty()) {
552 std::optional<Acts::BoundTrackParameters> startPars = caloExt->
lastParameters();
559 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
564 const Acts::Surface& target{msSector->
surface()};
565 if (target.geometryId() == startPars->referenceSurface().geometryId()) {
569 auto surfPars = muTag->
extrapolatedParsID(Acts::toUnderlying(segment.chamberIndex()));
571 startPars = surfPars;
572 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Recycle cached parameters from muTag\n"
576 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Extrapolation to "<<
printID(segment)<<
" failed somehow");
580 if (!extpPars.ok()) {
581 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Extrapolation keeps failing");
584 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Updated parameters to \n"<<(*extpPars));
585 startPars = *extpPars;
590 float bestMatchScore{std::numeric_limits<float>::max()};
591 Acts::BoundVector bestPars{Acts::BoundVector::Zero()};
593 auto dumpBestSeg = [&]() {
597 result.recoSegs.push_back(
m_recoSegs->push_back(*bestSeg));
598 result.matchScores.push_back(bestMatchScore);
599 result.deltaPhi.push_back(toDeg(bestPars[Acts::eBoundPhi]));
600 result.deltaTheta.push_back(toDeg(bestPars[Acts::eBoundTheta]));
601 result.deltaY0.push_back(bestPars[Acts::eBoundLoc1]);
602 result.deltaX0.push_back(bestPars[Acts::eBoundLoc0]);
603 result.goodExtp.push_back(1);
604 result.taggedSeg.push_back(muTag && Acts::rangeContainsValue(muTag->
segments(), bestSeg));
606 bestMatchScore = std::numeric_limits<float>::max();
607 bestPars = Acts::BoundVector::Zero();
610 for (
auto segItr = compatibleSegs.begin(); segItr != compatibleSegs.end(); ) {
613 if (!nextParameters(*testMe)) {
614 result.recoSegs.push_back(
m_recoSegs->push_back(*testMe));
615 result.matchScores.push_back(-1.f);
616 result.deltaX0.push_back(1._m);
617 result.deltaY0.push_back(1._m);
618 result.deltaTheta.push_back(180.);
619 result.deltaPhi.push_back(180.);
620 result.goodExtp.push_back(0);
621 result.taggedSeg.push_back(0);
622 segItr = std::find_if(std::next(segItr),compatibleSegs.end(), [&](
const xAOD::MuonSegment* assocSeg){
623 return getEnvelope(*testMe) != getEnvelope(*assocSeg);
633 Acts::BoundVector dPars = segmentPars.parameters() - startPars->parameters();
636 dPars[Acts::eBoundPhi] = dPars[Acts::eBoundLoc0] = 0.;
641 dPars[Acts::eBoundQOverP] = dPars[Acts::eBoundTime] = 0.;
642 Acts::BoundMatrix covariance{Acts::BoundMatrix::Identity()};
643 covariance(Acts::eBoundLoc0, Acts::eBoundLoc0) = Acts::square(
m_toleranceX0.value());
644 covariance(Acts::eBoundLoc1, Acts::eBoundLoc1) = Acts::square(
m_toleranceY0.value());
645 covariance(Acts::eBoundTheta, Acts::eBoundTheta) = Acts::square(
m_toleranceTheta.value());
646 covariance(Acts::eBoundPhi, Acts::eBoundPhi) = Acts::square(
m_tolerancePhi.value());
647 if (startPars->covariance()) {
648 covariance += (*startPars->covariance());
650 if (segmentPars.covariance()) {
651 covariance += (*segmentPars.covariance());
653 const float chi2 = dPars.dot(covariance.inverse()*dPars);
654 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Difference: "<<Acts::toString(dPars)
655 <<
", covariance: \n"<<Acts::toString(covariance)<<
",\nchi2: "<<
chi2);
656 if (
chi2 < bestMatchScore) {
657 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Best parameters on surface thus far");
658 bestMatchScore =
chi2;
660 bestPars = std::move(dPars);
675 return StatusCode::SUCCESS;
679 ATH_MSG_VERBOSE(
"iMuon " << muon->index() <<
" pT: "<<(muon->pt() *MeVtoGeV)<<
" [GeV], eta: "
680 <<muon->eta() <<
", phi: "<<toDeg(muon->phi())<<
", q: "<<muon->charge()
681 <<
", nSegments: "<<muon->nMuonSegments());
682 const xAOD::TrackParticle* track = muon->trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle);
689 for (
size_t s = 0; s < muon->nMuonSegments(); ++s) {
692 ATH_MSG_VERBOSE(std::format(
"Legacy muon-segment link: segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
703 if (legacyRecoSegs->
size()) {
719 return StatusCode::SUCCESS;
723 return StatusCode::SUCCESS;
731 Amg::toString(seg->position())<<
", eta: "<<seg->direction().eta()
732 <<
", phi: "<<toDeg(seg->direction().phi()));
735 if (truthSegs->
size()) {
742 const std::size_t nT = truthMuons->
size() - 1;
743 if (!truthMuons->
empty()) {
752 <<
", eta: "<<truth->eta()<<
", phi: "<<toDeg(truth->phi())<<
", q: "<<truth->charge());
756 return StatusCode::SUCCESS;
774 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
775 const Acts::MagneticFieldContext mfContext =
m_ctxProvider.getMagneticFieldContext(ctx);
781 std::vector<unsigned>> truthToSeedMatchCounter{};
783 if (!trkSeeds->empty()) {
790 m_seedType+= Acts::toUnderlying(seed.location());
794 auto startPars =
m_seedingTool->estimateStartParameters(ctx, seed);
795 if (startPars.ok()) {
805 truthSeg !=
nullptr) {
807 if (seedIdx >= matchCounter.size()) {
808 matchCounter.resize(seedIdx +1);
810 ++matchCounter[seedIdx];
820 for (
auto& [truthMuon, matches] : truthToSeedMatchCounter) {
821 const unsigned tIndex =
m_truthTrks->find(truthMuon);
826 while (std::count_if(matches.begin(), matches.end(),
827 [](
const unsigned nMatched){
830 auto bestMatch = std::ranges::max_element(matches);
831 const std::size_t seedIdx = std::distance(matches.begin(), bestMatch);
853 return xAOD::TruthHelpers::getTruthParticle(*idTrk) ==
854 xAOD::TruthHelpers::getTruthParticle(*p);
864 if (idTag->extrapolatedParsID(Acts::hashString(
"@CaloExit"))){
869 return StatusCode::SUCCESS;
877 return StatusCode::SUCCESS;
881 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, const std::string &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 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.
const xAOD::TruthParticle * truthTreeParticle(const xAOD::IParticle &part) const
Returns the matched truth particle that is dumped in the tree.
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)