8#include "CaloGeoHelpers/CaloSampling.h"
16#include "GaudiKernel/PhysicalConstants.h"
27 constexpr double inv_c = 1./Gaudi::Units::c_light;
32 ISvcLocator* pSvcLocator)
47 return StatusCode::SUCCESS;
70 return StatusCode::SUCCESS;
89 throw std::runtime_error(
"Could not load the " + key.key() +
" segment container");
91 unsigned int ncbCounter = 0;
92 for (
const Trk::Segment *ncbSegment : *ncbSegmentHandle) {
98 ATH_MSG_WARNING(
"Found a muon segment in the container which pretends not to be a muon segment..");
103 if (stIndex != Muon::MuonStationIndex::StIndex::EI) {
111 constexpr int highestSegQual = 3;
116 cache.m_indexSeg.push_back(segLink);
120 cache.m_resultSeg.assign(cache.m_indexSeg.size(), 0);
124 if (!caloClusterContainerReadHandle.
isPresent()){
125 throw std::runtime_error(
"Failed to load the calorimeter cluster container");
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,
135 CaloSampling::CaloSample::HEC0, CaloSampling::CaloSample::HEC1, CaloSampling::CaloSample::HEC2, CaloSampling::CaloSample::HEC3,
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};
142 unsigned int caloClusterCounter = 0;
143 for (
const xAOD::CaloCluster* thisCaloCluster : *caloClusterContainerReadHandle) {
144 ++caloClusterCounter;
146 for (
auto lay : caloLayers){
147 eClus +=thisCaloCluster->eSample(lay);
159 rClus = rClus / std::cosh(thisCaloCluster->eta());
167 const double phiClus = thisCaloCluster->phi();
170 std::vector<int> matchedSegmentsPerCluster(cache.m_indexSeg.size(), 0);
173 for (
unsigned int j = 0; j < cache.m_indexSeg.size(); j++) {
177 const double phiSeg = globalPos.phi();
183 <<
"Segment: "<<
Amg::toString(globalPos)<<
", phi: "<<globalPos.phi()
184 <<
" --- Cluster: "<<phiClus);
188 const double rSeg = globalPos.perp();
192 <<
"Segment: "<<
Amg::toString(globalPos)<<
", phi: "<<globalPos.perp()
193 <<
" --- Cluster: "<<rClus);
196 matchedSegmentsPerCluster[j] = 1;
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;
212 cache.m_resultClus.assign(cache.m_indexClus.size(), 1);
219 unsigned int nMeas{0};
229 time += mmPrd->
time();
232 time += sTgcPrd->
time();
235 constexpr double tdcBinSize = 0.78125;
236 time += tdcBinSize * mdtPrd->
tdc();
242 time += cscPrd->
time();
249 return time / std::max(nMeas, 1u);
264 for (
unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size(); ++segIndex) {
269 double zSeg = globalPos.z();
278 cache.m_numSegment++;
283 double inTime = -(-std::abs(zSeg) + globalPos.mag()) * inv_c;
284 double early = -(std::abs(zSeg) + globalPos.mag()) * inv_c;
290 if (timeStatus == 2) {
291 cache.m_numSegmentEarly++;
297 unsigned int segIndexA = segIndex;
300 int timeStatusA = timeStatus;
302 double phiSegA = globalPos.phi();
304 for (
unsigned int segIndexC = 0; segIndexC < cache.m_indexSeg.size(); segIndexC++) {
309 double zSegC = globalPos.z();
321 double inTime = -(-std::abs(zSegC) + globalPos.mag()) * inv_c;
322 double early = -(std::abs(zSegC) + globalPos.mag()) * inv_c;
328 double phiSegC = globalPos.phi();
334 cache.m_numSegmentACNoTime++;
338 if (timeStatusA == 0 || timeStatusC == 0)
343 cache.m_numSegmentAC++;
364 for (
unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
373 rClus = rClus / std::cosh(clus->
eta());
374 double zClus = rClus * std::sinh(clus->
eta());
375 double tClus = clus->
time();
378 double expectedClusterTimeAC = -(zClus + std::hypot(rClus, zClus)) * inv_c;
379 double expectedClusterTimeCA = -(-zClus + std::hypot(rClus, zClus)) * inv_c;
381 for (
unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size(); segIndex++) {
389 double zSeg = globalPos.z();
395 double inTime = -(-std::abs(zSeg) + globalPos.mag()) * inv_c;
396 double early = -(std::abs(zSeg) + globalPos.mag()) * inv_c;
404 if ((zSeg > 0 && timeStatus == 2) || (zSeg < 0 && timeStatus == 1))
406 if ((zSeg > 0 && timeStatus == 1) || (zSeg < 0 && timeStatus == 2))
411 if (std::abs(tClus - expectedClusterTimeAC) <
m_cutClusTime ||
425 if (direction == 1) {
426 if (std::abs(tClus - expectedClusterTimeAC) <
m_cutClusTime) {
435 }
else if (direction == -1) {
436 if (std::abs(tClus - expectedClusterTimeCA) <
m_cutClusTime) {
447 cache.m_resultClus[clusIndex] |= cache.m_matchMatrix[clusIndex][segIndex];
448 cache.m_resultSeg[segIndex] |= cache.m_matchMatrix[clusIndex][segIndex];
452 cache.m_numNoTimeLoose++;
454 cache.m_numNoTimeMedium++;
456 cache.m_numNoTimeTight++;
459 cache.m_numOneSidedLoose++;
461 cache.m_numOneSidedMedium++;
463 cache.m_numOneSidedTight++;
479 for (
unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size(); clusIndex++) {
481 for (
unsigned int segIndexA = 0; segIndexA < cache.m_indexSeg.size(); segIndexA++) {
489 double zSegA = globalPos.z();
498 double inTime = -(-std::abs(zSegA) + globalPos.mag()) * inv_c;
499 double early = -(std::abs(zSegA) + globalPos.mag()) * inv_c;
506 for (
unsigned int segIndexC = 0; segIndexC < cache.m_indexSeg.size(); segIndexC++) {
514 double zSegC = globalPos.z();
525 double inTime = -(-std::abs(zSegC) + globalPos.mag()) * inv_c;
526 double early = -(std::abs(zSegC) + globalPos.mag()) * inv_c;
536 cache.m_resultSeg[segIndexA] |= cache.m_matchMatrix[clusIndex][segIndexA];
537 cache.m_resultSeg[segIndexC] |= cache.m_matchMatrix[clusIndex][segIndexC];
539 if (timeStatusA == 0 || timeStatusC == 0)
546 cache.m_resultSeg[segIndexA] |= cache.m_matchMatrix[clusIndex][segIndexA];
547 cache.m_resultSeg[segIndexC] |= cache.m_matchMatrix[clusIndex][segIndexC];
550 if (timeStatusA == 2)
552 if (timeStatusC == 2)
557 cache.m_resultClus[clusIndex] |= cache.m_matchMatrix[clusIndex][segIndexA];
561 cache.m_numTwoSidedNoTime++;
563 cache.m_numTwoSided++;
576 cache.m_numClusterShape = 0;
577 cache.m_drdzClus.clear();
579 for (
unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
587 rClus = rClus / cosh(clus->
eta());
588 double zClus = rClus * sinh(clus->
eta());
600 for (; firstCell != lastCell; ++firstCell) {
603 if (cell->time() == 0.)
605 if (cell->energy() < 100.)
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);
620 dr = sqrt(dr / nCell);
621 dz = sqrt(dz / nCell);
626 cache.m_drdzClus.push_back(drdz);
632 for (
unsigned int segIndex = 0; segIndex < cache.m_indexSeg.size();
634 if (!(cache.m_matchMatrix[clusIndex][segIndex] & 1))
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];
642 cache.m_resultClus[clusIndex] =
644 cache.m_numClusterShape++;
657 Cache& cache)
const {
659 cache.m_indexJet.clear();
660 cache.m_resultJet.clear();
666 if (!jetContainerReadHandle.
isValid()) {
672 unsigned int jetCounter = 0;
673 for (
const auto *thisJet : *jetContainerReadHandle) {
674 bool isFakeJet =
false;
681 for (; constIt != constItE; ++constIt) {
687 for (
unsigned int clusIndex = 0; clusIndex < cache.m_indexClus.size();
691 if (jetConst == clus) {
693 resultJet = resultJet | cache.m_resultClus[clusIndex];
701 cache.m_indexJet.push_back(jetLink);
702 cache.m_resultJet.push_back(resultJet);
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);
735 for (
unsigned int i = 0; i < cache.m_indexSeg.size(); i++) {
736 decision |= cache.m_resultSeg[i];
738 for (
unsigned int i = 0; i < cache.m_indexClus.size(); i++) {
739 decision |= cache.m_resultClus[i];
741 writeHandle->SetDecision(decision);
743 writeHandle->SetDirection(cache.m_direction);
745 writeHandle->FillIndexSeg(cache.m_indexSeg);
746 writeHandle->FillResultSeg(&cache.m_resultSeg);
747 writeHandle->FillIndexClus(cache.m_indexClus);
748 writeHandle->FillMatchMatrix(&cache.m_matchMatrix);
750 writeHandle->FillResultClus(&cache.m_resultClus);
751 writeHandle->FillIndexJet(cache.m_indexJet);
752 writeHandle->FillDrdzClus(&cache.m_drdzClus);
754 writeHandle->FillIndexJet(cache.m_indexJet);
755 writeHandle->FillResultJet(&cache.m_resultJet);
758 << cache.m_numSegment <<
" " << cache.m_numSegmentEarly <<
" "
759 << cache.m_numSegmentACNoTime <<
" " << cache.m_numSegmentAC);
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);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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.
This class groups all DetDescr information related to a CaloCell.
ElementLink implementation for ROOT usage.
bool toIndexedElement(BaseConstReference container, index_type index)
Set link to point to given index (slower).
Class representing clusters from the CSC.
double time() const
Returns the time.
Class to represent MM measurements.
short int time() const
Returns the time (in ns).
Class to represent measurements from the Monitored Drift Tubes.
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.
const Amg::Vector3D & globalDirection() const
global direction
virtual const Amg::Vector3D & globalPosition() const override final
global position
Class to represent sTgc measurements.
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.
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[
@ CaloCluster
The object is a calorimeter cluster.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.