ATLAS Offline Software
Loading...
Searching...
No Matches
TileTBCellMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
11#include "TileEvent/TileCell.h"
12
15
16#include <algorithm>
17#include <string>
18
19using Athena::Units::GeV;
20
22
23 ATH_MSG_INFO("in initialize()");
25
26 ATH_CHECK( m_caloCellContainerKey.initialize() );
27
28 ATH_CHECK( m_cablingSvc.retrieve() );
29 m_cabling = m_cablingSvc->cablingService();
30
31 ATH_CHECK( detStore()->retrieve(m_tileID) );
32 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
33
34 std::vector<std::string> modules;
35 for (int fragID : m_fragIDs) {
36 int ros = fragID >> 8;
37 int drawer = fragID & 0x3F;
38 modules.push_back(TileCalibUtils::getDrawerString(ros, drawer));
40 }
41
42 std::ostringstream os;
43 if ( m_fragIDs.size() != 0) {
44 std::sort(m_fragIDs.begin(), m_fragIDs.end());
45 for (int fragID : m_fragIDs) {
46 unsigned int ros = fragID >> 8;
47 unsigned int drawer = fragID & 0xFF;
48 std::string module = TileCalibUtils::getDrawerString(ros, drawer);
49 os << " " << module << "/0x" << std::hex << fragID << std::dec;
50 }
51 } else {
52 os << "NONE";
53 }
54
55 ATH_MSG_INFO("Monitored modules/frag ID:" << os.str());
56
57
58 std::map<std::string, unsigned int> roses = { {"AUX", 0}, {"LBA", 1}, {"LBC", 2}, {"EBA", 3}, {"EBC", 4} };
59 for (const std::string& maskedModuleChannels : m_masked) {
60
61 std::string module = maskedModuleChannels.substr(0, 5);
62 std::string partition = module.substr(0, 3);
63 if (roses.count(partition) != 1) {
64 ATH_MSG_WARNING("There no such partition: " << partition << " in module: " << module
65 << " => skip because of bad format: " << maskedModuleChannels);
66 continue;
67 }
68
69 unsigned int drawer = std::stoi(module.substr(3, 2)) - 1;
70 if (drawer >= TileCalibUtils::MAX_DRAWER) {
71 ATH_MSG_WARNING("There no such drawer: " << drawer + 1 << " in module: " << module
72 << " => skip because of bad format: " << maskedModuleChannels);
73 continue;
74 }
75
76 unsigned int ros = roses.at(partition);
77 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
78
79 std::string gain = maskedModuleChannels.substr(5,7);
80 unsigned int adc = std::stoi(gain);
81
82 if (adc >= TileCalibUtils::MAX_GAIN) {
83 ATH_MSG_WARNING("There no such gain: " << gain << " => skip because of bad format: " << maskedModuleChannels);
84 continue;
85 }
86
87 std::stringstream channels(maskedModuleChannels.substr(7));
88 std::string channel;
89 while (std::getline(channels, channel, ',')) {
90 if (!channel.empty()) {
91 unsigned int chan = std::stoi(channel);
92 if (chan >= TileCalibUtils::MAX_CHAN) {
93 ATH_MSG_WARNING("There no such channel: " << chan << " in channels: " << channels.str()
94 << " => skip because of bad format: " << maskedModuleChannels);
95 continue;
96 }
97 m_maskedChannels[drawerIdx][chan] |= (1U << adc);
98 ATH_MSG_INFO(TileCalibUtils::getDrawerString(ros, drawer) << " ch" << chan << (adc ? " HG" : " LG") << ": masked!");
99 }
100 }
101
102 }
103
104 for (unsigned int ros = 0; ros < TileCalibUtils::MAX_ROS; ++ros) {
105 for (unsigned int drawer = 0; drawer < TileCalibUtils::getMaxDrawer(ros); ++drawer) {
106 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
107 m_drawerIdxToROS[drawerIdx] = ros;
108 m_drawerIdxToDrawer[drawerIdx] = drawer;
109 }
110 }
111
112 using namespace Monitored;
113
114 m_sampleEnergyGroups = buildToolMap<int>(m_tools, "TileSampleEnergy", modules);
115 m_energyGroups = buildToolMap<int>(m_tools, "TileCellEnergy", modules);
116 m_energyDiffGroups = buildToolMap<int>(m_tools, "TileCellEnergyDiff", modules);
117 m_energy2VsEnergy1Groups = buildToolMap<int>(m_tools, "TileCellEnergyLeftVsRightPMT", modules);
118 m_timeGroups = buildToolMap<int>(m_tools, "TileCellTime", modules);
119 m_timeDiffGroups = buildToolMap<int>(m_tools, "TileCellTimeDiff", modules);
120 m_time2VsTime1Groups = buildToolMap<int>(m_tools, "TileCellTimeLeftVsRightPMT", modules);
121
123 m_channelEnergyGroups = buildToolMap<int>(m_tools, "TileChannelEnergy", modules);
124 m_channelTimeGroups = buildToolMap<int>(m_tools, "TileChannelTime", modules);
125 }
126
128
129 return StatusCode::SUCCESS;
130}
131
132
133StatusCode TileTBCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
134
135 // In case you want to measure the execution time
136 auto timer = Monitored::Timer("TIME_execute");
137
138 constexpr int allSamples = TileID::SAMP_E; // To be used to keep total energy from all samples
139 constexpr int nSamples = allSamples + 1;
140
141 double sampleEnergy[TileCalibUtils::MAX_DRAWERIDX][nSamples] = {{0}};
142
144 ATH_CHECK( caloCellContainer.isValid() );
145
146 if (!caloCellContainer->empty()) {
147 for (const CaloCell* cell : *caloCellContainer) {
148 Identifier id = cell->ID();
149 if (m_tileID->is_tile(id)) {
150 const TileCell* tile_cell = dynamic_cast<const TileCell*>(cell);
151 if (!tile_cell) continue;
152
153 int drawer = 0; // The same for both channels
154 int channel1 = -1;
155 int channel2 = -1;
156
157 int ros1 = -1;
158 int ros2 = -1;
159
160 int drawerIdx1 = -1;
161 int drawerIdx2 = -1;
162
163 int gain1 = tile_cell->gain1(); // Gain of first PMT
164 int gain2 = tile_cell->gain2(); // Gain of second PMT
165
166 const CaloDetDescrElement* caloDDE = tile_cell->caloDDE();
167
168 IdentifierHash hash1 = caloDDE->onl1();
169 if (hash1 != TileHWID::NOT_VALID_HASH) {
170 HWIdentifier channel1_id = m_tileHWID->channel_id(hash1);
171 channel1 = m_tileHWID->channel(channel1_id);
172 drawer = m_tileHWID->drawer(channel1_id);
173 ros1 = m_tileHWID->ros(channel1_id);
174 drawerIdx1 = TileCalibUtils::getDrawerIdx(ros1, drawer);
175 }
176
177 IdentifierHash hash2 = caloDDE->onl2();
178 if (hash2 != TileHWID::NOT_VALID_HASH) {
179 HWIdentifier channel2_id = m_tileHWID->channel_id(hash2);
180 channel2 = m_tileHWID->channel(channel2_id);
181 drawer = m_tileHWID->drawer(channel2_id);
182 ros2 = m_tileHWID->ros(channel2_id);
183 drawerIdx2 = TileCalibUtils::getDrawerIdx(ros2, drawer);
184 }
185
186 if (!((drawerIdx1 >= 0 && m_monitoredDrawerIdx[drawerIdx1])
187 || (drawerIdx2 >= 0 && m_monitoredDrawerIdx[drawerIdx2]))) continue;
188
189 bool isOkChannel1 = (channel1 > -1 && gain1 != CaloGain::INVALIDGAIN);
190 bool isOkChannel2 = (channel2 > -1 && gain2 != CaloGain::INVALIDGAIN);
191
192 bool isMaskedChannel1 = isOkChannel1 && ((m_maskedChannels[drawerIdx1][channel1] >> gain1) & 1U);
193 bool isMaskedChannel2 = isOkChannel2 && ((m_maskedChannels[drawerIdx2][channel2] >> gain2) & 1U);
194
195 int sample = m_tileID->sample(id);
196 int tower = m_tileID->tower(id);
197
198 bool single_PMT_scin = (sample == TileID::SAMP_E);
199 std::string moduleName = TileCalibUtils::getDrawerString(ros1, drawer);
200 std::string sampleTowerSuffix = "_" + std::to_string(sample) + "_" + std::to_string(tower);
201
202 // Keep energy in GeV;
203 double energy = cell->energy() * m_scaleFactor * (1.0 / GeV);
204 double energy1 = tile_cell->ene1() * m_scaleFactor * (1.0 / GeV);
205 double energy2 = tile_cell->ene2() * m_scaleFactor * (1.0 / GeV);
206 double energyDiff = (single_PMT_scin) ? 0.0 : tile_cell->eneDiff() * (1.0 / GeV);
207 double time = cell->time();
208 double time1 = tile_cell->time1();
209 double time2 = tile_cell->time2();
210 double timeDiff = (single_PMT_scin) ? 0.0 : 2. * tile_cell->timeDiff(); // Attention! factor of 2 is needed here
211
213 if (isOkChannel1) {
214 auto monChannel1Energy = Monitored::Scalar<double>("energy_" + std::to_string(channel1), energy1);
215 fill(m_tools[m_channelEnergyGroups.at(moduleName)], monChannel1Energy);
216 }
217 if (isOkChannel2) {
218 auto monChannel2Energy = Monitored::Scalar<double>("energy_" + std::to_string(channel2), energy2);
219 fill(m_tools[m_channelEnergyGroups.at(moduleName)], monChannel2Energy);
220 }
221
222 if (energy > m_energyThresholdForTimeInGeV) {
223 if (isOkChannel1) {
224 auto monChannel1Time = Monitored::Scalar<double>("time_" + std::to_string(channel1), time1);
225 fill(m_tools[m_channelTimeGroups.at(moduleName)], monChannel1Time);
226 }
227 if (isOkChannel2) {
228 auto monChannel2Time = Monitored::Scalar<double>("time_" + std::to_string(channel2), time2);
229 fill(m_tools[m_channelTimeGroups.at(moduleName)], monChannel2Time);
230 }
231 }
232 }
233
234 if (sample < TileID::SAMP_E) { // Normal Tile cells with two channels (in TB setup)
235 auto monEnergy = Monitored::Scalar<double>("energy" + sampleTowerSuffix, energy);
236 fill(m_tools[m_energyGroups.at(moduleName)], monEnergy);
237
238 auto monEnergyDiff = Monitored::Scalar<double>("energyDiff" + sampleTowerSuffix, energyDiff);
239 fill(m_tools[m_energyDiffGroups.at(moduleName)], monEnergyDiff);
240
241 auto monEnergy1 = Monitored::Scalar<double>("energy1" + sampleTowerSuffix, energy1);
242 auto monEnergy2 = Monitored::Scalar<double>("energy2" + sampleTowerSuffix, energy2);
243 fill(m_tools[m_energy2VsEnergy1Groups.at(moduleName)], monEnergy1, monEnergy2);
244
245 if (energy > m_energyThresholdForTimeInGeV) {
246 auto monTime = Monitored::Scalar<double>("time" + sampleTowerSuffix, time);
247 fill(m_tools[m_timeGroups.at(moduleName)], monTime);
248
249 auto monTimeDiff = Monitored::Scalar<double>("timeDiff" + sampleTowerSuffix, timeDiff);
250 fill(m_tools[m_timeDiffGroups.at(moduleName)], monTimeDiff);
251
252 auto monTime1 = Monitored::Scalar<double>("time1" + sampleTowerSuffix, time1);
253 auto monTime2 = Monitored::Scalar<double>("time2" + sampleTowerSuffix, time2);
254 fill(m_tools[m_time2VsTime1Groups.at(moduleName)], monTime1, monTime2);
255 }
256
257 if (isMaskedChannel1 && !isMaskedChannel2) {
258 energy = energy2 * 2.0;
259 } else if (isMaskedChannel2 && !isMaskedChannel1) {
260 energy = energy1 * 2.0;
261 } else if (isMaskedChannel1 && isMaskedChannel2) {
262 energy = 0.0;
263 }
264 sampleEnergy[drawerIdx1][sample] += energy;
265 sampleEnergy[drawerIdx1][allSamples] += energy;
266 }
267 }
268 }
269
270
271 for (unsigned int drawerIdx = 0; drawerIdx < TileCalibUtils::MAX_DRAWERIDX; ++drawerIdx) {
272 if (m_monitoredDrawerIdx[drawerIdx]) {
273 unsigned int ros = m_drawerIdxToROS[drawerIdx];
274 unsigned int drawer = m_drawerIdxToDrawer[drawerIdx];
275 std::string moduleName = TileCalibUtils::getDrawerString(ros, drawer);
276
277 auto monEnergy = Monitored::Scalar<double>("energy", sampleEnergy[drawerIdx][allSamples]);
278 auto monEnergyA = Monitored::Scalar<double>("energyA", sampleEnergy[drawerIdx][TileID::SAMP_A]);
279 auto monEnergyBC = Monitored::Scalar<double>("energyBC", sampleEnergy[drawerIdx][TileID::SAMP_BC]);
280 auto monEnergyD = Monitored::Scalar<double>("energyD", sampleEnergy[drawerIdx][TileID::SAMP_D]);
281 fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergy);
282 fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergyA, monEnergyBC);
283 fill(m_tools[m_sampleEnergyGroups.at(moduleName)], monEnergyD);
284 }
285 }
286 }
287
288
289 fill("TileTBCellMonExecuteTime", timer);
290
291 return StatusCode::SUCCESS;
292}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Handle class for reading from StoreGate.
Wrapper to avoid constant divisions when using units.
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
This class groups all DetDescr information related to a CaloCell.
IdentifierHash onl2() const
cell online identifier 2
IdentifierHash onl1() const
cell online identifier 1
This is a "hash" representation of an Identifier.
Declare a monitored scalar variable.
A monitored timer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const unsigned int MAX_DRAWERIDX
Maximal drawer index.
static const unsigned int MAX_ROS
Number of ROSs.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static const unsigned int MAX_GAIN
Number of gains per channel.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
static const unsigned int MAX_CHAN
Number of channels in drawer.
float time1(void) const
get time of first PMT
Definition TileCell.h:192
float eneDiff(void) const
all get methods
Definition TileCell.h:182
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
int gain1(void) const
get gain of first PMT
Definition TileCell.cxx:168
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
float timeDiff(void) const
get time diff for two PMTs (data member)
Definition TileCell.h:184
float time2(void) const
get time of second PMT
Definition TileCell.h:194
float ene2(void) const
get energy of second PMT
Definition TileCell.h:189
@ NOT_VALID_HASH
Definition TileHWID.h:314
std::map< std::string, int > m_energyDiffGroups
const TileCablingService * m_cabling
std::map< std::string, int > m_channelTimeGroups
virtual StatusCode initialize() override
initialize
std::array< unsigned int, TileCalibUtils::MAX_DRAWERIDX > m_drawerIdxToDrawer
std::map< std::string, int > m_timeDiffGroups
Gaudi::Property< std::vector< std::string > > m_masked
std::map< std::string, int > m_channelEnergyGroups
Gaudi::Property< float > m_scaleFactor
std::map< std::string, int > m_energyGroups
std::map< std::string, int > m_sampleEnergyGroups
std::map< std::string, int > m_timeGroups
Gaudi::Property< bool > m_fillHistogramsPerChannel
std::array< unsigned int, TileCalibUtils::MAX_DRAWERIDX > m_drawerIdxToROS
Gaudi::Property< float > m_energyThresholdForTime
std::map< std::string, int > m_time2VsTime1Groups
std::array< std::array< unsigned char, TileCalibUtils::MAX_CHAN >, TileCalibUtils::MAX_DRAWERIDX > m_maskedChannels
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
SG::ReadHandleKey< CaloCellContainer > m_caloCellContainerKey
Gaudi::Property< std::vector< int > > m_fragIDs
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
std::map< std::string, int > m_energy2VsEnergy1Groups
std::array< bool, TileCalibUtils::MAX_DRAWERIDX > m_monitoredDrawerIdx
@ INVALIDGAIN
Definition CaloGain.h:18
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)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void fill(H5::Group &out_file, size_t iterations)