ATLAS Offline Software
Loading...
Searching...
No Matches
TileCellSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Tile includes
6#include "TileCellSelector.h"
14
15// Calo includes
17
18// Atlas includes
20#include "CxxUtils/StrFormat.h"
21
22#include "boost/date_time/local_time/local_time.hpp"
23#include "boost/date_time/posix_time/posix_time.hpp"
24#include <sstream>
25#include <iomanip>
26#include <numeric>
27#include <inttypes.h>
28
29using xAOD::EventInfo;
30
31static std::string drwname(int id) {
32 static const char name[5][6] = { "", "LBA", "LBC", "EBA", "EBC" };
33 return CxxUtils::strformat ("%s%2.2d", name[id >> 8], id % 0x100 + 1);
34}
35
36TileCellSelector::TileCellSelector(const std::string& name, ISvcLocator* pSvcLocator)
37 : AthAlgorithm(name, pSvcLocator)
38 , m_counter(0)
39 , m_accept(0)
40 , m_minCell(0)
41 , m_maxCell(0)
42 , m_minChan(0)
43 , m_maxChan(0)
44 , m_jump(0)
45 , m_const(0)
46 , m_overLG(0)
47 , m_overHG(0)
48 , m_underLG(0)
49 , m_underHG(0)
50 , m_dqerr(0)
51 , m_dmuerr(0)
52 , m_warnerr(0)
53 , m_tileID(0)
54 , m_tileHWID(0)
55 , m_cabling(0)
56 , m_runNum(0)
57 , m_lumiBlock(0)
58 , m_evtNum(0)
59 , m_evtBCID(0)
60 , m_tileFlag(0)
61 , m_tileError(0)
62 , m_readCells(true)
63 , m_readRawChannels(true)
64 , m_readDigits(true)
65 , m_tileInfo(0)
66{
67
68 declareProperty( "MinEnergyCell", m_minEneCell = -5000.); // cut on cell energy
69 declareProperty( "MaxEnergyCell", m_maxEneCell = 1000000.); // cut on cell energy
70 declareProperty( "PtnEnergyCell", m_ptnEneCell = 101); // cell energy pattern, accept events only below min (+1), between min-max (+10), above max (+100)
71 declareProperty( "MinEnergyChan", m_minEneChan[0] = -5000.); // cut on channel energy
72 declareProperty( "MaxEnergyChan", m_maxEneChan[0] = 500000.); // cut on channel energy
73 declareProperty( "PtnEnergyChan", m_ptnEneChan[0] = 101); // channel energy pattern
74 declareProperty( "MinEnergyGap", m_minEneChan[1] = -10000.); // cut on channel energy
75 declareProperty( "MaxEnergyGap", m_maxEneChan[1] = 500000.); // cut on channel energy
76 declareProperty( "PtnEnergyGap", m_ptnEneChan[1] = 101); // channel energy pattern
77 declareProperty( "MinEnergyMBTS", m_minEneChan[2] = -10000.); // cut on channel energy
78 declareProperty( "MaxEnergyMBTS", m_maxEneChan[2] = 500000.); // cut on channel energy
79 declareProperty( "PtnEnergyMBTS", m_ptnEneChan[2] = 101); // channel energy pattern
80
81 declareProperty( "MinTimeCell", m_minTimeCell = -100.); // cut on cell time
82 declareProperty( "MaxTimeCell", m_maxTimeCell = 100.); // cut on cell time
83 declareProperty( "PtnTimeCell", m_ptnTimeCell = 10); // cell time pattern, accept events only below min (+1), between min-max (+10), above max (+100)
84 declareProperty( "MinTimeChan", m_minTimeChan[0] = -100.); // cut on channel time
85 declareProperty( "MaxTimeChan", m_maxTimeChan[0] = 100.); // cut on channel time
86 declareProperty( "PtnTimeChan", m_ptnTimeChan[0] = 10); // channel time pattern
87 declareProperty( "MinTimeGap", m_minTimeChan[1] = -100.); // cut on channel time
88 declareProperty( "MaxTimeGap", m_maxTimeChan[1] = 100.); // cut on channel time
89 declareProperty( "PtnTimeGap", m_ptnTimeChan[1] = 10); // channel time pattern
90 declareProperty( "MinTimeMBTS", m_minTimeChan[2] = -100.); // cut on channel time
91 declareProperty( "MaxTimeMBTS", m_maxTimeChan[2] = 100.); // cut on channel time
92 declareProperty( "PtnTimeMBTS", m_ptnTimeChan[2] = 10); // channel time pattern
93
94 declareProperty( "SelectGain", m_selectGain = 2); // 0 - select LG only, 1 - HG only, 2 - both gains
97
98 // pattern - decimal number with up to 5 digits
99 // only values 1(=true) and 0(=false) for every digit are used
100 // digit 0 set to 1 - accept event if value < min
101 // digit 1 set to 1 - accept event if min < value < max
102 // digit 2 set to 1 - accept event if value > max
103 // digit 3 set to 1 - accept ene only if quality is good
104 // or accept time if time != 0
105 // digit 4 set to 1 - accept ene only if quality is bad
106 // or accept time if time == 0
107
108 declareProperty( "SecondMaxLevel",m_secondMaxLevel = 0.3); // sample below max should be above (max-min)*m_secondMax
109 declareProperty( "JumpDeltaHG", m_jumpDeltaHG = 50.0); // minimal jump in high gain
110 declareProperty( "JumpDeltaLG", m_jumpDeltaLG = 10.0); // minimal jump in low gain
111 declareProperty( "PedDetlaHG", m_pedDeltaHG = 4.1); // max variation of "const" value in high gain
112 declareProperty( "PedDetlaLG", m_pedDeltaLG = 4.1); // max variation of "const" value in low gain
113 declareProperty( "ConstLength", m_constLength = 6); // min number of consecutive samples of the same value
114 declareProperty( "MinBadDMU", m_minBadDMU = 4); // min number of bad DMUs to accept event
115 declareProperty( "MaxBadDMU", m_maxBadDMU = 15); // max number of bad DMUs to accept event
116 declareProperty( "MinBadMB", m_minBadMB = 4); // min number of bad motherboards in a drawer to accept event
117 declareProperty( "SkipEmpty", m_skipEmpty = true); // ignore empty channels in selection or not
118 declareProperty( "SkipMasked", m_skipMasked = true); // ignore masked channels in selection or not
119 declareProperty( "SkipMBTS", m_skipMBTS = true); // ignore MBTS channels in selection or not
120 declareProperty( "CheckDCS", m_checkDCS = true); // additional check for DCS status
121 declareProperty( "DrawerToDump", m_drawer); // for which drawer all channels should be printed
122 declareProperty( "DrawerToCheck",m_drawerToCheck); // for which drawer all checks should be performed
123 declareProperty( "ChannelToCheck",m_chanToCheck); // for which channels all checks should be performed
124
125 declareProperty( "CheckJumps", m_checkJumps = true); // global flag which allows to swithc on/off all checks in digits
126 declareProperty( "CheckDMUs", m_checkDMUs = true); // global flag which allows to swithc on/off DMU checks
127 declareProperty( "CheckOverLG" ,m_checkOverLG = true); // select events with overflow in low gain
128 declareProperty( "CheckOverHG", m_checkOverHG = false); // select events with overflow in high gain
129 declareProperty( "CheckUnderLG", m_checkUnderLG = false); // select events with underflow in low gain
130 declareProperty( "CheckUnderHG", m_checkUnderHG = false); // select events with underflow in high gain
131 declareProperty( "OverflowLG", m_overflowLG = -0.1); // threshold for overflow in low gain (smaller than ADCmax by this value)
132 declareProperty( "OverflowHG", m_overflowHG = -1.1); // threshold for overflow in high gain (smaller than ADCmax by this value)
133 declareProperty( "UnderflowLG", m_underflowLG = 0.1); // threshold for underflow in low gain
134 declareProperty( "UnderflowHG", m_underflowHG = 2.1); // threshold for underflow in high gain
135
136 declareProperty( "CheckWarning", m_checkWarning = false); // select events with warning status in TileCal status word
137 declareProperty( "CheckError", m_checkError = false); // select events with error status in TileCal status word
138 declareProperty( "PrintOnly", m_printOnly = false); // only print acccepted events, but do not accept anything
139
140 declareProperty( "MaxVerboseCnt",m_maxVerboseCnt=20); // max number of verbose output lines about drawer off
141
142 declareProperty("TileInfoName", m_infoName = "TileInfo");
143}
144
145
148
149
150
151
153 //ATH_MSG_DEBUG("in initialize()");
154
155 ATH_CHECK( m_eventInfoKey.initialize() );
156
157 ATH_CHECK(detStore()->retrieve(m_tileID, "TileID"));
158 ATH_CHECK(detStore()->retrieve(m_tileHWID, "TileHWID"));
159
161 m_ADCmaxMinusEps = m_tileInfo->ADCmax() - 0.01;
162 m_ADCmaskValueMinusEps = m_tileInfo->ADCmaskValue() - 0.01; // indicates channels which were masked in background dataset
163
165
166 ATH_CHECK(m_tileBadChanTool.retrieve());
167
168 if (m_checkDCS) {
169 ATH_CHECK(m_tileDCS.retrieve());
170 } else {
171 m_tileDCS.disable();
172 }
173
174 ATH_MSG_INFO( "Cell container "
175 << ((m_cellContainerKey.key().empty()) ? "NOT SET" : m_cellContainerKey.key()) );
176 ATH_MSG_INFO( "Digits container "
177 << ((m_digitsContainerKey.key().empty()) ? "NOT SET" : m_digitsContainerKey.key()));
178 ATH_MSG_INFO( "RawChannel container "
179 << ((m_rawChannelContainerKey.key().empty()) ? "NOT SET" : m_rawChannelContainerKey.key()));
180
181 ATH_MSG_INFO( "CheckJumps " << ((m_checkJumps) ? "true" : "false"));
182 ATH_MSG_INFO( "CheckDMUs " << ((m_checkDMUs) ? "true" : "false"));
183 ATH_MSG_INFO( "CheckOverLG " << ((m_checkOverLG) ? "true" : "false"));
184 ATH_MSG_INFO( "CheckOverHG " << ((m_checkOverHG) ? "true" : "false"));
185 ATH_MSG_INFO( "CheckUnderLG " << ((m_checkUnderLG) ? "true" : "false"));
186 ATH_MSG_INFO( "CheckUnderHG " << ((m_checkUnderHG) ? "true" : "false"));
187
188 if (m_overflowLG < 0) m_overflowLG += m_tileInfo->ADCmax();
189 if (m_overflowHG < 0) m_overflowHG += m_tileInfo->ADCmax();
190 ATH_MSG_INFO( "OverflowLG " << m_overflowLG);
191 ATH_MSG_INFO( "OverflowHG " << m_overflowHG);
192 ATH_MSG_INFO( "UnderflowLG " << m_underflowLG);
193 ATH_MSG_INFO( "UnderflowHG " << m_underflowHG);
194
195 ATH_MSG_INFO( "SkipEmpty " << ((m_skipEmpty) ? "true" : "false"));
196 ATH_MSG_INFO( "SkipMasked " << ((m_skipMasked) ? "true" : "false"));
197 ATH_MSG_INFO( "SkipMBTS " << ((m_skipMBTS) ? "true" : "false"));
198 ATH_MSG_INFO( "CheckDCS " << ((m_checkDCS) ? "true" : "false"));
199
200
201 m_readCells = !m_cellContainerKey.key().empty();
203 m_readDigits = !m_digitsContainerKey.key().empty();
204
205 if (m_readCells) {
206 ATH_MSG_INFO( "MinEnergyCell < " << m_minEneCell);
207 ATH_MSG_INFO( "MaxEnergyCell > " << m_maxEneCell);
208 ATH_MSG_INFO( "PtnEnergyCell = " << m_ptnEneCell);
209 ATH_MSG_INFO( "MinTimeCell < " << m_minTimeCell);
210 ATH_MSG_INFO( "MaxTimeCell > " << m_maxTimeCell);
211 ATH_MSG_INFO( "PtnTimeCell = " << m_ptnTimeCell);
212
213 ATH_CHECK( m_cellContainerKey.initialize() );
214 }
215
217 ATH_MSG_INFO( "MinEnergyChan < " << m_minEneChan[0]);
218 ATH_MSG_INFO( "MaxEnergyChan > " << m_maxEneChan[0]);
219 ATH_MSG_INFO( "PtnEnergyChan = " << m_ptnEneChan[0]);
220 ATH_MSG_INFO( "MinEnergyGap < " << m_minEneChan[1]);
221 ATH_MSG_INFO( "MaxEnergyGap > " << m_maxEneChan[1]);
222 ATH_MSG_INFO( "PtnEnergyGap = " << m_ptnEneChan[1]);
223 ATH_MSG_INFO( "MinTimeChan < " << m_minTimeChan[0]);
224 ATH_MSG_INFO( "MaxTimeChan > " << m_maxTimeChan[0]);
225 ATH_MSG_INFO( "PtnTimeChan = " << m_ptnTimeChan[0]);
226 ATH_MSG_INFO( "MinTimeGap < " << m_minTimeChan[1]);
227 ATH_MSG_INFO( "MaxTimeGap > " << m_maxTimeChan[1]);
228 ATH_MSG_INFO( "PtnTimeGap = " << m_ptnTimeChan[1]);
229 }
230
231 if (m_readRawChannels) {
232 ATH_MSG_INFO( "MinEnergyMBTS < " << m_minEneChan[2]);
233 ATH_MSG_INFO( "MaxEnergyMBTS > " << m_maxEneChan[2]);
234 ATH_MSG_INFO( "PtnEnergyMBTS = " << m_ptnEneChan[2]);
235 ATH_MSG_INFO( "MinTimeMBTS < " << m_minTimeChan[2]);
236 ATH_MSG_INFO( "MaxTimeMBTS > " << m_maxTimeChan[2]);
237 ATH_MSG_INFO( "PtnTimeMBTS = " << m_ptnTimeChan[2]);
238
239 ATH_CHECK( m_rawChannelContainerKey.initialize() );
240 }
241
242 switch (m_selectGain) {
243 case 0:
244 ATH_MSG_INFO( "Select Low gain channels only");
247 break;
248 case 1:
249 ATH_MSG_INFO( "Select High gain channels only");
252 break;
253 default:
254 ATH_MSG_INFO( "Select both gains");
255 break;
256 }
257
258 if (!m_digitsContainerKey.key().empty()) {
259 if (m_checkJumps) {
260 ATH_MSG_INFO( "JumpDeltaHG " << m_jumpDeltaHG);
261 ATH_MSG_INFO( "JumpDeltaLG " << m_jumpDeltaLG);
262 ATH_MSG_INFO( "PedDetlaHG " << m_pedDeltaHG);
263 ATH_MSG_INFO( "PedDetlaLG " << m_pedDeltaLG);
264 ATH_MSG_INFO( "ConstLength " << m_constLength);
265 }
266
267 ATH_CHECK( m_digitsContainerKey.initialize() );
268
269 }
270
271 if (!m_rawChannelContainerKey.key().empty()) {
272 if (m_checkDMUs) {
273 ATH_MSG_INFO( "MinBadDMU " << m_minBadDMU);
274 ATH_MSG_INFO( "MaxBadDMU " << m_maxBadDMU);
275 ATH_MSG_INFO( "MinBadMB " << m_minBadMB);
276 } else {
277 m_minBadDMU = 99;
278 m_maxBadDMU = -1;
279 m_minBadMB = 99;
280 }
281 ATH_MSG_INFO( "MaxVerboseCnt " << m_maxVerboseCnt);
282 }
283
284 ATH_MSG_INFO( "CheckWarning " << ((m_checkWarning)? "true" : "false"));
285 ATH_MSG_INFO( "CheckError " << ((m_checkError) ? "true" : "false"));
286 ATH_MSG_INFO( "PrintOnly " << ((m_printOnly) ? "true" : "false"));
287
288 if (m_drawer.size()>0) {
289 msg(MSG::INFO) << "Drawers which will be always printed:" << MSG::hex;
290 for (int frag: m_drawer) msg(MSG::INFO) << " 0x" << frag;
291 msg(MSG::INFO) << MSG::dec << endmsg;
292 }
293
294 if (m_drawerToCheck.size()>0) {
295 msg(MSG::INFO) << "Only those drawers will be checked:" << MSG::hex;
296 for (int frag: m_drawerToCheck) msg(MSG::INFO) << " 0x" << frag;
297 msg(MSG::INFO) << MSG::dec << endmsg;
298 }
299
300 if (m_chanToCheck.size()>0) {
301 msg(MSG::INFO) << "Only those channels will be checked:";
302 for (int ch: m_chanToCheck) msg(MSG::INFO) << " " << ch;
303 msg(MSG::INFO) << endmsg;
304 }
305
307
308 //ATH_MSG_DEBUG ("initialize() successful");
309
310 // convert patterns fo bolean arrays
311
312 int digit=1;
313 int scale=10;
314 for (int i=0; i<ptnlength; ++i) {
315
316 int bit=(m_ptnEneCell/digit)%scale;
317 m_bitEneCell[i] = (bit!=0);
318
319 bit=(m_ptnTimeCell/digit)%scale;
320 m_bitTimeCell[i] = (bit!=0);
321
322 for (int j=0; j<3; ++j) {
323
324 int bit=(m_ptnEneChan[j]/digit)%scale;
325 m_bitEneChan[j][i] = (bit!=0);
326
327 bit=(m_ptnTimeChan[j]/digit)%scale;
328 m_bitTimeChan[j][i] = (bit!=0);
329 }
330
331 digit *= scale;
332 }
333
334 m_chanToSkip.clear();
335 m_drawerToSkip.clear();
336 if (m_drawerToCheck.size()>0 || m_chanToCheck.size()>0 ) {
337 if (m_drawerToCheck.size()==0) {
338 m_drawerToCheck.resize(256);
339 auto itr = m_drawerToCheck.begin();
340 for (int frag : {0x100,0x200,0x300,0x400}) {
341 auto itr1 = itr+64;
342 std::iota(itr, itr1, frag);
343 itr = itr1;
344 }
345 } else if (m_chanToCheck.size()==0) {
346 m_chanToCheck.resize(48);
347 std::iota(m_chanToCheck.begin(), m_chanToCheck.end(), 0);
348 }
350 m_drawerToSkip.resize(1+TileCalibUtils::getDrawerIdx(4,63),true);
351 IdContext chan_context = m_tileHWID->channel_context();
352 IdentifierHash hash;
353 for (int frag : m_drawerToCheck) {
354 int ros = frag >> 8;
355 int drawer = frag & 0x3F;
356 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros,drawer);
357 m_drawerToSkip[drawerIdx] = false;
358 HWIdentifier ch_id = m_tileHWID->channel_id(ros,drawer,0);
359 m_tileHWID->get_hash(ch_id, hash, &chan_context);
360 for (int chan: m_chanToCheck)
361 m_chanToSkip[hash+chan] = false;
362 }
363 } else {
366 m_drawerToSkip.resize(1+TileCalibUtils::getDrawerIdx(4,63),false);
367 }
368
369 ATH_CHECK( m_dqStatusKey.initialize() );
370
371 return StatusCode::SUCCESS;
372}
373
374
375StatusCode TileCellSelector::execute(const EventContext& ctx) {
376 //ATH_MSG_DEBUG ("execute()");
377
378
379 ++m_counter;
380
382 if ( eventInfo.isValid() ) {
383 m_runNum = eventInfo->runNumber();
384 m_lumiBlock = eventInfo->lumiBlock();
385 m_evtNum = eventInfo->eventNumber();
386 m_evtBCID = eventInfo->bcid();
387 m_tileFlag = eventInfo->eventFlags(EventInfo::Tile);
388 m_tileError = eventInfo->errorState(EventInfo::Tile);
389 } else {
390 m_runNum = 0;
391 m_evtNum = 0;
392 m_lumiBlock = 0;
393 m_evtBCID = 0;
394 m_tileFlag = 0;
395 m_tileError = 0;
396 }
397
398 std::ostringstream evState;
399 evState << "Run "<< std::setw(6) << m_runNum
400 <<" LB "<< std::setw(4) << m_lumiBlock
401 <<" Evt "<< std::setw(9) << m_evtNum
402 <<" ErrState " << m_tileError
403 <<" Flags 0x" << std::hex << m_tileFlag << std::dec;
404
405 std::ostringstream evtnum;
406 evtnum << "Run "<< std::setw(6) << m_runNum
407 <<" LB "<< std::setw(4) << m_lumiBlock
408 <<" Evt "<< std::setw(9) << m_evtNum
409 <<" BCID "<< std::setw(4) << m_evtBCID;
410
411 std::ostringstream nevtnum;
412 nevtnum << evtnum.str()
413 <<" nevt "<< std::setw(6) << m_counter;
414
415 bool emptyBad = true;
416 bool badFromCell = false;
417 m_chanBad.clear();
418 m_chanBad.resize(1+TileHWID::NOT_VALID_HASH,true);
419 m_chanEne.clear();
421 m_chanTime.clear();
423 m_chanQua.clear();
425 m_chanSel.clear();
426 m_chanSel.resize(1+TileHWID::NOT_VALID_HASH,false);
427
428 IdContext chan_context = m_tileHWID->channel_context();
429 IdentifierHash hash;
430 for (size_t i=0; i<m_drawer.size(); ++i) {
431 HWIdentifier drawer_id = m_tileHWID->drawer_id(m_drawer[i]);
432 HWIdentifier ch_id = m_tileHWID->channel_id(drawer_id,0);
433 m_tileHWID->get_hash(ch_id, hash, &chan_context);
434 auto itr = m_chanSel.begin() + hash;
435 std::fill(itr,itr+48,true);
436 }
437
438 bool statusOk = (m_checkWarning && m_tileError == EventInfo::Warning) ||
440 if (statusOk) {
441 ++m_warnerr;
442
443 using namespace boost::local_time;
444 using namespace boost::posix_time;
445 static const time_zone_ptr gva_tz(new posix_time_zone((std::string)"CET+01CEST01:00:00,M3.5.0/02:00:00,M10.5.0/03:00:00"));
446 local_date_time gva_time(from_time_t(eventInfo->timeStamp()),gva_tz);
447 evState << " " << gva_time << " ";
448
449
450 const char * part[5] = { "UNK", "LBA", "LBC", "EBA", "EBC" };
452 int dn = (m_tileFlag >> 16) & 0xF;
453 int n1 = (m_tileFlag >> 20) & 0x3F;
454 int n2 = (n1 + dn - 1) % 64;
455 int rr = ((m_tileFlag >> 26) & 0x3) + 1;
456 evState << " " << part[rr] <<std::setw(2)<<std::setfill('0')<<n1+1
457 << " - " << part[rr] <<std::setw(2)<<std::setfill('0')<<n2+1
458 << " " << dn << " consec bad ";
459 }
460 else if (m_tileError == EventInfo::Error) {
461 int dn = (m_tileFlag >> 16) & 0xF;
462 int p0 = m_tileFlag & 0xF; // sends any data above threshold
463 int p1 = (m_tileFlag >> 20) & 0xF; // 16 drawers masked
464 int p2 = (m_tileFlag >> 24) & 0xF; // 16 drawers off
465 int pp = 1;
466 for (int rr = 1; rr < 5; ++rr) {
467 if ((p2 & pp) || (p1 & pp)) {
468 evState << " " << part[rr];
469 if (p2 & pp) {
470 if (p0 & pp) evState << " off";
471 else evState << " OFF";
472 }
473 if (p1 & pp) {
474 if (p0 & pp) evState << " mask";
475 else evState << " MASK";
476 }
477 }
478 pp <<= 1;
479 }
480 evState << " " << dn << " consec bad ";
481 }
482
483 if (m_checkDCS) {
484 int n1 = -1;
485 int n2 = -1;
486 int dn = 0;
487 int rr = 0;
488 int m1 = -1;
489 int m2 = -1;
490 int dm = -1;
491 std::vector<int> allmod;
492 std::vector<int> consec;
493 for (int ros = 1; ros < 5; ++ros) {
494 int drmax = 65;
495 for (int dr = 0; dr < drmax; ++dr) {
496 int drawer = dr % 64;
497 if (m_tileDCS->getDCSStatus(ros, drawer) == TileDCSState::ALERT_DRAWER) {
498 if (m1 < 0) m1 = dr;
499 m2 = dr;
500 if (dr < 64) allmod.push_back((ros << 8) + dr);
501 } else if (m1 >= 0) {
502 dm = m2 - m1 + 1;
503 if (m1 == 0) drmax += dm;
504 if (dm > dn) {
505 n1 = m1;
506 n2 = m2;
507 dn = dm;
508 rr = ros;
509 consec.clear();
510 consec.push_back((ros << 8) + m1);
511 } else if (dm == dn) {
512 if (m1 < 64) consec.push_back((ros << 8) + m1);
513 }
514 m1 = m2 = -1;
515 }
516 }
517 }
518 evState << " DCS " << allmod.size() << " off ";
519 if (dn > 1) {
520 evState << dn;
521 if (consec.size() > 1) evState << "*" << (consec.size());
522 evState << " consec "
523 << part[rr] << std::setw(2) << std::setfill('0') << (n1 % 64) + 1 << " - "
524 << part[rr] << std::setw(2) << std::setfill('0') << (n2 % 64) + 1 << " ";
525 n1 += (rr << 8);
526 n2 += (rr << 8);
527 for (size_t n = 1; n < consec.size(); ++n) {
528 m1 = consec[n];
529 m2 = m1 + dn - 1;
530 evState << part[m1 >> 8] << std::setw(2) << std::setfill('0') << (m1 % 64) + 1 << " - "
531 << part[m2 >> 8] << std::setw(2) << std::setfill('0') << (m2 % 64) + 1 << " ";
532 for (size_t m = 0; m < allmod.size(); ++m) {
533 int mm = allmod[m];
534 if (mm >= m1 && mm <= m2) {
535 allmod[m] += n1 - m1;
536 }
537 }
538 }
539 } else {
540 n1 = n2 = dn = 0;
541 }
542 if (allmod.size() > (size_t) dn) {
543 for (size_t m = 0; m < allmod.size(); ++m) {
544 int mm = allmod[m];
545 if (!(mm >= n1 && mm <= n2)) {
546 evState << part[mm >> 8] << std::setw(2) << std::setfill('0') << (mm % 64) + 1 << " ";
547 }
548 }
549 }
550 }
551
552 ATH_MSG_DEBUG (evState.str() << " accepted");
553 }
554
555 int rawdata = -1;
556 const TileCell* cellminCh = 0;
557 const TileCell* cellmaxCh = 0;
558 const TileCell* tcellminCh = 0;
559 const TileCell* tcellmaxCh = 0;
560
561 if (m_readCells) {
562
563 // Get Calo cell container
565
566 if (!cellContainer.isValid()) {
567
568 ATH_MSG_WARNING("Unable to read CaloCellContainer from EventStore, disable reading of this container");
569 m_readCells = false;
570
571 } else {
572
573 float emin = 0.;
574 float emax = 0.;
575 float tmin = 0.;
576 float tmax = 0.;
577 float chmin = 0.;
578 float chmax = 0.;
579 float tcmin = 0.;
580 float tcmax = 0.;
581 const TileCell* cellmin = 0;
582 const TileCell* cellmax = 0;
583 const TileCell* tcellmin = 0;
584 const TileCell* tcellmax = 0;
585
586 // special case - check overflow here if digits container is not available
587 // should be careful here, because in TileCell overflow bit is set to 1
588 // both for overflow and underflow and underflow is HG are very often in gap cells
589 // also, overflow in HG might be masked if quality is too bad, so we'll not select all overflows...
590 // that's why only overflow in LG are checked
591 bool checkOver = (m_checkOverLG && m_digitsContainerKey.key().empty());
592
593 for (const CaloCell* cell : *cellContainer) {
594
595 Identifier id = cell->ID();
596 if ( m_tileID->is_tile(id) ) {
597 const TileCell* tile_cell = dynamic_cast<const TileCell*> (cell);
598 if (tile_cell==0) continue;
599 const CaloDetDescrElement * caloDDE = cell->caloDDE();
600 IdentifierHash hash1 = caloDDE->onl1();
601 IdentifierHash hash2 = caloDDE->onl2();
602 if ( m_chanToSkip[hash1] && m_chanToSkip[hash2] ) continue;
603 int ch_type = (hash2 == TileHWID::NOT_VALID_HASH) ? 1 : 0;
604 if (rawdata < 0) {
605 rawdata = (tile_cell->qbit1() & TileCell::MASK_CMPC) ? 0 : 1;
606 }
607
608 bool bad1 = tile_cell->badch1();
609 bool bad2 = tile_cell->badch2();
610 float ene1 = tile_cell->ene1();
611 float ene2 = tile_cell->ene2();
612 float time1 = tile_cell->time1();
613 float time2 = tile_cell->time2();
614 m_chanBad[hash1] = bad1;
615 m_chanBad[hash2] = bad2;
616 m_chanEne[hash1] = ene1;
617 m_chanEne[hash2] = ene2;
618 m_chanTime[hash1] = time1;
619 m_chanTime[hash2] = time2;
620 m_chanQua[hash1] = tile_cell->qual1();
621 m_chanQua[hash2] = tile_cell->qual2();
622
623 float ene = tile_cell->energy();
624 bool eneOk = false;
625 if (ene < m_minEneCell) {
626 eneOk = m_bitEneCell[0];
627 } else if (ene > m_maxEneCell) {
628 eneOk = m_bitEneCell[2];
629 } else {
630 eneOk = m_bitEneCell[1];
631 }
632
633 if (eneOk) {
634 if (bad1 && bad2) {
635 if (m_bitEneCell[3]) eneOk = false; // request good cells only, but cell is bad
636 } else {
637 if (m_bitEneCell[4]) eneOk = false; // request bad cells only, but cell is good
638 }
639 }
640
641 float time = tile_cell->time();
642 bool timeOk = false;
643 if (time < m_minTimeCell) {
644 timeOk = m_bitTimeCell[0];
645 } else if (time > m_maxTimeCell ) {
646 timeOk = m_bitTimeCell[2];
647 } else {
648 timeOk = m_bitTimeCell[1];
649 }
650
651 if (timeOk) {
652 if (time != 0.) {
653 if (m_bitTimeCell[4]) timeOk = false; // request time==0 only, but time!=0
654 } else {
655 if (m_bitTimeCell[3]) timeOk = false; // request time!=0 only, but time==0
656 }
657 }
658
659 if (timeOk && eneOk) {
660
661 ATH_MSG_VERBOSE( evtnum.str()
662 << " cell " << std::left << std::setw(14) << m_tileID->to_string(id,-2)
663 << " ene = " << ene << " time = " << time);
664
665 m_chanSel[hash1] = true;
666 m_chanSel[hash2] = true;
667
668 if (ene < emin) {
669 emin = ene;
670 cellmin = tile_cell;
671 } else if (ene > emax) {
672 emax = ene;
673 cellmax = tile_cell;
674 }
675
676 if (time<tmin) {
677 tmin = time;
678 tcellmin = tile_cell;
679 }
680 else if (time>tmax) {
681 tmax = time;
682 tcellmax = tile_cell;
683 }
684 }
685
686 if ( !(bad1 && bad2) ) {
687
688 bool ene1Ok = false;
689 bool time1Ok = false;
690
691 if ( !(bad1 || m_skipGain[tile_cell->gain1()]) ) {
692 if (time1 < m_minTimeChan[ch_type] ) {
693 time1Ok = m_bitTimeChan[ch_type][0];
694 } else if (time1 > m_maxTimeChan[ch_type] ) {
695 time1Ok = m_bitTimeChan[ch_type][2];
696 } else {
697 time1Ok = m_bitTimeChan[ch_type][1];
698 }
699
700 if (ene1 < m_minEneChan[ch_type] ) {
701 ene1Ok = m_bitEneChan[ch_type][0];
702 } else if (ene1 > m_maxEneChan[ch_type] ) {
703 ene1Ok = m_bitEneChan[ch_type][2];
704 } else {
705 ene1Ok = m_bitEneChan[ch_type][1];
706 }
707
708 if (ene1Ok) {
709 if (m_bitEneChan[ch_type][4]) ene1Ok = false; // request bad chan only, but chan is good
710 }
711
712 if (time1Ok) {
713 if (time1 != 0.) {
714 if (m_bitTimeChan[ch_type][4]) time1Ok = false; // request time==0 only, but time!=0
715 } else {
716 if (m_bitTimeChan[ch_type][3]) time1Ok = false; // request time!=0 only, but time==0
717 }
718 }
719 }
720
721 bool ene2Ok = false;
722 bool time2Ok = false;
723
724 if ( !(bad2 || m_skipGain[tile_cell->gain2()]) ) {
725 if (ene2 < m_minEneChan[ch_type] ) {
726 ene2Ok = m_bitEneChan[ch_type][0];
727 } else if (ene2 > m_maxEneChan[ch_type] ) {
728 ene2Ok = m_bitEneChan[ch_type][2];
729 } else {
730 ene2Ok = m_bitEneChan[ch_type][1];
731 }
732
733 if (time2 < m_minTimeChan[ch_type] ) {
734 time2Ok = m_bitTimeChan[ch_type][0];
735 } else if (time2 > m_maxTimeChan[ch_type] ) {
736 time2Ok = m_bitTimeChan[ch_type][2];
737 } else {
738 time2Ok = m_bitTimeChan[ch_type][1];
739 }
740
741 if (ene2Ok) {
742 if (m_bitEneChan[ch_type][4]) ene2Ok = false; // request bad chan only, but chan is good
743 }
744
745 if (time2Ok) {
746 if (time2 != 0.) {
747 if (m_bitTimeChan[ch_type][4]) time2Ok = false; // request time==0 only, but time!=0
748 } else {
749 if (m_bitTimeChan[ch_type][3]) time2Ok = false; // request time!=0 only, but time==0
750 }
751 }
752 }
753
754 bool over1=false;
755 bool over2=false;
756 if (checkOver) {
757 over1 = ( (!bad1) && (tile_cell->qbit1() & TileCell::MASK_OVER) && tile_cell->gain1()==TileID::LOWGAIN);
758 over2 = ( (!bad2) && (tile_cell->qbit2() & TileCell::MASK_OVER) && tile_cell->gain2()==TileID::LOWGAIN);
759 }
760
761 if ((ene1Ok && time1Ok) || over1) {
762
763 ATH_MSG_VERBOSE( evtnum.str()
764 << " cell " << std::left << std::setw(14) << m_tileID->to_string(id,-2)
765 << " ch_ene1 = " << ene1 << " ch_t1 = " << time1
766 << ((over1)?" overflow":""));
767
768 m_chanSel[hash1] = true;
769 m_chanSel[hash2] = true;
770
771 if (ene1 < chmin) {
772 chmin = ene1;
773 cellminCh = tile_cell;
774 } else if (ene1 > chmax) {
775 chmax = ene1;
776 cellmaxCh = tile_cell;
777 }
778
779 if (time1 < tcmin) {
780 tcmin = time1;
781 tcellminCh = tile_cell;
782 } else if (time1 > tcmax) {
783 tcmax = time1;
784 tcellmaxCh = tile_cell;
785 }
786 }
787
788 if ((ene2Ok && time2Ok) || over2) {
789
790 ATH_MSG_VERBOSE( evtnum.str()
791 << " cell " << std::left << std::setw(14) << m_tileID->to_string(id,-2)
792 << " ch_ene2 = " << ene2 << " ch_t2 = " << time2
793 << ((over2)?" overflow":""));
794
795 m_chanSel[hash1] = true;
796 m_chanSel[hash2] = true;
797
798 if (ene2 < chmin) {
799 chmin = ene2;
800 cellminCh = tile_cell;
801 } else if (ene2 > chmax) {
802 chmax = ene2;
803 cellmaxCh = tile_cell;
804 }
805
806 if (time2 < tcmin) {
807 tcmin = time2;
808 tcellminCh = tile_cell;
809 } else if (time2 > tcmax) {
810 tcmax = time2;
811 tcellmaxCh = tile_cell;
812 }
813 }
814
815 }
816 }
817 }
818
819 if (tcellmin && tcellmin != cellmin && tcellmin != cellmax) {
820 ATH_MSG_DEBUG( nevtnum.str()
821 << " cell " << std::left << std::setw(14) << m_tileID->to_string(tcellmin->ID(),-2)
822 << " ene = " << tcellmin->energy()
823 << " tmin = " << tcellmin->time());
824 }
825 if (tcellmax && tcellmax != cellmin && tcellmax != cellmax) {
826 ATH_MSG_DEBUG( nevtnum.str()
827 << " cell " << std::left << std::setw(14) << m_tileID->to_string(tcellmax->ID(),-2)
828 << " ene = " << tcellmax->energy()
829 << " tmax = " << tcellmax->energy());
830 }
831
832 if (tcellminCh && tcellminCh != cellminCh && tcellminCh != cellmaxCh) {
833 ATH_MSG_DEBUG( nevtnum.str()
834 << " cell " << std::left << std::setw(14) << m_tileID->to_string(tcellminCh->ID(),-2)
835 << " ch_ene = " << tcellminCh->ene1() << " " << tcellminCh->ene2()
836 << " ch_tmin = " << tcellminCh->time1() << " " << tcellminCh->time2());
837 }
838 if (tcellmaxCh && tcellmaxCh != cellminCh && tcellmaxCh != cellmaxCh) {
839 ATH_MSG_DEBUG( nevtnum.str()
840 << " cell " << std::left << std::setw(14) << m_tileID->to_string(tcellmaxCh->ID(),-2)
841 << " ch_ene = " << tcellmaxCh->ene1() << " " << tcellmaxCh->ene2()
842 << " ch_tmax = " << tcellmaxCh->time1() << " " << tcellmaxCh->time2());
843 }
844
845 if (cellmin) {
846 ++m_minCell;
847 statusOk = true;
848 const char * tit = (tcellmin == cellmin) ? " tmin = ": ((tcellmax == cellmin) ? " tmax = ": " t = ");
849 if (cellminCh!=cellmin) {
850 ATH_MSG_DEBUG( nevtnum.str()
851 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellmin->ID(),-2)
852 << " emin = " << emin
853 << tit << cellmin->time()
854 << " accepted");
855
856 } else {
857 ATH_MSG_DEBUG( nevtnum.str()
858 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellmin->ID(),-2)
859 << " emin = " << emin
860 << " ch_emin = " << chmin
861 << tit << cellmin->time()
862 << " accepted");
863 }
864 }
865
866 if (cellminCh) {
867 ++m_minChan;
868 statusOk = true;
869 const char * tit = (tcellminCh == cellminCh) ? " tmin = ": ((tcellmaxCh == cellminCh) ? " tmax = ": " t = ");
870 if (cellminCh!=cellmin) {
871 ATH_MSG_DEBUG( nevtnum.str()
872 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellminCh->ID(),-2)
873 << " ch_emin = " << chmin
874 << tit << cellminCh->time()
875 << " accepted");
876 }
877 }
878
879 if (cellmax) {
880 ++m_maxCell;
881 statusOk = true;
882 const char * tit = (tcellmin == cellmax) ? " tmin = ": ((tcellmax == cellmax) ? " tmax = ": " t = ");
883 if (cellmaxCh!=cellmax) {
884 ATH_MSG_DEBUG( nevtnum.str()
885 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellmax->ID(),-2)
886 << " emax = " << emax
887 << tit << cellmax->time()
888 << " accepted");
889
890 } else {
891 ATH_MSG_DEBUG( nevtnum.str()
892 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellmax->ID(),-2)
893 << " emax = " << emax
894 << " ch_emax = " << chmax
895 << tit << cellmax->time()
896 << " accepted");
897 }
898 }
899
900 if (cellmaxCh) {
901 ++m_maxChan;
902 statusOk = true;
903 const char * tit = (tcellminCh == cellmaxCh) ? " tmin = ": ((tcellmaxCh == cellmaxCh) ? " tmax = ": " t = ");
904 if (cellmaxCh!=cellmax) {
905 ATH_MSG_DEBUG( nevtnum.str()
906 << " cell " << std::left << std::setw(14) << m_tileID->to_string(cellmaxCh->ID(),-2)
907 << " ch_emax = " << chmax
908 << tit << cellmaxCh->time()
909 << " accepted");
910 }
911 }
912
913 emptyBad = false;
914 badFromCell = true;
915 }
916 }
917
918 const TileDQstatus* DQstatus(0);
919
920 if (m_readRawChannels) {
921
922 // Get Tile RawChannel container
924
925 if ( !rawChannelContainer.isValid() ) {
926 ATH_MSG_WARNING("Unable to read TileRawChannelContainer from EventStore, disable reading of this container");
927 m_readRawChannels = false;
928
929 } else {
930
931 float chmin = 0; // m_minEneChan[0];
932 float chmax = 0; // m_maxEneChan[0];
933 float tcmin = 0.;
934 float tcmax = 0.;
935 const TileRawChannel* minCh = 0;
936 const TileRawChannel* maxCh = 0;
937 const TileRawChannel* tminCh = 0;
938 const TileRawChannel* tmaxCh = 0;
939 TileRawChannelUnit::UNIT rChUnit = rawChannelContainer->get_unit();
940 bool allowAmpCheck = ( ( rChUnit == TileRawChannelUnit::MegaElectronVolts || // allow MeV only as units
942 bool fillChanEne = ( !m_readCells && allowAmpCheck ); // use amplitude from channel if cell container was not checked
943 if (!fillChanEne) {
944 m_chanDsp.clear();
946 m_chanTDsp.clear();
948 }
949
951 DQstatus = SG::makeHandle (m_dqStatusKey, ctx).get();
952 else
953 rawdata = 0;
954
955 IdContext chan_context = m_tileHWID->channel_context();
956 IdentifierHash hash;
957 int index=0, pmt;
958
959 int nbadMax = 0;
960 int nbadMBMax = 0;
961 const TileRawChannelCollection * collMax = 0;
962 const TileRawChannelCollection * collMBMax = 0;
963
964 bool someDQerrors = false;
965
966 for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
967
968 int frag = rawChannelCollection->identify();
969 bool eb = (frag > 0x2ff);
970 bool ebsp = (frag == 0x30e || frag == 0x411);
971
972 int ros = frag >> 8;
973 int drawer = frag & 0x3F;
974 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros,drawer);
975 if ( m_drawerToSkip[drawerIdx] ) continue;
976
977 int chMBTS = -1;
978 if (eb) {
979 for (int ch: {12,4,0}) {
980 m_cabling->h2s_cell_id_index(ros,drawer,ch,index,pmt);
981 if (index == -2) {
982 chMBTS = ch;
983 break;
984 }
985 }
986 }
987
988 HWIdentifier ch_id = m_tileHWID->channel_id(ros,drawer,0);
989 m_tileHWID->get_hash(ch_id, hash, &chan_context);
990 int hashNext = index = (int)hash + 48; // hash ID of the channel after current drawer
991
992 // all error words contains information in last 16 bits only
993 // but they are stored in collection as 32 bit numbers
994 uint32_t RODBCID = rawChannelCollection->getRODBCID();
995 uint32_t DSPBCID = rawChannelCollection->getFragDSPBCID();
996 uint32_t GlobalCRCErr = rawChannelCollection->getFragGlobalCRC() & 0x1;
997 uint32_t FE_DMUmask = rawChannelCollection->getFragFEChipMask();
998 uint32_t ROD_DMUmask = rawChannelCollection->getFragRODChipMask();
999 uint32_t BCIDErr = rawChannelCollection->getFragBCID();
1000 uint32_t MemoryParityErr = rawChannelCollection->getFragMemoryPar();
1001 uint32_t HeaderFormatErr = rawChannelCollection->getFragHeaderBit();
1002 uint32_t HeaderParityErr = rawChannelCollection->getFragHeaderPar();
1003 uint32_t SampleFormatErr = rawChannelCollection->getFragSampleBit();
1004 uint32_t SampleParityErr = rawChannelCollection->getFragSamplePar();
1005 uint32_t SingleStrobeErr = rawChannelCollection->getFragSstrobe();
1006 uint32_t DoubleStrobeErr = rawChannelCollection->getFragDstrobe();
1007
1008 if (RODBCID!=0 && RODBCID != m_evtBCID ) {
1009 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1010 ATH_MSG_VERBOSE( evtnum.str()
1011 << " drw " << drwname(rawChannelCollection->identify())
1012 << " ROD BCID " << RODBCID << " is wrong - skipping");
1013
1014 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1015 ATH_MSG_VERBOSE( nevtnum.str()
1016 << " suppressing further messages about drawer 0x" << std::hex << rawChannelCollection->identify()
1017 << std::dec << " being bad");
1018 }
1019 someDQerrors = true;
1020 continue;
1021 }
1022
1023 if (DSPBCID >= 0x7FFF
1024 && GlobalCRCErr
1025 && FE_DMUmask == 0xFFFF
1026 && ROD_DMUmask == 0xFFFF
1027 && BCIDErr == 0xFFFF
1028 && MemoryParityErr == 0xFFFF
1029 && HeaderFormatErr == 0xFFFF
1030 && HeaderParityErr == 0xFFFF
1031 && SampleFormatErr == 0xFFFF
1032 && SampleParityErr == 0xFFFF
1033 && SingleStrobeErr == 0xFFFF
1034 && DoubleStrobeErr == 0xFFFF) {
1035
1036 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1037 ATH_MSG_VERBOSE( evtnum.str()
1038 << " drw " << drwname(rawChannelCollection->identify())
1039 << " is OFF - skipping");
1040
1041 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1042 ATH_MSG_VERBOSE( nevtnum.str()
1043 << " suppressing further messages about drawer 0x" << std::hex
1044 << rawChannelCollection->identify()
1045 << std::dec << " being bad");
1046 }
1047 continue;
1048 }
1049
1050 if (DSPBCID == 0
1051 && GlobalCRCErr == 0
1052 && FE_DMUmask == 0
1053 && ROD_DMUmask == 0
1054 && BCIDErr == 0
1055 && MemoryParityErr == 0
1056 && HeaderFormatErr == 0
1057 && HeaderParityErr == 0
1058 && SampleFormatErr == 0
1059 && SampleParityErr == 0
1060 && SingleStrobeErr == 0
1061 && DoubleStrobeErr == 0) {
1062
1063 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1064 ATH_MSG_VERBOSE( evtnum.str()
1065 << " drw " << drwname(rawChannelCollection->identify())
1066 << " is MISSING - skipping");
1067
1068 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1069 ATH_MSG_VERBOSE( nevtnum.str()
1070 << " suppressing further messages about drawer 0x" << std::hex
1071 << rawChannelCollection->identify() << std::dec << " being bad");
1072 }
1073 continue;
1074 }
1075
1076 if (GlobalCRCErr) {
1077 GlobalCRCErr = 0xFFFF; // global error - all wrong
1078 if (m_maxBadDMU<16) {
1079 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1080 ATH_MSG_VERBOSE( evtnum.str()
1081 << " drw " << drwname(rawChannelCollection->identify())
1082 << " global CRC error - skipping");
1083
1084 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1085 ATH_MSG_VERBOSE( nevtnum.str()
1086 << " suppressing further messages about drawer 0x" << std::hex
1087 << rawChannelCollection->identify() << std::dec << " being bad");
1088 }
1089 someDQerrors = true;
1090 continue;
1091 }
1092 }
1093
1094 if (HeaderFormatErr || HeaderParityErr || SampleFormatErr || SampleParityErr ) {
1095 FE_DMUmask = 0xFFFF; // can not trust FE mask, assume that all DMUs are good
1096 } else {
1097 if (eb) { // extended barrel
1098 if (ebsp) FE_DMUmask<<=1; // shift by one DMU in EBA15 EBC18
1099 FE_DMUmask = (FE_DMUmask & 0xFF) | ((FE_DMUmask & 0xF00)<<2); // shift upper half by two DMUs
1100 }
1101 }
1102
1103 FE_DMUmask = ~FE_DMUmask & 0xFFFF; // inversion for FE CRC
1104 ROD_DMUmask = ~ROD_DMUmask & 0xFFFF; // inversion for ROD CRC
1105
1106 if (BCIDErr & 0x2) { // DMU1 (second DMU) is bad - can not trust others
1107 BCIDErr = 0xFFFF; // assume that all DMUs are bad
1108 if (m_maxBadDMU < 16) {
1109 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1110 ATH_MSG_VERBOSE( evtnum.str()
1111 << " drw " << drwname(rawChannelCollection->identify())
1112 << " BCID in DMU1 is bad - skipping");
1113
1114 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1115 ATH_MSG_VERBOSE( nevtnum.str()
1116 << " suppressing further messages about drawer 0x"
1117 << std::hex << rawChannelCollection->identify() << std::dec << " being bad");
1118 }
1119 someDQerrors = true;
1120 continue;
1121 }
1122
1123 } else {
1124 // additional check if DQ frag BCID is the same as event BCID
1125 if ( DSPBCID!=0xDEAD && DSPBCID!=m_evtBCID ) { // DSP BCID doesn't match! all wrong
1126 BCIDErr = 0xFFFF;
1127 if (m_maxBadDMU < 16) {
1128 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1129 ATH_MSG_VERBOSE( evtnum.str()
1130 << " drw " << drwname(rawChannelCollection->identify())
1131 << " DSP BCID is wrong - skipping");
1132
1133 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1134 ATH_MSG_VERBOSE( nevtnum.str()
1135 << " suppressing further messages about drawer 0x"
1136 << std::hex << rawChannelCollection->identify() << std::dec << " being bad");
1137 }
1138 someDQerrors = true;
1139 continue;
1140 }
1141 }
1142 }
1143
1144 uint32_t error = GlobalCRCErr | FE_DMUmask | ROD_DMUmask | BCIDErr | MemoryParityErr |
1145 HeaderFormatErr | HeaderParityErr | SampleFormatErr | SampleParityErr;
1146
1147 if (error==0xFFFF && m_maxBadDMU<16) {
1148 if (m_nDrawerOff[drawerIdx] < m_maxVerboseCnt) {
1149 ATH_MSG_VERBOSE( evtnum.str()
1150 << " drw " << drwname(rawChannelCollection->identify())
1151 << " whole drawer is bad - skipping");
1152
1153 if (++m_nDrawerOff[drawerIdx] == m_maxVerboseCnt)
1154 ATH_MSG_VERBOSE( nevtnum.str()
1155 << " suppressing further messages about drawer 0x"
1156 << std::hex << rawChannelCollection->identify() << std::dec << " being bad");
1157 }
1158 someDQerrors = true;
1159 continue;
1160 }
1161
1162 // no global error detected - wait m_max_verbose_cnt good events and eventually enable error messages again
1163 if (m_nDrawerOff[drawerIdx]>=m_maxVerboseCnt) {
1164 if (++m_nDrawerOff[drawerIdx] == 2*m_maxVerboseCnt) {
1165 m_nDrawerOff[drawerIdx] = 0;
1166 ATH_MSG_VERBOSE( nevtnum.str()
1167 << " enabling messages about drawer 0x" << std::hex
1168 << rawChannelCollection->identify()
1169 << std::dec << " being bad after " << m_maxVerboseCnt << " good events");
1170 }
1171 }
1172
1173 uint32_t errMB = BCIDErr;
1174 if (eb) { // do not count non-existing DMUs in EB
1175 if (ebsp) {
1176 errMB &= 0x3cfe;
1177 } else {
1178 errMB &= 0x3cff;
1179 }
1180 }
1181 int nbadMB = 0;
1182 while (errMB) {
1183 if (errMB & 0xF) ++nbadMB;
1184 errMB >>= 4;
1185 }
1186 someDQerrors = (nbadMB >= m_minBadMB);
1187 if (nbadMB > nbadMBMax) {
1188 nbadMBMax = nbadMB;
1189 collMBMax = rawChannelCollection;
1190 }
1191
1192 int nerr = 0;
1193 for (uint32_t i = 0x8000; i != 0; i >>= 1) {
1194 if (error&i) {
1195 ++nerr;
1196 index-=3;
1197 } else {
1198 if (emptyBad && nbadMB < 4) {
1199 m_chanBad[--index] = false;
1200 m_chanBad[--index] = false;
1201 m_chanBad[--index] = false;
1202 } else {
1203 index -= 3;
1204 }
1205 }
1206 }
1207 //if (chMBTS>=0) m_chanBad[index+chMBTS] = true; // ignore completely MBTS channel
1208 int nbad = ((ebsp) ? nerr-5 : ((eb) ? nerr-4 : nerr));
1209
1210 if (nbad >= m_minBadDMU && nerr <= m_maxBadDMU) {
1211 someDQerrors = true;
1212 if (nbad > nbadMax) {
1213 nbadMax = nbad;
1214 collMax = rawChannelCollection;
1215 }
1216 }
1217 if (someDQerrors) { // will print later samples for all channels in a drawer
1218 for ( ; index<hashNext; ++index) { // but if drawer was completely bad, this loop will be skipped
1219 m_chanSel[index] = true;
1220 }
1221 }
1222
1223 if (allowAmpCheck || emptyBad) {
1224
1225 for (const TileRawChannel* rawChannel : *rawChannelCollection) {
1226
1227 HWIdentifier adcId = rawChannel->adc_HWID();
1228 HWIdentifier chId = m_tileHWID->channel_id(adcId);
1229 m_tileHWID->get_hash(chId, hash, &chan_context);
1230 if ( m_chanToSkip[hash] ) continue;
1231 int adc = m_tileHWID->adc(adcId);
1232 int channel = m_tileHWID->channel(adcId);
1233 int ch_type = 0;
1234 if (channel == chMBTS) {
1235 ch_type = 2;
1236 } else if ( (ebsp && (channel == 18 || channel == 19 || channel == 12 || channel == 13) )
1237 || (eb && (channel == 0 || channel == 1 || channel == 12 || channel == 13) ) ) {
1238 ch_type = 1;
1239 }
1240 if (emptyBad && !m_chanBad[hash] ) {
1241 m_chanBad[hash] = m_tileBadChanTool->getAdcStatus(drawerIdx,channel,adc).isBad() ||
1242 (DQstatus && !DQstatus->isAdcDQgood(ros,drawer,channel,adc)) ||
1243 (m_checkDCS && m_tileDCS->getDCSStatus(ros, drawer, channel) > TileDCSState::WARNING);
1244 }
1245
1246 if (allowAmpCheck) {
1247
1248 float amp = rawChannel->amplitude();
1249 float time = rawChannel->time();
1250 if (fillChanEne) {
1251 m_chanEne[hash] = amp;
1252 m_chanTime[hash] = time;
1253 m_chanQua[hash] = rawChannel->quality();
1254 } else {
1255 m_chanDsp[hash] = amp;
1256 m_chanTDsp[hash] = time;
1257 }
1258
1259 if ( (m_skipMasked && m_chanBad[hash]) ||
1260 (m_skipMBTS && channel == chMBTS) ||
1261 (m_skipEmpty && TileDQstatus::isChEmpty(ros, drawer, channel) > 0) ||
1262 m_skipGain[adc] )
1263 continue;
1264
1265 bool ampOk = false;
1266 if (amp < m_minEneChan[ch_type] ) {
1267 ampOk = m_bitEneChan[ch_type][0];
1268 } else if (amp > m_maxEneChan[ch_type] ) {
1269 ampOk = m_bitEneChan[ch_type][2];
1270 } else {
1271 ampOk = m_bitEneChan[ch_type][1];
1272 }
1273
1274 bool timeOk = false;
1275 if (time < m_minTimeChan[ch_type] ) {
1276 timeOk = m_bitTimeChan[ch_type][0];
1277 } else if (time > m_maxTimeChan[ch_type] ) {
1278 timeOk = m_bitTimeChan[ch_type][2];
1279 } else {
1280 timeOk = m_bitTimeChan[ch_type][1];
1281 }
1282
1283 if (ampOk && timeOk) {
1284
1285 ATH_MSG_VERBOSE(evtnum.str()
1286 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(adcId)
1287 << " ch_ene = " << amp << " ch_t = " << time);
1288
1289 m_chanSel[hash] = true;
1290
1291 if (amp < chmin) {
1292 chmin = amp;
1293 minCh = rawChannel;
1294 } else if (amp > chmax) {
1295 chmax = amp;
1296 maxCh = rawChannel;
1297 }
1298
1299 if (time<tcmin) {
1300 tcmin = time;
1301 tminCh = rawChannel;
1302 }
1303 else if (time>tcmax) {
1304 tcmax = time;
1305 tmaxCh = rawChannel;
1306 }
1307 }
1308 }
1309 }
1310 }
1311
1312 for (index = hashNext - 48; index < hashNext; ++index) {
1313 if ((m_chanSel[index] && rawdata) || someDQerrors) {
1314 ATH_MSG_VERBOSE(evtnum.str()
1315 << " drw " << drwname(rawChannelCollection->identify())
1316 << " nBadMB = " << nbadMB
1317 << " nBadDMU = " << nbad
1318 << " EvtBCID = " << m_evtBCID
1319 << " DSPBCID = " << rawChannelCollection->getFragDSPBCID()
1320 << " GlobCRC = " << rawChannelCollection->getFragGlobalCRC() << " " << GlobalCRCErr
1321 << " error = 0x" << std::hex << error
1322 << " FE_CRC = 0x" << rawChannelCollection->getFragFEChipMask() << " 0x" << FE_DMUmask
1323 << " ROD_CRC = 0x" << rawChannelCollection->getFragRODChipMask() << " 0x" << ROD_DMUmask
1324 << " BCIDErr = 0x" << rawChannelCollection->getFragBCID() << " 0x" << BCIDErr
1325 << " MemPar = 0x" << rawChannelCollection->getFragMemoryPar()
1326 << " HeadForm = 0x"<< rawChannelCollection->getFragHeaderBit()
1327 << " HeadPar = 0x" << rawChannelCollection->getFragHeaderPar()
1328 << " SampForm = 0x"<< rawChannelCollection->getFragSampleBit()
1329 << " SampPar = 0x" << rawChannelCollection->getFragSamplePar()
1330 << std::dec);
1331 break;
1332 }
1333 }
1334 }
1335
1336 if (nbadMBMax >= m_minBadMB) {
1337 ++m_dqerr;
1338 statusOk = true;
1339 ATH_MSG_DEBUG( nevtnum.str()
1340 << " drw " << drwname((collMBMax) ? collMBMax->identify() : 0)
1341 << " nBadMB = " << nbadMBMax
1342 << " accepted");
1343
1344 } else if (nbadMax >= m_minBadDMU && nbadMax <= m_maxBadDMU) {
1345 ++m_dqerr;
1346 statusOk = true;
1347 ATH_MSG_DEBUG( nevtnum.str()
1348 << " drw " << drwname((collMax)?collMax->identify():0)
1349 << " nBadDMU = " << nbadMax
1350 << " accepted");
1351 }
1352
1353 if (tminCh && tminCh != minCh && tminCh != maxCh) {
1354 ATH_MSG_DEBUG(nevtnum.str()
1355 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(tminCh->adc_HWID())
1356 << " ch_e = " << tminCh->amplitude()
1357 << " tmin =" << tminCh->time());
1358 }
1359
1360 if (tmaxCh && tmaxCh != minCh && tmaxCh != maxCh) {
1361 ATH_MSG_DEBUG(nevtnum.str()
1362 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(tmaxCh->adc_HWID())
1363 << " ch_e = " << tmaxCh->amplitude()
1364 << " tmax = " << tmaxCh->time());
1365 }
1366
1367 if (minCh) {
1368 if (!cellminCh) ++m_minChan;
1369 statusOk = true;
1370 const char * tit = (tminCh == minCh) ? " tmin = ": ((tmaxCh == minCh) ? " tmax = ": " t = ");
1371 ATH_MSG_DEBUG(nevtnum.str()
1372 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(minCh->adc_HWID())
1373 << " ch_emin = " << chmin
1374 << tit << minCh->time()
1375 << " accepted");
1376 }
1377 if (maxCh) {
1378 if (!cellmaxCh) ++m_maxChan;
1379 statusOk = true;
1380 const char * tit = (tminCh == maxCh) ? " tmin = ": ((tmaxCh == maxCh) ? " tmax = ": " t = ");
1381 ATH_MSG_DEBUG(nevtnum.str()
1382 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(maxCh->adc_HWID())
1383 << " ch_emax = " << chmax
1384 << tit << maxCh->time()
1385 << " accepted");
1386 }
1387 emptyBad = false;
1388 }
1389 }
1390
1391
1392 if (m_readDigits) {
1393
1394 // Pointer to a Tile digits container
1396
1397 if (!digitsContainer.isValid()) {
1398 ATH_MSG_WARNING("Unable to read TileDigitsContainer from EventStore, disable reading of this container");
1399 m_readDigits = false;
1400
1401 } else {
1402
1403 IdContext chan_context = m_tileHWID->channel_context();
1404 IdentifierHash hash;
1405 int index,pmt;
1406 int nConst = 0;
1407 int nJump = 0;
1408 int nDmuErr = 0;
1409 int nOverLG = 0;
1410 int nOverHG = 0;
1411 int nUnderLG = 0;
1412 int nUnderHG = 0;
1413
1414 for (const TileDigitsCollection * digitsCollection : *digitsContainer) {
1415
1416 int frag = digitsCollection->identify();
1417 bool eb = (frag > 0x2ff);
1418 bool ebsp = (frag == 0x30e || frag == 0x411);
1419
1420 int ros = frag >> 8;
1421 int drawer = frag & 0x3F;
1422 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros,drawer);
1423 if ( m_drawerToSkip[drawerIdx] ) continue;
1424
1425 int chMBTS = -1;
1426 if (eb) {
1427 for (int ch: {12,4,0}) {
1428 m_cabling->h2s_cell_id_index(ros,drawer,ch,index,pmt);
1429 if (index == -2) {
1430 chMBTS = ch;
1431 break;
1432 }
1433 }
1434 }
1435
1436 int nChBadDB = 0;
1437 int nChBadNC = 0;
1438 int nChBad = 0;
1439 int nChTot = 0;
1440 int nChDmu[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1441 int nChBadDmu[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1442
1443 for (const TileDigits* tile_digits : *digitsCollection) {
1444
1445 ++nChTot;
1446
1447 HWIdentifier adcId = tile_digits->adc_HWID();
1448 HWIdentifier chId = m_tileHWID->channel_id(adcId);
1449 m_tileHWID->get_hash(chId, hash, &chan_context);
1450 if ( m_chanToSkip[hash] ) continue;
1451 int channel = m_tileHWID->channel(adcId);
1452 int dmu = channel/3;
1453 ++nChDmu[dmu];
1454 int chEmpty = TileDQstatus::isChEmpty(ros, drawer, channel);
1455 bool isConnected = (chEmpty < 2);
1456 if (!isConnected) ++nChBadNC;
1457 int adc = m_tileHWID->adc(adcId);
1458 const char *cellname = "";
1459 int ch_type = 0;
1460 if (channel == chMBTS) {
1461 cellname = " MBTS";
1462 ch_type = 2;
1463 } else if ( (ebsp && (channel == 18 || channel == 19 || channel == 12 || channel == 13) )
1464 || (eb && (channel == 0 || channel == 1 || channel == 12 || channel == 13) ) ) {
1465 cellname = " GAP";
1466 ch_type = 1;
1467 } else if (chEmpty > 0) {
1468 cellname = " EMPTY";
1469 }
1470
1471 const char *badname = "";
1472 if (DQstatus && !DQstatus->isAdcDQgood(ros,drawer,channel,adc)) {
1473 badname = " BADDQ";
1474 if (isConnected) {
1475 ++nChBad;
1476 ++nChBadDmu[dmu];
1477 }
1478 } else if (m_checkDCS && m_tileDCS->getDCSStatus(ros, drawer, channel) > TileDCSState::WARNING) {
1479 badname = " BADDCS";
1480 } else if (m_tileBadChanTool->getAdcStatus(drawerIdx,channel,adc).isBad()) {
1481 badname = " BADDB";
1482 if (isConnected) {
1483 ++nChBadDB;
1484 }
1485 } else if (m_chanBad[hash]) {
1486 if (badFromCell) {
1487 if (ch_type != 2) badname = " BADQUAL";
1488 m_chanQua[hash] = 999;
1489 if (isConnected && ch_type!=2) {
1490 ++nChBad;
1491 ++nChBadDmu[dmu];
1492 }
1493 } else {
1494 badname = " BADUNKN"; // should never see this
1495 }
1496 } else if (badFromCell && m_chanEne[hash] == 0.0) {
1497 badname = " BADDIGI"; // temporary fix, (for May-2012 ESD), should never get this
1498 if (isConnected) {
1499 ++nChBad;
1500 ++nChBadDmu[dmu];
1501 }
1502 }
1503 const char *enename = " ene = ";
1504 const char *timename = " time = ";
1505 const char *qualname = " qual = ";
1506 if (badFromCell && badname[0] != 0) {
1507 enename = " BAD = ";
1508 if (m_chanDsp.size()) {
1509 qualname = " eDSP = ";
1510 m_chanQua[hash] = m_chanDsp[hash];
1511 }
1512 if (m_chanTDsp.size()) {
1513 timename = " tDSP = ";
1514 m_chanTime[hash] = m_chanTDsp[hash];
1515 }
1516 }
1517
1518 char badnm[30];
1519 sprintf(badnm," BADDIGIEX%s",badname);
1520 float dmin,dmax;
1521
1522 std::vector<float> samples = tile_digits->samples();
1523 int nSamp = samples.size();
1524 if (nSamp > 6) {
1525
1526 bool useCh= !( (m_skipMBTS && channel == chMBTS) ||
1527 (m_skipEmpty && chEmpty > 0) );
1528 bool checkCh = !( (m_skipMasked && m_chanBad[hash]) ) && useCh && m_checkJumps;
1529
1530 int err = TileRawChannelBuilder::CorruptedData(ros,drawer,channel,adc,samples,dmin,dmax,m_ADCmaxMinusEps,m_ADCmaskValueMinusEps);
1531
1532 if (badname[0]==0) {
1533 if (err && err>-3) { // do not consider all zeros in empty samples as error
1534 if (isConnected || err != -2) {
1535 if (checkCh) m_chanSel[hash] = true;
1536 badname = badnm;
1537 ++nChBad;
1538 ++nChBadDmu[dmu];
1539 if (!isConnected) --nChBadNC;
1540 }
1541 if (err > 0) {
1542 if (err < 10) {
1543 badnm[9] = 48+err;
1544 } else if (err < 36) {
1545 badnm[9] = 55+err;
1546 }
1547 } else {
1548 badnm[9] = 48;
1549 }
1550 } else {
1551 // old error types, used for tests in August 2012
1552 // expect to see only warningE7 and warningE8 for gap/crack
1553 int warn = Are3FF(samples, adc, ch_type);
1554 if (warn) {
1555 if (checkCh) m_chanSel[hash] = true;
1556 sprintf(badnm," warningE%d%s",warn,badname);
1557 badname = badnm;
1558 }
1559 }
1560 }
1561
1562 if ((!err) // channel without bad patterns
1563 && (useCh) // normal connected channel
1564 && (badname[0] == 0 || badname[1] == 'w' // no digital error
1565 || (badname[4] == 'Q' && !m_skipMasked))) { // error from TileCell but it is ignored
1566
1567 if (adc) { // HG
1568
1569 if (dmax > m_overflowHG) {
1570 m_chanSel[hash] = true; // always print overflows
1571 if (m_checkOverHG){
1572 ++nOverHG;
1573 }
1574 }
1575 if (dmin < m_underflowHG) {
1576 m_chanSel[hash] = true; // always print underflows
1577 if (m_checkUnderHG){
1578 ++nUnderHG;
1579 }
1580 }
1581
1582 } else { // LG
1583
1584 if (dmax > m_overflowLG) {
1585 m_chanSel[hash] = true; // always print overflows
1586 if (m_checkOverLG){
1587 ++nOverLG;
1588 }
1589 }
1590 if (dmin < m_underflowLG) {
1591 m_chanSel[hash] = true; // always print underflows
1592 if (m_checkUnderLG){
1593 ++nUnderLG;
1594 }
1595 }
1596 }
1597 }
1598
1599 bool someSampErrors = false;
1600
1601 if (m_checkJumps && (checkCh || m_chanSel[hash])) {
1602
1603 float pedDelta = (adc ? m_pedDeltaHG : m_pedDeltaLG);
1604 float jumpDelta = (adc ? m_jumpDeltaHG : m_jumpDeltaLG);
1605
1606 float ped = samples[0];
1607 float dmin = ped;
1608 float dmax = ped;
1609 int nped = 1;
1610 int npedmax = 1;
1611 bool cnstPed = true;
1612 bool cnstPedmax = true;
1613 for (int i = 1; i < nSamp; ++i) {
1614 float smp = samples[i];
1615 float dped = smp - ped;
1616 if (fabs(dped) < pedDelta) {
1617 ++nped;
1618 if (dped != 0.0) {
1619 cnstPed = false;
1620 ped += dped/nped;
1621 }
1622 } else {
1623 if (nped>npedmax) {
1624 npedmax=nped;
1625 cnstPedmax = cnstPed;
1626 }
1627 cnstPed = true;
1628 ped = smp;
1629 nped = 1;
1630 }
1631 if (smp<dmin) {
1632 dmin = smp;
1633 } else if (smp>dmax) {
1634 dmax = smp;
1635 }
1636 }
1637 if (nped>npedmax) {
1638 npedmax=nped;
1639 cnstPedmax = cnstPed;
1640 }
1641
1642 if (dmax - dmin >= jumpDelta) {
1643 bool accEmin = (m_chanEne[hash]<m_minEneChan[ch_type]);
1644 bool accEmax = (m_chanEne[hash]>m_maxEneChan[ch_type]);
1645 bool accCnst = false;
1646 bool accJump = false;
1647 bool cnstMin = true;
1648 bool cnstMax = true;
1649 bool jumpNeg = false;
1650 bool jumpPos = false;
1651 bool jumpEnd = false;
1652 bool jumpZer = false;
1653 bool jumpOve = false;
1654 bool narrowUp = false;
1655 bool narrowDown = false;
1656 if (npedmax >= m_constLength && ((dmax-ped) >= jumpDelta || (ped-dmin) >= jumpDelta) ) {
1657 ++nConst;
1658 accCnst = true;
1659 }
1660 int nmin = 0;
1661 int nmax = 0;
1662 int pmin = -1;
1663 int pmax = -1;
1664 float abovemin = dmax;
1665 float belowmax = dmin;
1666 for (int i = 0; i < nSamp; ++i) {
1667 float smp = samples[i];
1668 if (smp - dmin < pedDelta) {
1669 ++nmin;
1670 pmin = i;
1671 if (smp != dmin) cnstMin = false;
1672 }
1673 if (dmax - smp < pedDelta) {
1674 ++nmax;
1675 pmax = i;
1676 if (smp != dmax) cnstMax = false;
1677 }
1678 if (smp < abovemin && smp > dmin) {
1679 abovemin = smp;
1680 }
1681 if (smp > belowmax && smp < dmax) {
1682 belowmax = smp;
1683 }
1684 }
1685 if (nmax + nmin == nSamp) {
1686 if (nmax > 1 && nmin > 1) {
1687 ++nJump;
1688 accJump = true;
1689 } else if (nmax == 1) {
1690 if (pmax < nSamp - 1) { // ignore jump in last sample
1691 ++nJump;
1692 accJump = true;
1693 jumpPos = true;
1694 cnstMax = false;
1695 }
1696 if (pmax == 0 || pmax == nSamp - 1) {
1697 jumpEnd = true;
1698 }
1699 } else if (nmin == 1) {
1700 ++nJump;
1701 accJump = true;
1702 jumpNeg = true;
1703 cnstMin = false;
1704 if (pmin == 0 || pmin == nSamp - 1) {
1705 jumpEnd = true;
1706 }
1707 }
1708 }
1709 if (dmin == 0.0) {
1710 if (!accJump) {
1711 ++nJump;
1712 accJump = true;
1713 cnstMin = false;
1714 cnstMax = false;
1715 }
1716 jumpZer = true;
1717 }
1718 if (dmax > m_ADCmaxMinusEps) {
1719 if (!accJump) {
1720 ++nJump;
1721 accJump = true;
1722 cnstMin = false;
1723 cnstMax = false;
1724 }
1725 jumpOve = true;
1726 }
1727 float secondMax = (dmax-dmin)*m_secondMaxLevel;
1728 if (pmax > 0 && pmax < nSamp-1 && std::max(samples[pmax-1], samples[pmax+1]) < dmin+secondMax) {
1729 if (!accJump) {
1730 ++nJump;
1731 accJump = true;
1732 cnstMax = false;
1733 if (nmin + nmax != nSamp) {
1734 cnstMin = false;
1735 }
1736 }
1737 narrowUp = true;
1738 }
1739 if (pmin > 0 && pmin < nSamp - 1 && std::min(samples[pmin - 1], samples[pmin + 1]) > dmax - secondMax) {
1740 if (!accJump) {
1741 ++nJump;
1742 accJump = true;
1743 cnstMin = false;
1744 if (nmin + nmax != nSamp) {
1745 cnstMax = false;
1746 }
1747 }
1748 narrowDown = true;
1749 }
1750
1751 if (accEmin || accEmax || accCnst || accJump) {
1752 someSampErrors = true;
1753 ATH_MSG_VERBOSE (evtnum.str()
1754 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(adcId)
1755 << enename << m_chanEne[hash] << " samp = " << samples[0]
1756 << " " << samples[1] << " " << samples[2] << " " << samples[3]
1757 << " " << samples[4] << " " << samples[5] << " " << samples[6]
1758 << timename << m_chanTime[hash]
1759 << qualname << m_chanQua[hash]
1760 << cellname << badname
1761 << ((accEmin) ? " neg_e" : "")
1762 << ((accEmax) ? " pos_e" : "")
1763 << ((accCnst) ? " const" : "")
1764 << ((accCnst&&cnstPedmax) ? "Const" : "")
1765 << ((accJump) ? " jump" : "")
1766 << ((accJump&&jumpZer) ? "Zero" : "")
1767 << ((accJump&&jumpOve) ? "Over" : "")
1768 << ((accJump&&jumpPos) ? "SingleUp" : ((narrowUp) ? "NarrowUp" : "") )
1769 << ((accJump&&jumpNeg) ? "SingleDown" : ((narrowDown) ? "NarrowDown" : "") )
1770 << ((accJump&&jumpEnd) ? "AtEdge" : "")
1771 << ((accJump&&cnstMin) ? "ConstMin" : "")
1772 << ((accJump&&cnstMax) ? "ConstMax" : "")
1773 << " " << dmax-dmin);
1774 }
1775 }
1776 }
1777
1778 if (someSampErrors) {
1779 m_chanSel[hash] = true;
1780 } else if (m_chanSel[hash]) {
1781 bool accEmin = (m_chanEne[hash] < m_minEneChan[ch_type]);
1782 bool accEmax = (m_chanEne[hash] > m_maxEneChan[ch_type]);
1783 bool jumpOve = (dmax>m_ADCmaxMinusEps);
1784 bool jumpZer = (dmin < 0.01);
1785 ATH_MSG_VERBOSE(evtnum.str()
1786 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(adcId)
1787 << enename << m_chanEne[hash] << " samp = " << samples[0]
1788 << " " << samples[1] << " " << samples[2] << " " << samples[3]
1789 << " " << samples[4] << " " << samples[5] << " " << samples[6]
1790 << timename << m_chanTime[hash]
1791 << qualname << m_chanQua[hash]
1792 << cellname << badname
1793 << ((accEmin) ? " neg_e" : "")
1794 << ((accEmax) ? " pos_e" : "")
1795 <<((jumpZer) ? " underflow" : "")
1796 <<((jumpOve) ? " overflow" : "") );
1797 }
1798
1799 }
1800 }
1801 if (m_checkDMUs && nChBad > 1 && nChBad + nChBadDB + nChBadNC < nChTot) {
1802 int nChBad1 = 0;
1803 int nChBad2 = 0;
1804 int nDmuBad1 = 0;
1805 int nDmuBad2 = 0;
1806 int nDmuBad = 0;
1807 int nDmuTot = 0;
1808 bool has23 = false;
1809 for (int dmu = 0; dmu < 16; ++dmu) {
1810 if (nChDmu[dmu] > 0) {
1811 ++nDmuTot;
1812 if (nChBadDmu[dmu] > 0) {
1813 ++nDmuBad;
1814 if (dmu < 8) {
1815 nChBad1 += nChBadDmu[dmu];
1816 ++nDmuBad1;
1817 } else {
1818 nChBad2 += nChBadDmu[dmu];
1819 ++nDmuBad2;
1820 }
1821 if (nChBadDmu[dmu] == 2 && nChDmu[dmu] == 3) has23 = true;
1822 }
1823 }
1824 }
1825 if (nDmuBad == 1 /* && (!has23) */ ) continue;
1826 if (nDmuBad == 2 && nChBad < 3) continue;
1827
1828 if (nDmuBad>2 || nChBad > 9 || nChTot > 19 || has23) {
1829
1830 ++nDmuErr;
1831
1832 for (const TileDigits* tile_digits : *digitsCollection) {
1833
1834 HWIdentifier adcId = tile_digits->adc_HWID();
1835 HWIdentifier chId = m_tileHWID->channel_id(adcId);
1836 m_tileHWID->get_hash(chId, hash, &chan_context);
1837 if ( m_chanToSkip[hash] ) continue;
1838 std::vector<float> samples = tile_digits->samples();
1839
1840 if (!m_chanSel[hash] && samples.size()>6) {
1841 int channel = m_tileHWID->channel(adcId);
1842 int adc = m_tileHWID->adc(adcId);
1843 int chEmpty = TileDQstatus::isChEmpty(ros, drawer, channel);
1844 const char *cellname = "";
1845 int ch_type = 0;
1846 if (channel == chMBTS) {
1847 cellname = " MBTS";
1848 ch_type = 2;
1849 } else if ( (ebsp && (channel == 18 || channel == 19 || channel == 12 || channel == 13) )
1850 || (eb && (channel == 0 || channel == 1 || channel == 12 || channel == 13) ) ) {
1851 cellname = " GAP";
1852 ch_type = 1;
1853 } else if (chEmpty > 0) {
1854 cellname = " EMPTY";
1855 }
1856 const char *badname = "";
1857 if (m_tileBadChanTool->getAdcStatus(drawerIdx, channel, adc).isBad()) {
1858 badname = " BADDB";
1859 } else if (DQstatus && !DQstatus->isAdcDQgood(ros, drawer, channel, adc)) {
1860 badname = " BADDQ";
1861 } else if (m_checkDCS && m_tileDCS->getDCSStatus(ros, drawer, channel) > TileDCSState::WARNING) {
1862 badname = " BADDCS";
1863 } else if (m_chanBad[hash]) {
1864 if (badFromCell) {
1865 if (ch_type != 2) badname = " BADQUAL";
1866 m_chanQua[hash] = 999;
1867 } else {
1868 badname = " BADUNKN"; // should never see this
1869 }
1870 } else if (badFromCell && m_chanEne[hash] == 0.0) {
1871 badname = " BADDIGI"; // temporary fix, (for May-2012 ESD), should never get this
1872 }
1873
1874 char badnm[30];
1875 sprintf(badnm, " BADDIGIEX%s", badname);
1876 float dmin, dmax;
1877
1878 int err = TileRawChannelBuilder::CorruptedData(ros, drawer,
1879 channel, adc, samples, dmin, dmax, m_ADCmaxMinusEps,m_ADCmaskValueMinusEps);
1880 if (err) {
1881 bool isConnected = (chEmpty < 2);
1882 if (isConnected || err != -2) {
1883 badname = badnm;
1884 }
1885 if (err > 0) {
1886 if (err < 10) {
1887 badnm[9] = 48 + err;
1888 } else if (err < 36) {
1889 badnm[9] = 55 + err;
1890 }
1891 } else {
1892 badnm[9] = 48;
1893 }
1894 }
1895
1896 const char *enename = " ene = ";
1897 const char *timename = " time = ";
1898 const char *qualname = " qual = ";
1899 if (badFromCell && badname[0] != 0) {
1900 enename = " BAD = ";
1901 if (m_chanDsp.size()) {
1902 qualname = " eDSP = ";
1903 m_chanQua[hash] = m_chanDsp[hash];
1904 }
1905 if (m_chanTDsp.size()) {
1906 timename = " tDSP = ";
1907 m_chanTime[hash] = m_chanTDsp[hash];
1908 }
1909 }
1910
1911 bool accEmin = (m_chanEne[hash]<m_minEneChan[ch_type]);
1912 bool accEmax = (m_chanEne[hash]>m_maxEneChan[ch_type]);
1913 bool jumpOve = (dmax > m_ADCmaxMinusEps);
1914 bool jumpZer = (dmin < 0.01);
1915
1916 ATH_MSG_VERBOSE(evtnum.str()
1917 << " chan " << std::left << std::setw(14) << m_tileHWID->to_string(adcId)
1918 << enename << m_chanEne[hash] << " samp = " << samples[0]
1919 << " " << samples[1] << " " << samples[2] << " " << samples[3]
1920 << " " << samples[4] << " " << samples[5] << " " << samples[6]
1921 << timename << m_chanTime[hash]
1922 << qualname << m_chanQua[hash]
1923 << cellname << badname
1924 << ((accEmin) ? " neg_e" : "")
1925 << ((accEmax) ? " pos_e" : "")
1926 << ((jumpZer) ? " underflow" : "")
1927 << ((jumpOve) ? " overflow" : "") );
1928
1929 }
1930 }
1931 }
1932
1933 std::ostringstream badstr;
1934 badstr << " ch: " << nChBad1 << " + " << nChBad2 << " = " << nChBad << " / " << nChTot << " = " << 100*nChBad/nChTot
1935 << " % dmu: " << nDmuBad1 << " + " << nDmuBad2 << " = " << nDmuBad << " / " << nDmuTot << " ";
1936 for (int dmu=0; dmu<16; ++dmu) {
1937 if (nChDmu[dmu]>0) {
1938 badstr << " " << std::hex << dmu << "=" << nChBadDmu[dmu] << "/" << nChDmu[dmu];
1939 }
1940 }
1941 ATH_MSG_VERBOSE (evtnum.str()
1942 << " drw " << drwname(digitsCollection->identify()) << badstr.str());
1943 }
1944 }
1945
1946 if (nConst) {
1947 ++m_const;
1948 statusOk = true;
1949 ATH_MSG_DEBUG( nevtnum.str()
1950 << " n_const_sample_errors = " << nConst
1951 << " accepted");
1952 }
1953 if (nJump) {
1954 ++m_jump;
1955 statusOk = true;
1956 ATH_MSG_DEBUG( nevtnum.str()
1957 << " n_jump_sample_errors = " << nJump
1958 << " accepted");
1959 }
1960 if (nOverLG) {
1961 ++m_overLG;
1962 statusOk = true;
1963 ATH_MSG_DEBUG( nevtnum.str()
1964 << " n_overflow_LG = " << nOverLG
1965 << " accepted");
1966 }
1967 if (nOverHG) {
1968 ++m_overHG;
1969 statusOk = true;
1970 ATH_MSG_DEBUG(nevtnum.str()
1971 << " n_overflow_HG = " << nOverHG
1972 << " accepted");
1973 }
1974 if (nUnderLG) {
1975 ++m_underLG;
1976 statusOk = true;
1977 ATH_MSG_DEBUG( nevtnum.str()
1978 << " n_underflow_LG = " << nUnderLG
1979 << " accepted");
1980 }
1981 if (nUnderHG) {
1982 ++m_underHG;
1983 statusOk = true;
1984 ATH_MSG_DEBUG(nevtnum.str()
1985 << " n_underflow_HG = " << nUnderHG
1986 << " accepted");
1987 }
1988 if (nDmuErr) {
1989 ++m_dmuerr;
1990 statusOk = true;
1991 ATH_MSG_DEBUG( nevtnum.str()
1992 << " n_DMU_errors = " << nDmuErr
1993 << " accepted");
1994 }
1995 }
1996 }
1997
1998 if (m_printOnly)
1999 this->setFilterPassed (false, ctx);
2000 else
2001 this->setFilterPassed (statusOk, ctx);
2002
2003 if (statusOk) {
2004 ++m_accept;
2005 //ATH_MSG_VERBOSE (nevtnum.str() << " accepted");
2006 } else {
2007 //ATH_MSG_VERBOSE (nevtnum.str() << " rejected");
2008 }
2009
2010 return StatusCode::SUCCESS;
2011}
2012
2013
2014// this method is not used for the moment
2015void TileCellSelector::printCell(const TileCell * tile_cell) {
2016 if (tile_cell==0) return;
2017
2018 // int drw = 0; // drawer number, range 0-63, the same for both channels
2019 // int ch1 = -1, ch2 = -1; // channel number, range 0-47 or -1 for unknown
2020 int ros1 = 0, ros2 = 0;
2021
2022 const CaloDetDescrElement * caloDDE = tile_cell->caloDDE();
2023 //Identifier id = tile_cell->ID();
2024
2025 IdentifierHash hash1 = caloDDE->onl1();
2026 if (hash1 != TileHWID::NOT_VALID_HASH) {
2027 HWIdentifier hw1 = m_tileHWID->channel_id(hash1);
2028 //ch1 = m_tileHWID->channel(hw1);
2029 //drw = m_tileHWID->drawer(hw1);
2030 ros1 = m_tileHWID->ros(hw1);
2031 }
2032
2033 IdentifierHash hash2 = caloDDE->onl2();
2034 if (hash2 != TileHWID::NOT_VALID_HASH) {
2035 HWIdentifier hw2 = m_tileHWID->channel_id(hash2);
2036 //ch2 = m_tileHWID->channel(hw2);
2037 //drw = m_tileHWID->drawer(hw2);
2038 ros2 = m_tileHWID->ros(hw2);
2039 if (ros1 == 0) ros1=ros2;
2040 } else {
2041 ros2 = ros1;
2042 }
2043
2044 // something is wrong
2045 if (ros1 == 0) return;
2046 /*
2047 int module = m_tileID->module(id);
2048
2049 int samp = m_tileID->sample(id);
2050
2051 bool single_PMT_scin = (samp == TileID::SAMP_E);
2052 bool single_PMT_C10 = (m_tileID->section(id) == TileID::GAPDET &&
2053 samp == TileID::SAMP_C &&
2054 (! m_cabling->C10_connected(m_tileID->module(id))) );
2055
2056 // distinguish cells with one or two PMTs
2057 bool single_PMT = single_PMT_C10 || single_PMT_scin;
2058
2059 // distinguish normal cells and fantoms (e.g. non-existing D4 in EBA15, EBC18
2060 // or non-existing E3/E4 - they might appear in CaloCellContainer)
2061 bool real_cell = single_PMT_C10 || m_cabling->TileGap_connected(id);
2062
2063 // note that in single PMT cell both badch1() and badch2() are changed together
2064 bool badch1 = (tile_cell->badch1());
2065 bool badch2 = (tile_cell->badch2());
2066
2067 // 0 = both PMTs are good; 1= 1 PMT is bad; 2= both PMTs are bad, or PMT is bad for single PMT cell
2068 int cell_isbad = (int)badch1 + (int)badch2;
2069
2070 int gn1 = tile_cell->gain1(); // gain of first PMT
2071 int gn2 = tile_cell->gain2(); // gain of second PMT
2072
2073 bool ch1Ok = (ch1>-1 && gn1 != CaloGain::INVALIDGAIN);
2074 bool ch2Ok = (ch2>-1 && gn2 != CaloGain::INVALIDGAIN);
2075
2076 // get the cell energy, time and position info
2077 double energy = tile_cell->energy();
2078 double time = tile_cell->time();
2079 double eta = tile_cell->eta();
2080 double phi = tile_cell->phi();
2081 double ene1 = tile_cell->ene1();
2082 double ene2 = tile_cell->ene2();
2083 double ediff = (single_PMT) ? 0.0 : tile_cell->eneDiff();
2084 double eratio = (energy!=0.0) ? ediff/energy : 0.0;
2085 double t1 = tile_cell->time1();
2086 double t2 = tile_cell->time2();
2087 double tdiff = (single_PMT) ? 0.0 : tile_cell->timeDiff();
2088 */
2089}
2090
2092 //ATH_MSG_DEBUG ("finalize()");
2093
2094 ATH_MSG_INFO ("Processed " << m_counter << " events, accepted " << m_accept
2095 << " (" << m_minCell << "/" << m_minChan
2096 << "," << m_maxCell << "/" << m_maxChan
2097 << "," << m_jump << "/" << m_const
2098 << "," << m_overLG << "/" << m_overHG
2099 << "," << m_underLG << "/" << m_underHG
2100 << "," << m_dqerr << "/" << m_dmuerr
2101 << "," << m_warnerr << ") events.");
2102
2103 //ATH_MSG_DEBUG ("finalize() successful");
2104
2105 return StatusCode::SUCCESS;
2106}
2107
2108// copy of the function from OptFilter
2109// to see which channels will be masked
2110int TileCellSelector::Are3FF(std::vector<float> & OptFilterDigits, int gain, int ch_type) {
2111 bool allSaturated = true;
2112 int error = 0;
2113
2114 unsigned int nSamp = OptFilterDigits.size();
2115 if (nSamp) {
2116 float dmin = OptFilterDigits[0];
2117 float dmax = dmin;
2118
2119 for (unsigned int i = 1; i < nSamp; ++i) {
2120 float dig = OptFilterDigits[i];
2121 if (dig > dmax) dmax = dig;
2122 else if (dig < dmin) dmin = dig;
2123 }
2124 allSaturated = (dmin > m_ADCmaxMinusEps);
2125
2126 // FIXME:: set these parameters from JobOptions
2127 // FIXME:: move this method to base class
2128 const float epsilon = 4.1; // allow +/- 2 counts fluctuations around const value
2129 const float delta[4] = {29.9, 29.9, 49.9, 99.9}; // jump levels between constLG, constHG, non-constLG, non-constHG
2130 const float level0 = 29.9; // jump from this level to zero is bad
2131 const float level1 = 99.9; // jump from this level to m_tileInfo->ADCmax() is bad
2132 const float level2 = 199.9; // base line at this level is bad
2133 const float delt = std::min(std::min(std::min(delta[0], delta[1]), std::min(delta[2], delta[3])), level0);
2134
2135 if (!allSaturated && (dmax - dmin) > delt) {
2136 float abovemin = dmax;
2137 float belowmax = dmin;
2138 unsigned int nmin = 0;
2139 unsigned int nmax = 0;
2140 unsigned int pmin = nSamp;
2141 unsigned int pmax = nSamp;
2142 for (unsigned int i = 0; i < nSamp; ++i) {
2143 float smp = OptFilterDigits[i];
2144 if (smp - dmin < epsilon) {
2145 ++nmin;
2146 pmin = i;
2147 }
2148 if (dmax - smp < epsilon) {
2149 ++nmax;
2150 pmax = i;
2151 }
2152 if (smp < abovemin && smp > dmin) {
2153 abovemin = smp;
2154 }
2155 if (smp > belowmax && smp < dmax) {
2156 belowmax = smp;
2157 }
2158 }
2159
2160 if (abovemin != dmax || belowmax != dmin) { // more than two different values
2161 gain += 2; // shift index by 2, i.e. use thresholds for non-const levels
2162 }
2163
2164 if (dmin < 0.01 && dmax > m_ADCmaxMinusEps) { // jump from zero to saturation
2165 error = 1;
2166 } else if (dmin < 0.01 && abovemin > level0 && nmin > 1) { // at least two samples at zero, others - above pedestal
2167 error = 2;
2168 } else if (dmax > m_ADCmaxMinusEps && belowmax < level1 && nmax > 1) { // at least two saturated. others - close to pedestal
2169 error = 3;
2170 } else if (dmin>level2 && (gain==0 || ch_type<2) ) { // baseline above threshold is bad
2171 error = 9; // but should not apply that to MBTS
2172 } else if (nmax+nmin==nSamp && (dmax-dmin) > delta[gain]) {
2173 if (nmax>1 && nmin>1) { // at least 2 samples at two distinct levels
2174 error = 4;
2175 } else if (nmax==1) {
2176 if (pmax>0 && pmax<nSamp-1) { // jump up in one sample, but not at the edge
2177 error = 5;
2178 }
2179 } else if (nmin==1) { // jump down in one sample
2180 error = 6;
2181 }
2182 }
2183 if (!error && (dmax - dmin) > delta[gain]) {
2184 float secondMax = (dmax - dmin) * m_secondMaxLevel;
2185 if (pmax > 0 && pmax < nSamp - 1
2186 && std::max(OptFilterDigits[pmax - 1], OptFilterDigits[pmax + 1]) < dmin + secondMax) {
2187
2188 error = 7; // jump up in one sample in the middle. which is much higher than all others
2189 } else if (pmin > 0 && pmin < nSamp - 1
2190 && std::min(OptFilterDigits[pmin - 1], OptFilterDigits[pmin + 1]) > dmax - secondMax) {
2191
2192 error = 8; // jump down in one sample. which is much lower than all others
2193 }
2194 }
2195 }
2196 }
2197
2198 if (allSaturated)
2199 return 99;
2200 else
2201 return error;
2202}
const std::regex rr(r_r)
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
const int nmax(200)
Handle class for reading from StoreGate.
Provide helper functions to create formatted strings.
static std::string drwname(int id)
#define ptnlength
static const Attributes_t empty
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
virtual void setFilterPassed(bool state, const EventContext &ctx) const
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
double energy() const
get energy (data member)
Definition CaloCell.h:327
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
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 class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const TileCablingService * getInstance()
get pointer to service instance
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
std::vector< float > m_chanEne
bool m_bitTimeCell[ptnlength]
const TileCablingService * m_cabling
std::vector< int > m_chanToCheck
unsigned int m_minCell
int Are3FF(std::vector< float > &OptFilterDigits, int OptFilterGain, int ch_type)
std::vector< float > m_chanDsp
bool m_bitEneChan[3][ptnlength]
ToolHandle< ITileBadChanTool > m_tileBadChanTool
unsigned int m_jump
unsigned int m_runNum
unsigned int m_lumiBlock
SG::ReadHandleKey< TileDQstatus > m_dqStatusKey
std::vector< bool > m_chanSel
unsigned int m_evtBCID
unsigned int m_evtNum
TileCellSelector(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< bool > m_chanToSkip
unsigned int m_warnerr
ToolHandle< ITileDCSTool > m_tileDCS
unsigned int m_const
void printCell(const TileCell *cell)
unsigned int m_underLG
virtual StatusCode initialize() override
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
unsigned int m_dmuerr
std::vector< int > m_drawerToCheck
std::vector< bool > m_chanBad
bool m_bitTimeChan[3][ptnlength]
unsigned int m_underHG
SG::ReadHandleKey< TileDigitsContainer > m_digitsContainerKey
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
unsigned int m_counter
unsigned int m_maxCell
std::vector< int > m_drawer
unsigned int m_tileFlag
unsigned int m_accept
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
unsigned int m_overLG
virtual StatusCode finalize() override
const TileHWID * m_tileHWID
std::vector< int > m_nDrawerOff
std::vector< float > m_chanTime
unsigned int m_maxChan
unsigned int m_minChan
std::vector< bool > m_drawerToSkip
const TileInfo * m_tileInfo
unsigned int m_overHG
const TileID * m_tileID
std::vector< float > m_chanTDsp
std::vector< float > m_chanQua
unsigned int m_tileError
unsigned int m_dqerr
bool m_bitEneCell[ptnlength]
uint8_t qual1(void) const
get quality of first PMT (data member)
Definition TileCell.h:197
float time1(void) const
get time of first PMT
Definition TileCell.h:192
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
bool badch1(void) const
check if first PMT is in bad channel list and masked
Definition TileCell.h:209
uint8_t qbit2(void) const
get quality bits of second PMT (data member)
Definition TileCell.h:206
int gain1(void) const
get gain of first PMT
Definition TileCell.cxx:168
uint8_t qual2(void) const
get quality of second PMT (data member)
Definition TileCell.h:200
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
bool badch2(void) const
check if second PMT is in bad channel list and masked
Definition TileCell.h:212
float time2(void) const
get time of second PMT
Definition TileCell.h:194
@ MASK_OVER
Definition TileCell.h:64
@ MASK_CMPC
Definition TileCell.h:66
uint8_t qbit1(void) const
get quality bits of first PMT (data member)
Definition TileCell.h:203
float ene2(void) const
get energy of second PMT
Definition TileCell.h:189
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
static int isChEmpty(int partition, int drawer, int ch)
True if channel is not fully implemented.
@ NOT_VALID_HASH
Definition TileHWID.h:314
static int CorruptedData(int ros, int drawer, int channel, int gain, const std::vector< float > &digits, float &dmin, float &dmax, float ADCmaxMinusEps, float ADCmaskValueMinusEps)
float time(int ind=0) const
float amplitude(int ind=0) const
HWIdentifier adc_HWID(void) const
Definition TileRawData.h:53
@ Tile
The Tile calorimeter.
@ Warning
The sub-detector issued a warning.
@ Error
The sub-detector issued an error.
std::string strformat(const char *fmt,...)
return a std::string according to a format fmt and varargs
Definition StrFormat.cxx:49
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
EventInfo_v1 EventInfo
Definition of the latest event info version.