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