ATLAS Offline Software
Loading...
Searching...
No Matches
TileRawChannelTimeMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
11
13
14 ATH_MSG_DEBUG("in initialize()");
15
16 // initialize superclass
18
19 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
20
21 ATH_CHECK( m_cablingSvc.retrieve() );
22 m_cabling = m_cablingSvc->cablingService();
23
24 ATH_CHECK( m_rawChannelContainerKey.initialize() );
25 ATH_CHECK( m_DQstatusKey.initialize() );
26 ATH_CHECK( m_badChannelsKey.initialize() );
27 ATH_CHECK( m_DCSStateKey.initialize(m_checkDCS) );
28 ATH_CHECK( m_emScaleKey.initialize() );
29
30 using Tile = TileCalibUtils;
31 using namespace Monitored;
32
33 m_timeGroups = buildToolMap<int>(m_tools, "TileAverageTime", Tile::MAX_ROS - 1);
34 m_uncorrTimeGroups = buildToolMap<int>(m_tools, "TileAverageUncorrectedTime", Tile::MAX_ROS - 1);
35 m_timeLBGroups = buildToolMap<int>(m_tools, "TileAverageTimeLB", Tile::MAX_ROS - 1);
36 m_timeDiffLBGroups = buildToolMap<int>(m_tools, "TileAverageTimeDifferenceLB", m_partitionTimeDifferencePairs.size());
38 Tile::MAX_ROS - 1, Tile::MAX_DRAWER, s_nDigitizers);
39
40 m_amplitudeGroups = buildToolMap<int>(m_tools, "TileAverageAmplitude", Tile::MAX_ROS - 1);
41
42 std::vector<std::string> modules;
43 for (int fragID : m_amplitudeFragIDs) {
44 unsigned int ros = fragID >> 8;
45 unsigned int drawer = fragID & 0x3F;
46 modules.push_back(TileCalibUtils::getDrawerString(ros, drawer));
48 }
49
50 std::ostringstream os;
51 if ( m_amplitudeFragIDs.size() != 0) {
53 for (int fragID : m_amplitudeFragIDs) {
54 unsigned int ros = fragID >> 8;
55 unsigned int drawer = fragID & 0x3F;
56 std::string module = TileCalibUtils::getDrawerString(ros, drawer);
57 os << " " << module << "/0x" << std::hex << fragID << std::dec;
58 }
59 } else {
60 os << "NONE";
61 }
62
63 ATH_MSG_INFO("Monitored amplitude vs LB for modules/frag ID:" << os.str());
64
65 if (!modules.empty()) {
66 m_amplitudeVsLBGroups = buildToolMap<int>(m_tools, "TileAmplitudeVsLB", modules);
67 }
68
69 return StatusCode::SUCCESS;
70}
71
72
73StatusCode TileRawChannelTimeMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
74
75 using Tile = TileCalibUtils;
76
77 // In case you want to measure the execution time
78 auto timer = Monitored::Timer("TIME_execute");
79
80 const xAOD::EventInfo* eventInfo = GetEventInfo(ctx).get();
81
82 unsigned int lvl1TriggerType = eventInfo->level1TriggerType();
83 if (!m_triggerTypes.empty()
84 && std::find( m_triggerTypes.begin(), m_triggerTypes.end(), lvl1TriggerType) == m_triggerTypes.end()) {
85 fill("TileRawChanTimeMonExecuteTime", timer);
86 return StatusCode::SUCCESS;
87 }
88
89 unsigned int lumiBlock = eventInfo->lumiBlock();
90 auto monLumiBlock = Monitored::Scalar<double>("lumiBlock", lumiBlock);
91
92 std::vector<int> drawers[Tile::MAX_ROS - 1];
93 std::vector<int> channels[Tile::MAX_ROS - 1];
94 std::vector<double> channelTimes[Tile::MAX_ROS - 1];
95 std::vector<double> channelUncorrectedTimes[Tile::MAX_ROS - 1];
96 std::vector<double> channelAmplitudes[Tile::MAX_ROS - 1];
97
98 const TileDQstatus* dqStatus = SG::makeHandle(m_DQstatusKey, ctx).get();
99 const TileDCSState* dcsState = m_checkDCS ? SG::ReadCondHandle(m_DCSStateKey, ctx).cptr() : nullptr;
100
102 ATH_CHECK( emScale.isValid() );
103
105
107 ATH_CHECK( rawChannelContainer.isValid() );
108
109 TileRawChannelUnit::UNIT rawChannelUnit = rawChannelContainer->get_unit();
110
111 static const int channel2digitizer[48] = {7, 7, 7, 7, 7, 7,
112 6, 6, 6, 6, 6, 6,
113 5, 5, 5, 5, 5, 5,
114 4, 4, 4, 4, 4, 4,
115 3, 3, 3, 3, 3, 3,
116 2, 2, 2, 2, 2, 2,
117 1, 1, 1, 1, 1, 1,
118 0, 0, 0, 0, 0, 0};
119
120 int signalState[Tile::MAX_ROS - 1][Tile::MAX_DRAWER][s_nDigitizers] = {{{SIGNAL_NOT_EXPECTED}}};
121
122 for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
123 if (rawChannelCollection->empty() ) continue;
124
125 HWIdentifier adc_id = rawChannelCollection->front()->adc_HWID();
126 int ros = m_tileHWID->ros(adc_id);
127 int drawer = m_tileHWID->drawer(adc_id);
128 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
129 int partition = ros - 1;
130 std::string moduleName = TileCalibUtils::getDrawerString(ros, drawer);
131
132 for (const TileRawChannel* rawChannel : *rawChannelCollection) {
133
134 adc_id = rawChannel->adc_HWID();
135 int channel = m_tileHWID->channel(adc_id);
136 int adc = m_tileHWID->adc(adc_id);
137
138 if (m_cabling->isDisconnected(ros, drawer, channel)) {
139 ATH_MSG_VERBOSE(m_tileHWID->to_string(adc_id) << ": channlel is disconnected => skipping!");
140 continue;
141 }
142
143 if (!(dqStatus->isAdcDQgood(ros, drawer, channel, adc))) {
144 ATH_MSG_VERBOSE(m_tileHWID->to_string(adc_id) << ": DQ is BAD => skipping!");
145 continue;
146 }
147
148 if (m_checkDCS && dcsState->isStatusBad(ros, drawer, channel)) {
149 ATH_MSG_VERBOSE(m_tileHWID->to_string(adc_id) << ": DCS is Bad => skipping!");
150 continue;
151 }
152
153 TileBchStatus status = badChannels->getAdcStatus(adc_id);
154 if (status.isBad() || status.isBadTiming()) {
155 ATH_MSG_VERBOSE(m_tileHWID->to_string(adc_id) << ": Status or Timing is BAD => skipping!");
156 continue;
157 }
158
159 if (signalState[partition][drawer][channel2digitizer[channel]] != SIGNAL_PRESENT) {
160 signalState[partition][drawer][channel2digitizer[channel]] = SIGNAL_EXPECTED;
161 }
162
163 if (rawChannel->amplitude() < m_energyThresholds[adc]) {
164 ATH_MSG_VERBOSE(m_tileHWID->to_string(adc_id) << ": Energy is below threshold => skipping!");
165 continue;
166 }
167
168 signalState[partition][drawer][channel2digitizer[channel]] = SIGNAL_PRESENT;
169
170 drawers[partition].push_back(drawer);
171 channels[partition].push_back(channel);
172 channelTimes[partition].push_back(rawChannel->time());
173 channelUncorrectedTimes[partition].push_back(rawChannel->uncorrTime());
174
175 float amplitude = rawChannel->amplitude();
176 amplitude = emScale->calibrateChannel(drawerIdx, channel, adc, amplitude, rawChannelUnit, TileRawChannelUnit::PicoCoulombs);
177 channelAmplitudes[partition].push_back(amplitude);
178
179 if (m_amplitudeMonitoredDrawerIdx[drawerIdx]) {
180 auto monAmplitude = Monitored::Scalar<double>("amplitude_" + std::to_string(channel), amplitude);
181 fill(m_tools[m_amplitudeVsLBGroups.at(moduleName)], monLumiBlock, monAmplitude);
182 }
183 }
184 }
185
186 float partitionTime[4] = {0};
187
188 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
189 int nChannels = 0;
190 double averagePartitionTime = 0.0;
191 std::vector<double>& times = channelTimes[partition];
192
193 for (unsigned int channelIdx = 0; channelIdx < channels[partition].size(); ++ channelIdx) {
194 int channel = channels[partition][channelIdx];
195 if ( (partition > 1) // EB, exclude some channels (most likely single PMT) from calculating average time
196 && (channel < 6 || channel == 12 || channel == 13 || channel == 18 || channel == 19) ) continue;
197
198 averagePartitionTime += times[channelIdx];
199 ++nChannels;
200 }
201
202 if (nChannels > 0) {
203 averagePartitionTime /= nChannels;
204 partitionTime[partition] = averagePartitionTime - m_partitionTimeCorrection[partition];
205
206 std::transform(times.begin(), times.end(), times.begin(),
207 [averagePartitionTime] (double time) {return time - averagePartitionTime;});
208 }
209 }
210
211
212 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
213 if (!channelTimes[partition].empty()) {
214 auto monModule = Monitored::Collection("module", drawers[partition]);
215 auto monChannel = Monitored::Collection("channel", channels[partition]);
216 auto monTime = Monitored::Collection("time", channelTimes[partition]);
217 fill(m_tools[m_timeGroups[partition]], monModule, monChannel, monTime);
218
219 auto monUncorrTime = Monitored::Collection("time", channelUncorrectedTimes[partition]);
220 fill(m_tools[m_uncorrTimeGroups[partition]], monModule, monChannel, monUncorrTime);
221
222 auto monPartitionTime = Monitored::Scalar<float>("time", partitionTime[partition]);
223 fill(m_tools[m_timeLBGroups[partition]], monLumiBlock, monPartitionTime);
224
225 auto monAmplitude = Monitored::Collection("amplitude", channelAmplitudes[partition]);
226 fill(m_tools[m_amplitudeGroups[partition]], monModule, monChannel, monAmplitude);
227
228 for (unsigned int channelIdx = 0; channelIdx < channels[partition].size(); ++ channelIdx) {
229 int drawer = drawers[partition][channelIdx];
230 int digitizer = channel2digitizer[ channels[partition][channelIdx] ];
231 auto monTime = Monitored::Scalar<double>("time", channelTimes[partition][channelIdx]);
232 fill(m_tools[m_digiTimeLBGroups[partition][drawer][digitizer]], monLumiBlock, monTime);
233 }
234
235 if (m_fillFakeTime) {
236 for (unsigned int drawer = 0; drawer < Tile::MAX_DRAWER; ++drawer) {
237 for (unsigned int digitizer = 0; digitizer < s_nDigitizers; ++digitizer) {
238 if (signalState[partition][drawer][digitizer] == SIGNAL_EXPECTED) {
239 auto monTime = Monitored::Scalar<double>("time", m_fakeTime);
240 fill(m_tools[m_digiTimeLBGroups[partition][drawer][digitizer]], monLumiBlock, monTime);
241 }
242 }
243 }
244 }
245 }
246 }
247
248 for (unsigned int pairIdx = 0; pairIdx < m_partitionTimeDifferencePairs.size(); ++pairIdx) {
249 const std::pair<int, int>& partitionPair = m_partitionTimeDifferencePairs[pairIdx];
250 int partition1 = partitionPair.first;
251 int partition2 = partitionPair.second;
252 auto monTime = Monitored::Scalar<double>("time", partitionTime[partition1] - partitionTime[partition2]);
253 fill(m_tools[m_timeDiffLBGroups[pairIdx]], monLumiBlock, monTime);
254 }
255
256 fill("TileRawChanTimeMonExecuteTime", timer);
257
258 return StatusCode::SUCCESS;
259}
#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.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
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.
Declare a monitored scalar variable.
A monitored timer.
const_pointer_type cptr()
Class holding bad channel problems.
Static class providing several utility functions and constants.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Condition object to keep Tile DCS status from DB.
bool isStatusBad(unsigned int ros, unsigned int drawer) const
Return true if given Tile drawer considered as bad by summary drawer states per LVPS otherwise return...
Class that holds Data Quality fragment information and provides functions to extract the data quality...
bool isAdcDQgood(int partition, int drawer, int ch, int gain) const
returns status of single ADC returns False if there are any errors
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
Gaudi::Property< std::vector< std::pair< int, int > > > m_partitionTimeDifferencePairs
virtual StatusCode initialize() override
initialize
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
Gaudi::Property< std::vector< double > > m_partitionTimeCorrection
Gaudi::Property< std::vector< unsigned int > > m_triggerTypes
Gaudi::Property< std::vector< double > > m_energyThresholds
SG::ReadCondHandleKey< TileDCSState > m_DCSStateKey
Name of TileDCSState object in condition store.
Gaudi::Property< std::vector< int > > m_amplitudeFragIDs
std::vector< std::vector< std::vector< int > > > m_digiTimeLBGroups
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
std::array< bool, TileCalibUtils::MAX_DRAWERIDX > m_amplitudeMonitoredDrawerIdx
uint32_t lumiBlock() const
The current event's luminosity block number.
uint16_t level1TriggerType() const
The Level-1 trigger type.
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.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
EventInfo_v1 EventInfo
Definition of the latest event info version.
void fill(H5::Group &out_file, size_t iterations)