ATLAS Offline Software
MuonSimHitSortingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "MuonSimHitSortingAlg.h"
5 
6 #include <StoreGate/ReadHandle.h>
11 #include <GaudiKernel/SystemOfUnits.h>
12 namespace {
13  constexpr double tolerance = 1. * Gaudi::Units::micrometer;
14 }
15 
17  if (m_readKeys.empty()) {
18  ATH_MSG_FATAL("Please provide at least one container to sort");
19  return StatusCode::FAILURE;
20  }
21  ATH_CHECK(m_readKeys.initialize());
22  ATH_CHECK(m_writeKey.initialize());
23  ATH_CHECK(m_idHelperSvc.retrieve());
24  return StatusCode::SUCCESS;
25 }
26 StatusCode MuonSimHitSortingAlg::execute(const EventContext& ctx) const {
29  const xAOD::MuonSimHitContainer* hits{nullptr};
30  ATH_CHECK(SG::get(hits, inKey, ctx));
31 
32  std::ranges::copy(*hits, std::back_inserter(allSimHits));
33  }
34  std::stable_sort(allSimHits.begin(), allSimHits.end(),
35  [this](const xAOD::MuonSimHit* a, const xAOD::MuonSimHit* b){
37  const IdentifierHash hashA = m_idHelperSvc->detElementHash(a->identify());
38  const IdentifierHash hashB = m_idHelperSvc->detElementHash(a->identify());
39  if (hashA != hashB) {
40  return hashA < hashB;
41  }
43  if (a->identify() != b->identify()) {
44  return a->identify() < b->identify();
45  }
47  const float dT = a->globalTime() - b->globalTime();
48  if (std::abs(dT) > 0.1 * Gaudi::Units::picosecond) {
49  return dT < 0.;
50  }
52  if (std::abs(a->pdgId()) != std::abs(b->pdgId())){
53  return a->pdgId() > b->pdgId();
54  }
57  return a->genParticleLink().barcode() < b->genParticleLink().barcode();
58  });
59  if (m_removeDuplicates) {
60  std::vector<const xAOD::MuonSimHit*> dupFreeHits{};
61  dupFreeHits.reserve(allSimHits.size());
62  std::ranges::copy_if(allSimHits, std::back_inserter(dupFreeHits),
63  [&dupFreeHits, this] (const xAOD::MuonSimHit* hit) {
64  const int barcode = hit->genParticleLink().barcode();
65  const Identifier hitId = hit->identify();
66  const Amg::Vector3D lPos{xAOD::toEigen(hit->localPosition())};
67  const Amg::Vector3D lDir{xAOD::toEigen(hit->localDirection())};
68  ATH_MSG_VERBOSE("Check sim hit "<<m_idHelperSvc->toString(hitId)<<", pdgId:"<<hit->pdgId()
69  <<", barcode: "<<barcode
70  <<" at "<<Amg::toString(lPos, 2)<<"direction: "<<Amg::toString(lDir, 2));
71  return std::ranges::find_if(dupFreeHits,
72  [&](const xAOD::MuonSimHit* selHit) {
73  if (selHit->identify() != hitId ||
74  barcode != selHit->genParticleLink().barcode()) return false;
75  if (barcode) return true;
76  const Amg::Vector3D dPos = lPos - xAOD::toEigen(selHit->localPosition());
77  const Amg::Vector3D dDir = lDir - xAOD::toEigen(selHit->localDirection());
78  return dPos.mag() < tolerance && dDir.mag() < tolerance;
79  }) == dupFreeHits.end();
80  });
81  allSimHits.clear();
82  std::ranges::copy(dupFreeHits, std::back_inserter(allSimHits));
83  }
84  SG::WriteHandle writeHandle{m_writeKey, ctx};
85  if (m_writeDeepCopy) {
86  ATH_CHECK(writeHandle.record(std::make_unique<xAOD::MuonSimHitContainer>(),
87  std::make_unique<xAOD::MuonSimHitAuxContainer>()));
88  for (const xAOD::MuonSimHit* copy_me : allSimHits) {
89  xAOD::MuonSimHit* newHit = writeHandle->push_back(std::make_unique<xAOD::MuonSimHit>());
90  (*newHit) = (*copy_me);
91  }
92  } else {
93  ATH_CHECK(writeHandle.record(std::make_unique<xAOD::MuonSimHitContainer>(*allSimHits.asDataVector())));
94  }
95  return StatusCode::SUCCESS;
96 }
MuonSimHitSortingAlg::m_readKeys
SG::ReadHandleKeyArray< xAOD::MuonSimHitContainer > m_readKeys
Definition: MuonSimHitSortingAlg.h:22
xAOD::MuonSimHit_v1
Definition: MuonSimHit_v1.h:18
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
tolerance
constexpr double tolerance
Definition: runMdtGeoComparison.cxx:104
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
xAOD::MuonSimHit_v1::identify
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
Definition: xAODMuonSimHit_V1.cxx:42
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
MuonSimHitAuxContainer.h
python.SystemOfUnits.picosecond
float picosecond
Definition: SystemOfUnits.py:138
MuonSimHitSortingAlg.h
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::ReadHandleKey
Property holding a SG store/key/clid from which a ReadHandle is made.
Definition: StoreGate/StoreGate/ReadHandleKey.h:39
xAOD::MuonSimHit_v1::pdgId
int pdgId() const
Returns the pdgID of the traversing particle.
python.copyTCTOutput.dDir
dDir
Definition: copyTCTOutput.py:60
WriteHandle.h
Handle class for recording to StoreGate.
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonSimHitSortingAlg::m_writeKey
SG::WriteHandleKey< xAOD::MuonSimHitContainer > m_writeKey
Definition: MuonSimHitSortingAlg.h:23
MuonSimHitSortingAlg::initialize
StatusCode initialize() override
Definition: MuonSimHitSortingAlg.cxx:16
xAOD::MuonSimHit_v1::genParticleLink
const HepMcParticleLink & genParticleLink() const
Returns the link to the HepMC particle producing this hit.
Definition: xAODMuonSimHit_V1.cxx:68
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:287
python.SystemOfUnits.micrometer
float micrometer
Definition: SystemOfUnits.py:80
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
xAOD::MuonSimHit_v1::localDirection
ConstVectorMap< 3 > localDirection() const
Returns the local direction of the traversing particle.
Definition: xAODMuonSimHit_V1.cxx:66
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonSimHitSortingAlg::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonSimHitSortingAlg.h:25
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
tolerance
Definition: suep_shower.h:17
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonSimHitSortingAlg::execute
StatusCode execute(const EventContext &ctx) const override
Definition: MuonSimHitSortingAlg.cxx:26
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
a
TList * a
Definition: liststreamerinfos.cxx:10
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
xAOD::MuonSimHit_v1::localPosition
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
Definition: xAODMuonSimHit_V1.cxx:60
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
MuonDetectorDefs.h
calibdata.copy
bool copy
Definition: calibdata.py:26
ReadHandle.h
Handle class for reading from StoreGate.
Identifier
Definition: IdentifierFieldParser.cxx:14