ATLAS Offline Software
Loading...
Searching...
No Matches
InDetGlobalBeamSpotMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
16
17//main header
19
21
24
27
28#include <sstream>
29#include <cmath>
30
31
32
33InDetGlobalBeamSpotMonAlg::InDetGlobalBeamSpotMonAlg( const std::string & name, ISvcLocator* pSvcLocator) :
34 AthMonitorAlgorithm( name, pSvcLocator ),
35 m_useBeamspot(true),
38 m_minTrackPt(500)
39{
40 declareProperty("useBeamspot", m_useBeamspot, "turn on histograms for assumed beam spot position");
41 declareProperty("vxContainerWithBeamConstraint", m_vxContainerWithBeamConstraint, "turn on histograms for vertex-based beam spot monitoring" );
42 declareProperty("minTracksPerVtx", m_minTracksPerVtx, "minimum number of tracks per vertex" );
43 declareProperty("minTrackPt", m_minTrackPt, "minimum track pT (MeV)");
44}
45
47
48
56
57
58StatusCode InDetGlobalBeamSpotMonAlg::fillHistograms( const EventContext& ctx ) const {
59 using namespace Monitored;
60
61 //*******************************************************************************
62 //************************** Begin of filling Beam spot Histograms ******************
63 //*******************************************************************************
64 ATH_MSG_DEBUG("Filling InDetGlobalBeamSpotMonAlg");
65
66 // For histogram naming
67 auto bsGroup = getGroup("BeamSpot");
68
69 // Get beamspot information, if available
70 float beamSpotX = 0.;
71 float beamSpotY = 0.;
72 float beamSpotZ = 0.;
73 float beamTiltX = 0.;
74 float beamTiltY = 0.;
75 float scaleFactor = 1.;
76 if (m_useBeamspot) {
77
78
79 auto beamSpotHandle = SG::ReadCondHandle(m_beamSpotKey, ctx);
80
81 // check for tracks
82 if ( !(beamSpotHandle.isValid()) ) {
83 ATH_MSG_ERROR("InDetGlobalBeamSpotMonAlg: BeamSpot container "<< beamSpotHandle.key() << " could not be found.");
84 return StatusCode::RECOVERABLE;
85 } else {
86 ATH_MSG_DEBUG("InDetGlobalBeamSpotMonAlg: BeamSpot container "<< beamSpotHandle.fullKey() <<" is found.");
87 }
88
89
90
91 const Amg::Vector3D &bpos = beamSpotHandle->beamPos();
92
93 beamSpotX = bpos.x();
94 beamSpotY = bpos.y();
95 beamSpotZ = bpos.z();
96 auto beamSpotX_m = Monitored::Scalar<float>("m_bsX", beamSpotX );
97 auto beamSpotY_m = Monitored::Scalar<float>("m_bsY", beamSpotY );
98 auto beamSpotZ_m = Monitored::Scalar<float>("m_bsZ", beamSpotZ );
99 beamTiltX = beamSpotHandle->beamTilt(0);
100 beamTiltY = beamSpotHandle->beamTilt(1);
101 auto beamTiltX_m = Monitored::Scalar<float>("m_bsTiltX", 1e6*beamTiltX );
102 auto beamTiltY_m = Monitored::Scalar<float>("m_bsTiltY", 1e6*beamTiltY );
103 scaleFactor = 1000.; // Use microns for some histograms when showing distance relative to beamspot PJ not used here?!
104
105 fill(bsGroup,beamSpotX_m);
106 fill(bsGroup,beamSpotY_m);
107 fill(bsGroup,beamSpotZ_m);
108 fill(bsGroup,beamTiltX_m);
109 fill(bsGroup,beamTiltY_m);
110
111 ATH_MSG_DEBUG("InDetGlobalBeamSpotMonAlg: Beamspot x0 = " << beamSpotX_m << ", y0 = " << beamSpotY_m << ", z0 = " << beamSpotZ_m << ", tiltX = " << beamTiltX_m << ", tiltY = " << beamTiltY_m);
112 } // m_useBeamspot
113
114
115 auto trackCollection = SG::makeHandle(m_trackContainerName, ctx);
116
117 if(!(trackCollection.isValid())){
118 ATH_MSG_DEBUG ("InDetGlobalBeamSpotMonAlg: Could not retrieve TrackParticleContainer container with key "+m_trackContainerName.key());
119 return StatusCode::SUCCESS;
120 }
121
122
123 // Track monitoring
124 int nTracks = 0;
125
126 //range based for-loop
127 for (const xAOD::TrackParticle* tpb: *trackCollection) {
128
129 if ( !tpb )
130 {
131 ATH_MSG_DEBUG( "InDetGlobalBeamSpotMonAlg: NULL track pointer in collection" );
132 continue;
133 }
134
135
136 const Trk::Perigee* perigee = &(tpb->perigeeParameters());
137
138 if ( !perigee )
139 {
140 ATH_MSG_DEBUG( "InDetGlobalBeamSpotMonAlg: NULL track->perigeeParameters pointer " );
141 continue;
142 }
143
144
145
146 float theta = perigee->parameters()[Trk::theta];
147 float qOverPt = perigee->parameters()[Trk::qOverP]/sin(theta);
148 float charge = perigee->charge();
149 float z0 = perigee->parameters()[Trk::z0];
150 float phi0 = perigee->parameters()[Trk::phi0];
151 float d0 = perigee->parameters()[Trk::d0];
152 float pT = 0;
153
154 if ( qOverPt != 0 ){
155 pT = (1/qOverPt)*(charge);
156 // For all tracks
157 auto pT_m = Monitored::Scalar<float>("m_trkPt", pT/1000);
158 fill(bsGroup, pT_m);
159
160 // Select tracks to use for remaining histograms
161 if (pT<m_minTrackPt) continue;
162 }
163
164 nTracks++;
165
166 auto trkDPhi_m = Monitored::Scalar<float>("m_trkD0Phi", phi0);
167 auto trkD_m = Monitored::Scalar<float>("m_trkD0", d0*1e3);
168 fill(bsGroup, trkD_m, trkDPhi_m);
169 fill(bsGroup, trkD_m);
170
171 // Currently we do the direct calculation of d0corr. We could
172 // also use an extrapolator to calculate d0 wrt a
173 // Trk::StraightLineSurface constructed along the beam line.
174 if(m_useBeamspot){
175
176 float trkbeamlineTiltX=tpb->beamlineTiltX();
177 float trkbeamlineTiltY=tpb->beamlineTiltY();
178 float trkbeamspotx=tpb->vx();
179 float trkbeamspoty=tpb->vy();
180 float trkbeamspotz=tpb->vz();
181
182 float beamX = (beamSpotX-trkbeamspotx) + std::tan(beamTiltX-trkbeamlineTiltX) * (z0-beamSpotZ+trkbeamspotz);
183 float beamY = (beamSpotY-trkbeamspoty) + std::tan(beamTiltY-trkbeamlineTiltY) * (z0-beamSpotZ+trkbeamspotz);
184 float d0corr = d0 - ( -std::sin(phi0)*beamX + std::cos(phi0)*beamY );
185
186 auto trkDPhiCorr_m = Monitored::Scalar<float>("m_trkD0PhiCorr", phi0);
187 auto trkDCorr_m = Monitored::Scalar<float>("m_trkD0Corr", d0corr*1e3);
188 fill(bsGroup, trkDPhiCorr_m, trkDCorr_m);
189 fill(bsGroup, trkDCorr_m);
190 }
191 } // track iterator
192
193 auto trkNPt_m = Monitored::Scalar<float>("m_trkNPt", nTracks);
194 fill(bsGroup,trkNPt_m);
195
196 // Primary vertex monitoring - only if we have a primary vertex collection determined
197 // without beam constraint
199 ATH_MSG_DEBUG( "InDetGlobalBeamSpotMonAlg: vxContainerWithBeamConstraint is " << m_vxContainerWithBeamConstraint );
200
201 // Basic primary vertex monitoring
202 auto handle_vxContainer = SG::makeHandle(m_vxContainerName, ctx);
203
204 if (!handle_vxContainer.isValid()) {
205 ATH_MSG_DEBUG ("InDetGlobalBeamSpotMonAlg: Could not retrieve primary vertex container with key "+ m_vxContainerName.key());
206 return StatusCode::SUCCESS;
207 }
208 auto vertexContainer = handle_vxContainer.cptr();
209
210 auto pvN_m = Monitored::Scalar<float>("m_pvN", vertexContainer->size()-1); // exclude dummy vertex
211 fill(bsGroup, pvN_m);
212
213 int nPriVtx = 0;
214 int nPileupVtx = 0;
215
216 for(const auto vtx : *vertexContainer) {
217
218 if ( !vtx ) continue;
219
220 // Count different types of vertices
221 if (vtx->vertexType() == xAOD::VxType::PriVtx) nPriVtx++;
222 if (vtx->vertexType() == xAOD::VxType::PileUp) nPileupVtx++;
223
224 // Select primary vertex
225 if (vtx->vertexType() != xAOD::VxType::PriVtx) continue;
226 if (vtx->numberDoF() <= 0) continue;
227
228 if (vtx->nTrackParticles() < m_minTracksPerVtx) continue;
229 if(vtx->covariancePosition()(0,0) < 0) continue;
230 if(vtx->covariancePosition()(1,1) < 0) continue;
231 if(vtx->covariancePosition()(2,2) < 0) continue;
232
233 // Found good VxCandidate to monitor - now fill histograms
234 float x = vtx->position().x();
235 float y = vtx->position().y();
236 float z = vtx->position().z();
237 float beamX = beamSpotX + std::tan(beamTiltX) * (z-beamSpotZ);
238 float beamY = beamSpotY + std::tan(beamTiltY) * (z-beamSpotZ);
239 float beamZ = beamSpotZ;
240
241 auto pvXbeam_m = Monitored::Scalar<float>("m_pvXbeam", (x-beamX)*scaleFactor);
242 fill(bsGroup, pvXbeam_m);
243
244 auto pvYbeam_m = Monitored::Scalar<float>("m_pvYbeam", (y-beamY)*scaleFactor);
245 fill(bsGroup, pvYbeam_m);
246
247 auto pvZbeam_m = Monitored::Scalar<float>("m_pvZbeam", z-beamZ);
248 fill(bsGroup, pvZbeam_m);
249
250 auto pvErrX_m = Monitored::Scalar<float>("m_pvErrX", Amg::error( vtx->covariancePosition(), Trk::x));
251 fill(bsGroup, pvErrX_m);
252
253 auto pvErrY_m = Monitored::Scalar<float>("m_pvErrY", Amg::error( vtx->covariancePosition(), Trk::y));
254 fill(bsGroup, pvErrY_m);
255
256 auto pvErrZ_m = Monitored::Scalar<float>("m_pvErrZ", Amg::error( vtx->covariancePosition(), Trk::z));
257 fill(bsGroup, pvErrZ_m);
258
259 auto pvNTracks_m = Monitored::Scalar<float>("m_pvNTracks", vtx->nTrackParticles());
260 fill(bsGroup, pvNTracks_m);
261
262 auto pvChiSqDof_m = Monitored::Scalar<float>("m_pvChiSqDof", vtx->chiSquared() / vtx->numberDoF());
263 fill(bsGroup, pvChiSqDof_m);
264
265 auto pvX_m = Monitored::Scalar<float>("m_pvX", x);
266 auto pvY_m = Monitored::Scalar<float>("m_pvY", y);
267 auto pvZ_m = Monitored::Scalar<float>("m_pvZ", z);
268 fill(bsGroup, pvX_m, pvZ_m);
269 fill(bsGroup, pvY_m, pvZ_m);
270 fill(bsGroup, pvY_m, pvX_m);
271
272 // Histograms on original tracks used for primary vertex
273 for (unsigned int trkIter=0; trkIter!=vtx->nTrackParticles(); ++trkIter) {
274 const xAOD::TrackParticle* tp = vtx->trackParticle(trkIter);
275 if(!tp){
276 ATH_MSG_DEBUG ("InDetGlobalBeamSpotMonAlg: Could not retrieve track particle.");
277 continue;
278 }
279 const Trk::Perigee measuredPerigee = tp->perigeeParameters();
280 auto pvTrackPt_m = Monitored::Scalar<float>("m_pvTrackPt", measuredPerigee.pT()/1000.);
281 auto pvTrackEta_m = Monitored::Scalar<float>("m_pvTrackEta", measuredPerigee.eta());
282 fill(bsGroup, pvTrackPt_m);
283 fill(bsGroup, pvTrackEta_m);
284 }
285 } // vertex iterator
286
287 auto pvNPriVtx_m = Monitored::Scalar<float>("m_pvNPriVtx", nPriVtx);
288 auto pvNPileupVtx_m = Monitored::Scalar<float>("m_pvNPileupVtx", nPileupVtx);
289 fill(bsGroup, pvNPriVtx_m);
290 fill(bsGroup, pvNPileupVtx_m);
291 }
292
293 return StatusCode::SUCCESS;
294}
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
#define y
#define x
#define z
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
virtual StatusCode initialize() override
initialize
InDetGlobalBeamSpotMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< xAOD::VertexContainer > m_vxContainerName
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackContainerName
Declare a monitored scalar variable.
double eta() const
Access method for pseudorapidity - from momentum.
double charge() const
Returns the charge.
double pT() const
Access method for transverse momentum.
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Matrix< double, 3, 1 > Vector3D
Generic monitoring tool for athena components.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ x
Definition ParamDefs.h:55
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ y
Definition ParamDefs.h:56
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
@ PileUp
Pile-up vertex.
@ PriVtx
Primary vertex.
TrackParticle_v1 TrackParticle
Reference the current persistent version: