ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleClusterAssociationAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
11
13
14
16{
17
18 m_doDetEta = !m_detectorEtaDecor.key().empty();
19
20 ATH_CHECK( m_caloExtKey.initialize() );
22 ATH_CHECK( m_caloClusters.initialize() );
24 ATH_CHECK( m_assocClustersDecor.initialize() );
25 ATH_CHECK( m_sigmaWidthKey.initialize() );
26 ATH_CHECK(m_trkLinkKey.initialize());
27
29
30 ATH_CHECK( m_vertexContHandle.initialize( !m_vertexContHandle.empty() ) );
31 if(!m_vertexContHandle.empty() ) {
33 }
34
35 ATH_MSG_DEBUG(" cluster decoration = "<< m_assocClustersDecor.key() );
36 return StatusCode::SUCCESS;
37}
38
39StatusCode TrackParticleClusterAssociationAlg::execute(const EventContext& ctx) const
40{
41
42 ATH_MSG_DEBUG("excute()");
43 // get track particles
45 ATH_MSG_DEBUG("retrieved "<< m_trackParticleCollectionHandle.key()<< " size ="<< trackParticles->size() );
46
47 // pre-calculate a width of clusters, set it as dynamica attribute so we don't have to recalculate it
49 ATH_MSG_DEBUG("retrieved "<< m_caloClusters.key() << " size = "<< clusterContainer->size() );
51 //for(const xAOD::CaloCluster *cl : *clusterContainer){
52 for(const xAOD::CaloCluster *cl : *clusterContainer){
53 double rad;
54 cl->retrieveMoment(xAOD::CaloCluster::SECOND_R,rad);
55 double cent;
56 cl->retrieveMoment(xAOD::CaloCluster::CENTER_MAG,cent);
57
58 float cl_eta {99};
59 if (m_doDetEta)
60 {
62 cl_eta = detEta(*cl);
63 }
64 else
65 cl_eta = cl->eta();
66
67 double sigmaWidth = 0.0;
68 if(cent > 0) sigmaWidth = atan(sqrt(rad)/cent)*cosh(cl_eta);
69 sig_dec(*cl) = sigmaWidth;
70 }
71
72
73 // obtain the CaloExtension from the map in the event store
75 ATH_MSG_DEBUG("CaloExtensionCollection "<< m_caloExtKey.key() << " : size="<< caloExts->size() );
76
77 const xAOD::Vertex * pv0 = nullptr;
78 if(!m_vertexContHandle.empty()){
80 if(!vxCont->empty()) pv0=(*vxCont)[0]; // Hard code HS vertex as PV0
81 }
82
84 std::vector<ElementLink<xAOD::CaloClusterContainer>> > assoClustDecor(m_assocClustersDecor, ctx);
85
86 ATH_MSG_DEBUG("will decorate with "<<assoClustDecor.key()<< " and adding trkParam : "<< m_caloEntryParsDecor.key() );
87
88 // ******************************************
89 // main loop over tracks
90 unsigned int ntracks = 0;
91 for( const xAOD::TrackParticle* tp : *trackParticles){
92
93 // retrieve the vector of links to cluster (and creating it )
94 std::vector< ElementLink< xAOD::CaloClusterContainer > > & caloClusterLinks = assoClustDecor(*tp);
95
96 if( tp->pt() < m_ptCut ) continue;
97
98 if( pv0 != nullptr) if(! m_trackvertexassoTool->isCompatible(*tp, *pv0 )) continue;
99
100 ATH_MSG_DEBUG(" Selected track " << tp->index() << " pt " << tp->pt() << " eta " << tp->eta() << " phi " << tp->phi() );
101
102 // IMMPORTANT : this assumes a correspondance between the TrackParticleContainer and the CaloExtensionCollection !
103 const Trk::CaloExtension * caloExtension = (*caloExts)[tp->index() ] ;
104 if (caloExtension == nullptr ) {
105 ATH_MSG_DEBUG(" Selected track "<< tp->index() << " has no caloExtension ");
106 continue;
107 }
108
109 // build the associated clusters
110 std::vector<const xAOD::CaloCluster*> assoClusters = associatedClusters( *caloExtension, *clusterContainer, ctx);
111
112 // translate vector of links to cluster in ElementLink
113
114 caloClusterLinks.reserve( assoClusters.size() );
115 for(const xAOD::CaloCluster* cluster : assoClusters) caloClusterLinks.emplace_back( *clusterContainer,cluster->index() );
116 ntracks++;
117 }// end loop over tracks
118
119 // 2nd loop over track, only to decorate with Track parameter if requested.
120 if (! m_caloEntryParsDecor.empty() ){
121 // we can not do this in the above loop because declaring a WriteDecorHandle requires a non empty key
122 // (otherwise : run-time error).
124 for( const xAOD::TrackParticle* tp : *trackParticles){
125 const Trk::CaloExtension * caloExtension = (*caloExts)[tp->index() ] ;
126 if (caloExtension == nullptr ) trkParamDecor( *tp ) = nullptr ;
127 else trkParamDecor( *tp ) = caloExtension->caloEntryLayerIntersection();
128 }
129 }
130
131 ATH_MSG_DEBUG(" Total number of selected tracks: " << ntracks );
132
133 return StatusCode::SUCCESS;
134}
135
136
137std::vector<const xAOD::CaloCluster* >
139 const EventContext& ctx) const
140{
141 std::vector<const xAOD::CaloCluster* > clusters;
142
143 const Trk::TrackParameters* pars = caloExtension.caloEntryLayerIntersection();
144 if(!pars) {
145 ATH_MSG_WARNING( " NO TrackParameters caloExtension.caloEntryLayerIntersection() ");
146 return clusters;
147 }
148
149 float eta = pars->position().eta();
150 float phi = pars->position().phi();
151
152 double uncertEta = 0.;
153 double uncertPhi = 0.;
154 if(pars->covariance()) {
155 uncertEta = -2.*sin(pars->position().theta()) / (cos(2.*pars->position().theta())-1.) * sqrt((*pars->covariance())(Trk::theta,Trk::theta));
156 uncertPhi = sqrt((*pars->covariance())(Trk::phi,Trk::phi));
157 }
158 double uncertExtrp = uncertEta*uncertEta + uncertPhi*uncertPhi;
159
160 float dr2Cut0 = m_dr*m_dr;
161 // to access the pre-calculated width :
162 static const SG::AuxElement::ConstAccessor<float> sig_acc("sigmaWidth");
163
164 for(const xAOD::CaloCluster * cl : allClusters){
165
166 float dPhi = P4Helpers::deltaPhi( cl->phi(), phi);
167
168 float cl_eta {99};
169 if (m_doDetEta)
170 {
172 cl_eta = detEta(*cl);
173 }
174 else
175 cl_eta = cl->eta();
176
177 float dEta = cl_eta - eta;
178 float dr2 = dPhi*dPhi+ dEta*dEta;
179 float dr2Cut = dr2Cut0;
180
181 if(m_useCovariance) {
182
183 double sigmaWidth = sig_acc(*cl);
184 double uncertClus = 2.*sigmaWidth*sigmaWidth;
185 if(uncertExtrp>uncertClus){
186 ATH_MSG_DEBUG("Extrapolation uncertainty larger than cluster width! Returning without association.");
187 continue;
188 }
189
190 dr2Cut = (sigmaWidth+uncertEta)*(sigmaWidth+uncertEta)+(sigmaWidth+uncertPhi)*(sigmaWidth+uncertPhi);
191 }
192 if( dr2 < dr2Cut ) clusters.push_back( cl );
193 }
194
195 return clusters;
196}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#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.
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
SG::ReadHandleKey< CaloExtensionCollection > m_caloExtKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_assocClustersDecor
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > m_trkLinkKey
ToolHandle< CP::ITrackVertexAssociationTool > m_trackvertexassoTool
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_caloClusters
SG::ReadDecorHandleKey< xAOD::CaloClusterContainer > m_detectorEtaDecor
std::vector< const xAOD::CaloCluster * > associatedClusters(const Trk::CaloExtension &caloExtensions, const xAOD::CaloClusterContainer &allClusters, const EventContext &ctx) const
returns the clusters from allClusters which are close enough to caloExtensions
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackParticleCollectionHandle
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContHandle
SG::WriteDecorHandleKey< xAOD::CaloClusterContainer > m_sigmaWidthKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_caloEntryParsDecor
Tracking class to hold the extrapolation through calorimeter Layers Both the caloEntryLayerIntersecti...
const TrackParameters * caloEntryLayerIntersection() const
access to intersection with the calorimeter entry layer return nullptr if the intersection failed
@ SECOND_R
Second Moment in .
@ CENTER_MAG
Cluster Centroid ( ).
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition P4Helpers.h:34
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
ParametersBase< TrackParametersDim, Charged > TrackParameters
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
CaloClusterContainer_v1 CaloClusterContainer
Define the latest version of the calorimeter cluster container.