ATLAS Offline Software
Loading...
Searching...
No Matches
BeamBackgroundFiller.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8#include "CaloGeoHelpers/CaloSampling.h"
13
16#include "GaudiKernel/PhysicalConstants.h"
17
20
23
24#include <cmath>
25
26namespace {
27 constexpr double inv_c = 1./Gaudi::Units::c_light;
28}
29
30//------------------------------------------------------------------------------
32 ISvcLocator* pSvcLocator)
33 : AthReentrantAlgorithm(name, pSvcLocator) {
34}
35
36//------------------------------------------------------------------------------
38 CHECK(m_edmHelperSvc.retrieve());
39 CHECK(m_idHelperSvc.retrieve());
40
41 ATH_CHECK(m_segmentKeys.initialize());
42 ATH_CHECK(m_segmentSelector.retrieve(EnableTool{!m_segmentKeys.empty()}));
45
47 return StatusCode::SUCCESS;
48}
49
50//------------------------------------------------------------------------------
51StatusCode BeamBackgroundFiller::execute(const EventContext& ctx) const {
52
53 Cache cache{};
54 // find muon segments from beam background muon candidates and match them with
55 // calorimeter clusters
56 FillMatchMatrix(ctx, cache);
57 // apply Beam Background Identifiaction Methods
58 SegmentMethod(cache);
59 OneSidedMethod(cache);
60 TwoSidedMethod(cache);
61 ClusterShapeMethod(cache);
62 // identify fake jets
63 FindFakeJets(ctx, cache);
64
65 // fill the results into BeamBackgroundData
67 ATH_CHECK(writeHandle.record(std::make_unique<BeamBackgroundData>()));
68 FillBeamBackgroundData(writeHandle, cache);
69
70 return StatusCode::SUCCESS;
71}
72
73//------------------------------------------------------------------------------
80void BeamBackgroundFiller::FillMatchMatrix(const EventContext& ctx,
81 Cache& cache) const {
82 //
83
85 // select only the CSC segments with the global direction parallel to the
86 // beam pipe
87 SG::ReadHandle<Trk::SegmentCollection> ncbSegmentHandle(key, ctx);
88 if(!ncbSegmentHandle.isPresent()) {
89 throw std::runtime_error("Could not load the " + key.key() + " segment container");
90 }
91 unsigned int ncbCounter = 0;
92 for (const Trk::Segment *ncbSegment : *ncbSegmentHandle) {
93 ++ncbCounter;
94 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(ncbSegment);
95
96 const Identifier id = m_edmHelperSvc->chamberId(*seg);
97 if (!id.is_valid()|| !m_idHelperSvc->isMuon(id)) {
98 ATH_MSG_WARNING("Found a muon segment in the container which pretends not to be a muon segment..");
99 continue;
100 }
101 Muon::MuonStationIndex::StIndex stIndex = m_idHelperSvc->stationIndex(id);
103 if (stIndex != Muon::MuonStationIndex::StIndex::EI) {
104 ATH_MSG_VERBOSE("Segment "<<m_idHelperSvc->toStringChamber(id)<<" is not in EI");
105 continue;
106 }
107 const Amg::Vector3D& globalDir = seg->globalDirection();
108 if (std::abs(globalDir.theta()) < m_thetaCutNCB) {
109 continue;
110 }
111 constexpr int highestSegQual = 3;
112 if (!m_segmentSelector->select(*seg,false, highestSegQual)) {
113 continue;
114 }
115 ElementLink<Trk::SegmentCollection> segLink{*ncbSegmentHandle, ncbCounter - 1};
116 cache.m_indexSeg.push_back(segLink);
117 }
118 }
119
120 cache.m_resultSeg.assign(cache.m_indexSeg.size(), 0);
121
122 // find matching clusters
124 if (!caloClusterContainerReadHandle.isPresent()){
125 throw std::runtime_error("Failed to load the calorimeter cluster container");
126 }
127 ATH_MSG_DEBUG(m_caloClusterContainerReadHandleKey<< " retrieved from StoreGate");
128
129 constexpr std::array<CaloSampling::CaloSample, 24> caloLayers{CaloSampling::CaloSample::PreSamplerB,
130 CaloSampling::CaloSample::EMB1, CaloSampling::CaloSample::EMB2, CaloSampling::CaloSample::EMB3,
131 CaloSampling::CaloSample::PreSamplerE,
132 CaloSampling::CaloSample::EME1, CaloSampling::CaloSample::EME2, CaloSampling::CaloSample::EME3,
133 CaloSampling::CaloSample::FCAL0,
134
135 CaloSampling::CaloSample::HEC0, CaloSampling::CaloSample::HEC1, CaloSampling::CaloSample::HEC2, CaloSampling::CaloSample::HEC3,
136
137 CaloSampling::CaloSample::TileBar0, CaloSampling::CaloSample::TileBar1, CaloSampling::CaloSample::TileBar2,
138 CaloSampling::CaloSample::TileGap1, CaloSampling::CaloSample::TileGap2, CaloSampling::CaloSample::TileGap3,
139 CaloSampling::CaloSample::TileExt0, CaloSampling::CaloSample::TileExt1, CaloSampling::CaloSample::TileExt2, CaloSampling::CaloSample::FCAL1,
140 CaloSampling::CaloSample::FCAL2};
141
142 unsigned int caloClusterCounter = 0;
143 for (const xAOD::CaloCluster* thisCaloCluster : *caloClusterContainerReadHandle) {
144 ++caloClusterCounter;
145 double eClus{0.};
146 for (auto lay : caloLayers){
147 eClus +=thisCaloCluster->eSample(lay);
148 }
149 // ignore low energy clusters
150 if (eClus < m_clusEnergyCut){
151 ATH_MSG_VERBOSE("Cluster with energy "<<eClus<<" is below threshold "<<m_clusEnergyCut);
152 continue;
153 }
154 double rClus{0.};
155 if (!thisCaloCluster->retrieveMoment(xAOD::CaloCluster_v1::CENTER_MAG, rClus)) {
156 ATH_MSG_DEBUG("Failed to retrieve the CENTER_MAG moment");
157 continue;
158 }
159 rClus = rClus / std::cosh(thisCaloCluster->eta());
160
161 // remove clusters at low radius (outside the CSC acceptance)
162 if (rClus < m_clusRadiusLow || rClus > m_clusRadiusHigh) {
163 ATH_MSG_VERBOSE("Radius cut not passed "<<rClus<<" needs to be in "
165 continue;
166 }
167 const double phiClus = thisCaloCluster->phi();
168
169
170 std::vector<int> matchedSegmentsPerCluster(cache.m_indexSeg.size(), 0);
171 bool matched{false};
172
173 for (unsigned int j = 0; j < cache.m_indexSeg.size(); j++) {
174 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[j]));
175
176 const Amg::Vector3D& globalPos = seg->globalPosition();
177 const double phiSeg = globalPos.phi();
178
180 if (P4Helpers::deltaPhi(phiClus, phiSeg) < std::abs(m_cutDphiClusSeg)) {
181 ATH_MSG_VERBOSE("Delta phi "<<P4Helpers::deltaPhi(phiClus, phiSeg)
182 <<" exceeds maximum cut "<<m_cutDphiClusSeg
183 <<"Segment: "<<Amg::toString(globalPos)<<", phi: "<<globalPos.phi()
184 <<" --- Cluster: "<<phiClus);
185 continue;
186 }
187
188 const double rSeg = globalPos.perp();
189 // match in radius
190 if (std::abs(rClus - rSeg) > m_cutDradClusSeg) {
191 ATH_MSG_VERBOSE("Radial difference "<<std::abs(rClus - rSeg)<<" exceeds maximum cut "<<m_cutDradClusSeg
192 <<"Segment: "<<Amg::toString(globalPos)<<", phi: "<<globalPos.perp()
193 <<" --- Cluster: "<<rClus);
194 continue;
195 }
196 matchedSegmentsPerCluster[j] = 1;
197 matched = true;
198 cache.m_resultSeg[j] |= BeamBackgroundData::Matched;
199 }
200
201 if (!matched) {
202 ATH_MSG_VERBOSE("Calo cluster does not match with segment");
203 continue;
204 }
206 clusLink.toIndexedElement(*caloClusterContainerReadHandle, caloClusterCounter - 1);
207 cache.m_indexClus.push_back(std::move(clusLink));
208 cache.m_matchMatrix.push_back(std::move(matchedSegmentsPerCluster));
209 ++cache.m_numMatched;
210 }
211
212 cache.m_resultClus.assign(cache.m_indexClus.size(), 1);
213}
214
215
216
218 double time{0.};
219 unsigned int nMeas{0};
220 for (const Trk::MeasurementBase* meas : pMuonSegment.containedMeasurements()) {
221 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(meas);
222 if (!rot) {
223 continue;
224 }
225 ++nMeas;
226 const Trk::PrepRawData* prd = rot->prepRawData();
228 const Muon::MMPrepData* mmPrd = static_cast<const Muon::MMPrepData*>(prd);
229 time += mmPrd->time();
230 } else if (prd->type(Trk::PrepRawDataType::sTgcPrepData)) {
231 const Muon::sTgcPrepData* sTgcPrd = static_cast<const Muon::sTgcPrepData*>(prd);
232 time += sTgcPrd->time();
233 } else if (prd->type(Trk::PrepRawDataType::MdtPrepData)) {
234 const Muon::MdtPrepData* mdtPrd = static_cast<const Muon::MdtPrepData*>(prd);
235 constexpr double tdcBinSize = 0.78125; //25/32; exact number: (1000.0/40.079)/32.0
236 time += tdcBinSize * mdtPrd->tdc();
237 } else if (prd->type(Trk::PrepRawDataType::TgcPrepData)) {
239 --nMeas;
240 } else if (prd->type(Trk::PrepRawDataType::CscPrepData)) {
241 const Muon::CscPrepData* cscPrd = static_cast<const Muon::CscPrepData*>(prd);
242 time += cscPrd->time();
243 } else {
244 ATH_MSG_WARNING("You can't have "<<m_idHelperSvc->toString(prd->identify())<<" in a EI segment.");
245 --nMeas;
246 }
247
248 }
249 return time / std::max(nMeas, 1u);
250}
251//------------------------------------------------------------------------------
264 for (unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size(); ++segIndex) {
265
266 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[segIndex]));
267
268 const Amg::Vector3D& globalPos = seg->globalPosition();
269 double zSeg = globalPos.z();
270
272 if (zSeg < 0.) {
273 continue;
274 }
275
276
277 double tSeg = GetSegmentTime(*seg);
278 cache.m_numSegment++;
279 cache.m_resultSeg[segIndex] |= BeamBackgroundData::Segment;
280
281 // muon segment: in-time (1), early (2), ambiguous (0)
282 int timeStatus = 0;
283 double inTime = -(-std::abs(zSeg) + globalPos.mag()) * inv_c;
284 double early = -(std::abs(zSeg) + globalPos.mag()) * inv_c;
285 if (std::abs(tSeg - inTime) < m_cutMuonTime)
286 timeStatus = 1;
287 if (std::abs(tSeg - early) < m_cutMuonTime)
288 timeStatus = 2;
289
290 if (timeStatus == 2) {
291 cache.m_numSegmentEarly++;
292 cache.m_resultSeg[segIndex] |= BeamBackgroundData::SegmentEarly;
293 }
294
295
296
297 unsigned int segIndexA = segIndex;
298
299 double tSegA = tSeg;
300 int timeStatusA = timeStatus;
301
302 double phiSegA = globalPos.phi();
303
304 for (unsigned int segIndexC = 0; segIndexC < cache.m_indexSeg.size(); segIndexC++) {
305
306 const Muon::MuonSegment* segC = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[segIndexC]));
307
308 const Amg::Vector3D& globalPos = segC->globalPosition();
309 double zSegC = globalPos.z();
310
311 // take only the segments on side C (z < 0)
312 if (zSegC > 0.) {
313 continue;
314 }
315 double tSegC = GetSegmentTime(*segC);
316
317
318
319 // muon segment: in-time (1), early (2), ambiguous (0)
320 int timeStatusC = 0;
321 double inTime = -(-std::abs(zSegC) + globalPos.mag()) * inv_c;
322 double early = -(std::abs(zSegC) + globalPos.mag()) * inv_c;
323 if (std::abs(tSegC - inTime) < m_cutMuonTime)
324 timeStatusC = 1;
325 if (std::abs(tSegC - early) < m_cutMuonTime)
326 timeStatusC = 2;
327
328 double phiSegC = globalPos.phi();
329
330 // match in phi
331 if (std::abs(P4Helpers::deltaPhi(phiSegA, phiSegC)) > m_cutDphiSegAC) {
332 continue;
333 }
334 cache.m_numSegmentACNoTime++;
335 cache.m_resultSeg[segIndexA] |= BeamBackgroundData::SegmentACNoTime;
336 cache.m_resultSeg[segIndexC] |= BeamBackgroundData::SegmentACNoTime;
337
338 if (timeStatusA == 0 || timeStatusC == 0)
339 continue;
340
341 // check the time difference
342 if (std::abs(tSegA - tSegC) > m_cutTimeDiffAC) {
343 cache.m_numSegmentAC++;
344 cache.m_resultSeg[segIndexA] |= BeamBackgroundData::SegmentAC;
345 cache.m_resultSeg[segIndexC] |= BeamBackgroundData::SegmentAC;
346 }
347 }
348 }
349}
350
351//------------------------------------------------------------------------------
363 //
364 for (unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
365 clusIndex++) {
366
367 const xAOD::CaloCluster* clus = *(cache.m_indexClus[clusIndex]);
368
369 double rClus(0.);
371 continue;
372 }
373 rClus = rClus / std::cosh(clus->eta());
374 double zClus = rClus * std::sinh(clus->eta());
375 double tClus = clus->time();
376
377 // calculate expected cluster time
378 double expectedClusterTimeAC = -(zClus + std::hypot(rClus, zClus)) * inv_c;
379 double expectedClusterTimeCA = -(-zClus + std::hypot(rClus, zClus)) * inv_c;
380
381 for (unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size(); segIndex++) {
382
383 if (!(cache.m_matchMatrix[clusIndex][segIndex] & BeamBackgroundData::Matched)){
384 continue;
385 }
386 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[segIndex]));
387
388 const Amg::Vector3D& globalPos = seg->globalPosition();
389 double zSeg = globalPos.z();
390
391 double tSeg = GetSegmentTime(*seg);
392
393 // muon segment: in-time (1), early (2), ambiguous (0)
394 int timeStatus = 0;
395 double inTime = -(-std::abs(zSeg) + globalPos.mag()) * inv_c;
396 double early = -(std::abs(zSeg) + globalPos.mag()) * inv_c;
397 if (std::abs(tSeg - inTime) < m_cutMuonTime)
398 timeStatus = 1;
399 if (std::abs(tSeg - early) < m_cutMuonTime)
400 timeStatus = 2;
401
402 // reconstruct beam background direction: A->C (1), C->A (-1)
403 int direction = 0;
404 if ((zSeg > 0 && timeStatus == 2) || (zSeg < 0 && timeStatus == 1))
405 direction = 1;
406 if ((zSeg > 0 && timeStatus == 1) || (zSeg < 0 && timeStatus == 2))
407 direction = -1;
408
409 // check the cluster time without the beam background direction
410 // information
411 if (std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime ||
412 std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime) {
413 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::NoTimeLoose;
414 }
415 if ((std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime && -tClus > m_cutClusTime) ||
416 (std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime && -tClus > m_cutClusTime)) {
417 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::NoTimeMedium;
418 }
419 if ((std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime && -tClus > 2. * m_cutClusTime) ||
420 (std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime && -tClus > 2. * m_cutClusTime)) {
421 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::NoTimeTight;
422 }
423
424 // check the cluster time with the beam background direction information
425 if (direction == 1) {
426 if (std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime) {
427 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedLoose;
428 }
429 if (std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime && -tClus > m_cutClusTime) {
430 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedMedium;
431 }
432 if (std::abs(tClus - expectedClusterTimeAC) < m_cutClusTime && -tClus > 2. * m_cutClusTime) {
433 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedTight;
434 }
435 } else if (direction == -1) {
436 if (std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime) {
437 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedLoose;
438 }
439 if (std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime && -tClus > m_cutClusTime) {
440 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedMedium;
441 }
442 if (std::abs(tClus - expectedClusterTimeCA) < m_cutClusTime && -tClus > 2. * m_cutClusTime) {
443 cache.m_matchMatrix[clusIndex][segIndex] |= BeamBackgroundData::OneSidedTight;
444 }
445 }
446
447 cache.m_resultClus[clusIndex] |= cache.m_matchMatrix[clusIndex][segIndex];
448 cache.m_resultSeg[segIndex] |= cache.m_matchMatrix[clusIndex][segIndex];
449 }
450
451 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::NoTimeLoose)
452 cache.m_numNoTimeLoose++;
453 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::NoTimeMedium)
454 cache.m_numNoTimeMedium++;
455 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::NoTimeTight)
456 cache.m_numNoTimeTight++;
457
458 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::OneSidedLoose)
459 cache.m_numOneSidedLoose++;
460 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::OneSidedMedium)
461 cache.m_numOneSidedMedium++;
462 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::OneSidedTight)
463 cache.m_numOneSidedTight++;
464 }
465}
466
467//------------------------------------------------------------------------------
477
478
479 for (unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size(); clusIndex++) {
480
481 for (unsigned int segIndexA = 0; segIndexA < cache.m_indexSeg.size(); segIndexA++) {
482
483 if (!(cache.m_matchMatrix[clusIndex][segIndexA] & BeamBackgroundData::Matched))
484 continue;
485
486 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[segIndexA]));
487
488 const Amg::Vector3D& globalPos = seg->globalPosition();
489 double zSegA = globalPos.z();
490 // take only the segments on side A (z > 0)
491 if (zSegA < 0.) {
492 continue;
493 }
494 double tSegA = GetSegmentTime(*seg);
495
496 // muon segment: in-time (1), early (2), ambiguous (0)
497 int timeStatusA = 0;
498 double inTime = -(-std::abs(zSegA) + globalPos.mag()) * inv_c;
499 double early = -(std::abs(zSegA) + globalPos.mag()) * inv_c;
500 if (std::abs(tSegA - inTime) < m_cutMuonTime)
501 timeStatusA = 1;
502 if (std::abs(tSegA - early) < m_cutMuonTime)
503 timeStatusA = 2;
504
505
506 for (unsigned int segIndexC = 0; segIndexC < cache.m_indexSeg.size(); segIndexC++) {
507
508 if (!(cache.m_matchMatrix[clusIndex][segIndexC] & BeamBackgroundData::Matched)){
509 continue;
510 }
511 const Muon::MuonSegment* seg = static_cast<const Muon::MuonSegment*>(*(cache.m_indexSeg[segIndexC]));
512
513 const Amg::Vector3D& globalPos = seg->globalPosition();
514 double zSegC = globalPos.z();
515
516 // take only the segments on side C (z < 0)
517 if (zSegC > 0.) {
518 continue;
519 }
520
521 double tSegC = GetSegmentTime(*seg);
522
523 // muon segment: in-time (1), early (2), ambiguous (0)
524 int timeStatusC = 0;
525 double inTime = -(-std::abs(zSegC) + globalPos.mag()) * inv_c;
526 double early = -(std::abs(zSegC) + globalPos.mag()) * inv_c;
527 if (std::abs(tSegC - inTime) < m_cutMuonTime)
528 timeStatusC = 1;
529 if (std::abs(tSegC - early) < m_cutMuonTime)
530 timeStatusC = 2;
531
532
533
534 cache.m_matchMatrix[clusIndex][segIndexA] |=BeamBackgroundData::TwoSidedNoTime;
535 cache.m_matchMatrix[clusIndex][segIndexC] |=BeamBackgroundData::TwoSidedNoTime;
536 cache.m_resultSeg[segIndexA] |= cache.m_matchMatrix[clusIndex][segIndexA];
537 cache.m_resultSeg[segIndexC] |= cache.m_matchMatrix[clusIndex][segIndexC];
538
539 if (timeStatusA == 0 || timeStatusC == 0)
540 continue;
541
542 // check the time difference
543 if (std::abs(tSegA - tSegC) > m_cutTimeDiffAC) {
544 cache.m_matchMatrix[clusIndex][segIndexA] |= BeamBackgroundData::TwoSided;
545 cache.m_matchMatrix[clusIndex][segIndexC] |= BeamBackgroundData::TwoSided;
546 cache.m_resultSeg[segIndexA] |= cache.m_matchMatrix[clusIndex][segIndexA];
547 cache.m_resultSeg[segIndexC] |= cache.m_matchMatrix[clusIndex][segIndexC];
548
549 // direction of beam background
550 if (timeStatusA == 2)
551 cache.m_direction++; // A->C
552 if (timeStatusC == 2)
553 cache.m_direction--; // C->A
554 }
555 }
556
557 cache.m_resultClus[clusIndex] |= cache.m_matchMatrix[clusIndex][segIndexA];
558 }
559
560 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::TwoSidedNoTime)
561 cache.m_numTwoSidedNoTime++;
562 if (cache.m_resultClus[clusIndex] & BeamBackgroundData::TwoSided)
563 cache.m_numTwoSided++;
564 }
565}
566
567//------------------------------------------------------------------------------
576 cache.m_numClusterShape = 0;
577 cache.m_drdzClus.clear();
578
579 for (unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
580 clusIndex++) {
581
582 const xAOD::CaloCluster* clus = *(cache.m_indexClus[clusIndex]);
583
584 double rClus(0.);
586 rClus = 0;
587 rClus = rClus / cosh(clus->eta());
588 double zClus = rClus * sinh(clus->eta());
589
590 // calculate dr/dz
591 double dr = 0.;
592 double dz = 0.;
593 double drdz = -1.;
594 int nCell = 0;
595
596 if (clus->getCellLinks() != nullptr) {
599
600 for (; firstCell != lastCell; ++firstCell) {
601 const CaloCell* cell = *firstCell;
602
603 if (cell->time() == 0.)
604 continue;
605 if (cell->energy() < 100.)
606 continue;
607 nCell++;
608
609 // double rCell = sqrt(cell->x()*cell->x() + cell->y()*cell->y());
610 // double zCell = cell->z();
611 const CaloDetDescrElement* dde = cell->caloDDE();
612 const double rCell = dde->r();
613 const double zCell = dde->z();
614 dr = dr + (rCell - rClus) * (rCell - rClus);
615 dz = dz + (zCell - zClus) * (zCell - zClus);
616 }
617 }
618
619 if (nCell) {
620 dr = sqrt(dr / nCell);
621 dz = sqrt(dz / nCell);
622 if (dz > 0.)
623 drdz = dr / dz;
624 }
625
626 cache.m_drdzClus.push_back(drdz);
627
628 // check dr/dz
629 if (drdz < 0.)
630 continue;
631 if (drdz < m_cutDrdz) {
632 for (unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size();
633 segIndex++) {
634 if (!(cache.m_matchMatrix[clusIndex][segIndex] & 1))
635 continue;
636 cache.m_matchMatrix[clusIndex][segIndex] =
637 cache.m_matchMatrix[clusIndex][segIndex] |
639 cache.m_resultSeg[segIndex] = cache.m_resultSeg[segIndex] |
640 cache.m_matchMatrix[clusIndex][segIndex];
641 }
642 cache.m_resultClus[clusIndex] =
643 cache.m_resultClus[clusIndex] | BeamBackgroundData::ClusterShape;
644 cache.m_numClusterShape++;
645 }
646 }
647}
648
649//------------------------------------------------------------------------------
656void BeamBackgroundFiller::FindFakeJets(const EventContext& ctx,
657 Cache& cache) const {
658 cache.m_numJet = 0;
659 cache.m_indexJet.clear();
660 cache.m_resultJet.clear();
661
662 // find the jet that contains this cluster
663 SG::ReadHandle<xAOD::JetContainer> jetContainerReadHandle(
665
666 if (!jetContainerReadHandle.isValid()) {
667 ATH_MSG_WARNING("Invalid ReadHandle to JetContainer with name: "
669 } else {
670 ATH_MSG_DEBUG(m_jetContainerReadHandleKey << " retrieved from StoreGate");
671
672 unsigned int jetCounter = 0;
673 for (const auto *thisJet : *jetContainerReadHandle) {
674 bool isFakeJet = false;
675 int resultJet = 0;
676
677 xAOD::JetConstituentVector vec = thisJet->getConstituents();
680
681 for (; constIt != constItE; ++constIt) {
682 if (constIt->type() != xAOD::Type::CaloCluster)
683 continue;
684 const xAOD::CaloCluster* jetConst =
685 dynamic_cast<const xAOD::CaloCluster*>(constIt->rawConstituent());
686
687 for (unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
688 clusIndex++) {
689 const xAOD::CaloCluster* clus = *(cache.m_indexClus[clusIndex]);
690
691 if (jetConst == clus) {
692 isFakeJet = true;
693 resultJet = resultJet | cache.m_resultClus[clusIndex];
694 }
695 }
696 }
697
698 if (isFakeJet) {
700 jetLink.toIndexedElement(*jetContainerReadHandle, jetCounter);
701 cache.m_indexJet.push_back(jetLink);
702 cache.m_resultJet.push_back(resultJet);
703 cache.m_numJet++;
704 }
705 jetCounter++;
706 }
707 }
708}
709
710//------------------------------------------------------------------------------
716 Cache& cache) const{
717
718 writeHandle->SetNumSegment(cache.m_numSegment);
719 writeHandle->SetNumSegmentEarly(cache.m_numSegmentEarly);
720 writeHandle->SetNumSegmentACNoTime(cache.m_numSegmentACNoTime);
721 writeHandle->SetNumSegmentAC(cache.m_numSegmentAC);
722 writeHandle->SetNumMatched(cache.m_numMatched);
723 writeHandle->SetNumNoTimeLoose(cache.m_numNoTimeLoose);
724 writeHandle->SetNumNoTimeMedium(cache.m_numNoTimeMedium);
725 writeHandle->SetNumNoTimeTight(cache.m_numNoTimeTight);
726 writeHandle->SetNumOneSidedLoose(cache.m_numOneSidedLoose);
727 writeHandle->SetNumOneSidedMedium(cache.m_numOneSidedMedium);
728 writeHandle->SetNumOneSidedTight(cache.m_numOneSidedTight);
729 writeHandle->SetNumTwoSidedNoTime(cache.m_numTwoSidedNoTime);
730 writeHandle->SetNumTwoSided(cache.m_numTwoSided);
731 writeHandle->SetNumClusterShape(cache.m_numClusterShape);
732 writeHandle->SetNumJet(cache.m_numJet);
733
734 int decision = 0;
735 for (unsigned int i = 0; i < cache.m_indexSeg.size(); i++) {
736 decision |= cache.m_resultSeg[i];
737 }
738 for (unsigned int i = 0; i < cache.m_indexClus.size(); i++) {
739 decision |= cache.m_resultClus[i];
740 }
741 writeHandle->SetDecision(decision);
742
743 writeHandle->SetDirection(cache.m_direction);
744
745 writeHandle->FillIndexSeg(cache.m_indexSeg);
746 writeHandle->FillResultSeg(&cache.m_resultSeg);
747 writeHandle->FillIndexClus(cache.m_indexClus);
748 writeHandle->FillMatchMatrix(&cache.m_matchMatrix);
749
750 writeHandle->FillResultClus(&cache.m_resultClus);
751 writeHandle->FillIndexJet(cache.m_indexJet);
752 writeHandle->FillDrdzClus(&cache.m_drdzClus);
753
754 writeHandle->FillIndexJet(cache.m_indexJet);
755 writeHandle->FillResultJet(&cache.m_resultJet);
756
757 ATH_MSG_DEBUG("parallel segments "
758 << cache.m_numSegment << " " << cache.m_numSegmentEarly << " "
759 << cache.m_numSegmentACNoTime << " " << cache.m_numSegmentAC);
760
761 ATH_MSG_DEBUG("matched clusters "
762 << cache.m_numMatched << " " << cache.m_numNoTimeLoose << " "
763 << cache.m_numNoTimeMedium << " " << cache.m_numNoTimeTight
764 << " " << cache.m_numOneSidedLoose << " "
765 << cache.m_numOneSidedMedium << " " << cache.m_numOneSidedTight
766 << " " << cache.m_numTwoSidedNoTime << " "
767 << cache.m_numTwoSided << " " << cache.m_numClusterShape);
768}
769
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
This file defines helper classes to deal with jet constituents.
An algorithm that can be simultaneously executed in multiple threads.
Gaudi::Property< double > m_thetaCutNCB
Inclanation cut between the segment position and its direction.
SG::WriteHandleKey< BeamBackgroundData > m_beamBackgroundDataWriteHandleKey
Gaudi::Property< double > m_cutDradClusSeg
void SegmentMethod(Cache &cache) const
This function looks at the segments found by the FillMatchMatrix function.
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainerReadHandleKey
ReadHandleKey for JetContainer.
ToolHandle< Muon::IMuonSegmentSelectionTool > m_segmentSelector
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
virtual StatusCode initialize() override
void FindFakeJets(const EventContext &ctx, Cache &cache) const
This function checks whether the matched clusters are contained in any jets.
BeamBackgroundFiller(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKeyArray< Trk::SegmentCollection > m_segmentKeys
ReadHandleKey for Trk::SegmentCollection from CSC.
Gaudi::Property< double > m_cutDrdz
Gaudi::Property< double > m_clusRadiusLow
Gaudi::Property< double > m_cutTimeDiffAC
Gaudi::Property< double > m_cutDphiClusSeg
void ClusterShapeMethod(Cache &cache) const
This function is the implementation of the "Cluster-Shape Method".
void FillBeamBackgroundData(SG::WriteHandle< BeamBackgroundData > &beamBackgroundDataWriteHandle, Cache &cache) const
This function stores all the results in BeamBackgroundData.
void FillMatchMatrix(const EventContext &ctx, Cache &cache) const
This function selects the muon segments with the direction parallel to the beam pipe and calorimeter ...
void OneSidedMethod(Cache &cache) const
This function is the implementation of the "No-Time Method" and the "One-Sided Method".
Gaudi::Property< double > m_clusEnergyCut
Minimum cut on the cluster energy to be considered.
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_caloClusterContainerReadHandleKey
ReadHandleKey for CaloClusterContainer.
Gaudi::Property< double > m_cutDphiSegAC
Gaudi::Property< double > m_clusRadiusHigh
Gaudi::Property< double > m_cutClusTime
double GetSegmentTime(const Muon::MuonSegment &pMuonSegment) const
Gaudi::Property< double > m_cutMuonTime
virtual StatusCode execute(const EventContext &ctx) const override
void TwoSidedMethod(Cache &cache) const
This function is the implementation of the "Two-Sided No-Time Method" and the "Two-Sided Method" that...
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
This class groups all DetDescr information related to a CaloCell.
Class representing clusters from the CSC.
Definition CscPrepData.h:39
double time() const
Returns the time.
Class to represent MM measurements.
Definition MMPrepData.h:22
short int time() const
Returns the time (in ns).
Definition MMPrepData.h:222
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
int tdc() const
Returns the TDC (typically range is 0 to 2500).
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
Class to represent sTgc measurements.
short int time() const
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
bool isPresent() const
Is the referenced object present in SG?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
This class is the pure abstract base class for all fittable tracking measurements.
Identifier identify() const
return the identifier
virtual bool type(PrepRawDataType type) const
Interface method checking the type.
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.
Base class for all TrackSegment implementations, extends the common MeasurementBase.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version).
flt_t time() const
Access cluster time.
virtual double eta() const
The pseudorapidity ( ) of the particle.
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version).
const_cell_iterator cell_end() const
@ CENTER_MAG
Cluster Centroid ( ).
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version).
A vector of jet constituents at the scale used during jet finding.
Type::ObjectType type() const
The full 4-momentum of the particle.
const IParticle * rawConstituent() const
Access the real underlying IParticle.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 3, 1 > Vector3D
StIndex
enum to classify the different station layers in the muon spectrometer
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition P4Helpers.h:34
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.