ATLAS Offline Software
CaloClusterVertexFractionMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // in contrary to CaloClusterVertexFractionMakerAthAlg this is a CaloClusterCollectionProcessor and not an Athena Algorithm
7 
14 
15 #include "VxVertex/VxContainer.h"
17 
19 
20 #include "Particle/TrackParticle.h"
21 
22 #include <cmath>
23 
25 
26 
27 CaloClusterVertexFractionMaker::CaloClusterVertexFractionMaker(const std::string& type, const std::string& name, const IInterface* parent)
29  m_CALO_INNER_R(1450.), // millimeter
30  m_CALO_INNER_Z(3641.), // millimeter
31  m_dRMatchMax(0.1),
32  m_dR2MatchMax(0.), // will be overwritten in initialize
33  m_maxClusterEta(2.5),
34  m_extrapolator("Trk::Extrapolator/AtlasExtrapolator"),
35  m_vxContainerName("VxPrimaryCandidate")
36 {
37  declareProperty ( "Extrapolator", m_extrapolator );
38  declareProperty ( "VxContainerName", m_vxContainerName );
39  declareProperty ( "dRMatchMax", m_dRMatchMax );
40  declareProperty ( "maxClusterEta", m_maxClusterEta );
41 }
42 
44 {
45  // all delete statements are in finalize (otherwise genconf crashes .. no idea why)
46 }
47 
49 {
50  ATH_MSG_INFO( "Initializing " << name() );
51  ATH_MSG_INFO( "Only considering clusters with |eta| < " << m_maxClusterEta << "\tdRMatchMax Cluster-Track = " << m_dRMatchMax );
52 
54 
55  /* Get the extrapolator */
56  ATH_CHECK( m_extrapolator.retrieve() );
57  ATH_MSG_INFO( "Retrieved tool " << m_extrapolator );
58 
59  // a surface at the entrance to the calorimeter
60 // HepGeom::TranslateZ3D* translateAlongPositiveZ = new HepGeom::TranslateZ3D(m_CALO_INNER_Z);
61 // HepGeom::TranslateZ3D* translateAlongNegativeZ = new HepGeom::TranslateZ3D(-m_CALO_INNER_Z);
62  Amg::Transform3D translateAlongPositiveZ = Amg::Transform3D(Amg::Vector3D(0.,0.,m_CALO_INNER_Z));
63  Amg::Transform3D translateAlongNegativeZ = Amg::Transform3D(Amg::Vector3D(0.,0.,m_CALO_INNER_Z));
64 
65  m_cylinderSurface_atCaloEntrance = std::make_unique<Trk::CylinderSurface>(m_CALO_INNER_R, 8000.);
66  m_discSurface_atCaloEntrance_positiveZ = std::make_unique<Trk::DiscSurface>(translateAlongPositiveZ, 0., 10000.);
67  m_discSurface_atCaloEntrance_negativeZ = std::make_unique<Trk::DiscSurface>(translateAlongNegativeZ, 0., 10000.);
68 
69  return StatusCode::SUCCESS;
70 }
71 
74  xAOD::CaloClusterContainer* caloClusterContainer) const
75 {
76  const VxContainer* primcontainer(nullptr);
77  if ( evtStore()->contains<VxContainer> ( m_vxContainerName ) )
78  {
79  if ( evtStore()->retrieve ( primcontainer, m_vxContainerName ).isFailure() )
80  {
81  ATH_MSG_WARNING( "Could not retrieve collection " << m_vxContainerName << " in StoreGate, but contains<> says it is there." );
82  return StatusCode::FAILURE;
83  }
84  } else {
85  ATH_MSG_WARNING( "No collection " << m_vxContainerName << " in StoreGate." );
86  return StatusCode::FAILURE;
87  }
88 
89  // loop over vertices, extrapolate tracks to calo, remember num tracks per vertex (for cluster vertex fraction calculation later)
90  std::vector<unsigned int> numTracksPerVertex(primcontainer->size()-1, 0);
91  std::vector<float> trkParticlePt_atOrigin;
92  std::vector<float> trkParticleEta_atCaloEntrance;
93  std::vector<float> trkParticlePhi_atCaloEntrance;
94 
95  for (unsigned int v = 0 ; v < primcontainer->size()-1; ++v)
96  {
97  const std::vector<Trk::VxTrackAtVertex*>* vxTrackAtVertex = primcontainer->at(v)->vxTrackAtVertex();
98  for (std::vector<Trk::VxTrackAtVertex*>::const_iterator vxTrkItr = vxTrackAtVertex->begin(); vxTrkItr != vxTrackAtVertex->end(); ++vxTrkItr)
99  {
101  Trk::ITrackLink* trklink = (*vxTrkItr)->trackOrParticleLink();
102  Trk::LinkToTrackParticleBase* linkToTrackParticle = dynamic_cast<Trk::LinkToTrackParticleBase*>(trklink);
103  if (linkToTrackParticle != nullptr && linkToTrackParticle->isValid()) {
104  const Rec::TrackParticle* theTrackParticle = dynamic_cast<const Rec::TrackParticle*>(linkToTrackParticle->cachedElement());
105  if (theTrackParticle != nullptr)
106  {
107  const Trk::TrackParameters* trackParameters_atCaloEntrance(nullptr);
108  numTracksPerVertex.at(v)++;
109  trkParticlePt_atOrigin.push_back (theTrackParticle->pt()/1.e3);
110 
111  const Trk::TrackParameters* lastTrackParametersInID(nullptr);
112  const std::vector< const Trk::TrackParameters * >& trackParametersVector = theTrackParticle->trackParameters();
113  if (trackParametersVector.size() > 1) lastTrackParametersInID = trackParametersVector.at(trackParametersVector.size()-2);
114  else lastTrackParametersInID = trackParametersVector.at(0); // the perigee
115 
116  // very simplified way for now to decide to extrapolate a track to barrel or endcap
117  if (theTrackParticle->eta() >
118  1.35) // track most likely in endcap A, extrapolate track to a
119  // disc at ID exist in positive z direction
120  {
121  trackParameters_atCaloEntrance =
122  dynamic_cast<const Trk::AtaDisc*>(m_extrapolator->extrapolate(
123  ctx,
124  *lastTrackParametersInID,
127  true,
128  Trk::pion).release());
129  } else if (theTrackParticle->eta() <
130  -1.35) // track most likely in endcap C, extrapolate track
131  // to a disc at ID exist in negative z direction
132  {
133  trackParameters_atCaloEntrance =
134  dynamic_cast<const Trk::AtaDisc*>(m_extrapolator->extrapolate(
135  ctx,
136  *lastTrackParametersInID,
139  true,
140  Trk::pion).release());
141  } else // track is in barrel, extrapolate to cylinder at ID exit
142  {
143  trackParameters_atCaloEntrance =
144  dynamic_cast<const Trk::AtaCylinder*>(
145  m_extrapolator->extrapolate(ctx,
146  *lastTrackParametersInID,
149  true,
150  Trk::pion).release());
151  }
152  if (trackParameters_atCaloEntrance != nullptr) {
153  trkParticleEta_atCaloEntrance.push_back(trackParameters_atCaloEntrance->position().eta());
154  trkParticlePhi_atCaloEntrance.push_back(trackParameters_atCaloEntrance->position().phi());
155  ATH_MSG_DEBUG( "At calo entrance R(1150mm) " << *trackParameters_atCaloEntrance );
156  ATH_MSG_DEBUG( "TrkParticle eta/phi/pt[GeV] at calo " << trackParameters_atCaloEntrance->position().eta() << "\t"
157  << trackParameters_atCaloEntrance->position().phi() << "\t"
158  << trackParameters_atCaloEntrance->position().perp()/1.e3 );
159  delete trackParameters_atCaloEntrance;
160  } else {
161  trkParticleEta_atCaloEntrance.push_back(999.);
162  trkParticlePhi_atCaloEntrance.push_back(999.);
163  }
164  }
165  }
166  }
167  }
168 
169  double fabs_Dphi(9999.);
170  double fabs_Deta(9999.);
171  double dR2(9999.);
172  std::vector<float> sumPtOfMatchedTracksPerVertex(numTracksPerVertex.size(), 0.);
173 
174  for (xAOD::CaloClusterContainer::iterator clItr = caloClusterContainer->begin(); clItr != caloClusterContainer->end(); ++clItr)
175  {
176  xAOD::CaloCluster* theCluster = (*clItr);
177 // double cl_theta = 2.*atan(exp(-theCluster->eta()));
178 // double cl_et = theCluster->e()/1.e3*sin(cl_theta);
179  if (std::fabs(theCluster->eta()) < 2.5)
180  {
181  // Calculation of Cluster Vertex Fraction
182  std::vector<unsigned int>::iterator numTrksPerVertexItr = numTracksPerVertex.begin();
183  std::vector<unsigned int>::iterator numTrksPerVertexItrE = numTracksPerVertex.end();
184  unsigned int vertexCounter(0);
185  unsigned int totalTrackCounter(0);
186  for ( ; numTrksPerVertexItr != numTrksPerVertexItrE ; ++numTrksPerVertexItr, vertexCounter++)
187  {
188  sumPtOfMatchedTracksPerVertex.at(vertexCounter) = 0.;
189  for (unsigned int track = 0; track < (*numTrksPerVertexItr); ++track, totalTrackCounter++)
190  {
191  if (trkParticleEta_atCaloEntrance.at(totalTrackCounter) < 900.) // no need to check phi as well (not extrapolated eta is set to 999.)
192  {
193  fabs_Dphi = calculateDPhi(trkParticlePhi_atCaloEntrance.at(totalTrackCounter), theCluster->phi());
194  fabs_Deta = fabs(trkParticleEta_atCaloEntrance.at(totalTrackCounter) - theCluster->eta());
195  dR2 = fabs_Deta * fabs_Deta + fabs_Dphi * fabs_Dphi;
196  if (dR2 < m_dR2MatchMax) {
197  sumPtOfMatchedTracksPerVertex.at(vertexCounter) += trkParticlePt_atOrigin.at(totalTrackCounter);
198  }
199  }
200  }
201  }
202  double totalSumPtOfMatchedTracksWhichWereAlsoUsedInAVertex(0.);
203  for (unsigned int mTpV = 0; mTpV < sumPtOfMatchedTracksPerVertex.size(); ++mTpV) {
204  totalSumPtOfMatchedTracksWhichWereAlsoUsedInAVertex += sumPtOfMatchedTracksPerVertex.at(mTpV);
205  //std::cout << "CaloClusterVertexFractionMakerAOD: " << mTpV << "\t" << sumPtOfMatchedTracksPerVertex.at(mTpV) << std::endl;
206  }
207 
208  double cvf(-1.);
209  double ncvf(-1.);
210  if (totalSumPtOfMatchedTracksWhichWereAlsoUsedInAVertex > 0.)
211  {
212  double sumPtInPrimary = sumPtOfMatchedTracksPerVertex.at(0);
213  cvf = sumPtOfMatchedTracksPerVertex.at(0)/totalSumPtOfMatchedTracksWhichWereAlsoUsedInAVertex;
214  std::sort(sumPtOfMatchedTracksPerVertex.begin(), sumPtOfMatchedTracksPerVertex.end());
215  double highestSumPt = sumPtOfMatchedTracksPerVertex.at(sumPtOfMatchedTracksPerVertex.size()-1);
216  if (highestSumPt > 0) ncvf = sumPtInPrimary/highestSumPt;
217  }
218  //std::cout << "CaloClusterVertexFractionMakerAOD: cvf " << cvf << "\tncvf " << ncvf << std::endl;
219  theCluster->insertMoment(xAOD::CaloCluster::VERTEX_FRACTION, cvf); // false at the end writes the moment into the moment store of the cluster directly (the moment is then written to AOD as well)
220  theCluster->insertMoment(xAOD::CaloCluster::NVERTEX_FRACTION, ncvf); // false at the end writes the moment into the moment store of the cluster directly (the moment is then written to AOD as well)
221  } else {
222  theCluster->insertMoment(xAOD::CaloCluster::VERTEX_FRACTION, -1.); // false at the end writes the moment into the moment store of the cluster directly (the moment is then written to AOD as well)
223  theCluster->insertMoment(xAOD::CaloCluster::NVERTEX_FRACTION, -1.); // false at the end writes the moment into the moment store of the cluster directly (the moment is then written to AOD as well)
224  }
225  }
226 
227  return StatusCode::SUCCESS;
228 }
229 
230 double CaloClusterVertexFractionMaker::calculateDPhi(double phi1, double phi2)
231 {
232  double dPhi = std::fabs(phi1 - phi2);
233  if (dPhi > M_PI) dPhi = 2.*M_PI - dPhi;
234 // if (dPhi > 3.1415926535897931) dPhi = 6.2831853071795862 - dPhi;
235  return dPhi;
236 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
CaloClusterKineHelper.h
CaloClusterVertexFractionMaker::calculateDPhi
static double calculateDPhi(double phi1, double phi2)
Definition: CaloClusterVertexFractionMaker.cxx:230
TrackParameters.h
xAOD::CaloCluster_v1::VERTEX_FRACTION
@ VERTEX_FRACTION
Vertex fraction of this cluster wrt.
Definition: CaloCluster_v1.h:184
TrackParticle.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloClusterVertexFractionMaker::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override
Execute on an entire collection of clusters.
Definition: CaloClusterVertexFractionMaker.cxx:73
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
M_PI
#define M_PI
Definition: ActiveFraction.h:11
xAOD::CaloCluster_v1::insertMoment
void insertMoment(MomentType type, double value)
Definition: CaloCluster_v1.cxx:754
IExtrapolator.h
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
CaloClusterVertexFractionMaker.h
I4Momentum::pt
virtual double pt() const =0
transverse momentum
CaloClusterVertexFractionMaker::m_dR2MatchMax
double m_dR2MatchMax
Definition: CaloClusterVertexFractionMaker.h:34
CaloClusterVertexFractionMaker::m_dRMatchMax
double m_dRMatchMax
Definition: CaloClusterVertexFractionMaker.h:33
CaloClusterVertexFractionMaker::m_maxClusterEta
double m_maxClusterEta
Definition: CaloClusterVertexFractionMaker.h:35
GeoPrimitives.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
Trk::VxCandidate::vxTrackAtVertex
std::vector< Trk::VxTrackAtVertex * > * vxTrackAtVertex(void)
Unconst pointer to the vector of tracks Required by some of the vertex fitters.
Definition: VxCandidate.h:144
CaloClusterVertexFractionMaker::m_CALO_INNER_Z
const double m_CALO_INNER_Z
Definition: CaloClusterVertexFractionMaker.h:31
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
CaloClusterVertexFractionMaker::m_discSurface_atCaloEntrance_positiveZ
std::unique_ptr< Trk::Surface > m_discSurface_atCaloEntrance_positiveZ
Definition: CaloClusterVertexFractionMaker.h:44
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:530
Trk::pion
@ pion
Definition: ParticleHypothesis.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
CaloClusterVertexFractionMaker::m_cylinderSurface_atCaloEntrance
std::unique_ptr< Trk::Surface > m_cylinderSurface_atCaloEntrance
Definition: CaloClusterVertexFractionMaker.h:43
CylinderSurface.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
VxTrackAtVertex.h
I4Momentum::eta
virtual double eta() const =0
pseudo rapidity
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
VxContainer.h
Trk::ParametersBase
Definition: ParametersBase.h:55
VxContainer
Definition: VxContainer.h:28
CaloClusterVertexFractionMaker::initialize
virtual StatusCode initialize() override
Definition: CaloClusterVertexFractionMaker.cxx:48
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
CaloClusterVertexFractionMaker::CaloClusterVertexFractionMaker
CaloClusterVertexFractionMaker(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloClusterVertexFractionMaker.cxx:27
CaloClusterVertexFractionMaker::~CaloClusterVertexFractionMaker
~CaloClusterVertexFractionMaker()
Definition: CaloClusterVertexFractionMaker.cxx:43
LinkToTrackParticleBase.h
Trk::LinkToTrackParticleBase
Definition: LinkToTrackParticleBase.h:17
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
CaloClusterVertexFractionMaker::m_discSurface_atCaloEntrance_negativeZ
std::unique_ptr< Trk::Surface > m_discSurface_atCaloEntrance_negativeZ
Definition: CaloClusterVertexFractionMaker.h:45
Trk::TrackParticleBase::trackParameters
const std::vector< const TrackParameters * > & trackParameters() const
Returns the track parameters.
Definition: TrackParticleBase.h:243
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Rec::TrackParticle
Definition: Reconstruction/Particle/Particle/TrackParticle.h:47
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
python.PyAthena.v
v
Definition: PyAthena.py:157
CaloClusterVertexFractionMaker::m_CALO_INNER_R
const double m_CALO_INNER_R
Definition: CaloClusterVertexFractionMaker.h:30
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CaloClusterVertexFractionMaker::m_vxContainerName
std::string m_vxContainerName
Definition: CaloClusterVertexFractionMaker.h:41
DiscSurface.h
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
AthAlgTool
Definition: AthAlgTool.h:26
xAOD::CaloCluster_v1::NVERTEX_FRACTION
@ NVERTEX_FRACTION
slightly updated vertex fraction more pile up independent (similar to nJVF)
Definition: CaloCluster_v1.h:185
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CaloClusterVertexFractionMaker::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: CaloClusterVertexFractionMaker.h:38
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.