 |
ATLAS Offline Software
|
Go to the documentation of this file.
9 #include "GaudiKernel/EventContext.h"
10 #include "GaudiKernel/ISvcLocator.h"
26 #include "Acts/Definitions/Units.hpp"
27 #include "Acts/EventData/ParticleHypothesis.hpp"
28 #include "Acts/Propagator/ActorList.hpp"
29 #include "Acts/Propagator/Propagator.hpp"
30 #include "Acts/Propagator/MaterialInteractor.hpp"
31 #include "Acts/Propagator/EigenStepper.hpp"
32 #include "Acts/Propagator/Navigator.hpp"
33 #include "Acts/Propagator/detail/SteppingLogger.hpp"
34 #include "Acts/Surfaces/StrawSurface.hpp"
35 #include "Acts/Utilities/AngleHelpers.hpp"
38 using SegLink_t = std::vector<ElementLink<xAOD::MuonSegmentContainer>>;
42 struct PropagatorRecorder{
52 double actsPropabsMomentum{0.};
54 double actsStepSize{0.};
56 double actsHitWireDist{-1.};
98 ATH_MSG_INFO(
"ActsMuonTrackingGeometryTest successfully initialized");
99 return StatusCode::SUCCESS;
104 return StatusCode::SUCCESS;
109 const EventContext& ctx = Gaudi::Hive::currentContext();
122 const Acts::MagneticFieldContext mfContext = Acts::MagneticFieldContext(fieldCondObj);
124 auto anygctx = gctx->context();
129 if (!trackingGeometry) {
131 return StatusCode::FAILURE;
135 using Stepper = Acts::EigenStepper<>;
137 using Propagator = Acts::Propagator<Stepper,Navigator>;
138 using ActorList = Acts::ActorList<Acts::detail::SteppingLogger, Acts::MaterialInteractor, Acts::EndOfWorldReached>;
139 using PropagatorOptions = Propagator::Options<ActorList>;
141 Navigator::Config navCfg;
142 navCfg.trackingGeometry = trackingGeometry;
143 navCfg.resolveSensitive =
true;
144 navCfg.resolveMaterial=
false;
145 navCfg.resolvePassive =
true;
149 auto bField = std::make_shared<ATLASMagneticFieldWrapper>();
150 auto bfieldCache = bField->makeCache(mfContext);
152 auto stepper =
Stepper(bField);
154 PropagatorOptions
options(anygctx, mfContext);
163 auto& materialInteractor =
options.actorList.get<Acts::MaterialInteractor>();
164 materialInteractor.energyLoss =
false;
165 materialInteractor.multipleScattering =
false;
166 materialInteractor.recordInteractions =
false;
168 Propagator propagator(std::move(stepper), std::move(navigator),
173 ATH_MSG_DEBUG(
"Processing truth particle with PDG ID: " << truthParticle->pdgId() <<
" ,pT: "
174 << truthParticle->pt() <<
" , p: " << truthParticle->p4().P() <<
", eta: " << truthParticle->eta() <<
" , phi: " << truthParticle->phi());
177 if(std::abs(truthParticle->pdgId()) != 13 && std::abs(truthParticle->pdgId()) != 998) {
178 ATH_MSG_VERBOSE(
"Skipping truth particle with PDG ID: " << truthParticle->pdgId()<<
" only muons or charged geantinos are being processed");
187 std::vector<std::pair<const xAOD::MuonSegment*, std::vector<const xAOD::MuonSimHit*>>> muonSegmentWithSimHits;
188 const SegLink_t& segLink = segAcc(*truthParticle);
189 if (segLink.empty()) {
190 ATH_MSG_WARNING(
"No segment link found for truth particle with PDG ID: " << truthParticle->pdgId());
193 for(
const auto& truthSegLink: segLink) {
199 std::vector<const xAOD::MuonSimHit*> muonSimHits{unordedHits.begin(), unordedHits.end()};
201 muonSegmentWithSimHits.emplace_back(seg,muonSimHits);
205 const auto&
particle = truthParticle->p4();
222 if(muonSegmentWithSimHits.empty()) {
223 ATH_MSG_DEBUG(
"No segments found for truth particle with PDG ID: " << truthParticle->pdgId());
227 std::ranges::sort(muonSegmentWithSimHits,
228 [](
const auto&
a,
const auto&
b) {
229 return a.first->position().
perp() <
b.first->position().perp();
234 std::vector<const xAOD::MuonSimHit*>& muonSimHits = muonSegmentWithSimHits.front().second;
235 std::ranges::sort(muonSimHits,
239 return globalPos1.norm()<globalPos2.norm();
243 for(
const auto& simHit: muonSimHits){
249 startPropPos =
toGlobalTrf(*gctx, muonSimHits.front()->identify())*xAOD::toEigen(muonSimHits.front()->localPosition());
250 startPropDir =
toGlobalTrf(*gctx, muonSimHits.front()->identify()).linear()*xAOD::toEigen(muonSimHits.front()->localDirection());
251 startPropP =
energyToActs(muonSimHits.front()->kineticEnergy());
260 <<
Amg::toString(startPropDir)<<
" and momentum "<<startPropP);
264 Acts::BoundTrackParameters
start = Acts::BoundTrackParameters::createCurvilinear(
265 Acts::VectorHelpers::makeVector4(startPropPos, 0.), startPropDir,
266 truthParticle->charge() / startPropP,
268 actsParticleHypothesis);
272 const Acts::detail::SteppingLogger::result_type state =
result.value().get<Acts::detail::SteppingLogger::result_type>();
273 const Acts::MaterialInteractor::result_type material =
result.value().get<Acts::MaterialInteractor::result_type>();
278 std::vector<PropagatorRecorder> propagatedHits;
280 for(
const auto&
step : state.steps) {
295 PropagatorRecorder newRecord{};
297 newRecord.actsPropPos = toGap*
step.position;
298 newRecord.actsGlobalPos =
step.position;
299 newRecord.actsPropDir = toGap.linear()*
step.momentum.unit();
300 newRecord.actsPropabsMomentum =
step.momentum.norm();
301 newRecord.actsStepSize =
step.stepSize.value();
306 const auto* tubeSurf =
dynamic_cast<const Acts::StrawSurface*
>(&sCache->
surface());
309 Amg::Vector3D wireDir = toGap.linear()*tubeSurf->lineDirection(anygctx);
312 double distToWire =
Amg::lineDistance(wirePos, wireDir, localPropHit, dirPropHit);
313 newRecord.actsHitWireDist = distToWire;
318 propagatedHits.emplace_back(newRecord);
323 for (
const auto&[segment, simHits] : muonSegmentWithSimHits) {
328 const Amg::Vector3D localPos = xAOD::toEigen(simHit->localPosition());
331 const Amg::Vector3D localDir = xAOD::toEigen(simHit->localDirection());
352 auto it_begin = std::ranges::find_if(propagatedHits,
353 [
this,
ID](
const auto& propagatedHit) {
359 if(it_begin == propagatedHits.end()){
371 auto it_end = std::find_if(it_begin, propagatedHits.end(),
372 [
this,
ID](
const auto& propagatedHit) {
373 return m_idHelperSvc->detElId(ID) != m_idHelperSvc->detElId(propagatedHit.id) ||
374 layerHash(ID) != layerHash(propagatedHit.id);
378 auto it = std::min_element(it_begin, it_end,
379 [&localPos](
const PropagatorRecorder&
a,
380 const PropagatorRecorder&
b){
381 return (localPos -
a.actsPropPos).mag() < (localPos -
b.actsPropPos).mag();
400 m_event = ctx.eventID().event_number();
407 return StatusCode::SUCCESS;
def retrieve(aClass, aKey=None)
UnsignedIntegerProperty m_maxTargetSkipping
MuonVal::ThreeVectorBranch m_actsPropLoc
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Identifier identify() const override final
Returns the identifier of the Surface.
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
StatusCode execute() override
std::vector< Identifier > ID
StatusCode init(OWNER *instance)
Initialize method.
MuonVal::ThreeVectorBranch m_startGlob
Scalar perp() const
perp method - perpenticular length
MuonVal::ThreeVectorBranch m_truthLoc
Amg::Transform3D toGlobalTrf(const ActsTrk::GeometryContext &gctx, const Identifier &hitId) const
Acts::Navigator Navigator
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
DoubleProperty m_maxStepSize
UnsignedIntegerProperty m_maxSteps
MuonVal::MuonIdentifierBranch m_detId
constexpr double energyToActs(const double athenaE)
Converts an energy scalar from Athena to Acts units.
MuonVal::ScalarBranch< float > & m_truthPt
ServiceHandle< IAthRNGSvc > m_rndmGenSvc
StatusCode finalize() override
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
Class describing a MuonSegment.
MuonVal::ScalarBranch< float > & m_propLength
Gaudi::Property< bool > m_startFromFirstHit
: Helper class to connect the aligned transformations of each active sensor(layer) with the Acts::Sur...
Acts::Logging::Level actsLevelVector(MSG::Level lvl)
MuonVal::VectorBranch< float > & m_actsPropabsMomentum
Helper class to provide constant type-safe access to aux data.
virtual DetectorType detectorType() const =0
Returns the detector element type.
virtual IdentifierHash layerHash(const Identifier &measId) const =0
#define ATH_MSG_VERBOSE(x)
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
float y() const
Vertex y displacement.
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
MuonVal::ScalarBranch< unsigned int > & m_propSteps
MuonVal::VectorBranch< unsigned short > & m_gasGapId
void push_back(const Amg::Vector3D &vec)
interface using the Amg::Vector3D
IdentifierHash layerHash(const Identifier &id) const
Amg::Transform3D toLocalTrf(const ActsTrk::GeometryContext &gctx, const Identifier &hitId) const
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
MuonVal::ScalarBranch< float > & m_truthP
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
::StatusCode StatusCode
StatusCode definition for legacy code.
Class describing a truth particle in the MC record.
Eigen::Affine3d Transform3D
virtual void push_back(const Identifier &id)
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
DoubleProperty m_stepTolerance
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
const Acts::Surface & surface() const override final
Returns the dereferenced pointer cache.
ElementLink< MuonR4::SegmentContainer > SegLink_t
Abrivation of the link to the reco segment container
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_truthSegLinkKey
void push_back(const T &value)
Adds a new element at the end of the vector.
MuonVal::VectorBranch< unsigned short > & m_techIdx
Class describing a truth vertex in the MC record.
StatusCode initialize(bool used=true)
double lineDistance(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
: Calculates the shortest distance between two lines
MuonVal::ThreeVectorBranch m_truthGlob
Eigen::Matrix< double, 3, 1 > Vector3D
Acts::SympyStepper Stepper
Adapted from Acts Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction....
Amg::Vector3D dirFromAngles(const double phi, const double theta)
Constructs a direction vector from the azimuthal & polar angles.
MuonVal::VectorBranch< float > & m_actsHitWireDist
float x() const
Vertex x displacement.
Acts::Propagator< Stepper, Navigator > Propagator
DoubleProperty m_pathLimit
const MuonGMR4::MuonDetectorManager * m_r4DetMgr
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
#define ATH_MSG_WARNING(x)
MuonVal::VectorBranch< unsigned short > & m_isPropagated
float z() const
Vertex longitudinal distance along the beam line form the origin.
virtual IdentifierHash measurementHash(const Identifier &measId) const =0
Constructs the identifier hash from the full measurement Identifier.
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
StatusCode initialize() override
bool fill(const EventContext &ctx)
Fills the tree per call.
StatusCode write()
Finally write the TTree objects.
MuonVal::ThreeVectorBranch m_actsPropGlob
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
MuonVal::MuonTesterTree m_tree
MuonVal::ScalarBranch< unsigned int > & m_event
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
MuonVal::VectorBranch< float > & m_actsStepSize
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
void zero(TH2 *h)
zero the contents of a 2d histogram
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
MuonVal::ThreeVectorBranch m_truthDir
MuonVal::ThreeVectorBranch m_actsPropDir
constexpr int toInt(const EnumType enumVal)
const MuonReadoutElement * getReadoutElement(const Identifier &id) const
Returns a generic Muon readout element.