ATLAS Offline Software
Loading...
Searching...
No Matches
PixelAthClusterMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
11//for Amg::error helper function:
20
21
22PixelAthClusterMonAlg::PixelAthClusterMonAlg(const std::string& name, ISvcLocator* pSvcLocator) :
23 AthMonitorAlgorithm(name, pSvcLocator),
24 m_holeSearchTool("InDet::InDetTrackHoleSearchTool/InDetHoleSearchTool", this),
25 m_trackSelTool("InDet::InDetTrackSelectionTool/TrackSelectionTool", this),
26 m_atlasid(nullptr)
27{
28 declareProperty("HoleSearchTool", m_holeSearchTool);
29 declareProperty("TrackSelectionTool", m_trackSelTool);
30
31 declareProperty("doOnline", m_doOnline = false);
32 declareProperty("doLumiBlock", m_doLumiBlock = false);
33 declareProperty("doLowOccupancy", m_doLowOccupancy = false);
34 declareProperty("doHighOccupancy", m_doHighOccupancy = true);
35 declareProperty("doHeavyIonMon", m_doHeavyIonMon = false);
36 declareProperty("doFEPlots", m_doFEPlots = false);
37}
38
40
41
44 ATH_CHECK(detStore()->retrieve(m_atlasid, "AtlasID"));
45 if (!m_holeSearchTool.empty()) ATH_CHECK(m_holeSearchTool.retrieve());
46 if (!m_trackSelTool.empty()) ATH_CHECK(m_trackSelTool.retrieve());
47
48 ATH_CHECK(m_tracksKey.initialize());
49 ATH_CHECK(m_clustersKey.initialize());
50 ATH_CHECK( m_testPixelLayerTool.retrieve( DisableTool{m_testPixelLayerTool.empty()} ) );
51 return StatusCode::SUCCESS;
52}
53
54StatusCode PixelAthClusterMonAlg::fillHistograms(const EventContext& ctx) const {
55 using namespace Monitored;
56
57 int lb = GetEventInfo(ctx)->lumiBlock();
58
59 //*******************************************************************************
60 //************************** Begin of filling Status Histograms ******************
61 //*******************************************************************************
62
63
64 ATH_MSG_DEBUG("Filling Status Monitoring Histograms");
65 float index = 1.0;
66 float nBadMod[PixLayers::COUNT] = {
67 0.
68 };
69 float nDisabledMod[PixLayers::COUNT] = {
70 0.
71 };
72 float nBadAndDisabledMod[PixLayers::COUNT] = {
73 0.
74 };
75 int phiMod(-99);
76 int etaMod(-99);
77 bool copyFEval(false);
78 AccumulatorArrays clusPerEventArray = {{{0}}, {{0}}, {{0}}, {{0}}, {{0}}, {{0}}};
79 VecAccumulator2DMap Map_Of_Modules_Status(*this, "MapOfModulesStatus", true);
80
81 VecAccumulator2DMap Map_Of_FEs_Status(*this, "MapOfFEsStatus");
82
85 for (auto idIt = m_pixelid->wafer_begin(); idIt != m_pixelid->wafer_end(); ++idIt) {
86 Identifier waferID = *idIt;
87 IdentifierHash id_hash = m_pixelid->wafer_hash(waferID);
88
89 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(waferID), m_pixelid->layer_disk(waferID));
90 if (pixlayer == 99) continue;
91 getPhiEtaMod(waferID, phiMod, etaMod, copyFEval);
92
93 if (isActive( !m_pixelDetElStatusActiveOnly.empty() ? pixel_active.cptr() : nullptr, id_hash) )
94 {
95 if (isGood( !m_pixelDetElStatus.empty() ? pixel_status.cptr() : nullptr, id_hash) ) index = 0;
96 else {
97 index = 1; // active but bad modules
98 if (pixlayer == PixLayers::kIBL) {
99 int iblsublayer = (m_pixelid->eta_module(waferID) > -7 && m_pixelid->eta_module(waferID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
100 nBadMod[iblsublayer] += inv_nmod_per_layer[iblsublayer];
101 } else nBadMod[pixlayer] += inv_nmod_per_layer[pixlayer];
102 }
103 }
104 else {
105 index = 2; // inactive (disabled) modules
106 if (pixlayer == PixLayers::kIBL) {
107 int iblsublayer = (m_pixelid->eta_module(waferID) > -7 && m_pixelid->eta_module(waferID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
108 nDisabledMod[iblsublayer] += inv_nmod_per_layer[iblsublayer];
109 } else nDisabledMod[pixlayer] += inv_nmod_per_layer[pixlayer];
110 switch (pixlayer) {
111 case PixLayers::kECA:
112 clusPerEventArray.DA[phiMod][etaMod] = -1;
113 break;
114
115 case PixLayers::kECC:
116 clusPerEventArray.DC[phiMod][etaMod] = -1;
117 break;
118
120 clusPerEventArray.B0[phiMod][etaMod] = -1;
121 break;
122
124 clusPerEventArray.B1[phiMod][etaMod] = -1;
125 break;
126
128 clusPerEventArray.B2[phiMod][etaMod] = -1;
129 break;
130
131 case PixLayers::kIBL:
132 clusPerEventArray.IBL[phiMod][etaMod] = -1;
133 if (copyFEval) clusPerEventArray.IBL[phiMod][++etaMod] = -1;
134 break;
135 }
136 }
137
138 Map_Of_Modules_Status.add(pixlayer, waferID, index);
139
140 // Per FE Status
141 //
142 if (m_doFEPlots) {
143 int nFE = getNumberOfFEs(pixlayer, m_pixelid->eta_module(waferID));
144 for (int iFE = 0; iFE < nFE; iFE++) {
145 Identifier pixelID = m_pixelReadout->getPixelIdfromHash(id_hash, iFE, 1, 1);
146 if (not pixelID.is_valid()) continue;
147 auto [is_active,is_good ] =isChipGood( !m_pixelDetElStatusActiveOnly.empty() ? pixel_active.cptr() : nullptr,
148 !m_pixelDetElStatus.empty() ? pixel_status.cptr() : nullptr,
149 id_hash,
150 iFE);
151 if (is_active)
152 {
153 if (is_good) index = 0;
154 else index = 1;
155 }
156 else index = 2;
157 Map_Of_FEs_Status.add(pixlayer, waferID, iFE, index);
158 }
159 }
160 } // end of pixelid wafer loop
161
162 fill2DProfLayerAccum(Map_Of_Modules_Status);
163 fill1DProfLumiLayers("BadModulesPerLumi", lb, nBadMod);
164 fill1DProfLumiLayers("DisabledModulesPerLumi", lb, nDisabledMod);
165
166 for (unsigned int ii = 0; ii < PixLayers::COUNT; ii++) nBadAndDisabledMod[ii] = nBadMod[ii]+nDisabledMod[ii];
167 fill1DProfLumiLayers("BadAndDisabledModulesPerLumi", lb, nBadAndDisabledMod);
168
169 if (m_doFEPlots) fill2DProfLayerAccum(Map_Of_FEs_Status);
170
171 //*******************************************************************************
172 //*************************** End of filling Status Histograms ******************
173 //*******************************************************************************
174
175
176 //*******************************************************************************
177 //************************** Begin of filling Track Histograms ******************
178 //*******************************************************************************
179
180
181 ATH_MSG_DEBUG("Filling Track Monitoring Histograms");
182
183 VecAccumulator2DMap TSOS_Outlier(*this, "TSOSOutlier");
184 VecAccumulator2DMap TSOS_Outlier_FE(*this, "TSOSOutlierFE");
185 VecAccumulator2DMap TSOS_Hole(*this, "TSOSHole");
186 VecAccumulator2DMap TSOS_Hole_FE(*this, "TSOSHoleFE");
187 VecAccumulator2DMap TSOS_Measurement(*this, "TSOSMeasurement");
188 VecAccumulator2DMap TSOS_Measurement_FE(*this, "TSOSMeasurementFE");
189 VecAccumulator2DMap HolesRatio(*this, "HolesRatio");
190 VecAccumulator2DMap MissIBLhit(*this, "MissIBLhit");
191 VecAccumulator2DMap MissIBLpresentBLhit(*this, "MissIBLpresentBLhit");
192 VecAccumulator2DMap MissHitsRatio(*this, "MissHitsRatio");
193 auto trackGroup = getGroup("Track");
194
195 auto tracks = SG::makeHandle(m_tracksKey, ctx);
196
197 if (!(tracks.isValid())) {
198 ATH_MSG_ERROR("PixelMonitoring: Track container " << m_tracksKey.key() << " could not be found.");
199 auto dataread_err = Monitored::Scalar<int>("trkdataread_err", DataReadErrors::ContainerInvalid);
200 fill(trackGroup, dataread_err);
201 return StatusCode::RECOVERABLE;
202 } else {
203 ATH_MSG_DEBUG("PixelMonitoring: Track container " << tracks.name() << " is found.");
204 }
205
206 int ntracksPerEvent = 0;
207 bool havePixelHits(false);
208 std::vector<std::pair<Identifier, double> > ClusterIDs;
209
210 auto lbval = Monitored::Scalar<int>("pixclusmontool_lb", lb);
211
212 for (auto track: *tracks) {
213 if (track == nullptr || track->perigeeParameters() == nullptr || track->trackSummary() == nullptr ||
214 track->trackSummary()->get(Trk::numberOfPixelHits) == 0) {
215 ATH_MSG_DEBUG("PixelMonitoring: Track either invalid or it does not contain pixel hits, continuing...");
216 continue;
217 }
218
219 int nPixelHits = 0;
220 const Trk::Perigee* measPerigee = static_cast<const Trk::Perigee*>(track->perigeeParameters());
221 bool passJOTrkTightCut = static_cast<bool>(m_trackSelTool->accept(*track));
222 bool pass1hole1GeVptTightCut = (passJOTrkTightCut && (measPerigee->pT() / 1000.0 > 1.0)); // misshit ratios
223 bool pass1hole5GeVptTightCut = (passJOTrkTightCut && (measPerigee->pT() / 1000.0 > 5.0)); // eff vs lumi
224
225 if(measPerigee->pT()<1000.) continue; // Remove problematic low-pt tracks
226
227 const Trk::Track* trackWithHoles(track);
228 std::unique_ptr<const Trk::Track> trackWithHolesUnique = nullptr;
229 if (track->trackSummary()->get(Trk::numberOfPixelHoles) > 0) {
230 trackWithHolesUnique.reset(m_holeSearchTool->getTrackWithHoles(*track));
231 trackWithHoles = trackWithHolesUnique.get();
232 }
233 const Trk::TrackStates* trackStates = trackWithHoles->trackStateOnSurfaces();
234 for (auto trackStateOnSurface: *trackStates) {
235 const Trk::MeasurementBase* mesBase = trackStateOnSurface->measurementOnTrack();
236
237 const Trk::RIO_OnTrack* RIOOnTrack = nullptr;
238 if (mesBase && mesBase->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
239 RIOOnTrack = static_cast<const Trk::RIO_OnTrack*>(mesBase);
240 }
241
242 if (mesBase && !RIOOnTrack) continue; // skip pseudomeasurements
243 // but not hits, holes,
244 // outliers
245
246 const Trk::TrackParameters* trkParameters = trackStateOnSurface->trackParameters();
247 Identifier surfaceID;
248 if (mesBase && mesBase->associatedSurface().associatedDetectorElement()) {
249 surfaceID = mesBase->associatedSurface().associatedDetectorElement()->identify();
250 } else { // holes, perigee
251 if (trkParameters) {
252 surfaceID = trkParameters->associatedSurface().associatedDetectorElementIdentifier();
253 } else {
254 ATH_MSG_INFO("PixelMonitoring: pointer of TSOS to track parameters or associated surface is null");
255 continue;
256 }
257 }
258 if (!m_atlasid->is_pixel(surfaceID)) continue;
259 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(surfaceID), m_pixelid->layer_disk(surfaceID));
260 if (pixlayer == 99) continue;
261
262 float nOutlier = 0.;
263 float nHole = 0.;
264 auto effval = Monitored::Scalar<float>("HitEffAll_val", 0.);
265 auto efflb = Monitored::Scalar<float>("HitEffAll_lb", lb);
266 const InDetDD::SiDetectorElement *sde = dynamic_cast<const InDetDD::SiDetectorElement *>(trkParameters->associatedSurface().associatedDetectorElement());
267 const InDetDD::SiLocalPosition trkLocalPos = trkParameters->localPosition();
268 Identifier locPosID;
269
270 if (trackStateOnSurface->type(Trk::TrackStateOnSurface::Outlier))
271 {
272 nOutlier = 1.0;
273 const InDet::SiClusterOnTrack *siclus = dynamic_cast<const InDet::SiClusterOnTrack *>(mesBase);
274 if ( mesBase && siclus) {
275 locPosID = siclus->identify();
276 if ( !(locPosID.is_valid()) ) {
277 ATH_MSG_INFO("Pixel Monitoring: got invalid track local position on surface for an outlier.");
278 continue;
279 }
280 TSOS_Outlier.add(pixlayer, locPosID, 1.0);
281 if (!m_doOnline) {
282 TSOS_Outlier_FE.add(pixlayer, locPosID, m_pixelReadout->getFE(locPosID, locPosID), 1.0);
283 }
284 }
285 }
286 else if (trackStateOnSurface->type(Trk::TrackStateOnSurface::Hole))
287 {
288 nHole = 1.0;
289 locPosID = sde->identifierOfPosition(trkLocalPos);
290 if ( !(locPosID.is_valid()) ) {
291 ATH_MSG_INFO("Pixel Monitoring: got invalid track local position on surface for a hole.");
292 continue;
293 }
294 TSOS_Hole.add(pixlayer, locPosID, 1.0);
295 if (!m_doOnline) {
296 TSOS_Hole_FE.add(pixlayer, locPosID, m_pixelReadout->getFE(locPosID, locPosID), 1.0);
297 }
298 }
299 else if (trackStateOnSurface->type(Trk::TrackStateOnSurface::Measurement))
300 {
301 if (not mesBase) continue;
302 const InDetDD::SiDetectorElement* side =
303 dynamic_cast<const InDetDD::SiDetectorElement*>(mesBase->associatedSurface().associatedDetectorElement());
304 const InDet::SiClusterOnTrack* clus = dynamic_cast<const InDet::SiClusterOnTrack*>(mesBase);
305 if (!side || !clus) continue;
306 const InDet::SiCluster* RawDataClus = dynamic_cast<const InDet::SiCluster*>(clus->prepRawData());
307 if (!RawDataClus || !RawDataClus->detectorElement()->isPixel()) continue;
308
309 nPixelHits++;
310
311 locPosID = clus->identify();
312 if ( !(locPosID.is_valid()) ) {
313 ATH_MSG_INFO("Pixel Monitoring: got invalid cluster on track ID.");
314 continue;
315 }
316 TSOS_Measurement.add(pixlayer, locPosID, 1.0);
317 if (!m_doOnline) {
318 TSOS_Measurement_FE.add(pixlayer, locPosID, m_pixelReadout->getFE(locPosID, locPosID), 1.0);
319 }
320 effval = 1.;
321
322 const Trk::AtaPlane* trackAtPlane = dynamic_cast<const Trk::AtaPlane*>(trkParameters);
323 if (trackAtPlane) {
324 const Amg::Vector2D localpos = trackAtPlane->localPosition();
325
326 // Get local error matrix for hit and track and calc pull
327 const AmgSymMatrix(5) trackErrMat = (*trackAtPlane->covariance());
328 const Amg::MatrixX clusErrMat = clus->localCovariance();
329
330 double error_sum =
331 sqrt(pow(Amg::error(trackErrMat, Trk::locX), 2) + pow(Amg::error(clusErrMat, Trk::locX), 2));
332 auto resPhi = Monitored::Scalar<float>("res_phi", clus->localParameters()[Trk::locX] - localpos[0]);
333 fill(trackGroup, resPhi);
334 if (error_sum != 0) {
335 auto pullPhi = Monitored::Scalar<float>("pull_phi", resPhi / error_sum);
336 fill(trackGroup, pullPhi);
337 }
338
339 error_sum = sqrt(pow(Amg::error(trackErrMat, Trk::locY), 2) + pow(Amg::error(clusErrMat, Trk::locY), 2));
340 auto resEta = Monitored::Scalar<float>("res_eta", clus->localParameters()[Trk::locY] - localpos[1]);
341 fill(trackGroup, resEta);
342 if (error_sum != 0) {
343 auto pullEta = Monitored::Scalar<float>("pull_eta", resEta / error_sum);
344 fill(trackGroup, pullEta);
345 }
346 // Filling containers, which hold id's of hits and clusters on track
347 // _and_ incident angle information for later normalization
348
349 Amg::Vector3D mynormal = side->normal();
350 Amg::Vector3D mytrack = trackAtPlane->momentum();
351 double trknormcomp = mytrack.dot(mynormal);
352
353 double mytrack_mag = mytrack.mag();
354 double cosalpha = 0.;
355 if (mytrack_mag != 0) cosalpha = std::abs(trknormcomp / mytrack_mag);
356 ClusterIDs.emplace_back(clus->identify(), cosalpha);
357 }
358 } // end of measurement case
359 else continue;
360
361 if (pass1hole5GeVptTightCut) {
362 if (pixlayer == PixLayers::kIBL) {
363 int iblsublayer = (m_pixelid->eta_module(surfaceID) > -7 && m_pixelid->eta_module(surfaceID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
364 fill(pixLayersLabel[iblsublayer], efflb, effval);
365 } else fill(pixLayersLabel[pixlayer], efflb, effval);
366 }
367
368 if (pass1hole1GeVptTightCut && locPosID.is_valid()) {
369 HolesRatio.add(pixlayer, locPosID, nHole);
370 MissHitsRatio.add(pixlayer, locPosID, nOutlier + nHole);
371 }
372 } // end of TSOS loop
373
374 auto etanoibl = Monitored::Scalar<float>("eta_noibl", measPerigee->momentum().eta());
375 auto phinoibl = Monitored::Scalar<float>("phi_noibl", measPerigee->momentum().phi());
376 auto missibl = Monitored::Scalar<float>("missIBLhit", 0.);
377 bool expectIBLHit = m_testPixelLayerTool->expectHitInInnermostPixelLayer(measPerigee);
378 int nIBLHits=0, nBLHits=0;
379 const Trk::TrackSummary *trksumm = track->trackSummary();
380 if (trksumm){
381 nIBLHits = trksumm->get(Trk::numberOfInnermostPixelLayerHits);
383 }
384 if(expectIBLHit && nIBLHits==0 && pass1hole1GeVptTightCut){
385 std::vector<InDet::TrackStateOnPixelLayerInfo> trackStateIBLlayer;
386 if(m_testPixelLayerTool->getTrackStateOnInnermostPixelLayerInfo(measPerigee, trackStateIBLlayer)){
387 Identifier posid_prev;
388 for (auto &tstate : trackStateIBLlayer){
389 Identifier posid = tstate.pixelId();
390 if(posid==posid_prev)continue;
391 MissIBLhit.add(PixLayers::kIBL, posid, 1.);
392 if(nBLHits>0)MissIBLpresentBLhit.add(PixLayers::kIBL, posid, 1.);
393 missibl=1.;
394 fill(trackGroup,etanoibl,phinoibl,missibl);
395 posid_prev=posid;
396 }
397 }
398 } else if(expectIBLHit && pass1hole1GeVptTightCut) fill(trackGroup,etanoibl,phinoibl,missibl);
399
400 ntracksPerEvent++;
401 auto nph = Monitored::Scalar<int>("npixhits_per_track", nPixelHits);
402 auto nphwgt = Monitored::Scalar<float>("npixhits_per_track_wgt", 1.0);
403 fill(trackGroup, lbval, nph, nphwgt);
404
405 int trkfitndf = track->fitQuality()->numberDoF();
406 double trkfitchi2 = track->fitQuality()->chiSquared();
407 if (trkfitndf != 0) {
408 auto trkChiN = Monitored::Scalar<float>("fit_chi2byndf", trkfitchi2 / trkfitndf);
409 fill(trackGroup, trkChiN);
410 }
411 havePixelHits = havePixelHits || (nPixelHits > 0);
412 } // end of track loop
413
414 if (!havePixelHits) {
415 auto dataread_err = Monitored::Scalar<int>("trkdataread_err", DataReadErrors::EmptyContainer);
416 fill(trackGroup, dataread_err);
417 }
418
419 fill2DProfLayerAccum(HolesRatio);
420 fill2DProfLayerAccum(MissIBLhit);
421 fill2DProfLayerAccum(MissIBLpresentBLhit);
422 fill2DProfLayerAccum(MissHitsRatio);
423 fill2DProfLayerAccum(TSOS_Outlier);
424 fill2DProfLayerAccum(TSOS_Hole);
425 fill2DProfLayerAccum(TSOS_Measurement);
426 if (!m_doOnline) {
427 fill2DProfLayerAccum(TSOS_Outlier_FE);
428 fill2DProfLayerAccum(TSOS_Hole_FE);
429 fill2DProfLayerAccum(TSOS_Measurement_FE);
430 }
431
432 sort(ClusterIDs.begin(), ClusterIDs.end(),
433 [](const std::pair<Identifier, double>& left, const std::pair<Identifier, double>& right) {
434 return left.first < right.first;
435 });
436
437 auto nTrks = Monitored::Scalar<int>("ntrks_per_event", ntracksPerEvent);
438 fill(trackGroup, lbval, nTrks);
439
440 //*******************************************************************************
441 //**************************** End of filling Track Histograms ******************
442 //*******************************************************************************
443
444 //*******************************************************************************
445 //************************ Begin of filling Cluster Histograms ******************
446 //*******************************************************************************
447
448 ATH_MSG_DEBUG("Filling Cluster Monitoring Histograms");
449
450
451 auto clToTcosAlphaLB = Monitored::Scalar<float>("ClusterToTxCosAlphaOnTrack_lb", lb);
452
453 VecAccumulator2DMap Cluster_LVL1A_Mod(*this, "ClusterLVL1AMod");
454 VecAccumulator2DMap Cluster_LVL1A_SizeCut(*this, "ClusterLVL1ASizeCut");
455 VecAccumulator2DMap Cluster_LVL1A_Mod_OnTrack(*this, "ClusterLVL1AModOnTrack");
456 VecAccumulator2DMap Cluster_LVL1A_SizeCut_OnTrack(*this, "ClusterLVL1ASizeCutOnTrack");
457 VecAccumulator2DMap ClusterMap_Mon(*this, "ClusterMapMon");
458 VecAccumulator2DMap ClusterMap_Mon_OnTrack(*this, "ClusterMapMonOnTrack");
459 VecAccumulator2DMap Cluster_Size_Map_OnTrack(*this, "ClusterSizeMapOnTrack");
460 VecAccumulator2DMap Cluster_Occupancy(*this, "ClusterOccupancy");
461 VecAccumulator2DMap Cluster_Occupancy_OnTrack(*this, "ClusterOccupancyOnTrack");
462 VecAccumulator2DMap Clus_Occ_SizeCut(*this, "ClusOccSizeCut");
463 VecAccumulator2DMap Clus_Occ_SizeCut_OnTrack(*this, "ClusOccSizeCutOnTrack");
464 VecAccumulator2DMap Cluster_FE_Occupancy(*this, "ClusterFEOccupancy");
465 VecAccumulator2DMap Cluster_FE_Occupancy_OnTrack(*this, "ClusterFEOccupancyOnTrack");
466
467 auto clusterGroup = getGroup("Cluster");
468 auto clusterGroup_OnTrack = getGroup("Cluster_OnTrack");
469
470 auto pixel_clcontainer = SG::makeHandle(m_clustersKey, ctx);
471
472 if (!(pixel_clcontainer.isValid())) {
473 ATH_MSG_ERROR("Pixel Monitoring: Pixel Cluster container " << m_clustersKey.key() << " could not be found.");
474 auto dataread_err = Monitored::Scalar<int>("clsdataread_err", DataReadErrors::ContainerInvalid);
475 fill(clusterGroup, dataread_err);
476 return StatusCode::RECOVERABLE;
477 } else {
478 ATH_MSG_DEBUG("Pixel Monitoring: Pixel Cluster container " << pixel_clcontainer.name() << " is found.");
479 }
480
481 int nclusters = 0;
482 int nclusters_ontrack = 0;
483 float nclusters_mod[PixLayers::COUNT] = {
484 0.
485 };
486 float nclusters_ontrack_mod[PixLayers::COUNT] = {
487 0.
488 };
489
490 Identifier clusID;
491 for (auto colNext: *pixel_clcontainer) {
492 const InDet::PixelClusterCollection* ClusterCollection(colNext);
493 if (!ClusterCollection) {
494 ATH_MSG_DEBUG("Pixel Monitoring: Pixel Cluster container is empty.");
495 auto dataread_err = Monitored::Scalar<int>("clsdataread_err", DataReadErrors::CollectionInvalid);
496 fill(clusterGroup, dataread_err);
497 continue;
498 }
499
500 for (auto p_clus: *ClusterCollection) {
501 clusID = p_clus->identify();
502 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(clusID), m_pixelid->layer_disk(clusID));
503 if (pixlayer == 99) continue;
504 getPhiEtaMod(clusID, phiMod, etaMod, copyFEval);
505
506 const InDet::PixelCluster& cluster = *p_clus;
507 nclusters++;
508
509 // begin timing histos
510 //
511 auto clLVL1A = Monitored::Scalar<float>("Cluster_LVL1A_lvl1a", cluster.LVL1A());
512 fill(clusterGroup, clLVL1A);
513 Cluster_LVL1A_Mod.add(pixlayer, clusID, cluster.LVL1A() + 0.00001);
514 if (cluster.rdoList().size() > 1) Cluster_LVL1A_SizeCut.add(pixlayer, clusID, cluster.LVL1A() + 0.00001);
515 if (pixlayer == PixLayers::kIBL) {
516 int iblsublayer = (m_pixelid->eta_module(clusID) > -7 && m_pixelid->eta_module(clusID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
517 if (cluster.totalToT() > clusterToTMinCut[iblsublayer]) fill("ClusterLVL1AToTCut_" + pixLayersLabel[iblsublayer], clLVL1A);
518 nclusters_mod[iblsublayer]++;
519 } else {
520 if (cluster.totalToT() > clusterToTMinCut[pixlayer]) fill("ClusterLVL1AToTCut_" + pixLayersLabel[pixlayer], clLVL1A);
521 nclusters_mod[pixlayer]++;
522 }
523 //
524 // end timing histos
525 // begin cluster rate
526 //
527 if (m_doOnline) ClusterMap_Mon.add(pixlayer, clusID);
528 //
529 // end cluster rate
530 // begin cluster occupancy
531 //
532 Cluster_Occupancy.add(pixlayer, clusID);
533 if (m_doFEPlots) {
534 Cluster_FE_Occupancy.add(pixlayer, clusID, m_pixelReadout->getFE(clusID, clusID), 1.0);
535 }
536 if (cluster.rdoList().size() > 1) Clus_Occ_SizeCut.add(pixlayer, clusID);
537 // end cluster occupancy
538
539 double cosalpha(0.);
540 if (isClusterOnTrack(clusID, ClusterIDs, cosalpha)) {
541 nclusters_ontrack++;
542 switch (pixlayer) {
543 case PixLayers::kECA:
544 clusPerEventArray.DA[phiMod][etaMod]++;
545 break;
546
547 case PixLayers::kECC:
548 clusPerEventArray.DC[phiMod][etaMod]++;
549 break;
550
552 clusPerEventArray.B0[phiMod][etaMod]++;
553 break;
554
556 clusPerEventArray.B1[phiMod][etaMod]++;
557 break;
558
560 clusPerEventArray.B2[phiMod][etaMod]++;
561 break;
562
563 case PixLayers::kIBL:
564 clusPerEventArray.IBL[phiMod][etaMod]++;
565 break;
566 }
567 // begin timing histos
568 //
569 clLVL1A = cluster.LVL1A();
570 fill(clusterGroup_OnTrack, clLVL1A);
571 Cluster_LVL1A_Mod_OnTrack.add(pixlayer, clusID, cluster.LVL1A() + 0.00001);
572 if (cluster.rdoList().size() > 1) Cluster_LVL1A_SizeCut_OnTrack.add(pixlayer, clusID,
573 cluster.LVL1A() + 0.00001);
574 //
575 // end timing histos
576 // begin cluster sizes
577 //
578 auto clSize = Monitored::Scalar<float>("ClusterSizeOnTrack_clsize", cluster.rdoList().size());
579 auto clSizeEtaModule = Monitored::Scalar<float>("ClusterSizeOnTrack_em", m_pixelid->eta_module(clusID));
580 if (abs(m_pixelid->barrel_ec(clusID)) != 0) clSizeEtaModule = m_pixelid->layer_disk(clusID) + 1;
581 fill("ClusterGroupsizeVsEtaOnTrack_" + pixBaseLayersLabel[pixlayer], clSizeEtaModule, clSize);
582
583 Cluster_Size_Map_OnTrack.add(pixlayer, clusID, cluster.rdoList().size());
584 //
585 // end cluster sizes
586 // begin cluster rate
587 //
588 if (m_doOnline) ClusterMap_Mon_OnTrack.add(pixlayer, clusID);
589 //
590 // end cluster rate
591 // begin cluster occupancy
592 //
593 Cluster_Occupancy_OnTrack.add(pixlayer, clusID);
594 if (m_doFEPlots) {
595 Cluster_FE_Occupancy_OnTrack.add(pixlayer, clusID, m_pixelReadout->getFE(clusID, clusID), 1.0);
596 }
597 if (cluster.rdoList().size() > 1) Clus_Occ_SizeCut_OnTrack.add(pixlayer, clusID);
598 //
599 // end cluster occupancy
600 // begin cluster ToT, 1D timing, charge
601 //
602 if (pixlayer == PixLayers::kIBL)
603 {
604 pixlayer = (m_pixelid->eta_module(clusID) > -7 && m_pixelid->eta_module(clusID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
605 }
606 if (cluster.totalToT() > clusterToTMinCut[pixlayer]) fill("ClusterLVL1AToTCutOnTrack_" + pixLayersLabel[pixlayer], clLVL1A);
607
608 auto clToTcosAlpha = Monitored::Scalar<float>("ClusterToTxCosAlphaOnTrack_val", cluster.totalToT() * cosalpha);
609 fill(pixLayersLabel[pixlayer], clToTcosAlphaLB, clToTcosAlpha);
610
611 if (!m_doOnline) {
612 auto clQcosAlpha = Monitored::Scalar<float>("ClusterQxCosAlphaOnTrack_val", cluster.totalCharge() * cosalpha);
613 fill(pixLayersLabel[pixlayer], clQcosAlpha);
614 }
615 nclusters_ontrack_mod[pixlayer]++;
616 //
617 // end cluster ToT, 1D timing, charge
618 } // end on track
619 } // end cluster collection
620 }
621 fill2DProfLayerAccum(Cluster_LVL1A_Mod);
622 fill2DProfLayerAccum(Cluster_LVL1A_SizeCut);
623 fill2DProfLayerAccum(Cluster_LVL1A_Mod_OnTrack);
624 fill2DProfLayerAccum(Cluster_LVL1A_SizeCut_OnTrack);
625 if (m_doOnline) {
626 fill2DProfLayerAccum(ClusterMap_Mon);
627 fill2DProfLayerAccum(ClusterMap_Mon_OnTrack);
628 }
629 fill2DProfLayerAccum(Cluster_Size_Map_OnTrack);
630 fill2DProfLayerAccum(Cluster_Occupancy);
631 fill2DProfLayerAccum(Cluster_Occupancy_OnTrack);
632 fill2DProfLayerAccum(Clus_Occ_SizeCut);
633 fill2DProfLayerAccum(Clus_Occ_SizeCut_OnTrack);
634 if (m_doFEPlots) {
635 fill2DProfLayerAccum(Cluster_FE_Occupancy);
636 fill2DProfLayerAccum(Cluster_FE_Occupancy_OnTrack);
637 }
638 // begin cluster rates
639 //
640 auto nCls = Monitored::Scalar<int>("ClustersPerEvent_val", nclusters);
641 fill(clusterGroup, lbval, nCls);
642 auto nClsOnTrk = Monitored::Scalar<int>("ClustersPerEventOnTrack_val", nclusters_ontrack);
643 fill(clusterGroup_OnTrack, lbval, nClsOnTrk);
644 for (unsigned int ii = 0; ii < PixLayers::COUNT; ii++) {
645 auto vals = Monitored::Scalar<float>("ClustersPerEvent_val", nclusters_mod[ii]);
646 auto vals_ontrack = Monitored::Scalar<float>("ClustersPerEventOnTrack_val", nclusters_ontrack_mod[ii]);
647 fill(pixLayersLabel[ii], vals, vals_ontrack);
648 }
649
650 if (nclusters > 0) {
651 auto clsFracOnTrack = Monitored::Scalar<float>("cls_frac_ontrack", (float) nclusters_ontrack / nclusters);
652 fill(clusterGroup_OnTrack, lbval, clsFracOnTrack);
653 } else {
654 auto dataread_err = Monitored::Scalar<int>("clsdataread_err", DataReadErrors::EmptyContainer);
655 fill(clusterGroup, dataread_err);
656 }
657
658 fill1DProfLumiLayers("ClustersPerLumi", lb, nclusters_mod);
659 fill1DProfLumiLayers("ClustersPerLumiOnTrack", lb, nclusters_ontrack_mod);
660
661 fillFromArrays("ClusterOccupancyPP0OnTrack", clusPerEventArray);
662
663 if (ntracksPerEvent > 0) {
664 for (unsigned int ii = 0; ii < PixLayers::COUNT; ii++) nclusters_ontrack_mod[ii] /= ntracksPerEvent;
665 fill1DProfLumiLayers("NumClustersPerTrackPerLumi", lb, nclusters_ontrack_mod);
666 }
667 //
668 // end cluster rate
669 ClusterIDs.clear();
670
671 //*******************************************************************************
672 //************************** End of filling Cluster Histograms ******************
673 //*******************************************************************************
674
675 return StatusCode::SUCCESS;
676}
677
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
#define AmgSymMatrix(dim)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
const std::string pixBaseLayersLabel[PixLayers::NBASELAYERS]
const std::string pixLayersLabel[PixLayers::COUNT]
const int clusterToTMinCut[PixLayers::COUNT]
const float inv_nmod_per_layer[PixLayers::COUNT]
constexpr int pow(int base, int exp) noexcept
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Class to hold geometrical description of a silicon detector element.
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
RIO_OnTrack base class for Silicon detector in the InnerDetector.
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Declare a monitored scalar variable.
SG::ReadHandleKey< TrackCollection > m_tracksKey
ToolHandle< InDet::IInDetTestPixelLayerTool > m_testPixelLayerTool
tool to calculate expected hit information in innermost layers
ToolHandle< InDet::IInDetTrackSelectionTool > m_trackSelTool
const AtlasDetectorID * m_atlasid
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< InDet::PixelClusterContainer > m_clustersKey
PixelAthClusterMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< Trk::ITrackHoleSearchTool > m_holeSearchTool
virtual StatusCode initialize() override
initialize
void fill2DProfLayerAccum(const VecAccumulator2DMap &accumulator) const
take VecAccumulator2DMap and fill the corresponding group
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatusActiveOnly
Optional read handle to get status data to test whether a pixel detector element is active.
int getNumberOfFEs(int pixlayer, int etaMod) const
helper function to get number of FEs per module
bool isClusterOnTrack(Identifier id, std::vector< std::pair< Identifier, double > > const &ClusterIDs) const
checks if cluster is on track
void getPhiEtaMod(Identifier &id, int &phiMod, int &etaMod, bool &copyFE) const
helper function to get eta phi coordinates of per-layer arrays
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
bool isGood(const InDet::SiDetectorElementStatus *element_status, const IdentifierHash &module_hash) const
void fill1DProfLumiLayers(const std::string &prof1Dname, int lb, float *weights, int nlayers=PixLayers::COUNT) const
filling 1DProf per-lumi per-layer histograms ["ECA","ECC","BLayer","Layer1","Layer2",...
int getPixLayersID(int ec, int ld) const
helper function to get layers ID
std::tuple< bool, bool > isChipGood(const IdentifierHash &module_hash, unsigned int chip_i) const
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatus
Optional read handle to get status data to test whether a pixel detector element is good.
bool isActive(const InDet::SiDetectorElementStatus *element_status, const IdentifierHash &module_hash) const
void fillFromArrays(const std::string &namePP0, AccumulatorArrays &pixarrays, const std::string &name2DMap="") const
filling 1DProfile per-pp0(ROD) histograms for ["ECA","ECC","BLayer","Layer1","Layer2",...
SG::ReadHandle< InDet::SiDetectorElementStatus > getPixelDetElStatus(const SG::ReadHandleKey< InDet::SiDetectorElementStatus > &key, const EventContext &ctx) const
virtual StatusCode initialize() override
initialize
const_pointer_type cptr()
Dereference the pointer.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
double pT() const
Access method for transverse momentum.
Amg::Vector2D localPosition() const
Access method for the local coordinates, local parameter definitions differ for each surface type.
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
Identifier associatedDetectorElementIdentifier() const
return Identifier of the associated Detector Element
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
A summary of the information contained by a track.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
virtual Identifier identify() const =0
Identifier.
int lb
Definition globals.cxx:23
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.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
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, 2, 1 > Vector2D
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())
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
ParametersBase< TrackParametersDim, Charged > TrackParameters
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfNextToInnermostPixelLayerHits
these are the pixel hits, including the b-layer
@ numberOfInnermostPixelLayerHits
these are the hits in the 1st pixel layer
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
Definition index.py:1