ATLAS Offline Software
Loading...
Searching...
No Matches
TileClusterMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
7
9
11#include "AthenaKernel/Units.h"
12
13using Athena::Units::GeV;
14using Athena::Units::ns;
15
17
18 ATH_MSG_INFO("in initialize()");
19
21
22 using Tile = TileCalibUtils;
23 using namespace Monitored;
24
25 int nL1Triggers = getNumberOfL1Triggers();
26
27 m_clusterEtaPhiGroups = buildToolMap<int>(m_tools, "TileClusterEtaPhi", nL1Triggers);
28 m_clusterEtGroups = buildToolMap<int>(m_tools, "TileClusterEt", nL1Triggers);
29 m_clusterNCellsGroups = buildToolMap<int>(m_tools, "TileClusterNCells", nL1Triggers);
30 m_allClusterEnergyGroups = buildToolMap<int>(m_tools, "TileAllClusterEnergy", nL1Triggers);
31 m_allClusterEtaPhiGroups = buildToolMap<int>(m_tools, "TileAllClusterEtaPhi", nL1Triggers);
32 m_allClusterEneEtaPhiGroups = buildToolMap<int>(m_tools, "TileAllClusterEneEtaPhi", nL1Triggers);
33 m_nClustersGroups = buildToolMap<int>(m_tools, "TileNClusters", nL1Triggers);
34 m_clusterSumPxGroups = buildToolMap<int>(m_tools, "TileClusterSumPx", nL1Triggers);
35 m_clusterSumPyGroups = buildToolMap<int>(m_tools, "TileClusterSumPy", nL1Triggers);
36 m_clusterSumEtGroups = buildToolMap<int>(m_tools, "TileClusterSumEt", nL1Triggers);
37 m_clusterTimeDiffGroups = buildToolMap<int>(m_tools, "TileClusterTimeDiff", nL1Triggers);
38 m_clusterEneDiffGroups = buildToolMap<int>(m_tools, "TileClusterEneDiff", nL1Triggers);
39 m_clusterEtaPhiDiffGroups = buildToolMap<int>(m_tools, "TileClusterEtaPhiDiff", nL1Triggers);
41 Tile::MAX_ROS, nL1Triggers);
42
45 }
46
47 //=== TileID
48 ATH_CHECK( detStore()->retrieve(m_tileID) );
49
50 ATH_CHECK( m_cablingSvc.retrieve() );
51 m_cabling = m_cablingSvc->cablingService();
52
54}
55
56
57StatusCode TileClusterMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
58
59
60 // In case you want to measure the execution time
61 auto timer = Monitored::Timer("TIME_execute");
62
63 const xAOD::EventInfo* eventInfo = GetEventInfo(ctx).get();
64
65
66 // Indices of L1 trigger histograms to be filled in the current event
67 std::vector<int> l1TriggersIndices = getL1TriggerIndices(eventInfo->level1TriggerType());
68
70 ATH_CHECK( caloClusterContainer.isValid() );
71
72 int nClusters = caloClusterContainer->size();
73 ATH_MSG_DEBUG( "Number of clusters in the event: " << nClusters );
74
75 auto monNClusters = Monitored::Scalar<int>("nClusters", nClusters);
76 for (int l1TriggerIdx : l1TriggersIndices) {
77 fill(m_tools[m_nClustersGroups[l1TriggerIdx]], monNClusters);
78 }
79
80 if (nClusters == 0) {
81 return StatusCode::SUCCESS;
82 }
83
84 const xAOD::CaloCluster* mostEnCluster = *std::max_element(
85 caloClusterContainer->begin(), caloClusterContainer->end(),
86 [] (const xAOD::CaloCluster* cluster1, const xAOD::CaloCluster* cluster2) {
87 return cluster1->e() < cluster2->e();
88 });
89
90 const CaloCell* mostEnCell = nullptr;
91 double mostEnClusterPhi = 0.0;
92
93 if (mostEnCluster->e() > 0.0) {
94 mostEnClusterPhi = mostEnCluster->phi();
95
96 auto monEta = Monitored::Scalar<float>("eta", mostEnCluster->eta());
97 auto monPhi = Monitored::Scalar<float>("phi", mostEnCluster->phi());
98 auto monEnergy = Monitored::Scalar<float>("energy", mostEnCluster->e());
99 auto monEt = Monitored::Scalar<float>("et", mostEnCluster->et());
100 auto monNCells = Monitored::Scalar<int>("nCells", mostEnCluster->size());
101 for (int l1TriggerIdx : l1TriggersIndices) {
102 fill(m_tools[m_clusterEtaPhiGroups[l1TriggerIdx]], monEta, monPhi);
103 fill(m_tools[m_clusterEtGroups[l1TriggerIdx]], monEt);
104 fill(m_tools[m_clusterNCellsGroups[l1TriggerIdx]], monNCells);
105 }
106
107 if (mostEnCluster->getCellLinks()) {
108 mostEnCell = *std::max_element(mostEnCluster->begin(), mostEnCluster->end(),
109 [] (const CaloCell* cell1, const CaloCell* cell2) {
110 return cell1->energy() < cell2->energy();
111 });
112
113 int partition = getPartition(mostEnCell, m_tileID);
114 if (partition < PART_ALL) {
115 auto monEt = Monitored::Scalar<float>("Et", mostEnCluster->et());
116 for (int l1TriggerIdx : l1TriggersIndices) {
117 fill(m_tools[m_clusterEnergyGroups[partition][l1TriggerIdx]], monEnergy);
118 fill(m_tools[m_clusterEnergyGroups[PART_ALL][l1TriggerIdx]], monEnergy);
119 }
120 }
121 }
122 }
123
124
125 float sumPx = 0.;
126 float sumPy = 0.;
127
128 const xAOD::CaloCluster* correlCluster = nullptr;
129 double correlClusterEnergy = 0.0;
130
131 for (const xAOD::CaloCluster* cluster : *caloClusterContainer) {
132
133 float energy = cluster->e();
134 float phi = cluster->phi();
135 float pt = cluster->pt();
136 float px = pt * std::cos(phi);
137 float py = pt * std::sin(phi);
138
139 sumPx += px;
140 sumPy += py;
141
142 if (phi * mostEnClusterPhi < 0.0 // Opposite to the most energetic cluster
143 && energy > correlClusterEnergy) { // With maximum energy
144 correlCluster = cluster;
145 correlClusterEnergy = energy;
146 }
147
148 ATH_MSG_VERBOSE( "Cluster: nCells= " << cluster->size()
149 << ", Energy= " << energy
150 << ", Et()= " << cluster->et()
151 << ", Eta= " << cluster->eta()
152 << ", Phi= " << cluster->phi() );
153
154 }
155
156 auto monEta = Monitored::Collection("eta", *caloClusterContainer,
157 [] (const xAOD::CaloCluster* cluster) {
158 return cluster->eta();
159 });
160
161 auto monPhi = Monitored::Collection("phi", *caloClusterContainer,
162 [] (const xAOD::CaloCluster* cluster) {
163 return cluster->phi();
164 });
165
166 auto monEnergy = Monitored::Collection("energy", *caloClusterContainer,
167 [] (const xAOD::CaloCluster* cluster) {
168 return cluster->e();
169 });
170
171 float sumEt = sqrt(sumPx * sumPx + sumPy * sumPy);
172 auto monSumPx = Monitored::Scalar<float>("sumPx", sumPx);
173 auto monSumPy = Monitored::Scalar<float>("sumPy", sumPy);
174 auto monSumEt = Monitored::Scalar<float>("sumEt", sumEt);
175
176 for (int l1TriggerIdx : l1TriggersIndices) {
177 fill(m_tools[m_allClusterEnergyGroups[l1TriggerIdx]], monEnergy);
178 fill(m_tools[m_allClusterEtaPhiGroups[l1TriggerIdx]], monEta, monPhi);
179 fill(m_tools[m_allClusterEneEtaPhiGroups[l1TriggerIdx]], monEta, monPhi, monEnergy);
180 fill(m_tools[m_clusterSumPxGroups[l1TriggerIdx]], monSumPx);
181 fill(m_tools[m_clusterSumPyGroups[l1TriggerIdx]], monSumPy);
182 fill(m_tools[m_clusterSumEtGroups[l1TriggerIdx]], monSumEt);
183 }
184
185
186
187 if (mostEnCluster->e() > 0.0 && correlCluster) {
188
189 float energyDiff = (mostEnClusterPhi > 0.0) ? mostEnCluster->e() - correlCluster->e()
190 : correlCluster->e() - mostEnCluster->e();
191
192 float etaDelta = std::abs(correlCluster->eta()) - std::abs(mostEnCluster->eta());
193 float phiDelta = std::abs(correlCluster->phi() - mostEnCluster->phi());
194
195 auto monEta = Monitored::Scalar<float>("eta", etaDelta);
196 auto monPhi = Monitored::Scalar<float>("phi", phiDelta);
197 auto monEnergyDiff = Monitored::Scalar<float>("energyDiff", energyDiff);
198 for (int l1TriggerIdx : l1TriggersIndices) {
199 fill(m_tools[m_clusterEneDiffGroups[l1TriggerIdx]], monEnergyDiff);
200 fill(m_tools[m_clusterEtaPhiDiffGroups[l1TriggerIdx]], monEta, monPhi);
201 }
202
203 const CaloCell* correlCell = nullptr;
204 if (correlCluster->getCellLinks()) {
205 correlCell = *std::max_element( correlCluster->begin(), correlCluster->end(),
206 [] (const CaloCell* cell1, const CaloCell* cell2) {
207 return cell1->energy() < cell2->energy();
208 });
209 }
210
211 if (mostEnCell && correlCell) {
212 float timeDiff = mostEnCell->time() - correlCell->time();
213 auto monTimeDiff = Monitored::Scalar<float>("timeDiff", timeDiff);
214 for (int l1TriggerIdx : l1TriggersIndices) {
215 fill(m_tools[m_clusterTimeDiffGroups[l1TriggerIdx]], monTimeDiff);
216 }
217 }
218
219 }
220
221
224
225 std::set<Identifier> usedCells;
226 std::vector<float> partitionTime[MAX_PART];
227
228 for (const xAOD::CaloCluster* cluster : *caloClusterContainer) {
229 if (cluster->getCellLinks()) {
230 for (const CaloCell* cell : *cluster) {
231
232 Identifier id = cell->ID();
233
234 if (cell->badcell()
235 || cell->energy() < m_cellEnergyThresholdForTiming
236 || usedCells.find(id) != usedCells.end() ) continue;
237
238 usedCells.insert(id);
239
240 int sample = m_tileID->sample(id);
241 bool single_PMT_scin = (sample == TileID::SAMP_E);
242 bool single_PMT_C10 = (m_tileID->section(id) == TileID::GAPDET
243 && sample == TileID::SAMP_C
244 && (!m_cabling->C10_connected(m_tileID->module(id))) );
245
246 // distinguish cells with one or two PMTs
247 bool single_PMT = single_PMT_C10 || single_PMT_scin;
248
249 if (!single_PMT && !(sample == TileID::SAMP_D && m_tileID->tower(id) == 0)) {
250 int partition = getPartition(id, m_tileID);
251 if (partition < MAX_PART) {
252 partitionTime[partition].push_back(cell->time());
253 }
254 }
255 }
256 }
257 }
258
259 auto lumiBlock = Monitored::Scalar<int>("lumiBlock", eventInfo->lumiBlock());
260 for (int partition = 0; partition < MAX_PART; ++partition) {
261 if (!partitionTime[partition].empty()) {
262 auto monTime = Monitored::Collection("time", partitionTime[partition]);
263 fill(m_tools[m_partitionTimeLBGroups[partition]], lumiBlock, monTime);
264 fill(m_tools[m_partitionTimeLBGroups[PART_ALL]], lumiBlock, monTime);
265 }
266 }
267 }
268
269
270 fill("TileClusterMonExecuteTime", timer);
271
272 return StatusCode::SUCCESS;
273}
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
Wrapper to avoid constant divisions when using units.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
Declare a monitored scalar variable.
A monitored timer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Static class providing several utility functions and constants.
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
std::vector< std::vector< int > > m_clusterEnergyGroups
const TileCablingService * m_cabling
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_caloClusterContainerKey
Gaudi::Property< float > m_cellEnergyThresholdForTiming
Gaudi::Property< bool > m_fillTimingHistograms
virtual StatusCode initialize() override
initialize
int getNumberOfL1Triggers(void) const
Return number of L1 triggers for which histograms should be filled.
virtual StatusCode initialize() override
initialize
std::vector< int > getL1TriggerIndices(uint32_t lvl1TriggerType) const
Return indices of histograms to be filled according fired L1 trigger type.
Partition getPartition(const CaloCell *cell, const TileID *tileID) const
Return Partition for Tile cell or MAX_PART otherwise.
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
const_iterator end() const
const_iterator begin() const
virtual double eta() const
The pseudorapidity ( ) of the particle.
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
virtual double e() const
The total energy of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
uint32_t lumiBlock() const
The current event's luminosity block number.
@ Tile
The Tile calorimeter.
uint16_t level1TriggerType() const
The Level-1 trigger type.
@ Error
The sub-detector issued an error.
EventFlagErrorState errorState(EventFlagSubDet subDet) const
Get the error state for a particular sub-detector.
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
EventInfo_v1 EventInfo
Definition of the latest event info version.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
void fill(H5::Group &out_file, size_t iterations)