ATLAS Offline Software
Loading...
Searching...
No Matches
TileCellBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Tile includes
20
21// Calo includes
24#include "CaloDetDescr/CaloDetDescrElement.h"
27
28// Atlas includes
34
35#include "CLHEP/Units/SystemOfUnits.h"
36using CLHEP::MeV;
37
38// uncomment line below for debug output
39// #define ALLOW_DEBUG_COUT 1
40
41static const InterfaceID IID_ITileCellBuilder("TileCellBuilder", 1, 0);
42
43const InterfaceID& TileCellBuilder::interfaceID( ) {
45}
46
47//Constructor
48TileCellBuilder::TileCellBuilder(const std::string& type, const std::string& name,
49 const IInterface* parent)
50 : base_class(type, name, parent)
51 , m_eneForTimeCut(35. * MeV) // keep time only for cells above 70 MeV (more than 35 MeV in at least one PMT to be precise)
52 , m_eneForTimeCutMBTS(0.03675) // the same cut for MBTS, but in pC, corresponds to 3 ADC counts or 35 MeV
53 , m_qualityCut(254) // cut on overflow in quality (if quality is 255 - assume that channel is bad)
54 , m_eThreshold(-100000.)
55 , m_maxTimeDiff(100000.)
56 , m_maxTime (100000.)
57 , m_minTime(-100000.)
58 , m_maxChi2(100000.)
59 , m_minChi2(-100000.)
60 , m_thresholdNotSet(true)
61 , m_fullSizeCont(true)
62 , m_maskBadChannels(true)
63 , m_fakeCrackCells(false)
64 , m_tileID(nullptr)
65 , m_tileTBID(nullptr)
66 , m_tileHWID(nullptr)
67 , m_cabling(nullptr)
68 , m_tileMgr(nullptr)
69 , m_mbtsMgr(nullptr)
71 , m_run2(false)
72 , m_tileInfo(0)
73 , m_run2plus(false)
74{
75 declareInterface<TileCellBuilder>( this );
76
77 //memset(m_drawerRunStatus, 0, sizeof(m_drawerRunStatus));
78 //memset(m_eventErrorCounter, 0, sizeof(m_eventErrorCounter));
79
80 // never set energy to zero, but set it to some small number
81 // this will help TopoCluster to assign proper weight to the cell if needed
82 m_zeroEnergy = 0.5 * MeV; // half a MeV in both PMTs i.e. one MeV in a cell
83
85 m_minEneChan[0] = -5000. * MeV;
87 m_minEneChan[1] = -10000. * MeV;
89 m_minEneChan[2] = -999999. * MeV;
90
91 declareProperty( "MinEnergyChan", m_minEneChan[0]);
92 declareProperty( "MinEnergyGap", m_minEneChan[1]);
93 declareProperty( "MinEnergyMBTS", m_minEneChan[2]);
94
95 // Energy threshold in MeV that the Cell must exceed to be considered:
96 declareProperty("EThreshold",m_eThreshold);
97
98 // Maximum difference between times of two PMTs in cell:
99 declareProperty("MaxTimeDiff", m_maxTimeDiff);
100
101 // Maximum and minimum time for a cell to be included:
102 declareProperty("MaxTime", m_maxTime);
103 declareProperty("MinTime", m_minTime);
104
105 // Maximum and Minimum fit quality for cell to be considered:
106 declareProperty("MaxChi2", m_maxChi2);
107 declareProperty("MinChi2", m_minChi2);
108
109 declareProperty("fullSizeCont", m_fullSizeCont);
110
111 // put zero energy in bad channels and recover from single-channel failure using second PMT is a cell
112 declareProperty("maskBadChannels", m_maskBadChannels);
113
114 // create fake E3/E4 crack scintillators with zero energy when they do not exist
115 declareProperty("fakeCrackCells", m_fakeCrackCells);
116
117 // PMT energy will be set to this value if channel is bad
118 declareProperty("BadChannelZeroEnergy", m_zeroEnergy);
119 // PMT with energy above cut will preserve time info in ESD
120 declareProperty("EneForTimeCut", m_eneForTimeCut);
121 declareProperty("EneForTimeCutMBTS", m_eneForTimeCutMBTS);
122 // PMT with quality greater than this cut will be masked
123 declareProperty("QualityCut", m_qualityCut);
124
125 // apply time correction taking numbers from CondDB (if not yet done in OF)
126 declareProperty("correctTime", m_correctTime = false);
127
128 // apply parabolic amplitude correction (if not yet done in OF without iterations)
129 declareProperty("correctAmplitude", m_correctAmplitude = false);
130
131 // use parabolic amplitude correction for OF2 or OF1 method
132 declareProperty("OF2", m_of2 = true);
133
134 // merge DSP results with offline reco results
135 declareProperty("mergeChannels", m_mergeChannels = true);
136
137 // thresholds for parabolic amplitude correction
138 declareProperty("AmpMinForAmpCorrection", m_ampMinThresh = 15.0);
139 declareProperty("TimeMinForAmpCorrection", m_timeMinThresh = -12.5);
140 declareProperty("TimeMaxForAmpCorrection", m_timeMaxThresh = 12.5);
141
142 declareProperty("SkipGain", m_skipGain = -1); // never skip any gain by default
143
144 declareProperty("UseDemoCabling", m_useDemoCabling = 0); // if set to 2015 - assume TB 2015 cabling
145
146 declareProperty("TileInfoName", m_infoName = "TileInfo");
147
148 declareProperty("CheckDCS", m_checkDCS = false);
149}
150
156
161
162 // retrieve MBTS and Tile detector manager, TileID helper and TileIfno from det store
163 if (m_MBTSContainerKey.key().empty()) {
164 m_mbtsMgr = nullptr;
165 } else {
166
167 ATH_CHECK( m_MBTSContainerKey.initialize() );
168 ATH_MSG_INFO( "Storing MBTS cells in " << m_MBTSContainerKey.key() );
169
170 if (detStore()->retrieve(m_mbtsMgr).isFailure()) {
171 ATH_MSG_WARNING( "Unable to retrieve MbtsDetDescrManager from DetectorStore" );
172 m_mbtsMgr = nullptr;
173 }
174 }
175
176 ATH_CHECK( m_eventInfoKey.initialize() );
177 ATH_CHECK( m_DQstatusKey.initialize() );
178 ATH_CHECK( m_EventInfoTileStatusKey.initialize() );
179 ATH_CHECK( m_emScaleKey.initialize() );
180
181 ATH_CHECK( detStore()->retrieve(m_tileMgr) );
182 ATH_CHECK( detStore()->retrieve(m_tileID) );
183 ATH_CHECK( detStore()->retrieve(m_tileTBID) );
184 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
185
186 ATH_CHECK( m_badChannelsKey.initialize() );
187
188 // access tools and store them
189 ATH_CHECK( m_noiseFilterTools.retrieve() );
190
191 //=== get TileCondToolTiming
192 ATH_CHECK( m_tileToolTiming.retrieve() );
193
194 ATH_CHECK( m_DCSStateKey.initialize(m_checkDCS) );
195
196 ATH_CHECK( m_cablingSvc.retrieve() );
197 m_cabling = m_cablingSvc->cablingService();
198
199 reset(true, false);
200
201 m_run2 = m_cabling->isRun2Cabling();
202 m_run2plus = m_cabling->isRun2PlusCabling();
203
204 if (m_run2 && !m_E4prContainerKey.key().empty()) {
205 ATH_CHECK( m_E4prContainerKey.initialize() );
206 ATH_MSG_INFO( "Storing E4' cells in " << m_E4prContainerKey.key() );
207 } else {
208 m_E4prContainerKey = ""; // no E4' container for RUN1
209 }
210
211 if (m_cabling->getCablingType() == TileCablingService::UpgradeABC) {
213 m_notUpgradeCabling = false;
214 }
215
216 ATH_CHECK( m_rawChannelContainerKey.initialize() );
217
219 || m_dspRawChannelContainerKey.key().empty())) {
220 m_mergeChannels = false;
221 }
222
224 ATH_CHECK( m_eventInfoKey.initialize() );
225
226 ATH_MSG_INFO( "TileCellBuilder initialization completed" );
227
228 //=== get TileInfo
229 ATH_CHECK( detStore()->retrieve(m_tileInfo, m_infoName) );
230 m_ADCmaskValueMinusEps = m_tileInfo->ADCmaskValue() - 0.01; // indicates channels which were masked in background dataset
231 m_ADCmaskValuePlusEps = m_tileInfo->ADCmaskValue() + 0.01; // indicates channels which were masked in background dataset
232
233 return StatusCode::SUCCESS;
234}
235
236void TileCellBuilder::reset(bool /* fullSizeCont */, bool printReset) {
237
238 if (printReset) ATH_MSG_INFO( "Resetting options in " << name() );
239
240 // check if any threshold was set in jobOptions
241 m_thresholdNotSet = ((fabs(m_eThreshold + 100000.) < 1)
242 && (fabs(m_maxTimeDiff - 100000.) < 1)
243 && (fabs(m_maxTime - 100000.) < 1)
244 && (fabs(m_minTime + 100000.) < 1)
245 && (fabs(m_maxChi2 - 100000.) < 1)
246 && (fabs(m_minChi2 + 100000.) < 1));
247
248 if (m_thresholdNotSet) {
249 ATH_MSG_INFO( "none of thresholds set, all RawChannels will be converted to Cells");
250 } else {
251 ATH_MSG_INFO( "Ene threshold " << m_eThreshold << " MeV" );
252 ATH_MSG_INFO( "max time diff " << m_maxTimeDiff << " ns" );
253 ATH_MSG_INFO( "max time thr " << m_maxTime << " ns" );
254 ATH_MSG_INFO( "min time thr " << m_minTime << " ns" );
255 ATH_MSG_INFO( "max qual thr " << m_maxChi2 );
256 ATH_MSG_INFO( "min qual thr " << m_minChi2 );
257 }
258
259 // prepare empty vector for all cell pointers
260 m_fullSizeCont = true;
261
262 ATH_MSG_INFO( "taking RawChannels from '" << m_rawChannelContainerKey.key() << "'" );
263}
264
266
267 ATH_MSG_INFO( "Finalizing" );
268
269 return StatusCode::SUCCESS;
270}
271
272StatusCode TileCellBuilder::process (CaloCellContainer* theCellContainer,
273 const EventContext& ctx) const
274{
275 //**
276 //* Get TileRawChannels
277 //**
278
279 TileDrawerEvtStatusArray drawerEvtStatus;
280
282
283 if (!rawChannelContainer.isValid()) {
284 ATH_MSG_WARNING( " Could not find container " << m_rawChannelContainerKey.key() );
285 ATH_MSG_WARNING( " do not fill CaloCellContainer " );
286
287 } else {
288
289 ATH_MSG_DEBUG( "Container " << m_rawChannelContainerKey.key() << " with TileRawChannels found ");
290
291
292 VecParams params;
293 params.m_RChType = rawChannelContainer->get_type();
294 params.m_RChUnit = rawChannelContainer->get_unit();
295 params.m_correctAmplitude = m_correctAmplitude;
296 params.m_correctTime = m_correctTime;
297 params.m_of2 = m_of2;
298 unsigned int bsflags = rawChannelContainer->get_bsflags();
299 if (params.m_correctAmplitude || params.m_correctTime) {
300 int DataType = (bsflags & 0x30000000) >> 28;
301 if (DataType < 3) { // real data
302 bool of2 = ((bsflags & 0x4000000) != 0);
303 if (of2 != params.m_of2) {
304 params.m_of2 = of2;
305 ATH_MSG_WARNING( "OF2 flag in data is " << ((params.m_of2)?"True":"False"));
306 }
307 params.m_maxTimeCorr = 63.9375; // 64-1/16 ns is hard limit in DSP
308 if (params.m_correctAmplitude && ((bsflags & 0x3000000) != 0)) {
309 ATH_MSG_WARNING( "Using results of Opt filter with interations from DSP, disabling amplitude correction" );
310 params.m_correctAmplitude = false;
311 }
312 if (params.m_correctTime && ((bsflags & 0x3000000) == 0)) {
313 ATH_MSG_WARNING( "Using results of Opt filter without interations from DSP, disabling time correction" );
314 params.m_correctTime = false;
315 }
316 } else {
317 params.m_maxTimeCorr = ((bsflags >> 27) & 1) ? 100.0 : 75.0; // 100 or 75 ns is the limit for 9 or 7 samples
318 if (params.m_correctAmplitude && ((bsflags & 0x6000) != 0)) {
319 ATH_MSG_WARNING( "Amplitude correction was done already in optimal filter, disabling it here" );
320 params.m_correctAmplitude = false;
321 }
322 if (params.m_correctTime && ((bsflags & 0x9000) != 0)) {
323 ATH_MSG_WARNING( "Time correction was done already in optimal filter or best phase is used, disabling it here" );
324 params.m_correctTime = false;
325 }
326 }
327 }
328
329 std::unique_ptr<TileCellContainer> MBTSCells;
330 if (!m_MBTSContainerKey.key().empty()) {
331 MBTSCells = std::make_unique<TileCellContainer>(SG::VIEW_ELEMENTS);
332 }
333
334 std::unique_ptr<TileCellContainer> E4prCells;
335 if (!m_E4prContainerKey.key().empty()) {
336 E4prCells = std::make_unique<TileCellContainer>(SG::VIEW_ELEMENTS);
337 }
338
339 SelectAllObject<TileRawChannelContainer> selAll(rawChannelContainer.cptr());
340 SelectAllObject<TileRawChannelContainer>::const_iterator begin = selAll.begin();
341 SelectAllObject<TileRawChannelContainer>::const_iterator end = selAll.end();
342
345 && !m_dspRawChannelContainerKey.key().empty()) {
346
347 ATH_MSG_DEBUG( "Merging " << m_rawChannelContainerKey.key()
348 << " and " << m_dspRawChannelContainerKey.key() );
349
351
352 if (!dspRawChannelContainer.isValid()) {
353 // no DSP channels, build cells from primary container
354 ATH_MSG_DEBUG( " No " << m_dspRawChannelContainerKey.key() << " found, nothing to merge " );
355
356 } else {
357
358 const TileRawChannelContainer* dspContainer = dspRawChannelContainer.cptr();
359 std::unique_ptr<TileMutableRawChannelContainer> copiedDspContainer;
360
361 if (m_noiseFilterTools.size() > 0) {
362 ATH_MSG_DEBUG( " Running noise filter on " << m_dspRawChannelContainerKey.key()
363 << " (i.e. on second container only) " );
364
365 // apply noise filter on dsp container before merging it with offline container
366 copiedDspContainer = std::make_unique<TileMutableRawChannelContainer> (*dspContainer);
367 ATH_CHECK( copiedDspContainer->status() );
368 dspContainer = copiedDspContainer.get();
369
370 for (const ToolHandle<ITileRawChannelTool>& noiseFilterTool : m_noiseFilterTools) {
371 ATH_CHECK( noiseFilterTool->process(*copiedDspContainer, ctx) );
372 }
373 }
374
375 TileFragHash::TYPE dspType = dspContainer->get_type();
376 TileRawChannelUnit::UNIT dspUnit = dspContainer->get_unit();
377 unsigned int dspFlags = dspContainer->get_bsflags();
378 int DataType = (dspFlags & 0x30000000) >> 28;
379 float dspTimeCut = params.m_maxTimeCorr;
380 bool dspCorrectAmplitude = false, dspCorrectTime = false, dspOf2 = true;
381 if (DataType < 3) { // real data
382 dspOf2 = ((dspFlags & 0x4000000) != 0);
383 if (dspOf2 != params.m_of2) ATH_MSG_DEBUG( "OF2 flag in DSPcontainer is " << ((dspOf2)?"True":"False"));
384 dspTimeCut = 63.9375; // 64-1/16 ns is hard limit in DSP
385 dspCorrectAmplitude = ((dspFlags & 0x3000000) == 0);
386 dspCorrectTime = ((dspFlags & 0x3000000) != 0);
387 } else { // dsp container contains results of offline reco
388 dspTimeCut = ((dspFlags >> 27) & 1) ? 100.0 : 75.0; // 100 or 75 ns is the limit for 9 or 7 samples
389 }
390
391 SelectAllObject<TileRawChannelContainer> selAllDsp(dspContainer);
392 SelectAllObject<TileRawChannelContainer>::const_iterator beginDsp = selAllDsp.begin();
393 SelectAllObject<TileRawChannelContainer>::const_iterator endDsp = selAllDsp.end();
394
395 std::vector<const TileRawChannel *> oflVec;
396 std::vector<const TileRawChannel *> dspVec;
397
398 SelectAllObject<TileRawChannelContainer>::const_iterator oflItr = begin;
399 SelectAllObject<TileRawChannelContainer>::const_iterator dspItr = beginDsp;
400
401 if (oflItr != end) {
402 const TileRawChannel *p1 = (*oflItr);
403 HWIdentifier id1 = p1->adc_HWID();
404
405 for (; dspItr != endDsp; ++dspItr) {
406
407 const TileRawChannel *p2 = (*dspItr);
408 HWIdentifier id2 = p2->adc_HWID();
409
410 if (id2 < id1) {
411 dspVec.push_back(p2);
412 } else if (id2 == id1) {
413 oflVec.push_back(p1);
414 ++oflItr;
415 if (oflItr != end) {
416 p1 = (*oflItr);
417 id1 = p1->adc_HWID();
418 } else {
419 ++dspItr;
420 break;
421 }
422 } else {
423 while (id2 >= id1) {
424 oflVec.push_back(p1);
425 ++oflItr;
426 if (oflItr != end) {
427 p1 = (*oflItr);
428 bool id2gtid1 = (id2 > id1);
429 id1 = p1->adc_HWID();
430 if (id2gtid1 && (id2 < id1)) {
431 dspVec.push_back(p2); // id2 is in the gap between old and new id1 - keep it
432 }
433 } else {
434 if (id2 == id1) ++dspItr;
435 break;
436 }
437 }
438 if (id2 >= id1) break;
439 }
440 }
441 // copy all remaining channels
442 for (; oflItr != end; ++oflItr) {
443 oflVec.push_back(*oflItr);
444 }
445 }
446 for (; dspItr != endDsp; ++dspItr) {
447 dspVec.push_back(*dspItr);
448 }
449
450 VecParams params1 = params;
451 VecParams params2;
452 params2.m_RChType = dspType;
453 params2.m_RChUnit = dspUnit;
454 params2.m_maxTimeCorr = dspTimeCut;
455 params2.m_correctAmplitude = dspCorrectAmplitude;
456 params2.m_correctTime = dspCorrectTime;
457 params2.m_of2 = dspOf2;
458
459 // build here with special iterator over 2 vectors
461 params,
462 &oflVec, params1,
463 &dspVec, params2, 0);
465 params,
466 &oflVec, params1,
467 &dspVec, params2, 2);
468
469 ATH_MSG_DEBUG("Build raw channels from two vectors:"
470 << " offline vector size = " << oflVec.size()
471 << ", dsp vector size = " << dspVec.size() );
472
473 build (ctx, drawerEvtStatus, params, vecBeg, vecEnd, theCellContainer,
474 MBTSCells.get(), E4prCells.get());
475 begin = end;
476 }
477
478 }
479
480 if (begin != end) { // no merging applied, use original raw channel container
481
482 std::unique_ptr<TileMutableRawChannelContainer> copiedContainer;
483 std::unique_ptr<SelectAllObject<TileRawChannelContainer> > selCopied;
484
485 if (m_noiseFilterTools.size() > 0) {
486 ATH_MSG_DEBUG( " Running noise filter on " << m_rawChannelContainerKey.key() );
487 // apply noise filter on input container before sending it to the build() method
488 copiedContainer = std::make_unique<TileMutableRawChannelContainer> (*rawChannelContainer);
489 ATH_CHECK( copiedContainer->status() );
490
491 for (const ToolHandle<ITileRawChannelTool>& noiseFilterTool : m_noiseFilterTools)
492 {
493 ATH_CHECK( noiseFilterTool->process(*copiedContainer, ctx) );
494 }
495
496 selCopied = std::make_unique<SelectAllObject<TileRawChannelContainer> > (copiedContainer.get());
497 begin = selCopied->begin();
498 end = selCopied->end();
499 }
500
501 ATH_MSG_DEBUG( " Calling build() method for rawChannels from " << m_rawChannelContainerKey.key() );
502 build (ctx, drawerEvtStatus, params, begin, end, theCellContainer,
503 MBTSCells.get(), E4prCells.get());
504 }
505
506 if (!m_MBTSContainerKey.key().empty()) {
508 ATH_CHECK( MBTSContainer.record(std::move(MBTSCells)) );
509 }
510
511 if (!m_E4prContainerKey.key().empty()) {
513 ATH_CHECK( E4prContainer.record(std::move(E4prCells)) );
514 }
515
517
518 //specify that a given calorimeter has been filled
519 theCellContainer->setHasCalo(caloNum);
520 }
521
522 //enum EventFlagErrorState { NotSet, Warning, Error };
524 // flag will contain status of a given event
525 // every 4 bits - status of partitions LBA,LBC,EBA,EBC
526 // bits 0-3 - there is a signal above threshold in partitions
527 // bits 4-7 - there are channels with underflow (sample=0) in partition (since rel 17.2.6.4)
528 // bits 8-11 - there are channels with overflow (sample=m_tileInfo->ADCmax()) in partition (since rel 17.2.6.4)
529 // bits 12-15 - there are at least 16 drawers with bad quality in partition
530 // bits 16-19 - maximal length of consecutive bad area (since rel 17.2.6.5)
531 // bits 20-23 - there are at least 16 drawers which are completely masked in partition
532 // bits 24-27 - there are at least 16 drawers which do not send data in partition
533 // bits 28-31 - reserved for global good/warning/bad status
534 // bits 20-27 are also used for module number which gives warning status (since release 17.2.6.5)
535 // in case of warning we are sure that bits which indicates error are not filled
536 unsigned int flag = 0;
537
538 int drConsecMaxMax = 0;
539 int drConsecNum = 0;
540
541 for (int p = 1; p < 5; ++p) {
542 TileDrawerEvtStatus * evt = drawerEvtStatus[p];
543 //TileDrawerRunStatus * run = m_drawerRunStatus[p];
544 int drAbsent = 0;
545 int drMasked = 0;
546 int drConsec = 0;
547 int drConsecMax = 0;
548 int hasBadQ = 0;
549 int hasOver = 0;
550 int hasUnder = 0;
551 int hasSig = 0;
552 for (int d = 0; d < 64; ++d) {
553 if (evt[d].nChannels == 0) {
554 ++drConsec;
555 ++drAbsent;
556 //++(run[d].drawerAbsent);
557 } else if (evt[d].nMaskedChannels >= evt[d].nChannels) {
558 ++drConsec;
559 ++drMasked;
560 //++(run[d].drawerMasked);
561 } else {
562 if (drConsec > drConsecMax) {
563 drConsecMax = drConsec;
564 if (drConsecMax > drConsecMaxMax) {
565 drConsecMaxMax = drConsecMax;
566 drConsecNum = ((p - 1) << 6) | (d - drConsec);
567 }
568 }
569 drConsec = 0;
570 if (evt[d].nMaskedChannels > 0) {
571 //++(run[d].channelsMasked);
572 }
573 if (evt[d].nBadQuality) ++hasBadQ;
574 if (evt[d].nOverflow) ++hasOver;
575 if (evt[d].nUnderflow) ++hasUnder;
576 if (evt[d].nSomeSignal) ++hasSig;
577 }
578 }
579 if (drConsec != 0 && drConsecMax < 64) { // 64th drawer is bad - check transition from 64th to 1st drawer
580 for (int d = 0; d < drConsecMax; ++d) {
581 if (evt[d].nChannels == 0 || evt[d].nMaskedChannels >= evt[d].nChannels) {
582 ++drConsec;
583 } else {
584 break;
585 }
586 }
587 if (drConsec > drConsecMax) {
588 drConsecMax = drConsec;
589 }
590 }
591 unsigned int fl = 0;
592 if (drAbsent > 15) {
593 fl |= 0x01000000;
595 }
596 if (drMasked > 15) {
597 fl |= 0x00100000;
599 }
600 //if (drConsecMax > 1)fl |= 0x00010000; // want to use these bits for length of consecutive area
601 if (hasBadQ > 15) fl |= 0x00001000;
602 if (hasOver) fl |= 0x00000100;
603 if (hasUnder) fl |= 0x00000010;
604 if (hasSig) fl |= 0x00000001;
605
606#ifdef ALLOW_DEBUG_COUT
607 std::cout<<"partition "<<p<<" drAbsent "<<drAbsent<<" drMasked "<<drMasked<<" drConsec "<<drConsecMax
608 <<" hasBadQ "<<hasBadQ<<" hasOver "<<hasOver<<" hasUnder "<<hasUnder<<" hasSig "<<hasSig<<std::endl;
609#endif
610 flag |= fl << (p - 1);
611 }
612
613 // number of consecutively masked modules (if it's > 15 we have error already set)
614 flag |= (std::min(15, drConsecMaxMax) << 16);
615
616 if (drConsecMaxMax > 1 && error < xAOD::EventInfo::Warning) {
617 // setting warning flag
619 // putting starting module number of consecutive bad area
620 // instead of bits which indicates 16 masked or 16 absent modules in partition
621 flag |= (drConsecNum << 20);
622#ifdef ALLOW_DEBUG_COUT
623 std::cout<<"warning in partition " << (drConsecNum>>6)+1 << " for modules "
624 <<(drConsecNum)%64 <<" - " <<(drConsecNum+drConsecMaxMax-1)%64 <<std::endl;
625#endif
626 }
627
628#ifdef ALLOW_DEBUG_COUT
629 std::cout<<"partition flag 0x0"<<std::hex<<flag<<std::dec<<" error "<<error<<std::endl;
630#endif
631
632 //++m_eventErrorCounter[error]; // error index is 0 or 1 or 2 here
633 //++m_eventErrorCounter[3]; // count separately total number of events
634
635
636 // retrieve EventInfo
638
639 if (eventInfo.isValid()) {
640
641 if (flag != 0) {
642 ATH_MSG_DEBUG( " set eventInfo for Tile for this event to 0x" << MSG::hex << flag << MSG::dec );
643 if (!eventInfo->updateEventFlags(xAOD::EventInfo::Tile, flag)) {
644 ATH_MSG_WARNING( " cannot set eventInfo for Tile " );
645 }
646 }
647
649 ATH_MSG_DEBUG( " set error bits for Tile for this event to " << error );
650 if (!eventInfo->updateErrorState(xAOD::EventInfo::Tile, error)) {
651 ATH_MSG_WARNING( " cannot set error state for Tile " );
652 }
653 }
654
655 }
656 else {
657 ATH_MSG_WARNING( " cannot retrieve EventInfo, will not set Tile information " );
658 }
659
660 // Execution completed.
661 ATH_MSG_DEBUG( "TileCellBuilder execution completed." );
662
663 return StatusCode::SUCCESS;
664}
665
666//************************************************************************
667void TileCellBuilder::correctCell(TileCell* pCell, int correction, int pmt, int gain
668 , float ener, float time, unsigned char iqual, unsigned char qbit, int ch_type) const {
669//************************************************************************
670
671// Merge two pmts in one cell if needed
672// and apply corrections
673
674 // do not trust to energies below certain threshold
675 if (ener < m_minEneChan[ch_type]) {
676#ifdef ALLOW_DEBUG_COUT
677 std::cout << "channel with negative energy " << ener << " => setting quality to 255" << std::endl;
678#endif
679 iqual = 255;
680 }
681
682 switch (correction) {
683 case 1: // first pmt for this cell
684 pCell->addEnergy(ener, pmt, gain);
685 pCell->setTime(time); // overwrite time completely
686 pCell->setQuality(iqual, qbit, pmt);
687 pCell->setQuality(0, 0, 1 - pmt);
688 break;
689 case 2: // second pmt for this cell
690 pCell->addEnergy(ener, pmt, gain);
691 pCell->setTime(time, pmt); // calculate average time and timeDiff
692 pCell->setQuality(iqual, qbit, pmt);
693 break;
694 }
695}
696
697unsigned char TileCellBuilder::qbits (TileDrawerEvtStatusArray& drawerEvtStatus,
698 TileFragHash::TYPE RChType,
699 int ros,
700 int drawer,
701 bool count_over,
702 bool good_time,
703 bool good_ener,
704 bool overflow,
705 bool underflow,
706 bool overfit) const
707{
708 ++drawerEvtStatus[ros][drawer].nChannels;
709 // new feature in rel 17.2.7 - count underflows and overflows
710 if (count_over) {
711 if (overflow) ++drawerEvtStatus[ros][drawer].nOverflow;
712 if (underflow) ++drawerEvtStatus[ros][drawer].nUnderflow;
713 }
714#ifdef ALLOW_DEBUG_COUT
715 if (overflow) std::cout << "channel with overflow " << ((count_over)?"":"MBTS") << std::endl;
716 if (underflow) std::cout << "channel with underflow " << ((count_over)?"":"MBTS") << std::endl;
717 if (overfit) std::cout << "channel with corrected overflow " << ((count_over)?"":"MBTS") << std::endl;
718#endif
719
720 unsigned char qbit = (overfit) ? (TileFragHash::FitFilter & TileCell::MASK_ALGO)
721 : (RChType & TileCell::MASK_ALGO);
722 if (good_time) qbit |= TileCell::MASK_TIME;
723 if (overflow || underflow) qbit |= TileCell::MASK_OVER;
724
725 if (good_ener) {
726 qbit |= TileCell::MASK_AMPL;
727 if (count_over) {
728 ++drawerEvtStatus[ros][drawer].nSomeSignal;
729 }
730 }
731
732 return qbit;
733}
734
735// masking for MBTS with single channel
736bool
738 const TileDQstatus* DQstatus, const TileDCSState* dcsState,
739 const TileBadChannels* badChannels, TileCell* pCell, HWIdentifier hwid) const
740{
741 int ros = m_tileHWID->ros(hwid);
742 int drawer = m_tileHWID->drawer(hwid);
743 int chan = m_tileHWID->channel(hwid);
744 int gain = m_tileHWID->adc(hwid);
745 TileBchStatus chStatus = badChannels->getAdcStatus(hwid);
746
747 // check quality first
748 bool bad = ((int) pCell->qual1() > m_qualityCut);
749 if (bad) {
750 ++drawerEvtStatus[ros][drawer].nBadQuality;
751
752 } else {
753 // check bad status in DB
754 bad = chStatus.isBad();
755
756 // Now checking the DQ status
757 if (!bad && m_notUpgradeCabling && DQstatus) {
758 bad = !(DQstatus->isAdcDQgood(ros, drawer, chan, gain))
759 || (dcsState ? dcsState->isStatusBad(ros, drawer, chan) : false);
760 }
761 }
762
763 if (bad) {
764 // only one channel in this cell and it is bad
765 ++drawerEvtStatus[ros][drawer].nMaskedChannels;
766
767 //pCell->setEnergy(m_zeroEnergy,0.0,TileID::LOWGAIN,CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
768 //pCell->setTime(0.0); // reset time completely
769 //pCell->setQuality(255,TileCell::MASK_BADCH,0); // reset quality flag for first pmt
770
771 if (gain == CaloGain::INVALIDGAIN) {
772 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
773 } else {
774 pCell->setEnergy(0.0, 0.0); // reset energy completely without changing the gain
775 }
776 pCell->setTime(-100.0); // reset time to big negative number to distinguish this bad cell from good cells
777 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
778 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
779
780 return true;
781
782 } else if (chStatus.isBadTiming()) {
783 pCell->setTime(0.0); // channel with bad timing - no cell time
784 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
785 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
786 }
787
788 return false;
789}
790
791
792// masking for normal cells
794 const TileDQstatus* DQstatus, const TileDCSState* dcsState,
795 const TileBadChannels* badChannels, TileCell* pCell) const
796{
797 bool single_PMT_C10 = false;
798
799 const CaloDetDescrElement* caloDDE = pCell->caloDDE();
800
801 IdentifierHash hash1 = caloDDE->onl1();
802 IdentifierHash hash2 = caloDDE->onl2();
803
804 int gain1 = pCell->gain1();
805
806 HWIdentifier ch_id1 = m_tileHWID->channel_id(hash1);
807
808 int ros1 = m_tileHWID->ros(ch_id1);
809 int drawer1 = m_tileHWID->drawer(ch_id1);
810 int chan1 = m_tileHWID->channel(ch_id1);
811
812 HWIdentifier adc_id1 = m_tileHWID->adc_id(ros1, drawer1, chan1, ((gain1 < 0) ? 1 : gain1));
813 const TileBchStatus& chStatus1 = badChannels->getAdcStatus(adc_id1);
814
815 // check quality first
816 bool bad1 = ((int) pCell->qual1() > m_qualityCut);
817 if (bad1) {
818 ++drawerEvtStatus[ros1][drawer1].nBadQuality;
819
820 } else {
821 // check bad status in DB
822 bad1 = (gain1 < 0) || chStatus1.isBad();
823
824 // Now checking the DQ status
825 if (!bad1 && m_notUpgradeCabling && DQstatus) {
826 bad1 = !(DQstatus->isAdcDQgood(ros1, drawer1, chan1, gain1))
827 || (dcsState ? dcsState->isStatusBad(ros1, drawer1, chan1) : false);
828 }
829 }
830
831 if (hash2 == TileHWID::NOT_VALID_HASH) {
832 // gap/crack scintillators with one PMT per cell
833
834 if (bad1) {
835 // only one channel in this cell and it is bad
836 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
837
838 if (gain1 == CaloGain::INVALIDGAIN) {
839 pCell->setEnergy(m_zeroEnergy, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
840 } else {
841 pCell->setEnergy(m_zeroEnergy, 0.0); // reset energy completely without changing gain
842 }
843 pCell->setTime(0.0); // reset time completely
844 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
845 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
846
847 return true;
848
849 } else if (chStatus1.isBadTiming()) {
850 pCell->setTime(0.0); // channel with bad timing - no cell time
851 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
852 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
853 }
854
855 } else { //cell has both PMTs
856
857 int gain2 = pCell->gain2();
858
859 HWIdentifier ch_id2 = m_tileHWID->channel_id(hash2);
860
861 int ros2 = m_tileHWID->ros(ch_id2);
862 int drawer2 = m_tileHWID->drawer(ch_id2);
863 int chan2 = m_tileHWID->channel(ch_id2);
864
865 HWIdentifier adc_id2 = m_tileHWID->adc_id(ros2, drawer2, chan2, ((gain2 < 0) ? 1 : gain2));
866 const TileBchStatus& chStatus2 = badChannels->getAdcStatus(adc_id2);
867
868 // check quality first
869 bool bad2 = ((int) pCell->qual2() > m_qualityCut);
870 if (bad2) {
871 ++drawerEvtStatus[ros2][drawer2].nBadQuality;
872
873 } else {
874 // check bad status in DB
875 bad2 = (gain2 < 0) || chStatus2.isBad();
876
877 // Now checking the DQ status
878 if (!bad2 && m_notUpgradeCabling && DQstatus) {
879 bad2 = !(DQstatus->isAdcDQgood(ros2, drawer2, chan2, gain2))
880 || (dcsState ? dcsState->isStatusBad(ros2, drawer2, chan2) : false);
881 }
882 }
883
884 single_PMT_C10 = (((ros2 == TileHWID::EXTBAR_POS && chan1 == 4)
885 || (ros2 == TileHWID::EXTBAR_NEG && chan2 == 4))
886 && !m_cabling->C10_connected(drawer2));
887 if (single_PMT_C10) {
888 // for special C10 disconnected channel might be masked in DB
889 // and energy of good channel is taken twice with correct weight
890 // but if this channel is not masked in DB - set its bad status
891 // equal to bad status of real channel, so that cell is masked correctly
892 // if real channel connected to a cell is bad
893#ifdef ALLOW_DEBUG_COUT
894 static int cnt=0;
895 if (++cnt < 17) {
896 std::cout << "special C10 in " << ((ros2==TileHWID::EXTBAR_POS) ? "EBA" : "EBC")
897 << drawer2+1 << " status " << chan1 << "/" << chan2 << " "
898 << (chStatus1.isBad()?"bad":"good") << "/"
899 << (chStatus2.isBad()?"bad":"good") << "/"
900 << ((m_run2plus)?" RUN2+ cabling": "RUN1 cabling")
901 << std::endl;
902 }
903#endif
904 if (chan1 == 4) {
905 if (m_run2plus || !chStatus1.isBad()) {
906#ifdef ALLOW_DEBUG_COUT
907 if (cnt < 17) {
908 std::cout << "Ene of chan1 was " << pCell->ene1() << " changing to half of " << pCell->ene2()
909 << " and setting bad1=true" << std::endl;
910 }
911#endif
912 pCell->setEnergy(pCell->ene2()/2., pCell->ene2()/2., gain2, gain2);
913 //bad1 = bad2;
914 bad1 = true;
915 --drawerEvtStatus[ros1][drawer1].nMaskedChannels; // since it's fake masking, decrease counter by 1 in advance
916 }
917 } else {
918 if (m_run2plus || !chStatus2.isBad()) {
919#ifdef ALLOW_DEBUG_COUT
920 if (cnt < 17) {
921 std::cout << "Ene of chan2 was " << pCell->ene2() << " changing to half of " << pCell->ene1()
922 << " and setting bad2=true" << std::endl;
923 }
924#endif
925 pCell->setEnergy(pCell->ene1()/2., pCell->ene1()/2., gain1, gain1);
926 //bad2 = bad1;
927 bad2 = true;
928 --drawerEvtStatus[ros2][drawer2].nMaskedChannels; // since it's fake masking, decrease counter by 1 in advance
929 }
930 }
931 }
932 if (bad1 && bad2) {
933 // both channels are bad
934 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
935 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
936
937 if (gain1 == CaloGain::INVALIDGAIN || gain2 == CaloGain::INVALIDGAIN) {
938 if (gain1 == CaloGain::INVALIDGAIN) gain1 = 0; // this is TileID::LOWGAIN; - commented out to make Coverity happy
939 if (gain2 == CaloGain::INVALIDGAIN) gain2 = 0; // this is TileID::LOWGAIN; - commented out to make Coverity happy
940 pCell->setEnergy(m_zeroEnergy, m_zeroEnergy, gain1, gain2); // reset energy completely, indicate problem putting low gain
941 } else {
942 pCell->setEnergy(m_zeroEnergy, m_zeroEnergy); // reset energy completely without changing gain
943 }
944 pCell->setTime(0.0); // reset time completely
945 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit1() & TileCell::MASK_ALGO)), 0); // reset quality flag for first pmt
946 pCell->setQuality(255, (TileCell::MASK_BADCH | (pCell->qbit2() & TileCell::MASK_ALGO)), 1); // reset quality flag for second pmt
947
948 return true;
949
950 } else if (bad1 && !bad2) {
951 // first channel is bad
952 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
953
954 float ene2 = pCell->ene2();
955 pCell->setEnergy(ene2, ene2, gain2, gain2); // use energy/gain from second pmt for both pmts
956
957 uint8_t qualCorrection = (gain1 != CaloGain::INVALIDGAIN) ? (gain1 - gain2) : 0;
958 uint8_t qual2 = pCell->qual2();
959 uint8_t qual1 = qual2 + qualCorrection; // if gains are different, qua11 and qual2 will be different
960 if (qual1 > m_qualityCut && gain1 > gain2) qual1 = qual2 - qualCorrection; // new feature in release 17.2
961
962 if (chStatus2.isBadTiming()) {
963 pCell->setTime(0.0); // time in second pmt is bad - no cell time
964 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
965 uint8_t qbit1 = qbit2 | TileCell::MASK_BADCH; // set bad channel bit for first pmt
966 pCell->setQuality(qual1, qbit1, 0); // change quality and qbits for first pmt
967 pCell->setQuality(qual2, qbit2, 1); // update qbits for second pmt
968 } else {
969 pCell->setTime(pCell->time2()); // use time from second pmt as cell time
970 pCell->setQuality(qual1, (pCell->qbit2() | TileCell::MASK_BADCH), 0); // change quality flag for first pmt
971 }
972
973 return true;
974
975 } else if (!bad1 && bad2) {
976 // second channel is bad
977 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
978
979 float ene1 = pCell->ene1();
980 pCell->setEnergy(ene1, ene1, gain1, gain1); // use energy/gain from first pmt for both pmts
981
982 uint8_t qualCorrection = (gain2 != CaloGain::INVALIDGAIN) ? (gain2 - gain1) : 0;
983 uint8_t qual1 = pCell->qual1();
984 uint8_t qual2 = qual1 + qualCorrection; // if gains are different, qua11 and qual2 will be different
985 if (qual2 > m_qualityCut && gain2 > gain1) qual2 = qual1 - qualCorrection; // new feature in release 17.2
986
987 if (chStatus1.isBadTiming()) {
988 pCell->setTime(0.0); // time in first pmt is bad - no cell time
989 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
990 uint8_t qbit2 = qbit1 | TileCell::MASK_BADCH; // set bad channel bit for second pmt
991 pCell->setQuality(qual1, qbit1, 0); // update qbits for first pmt
992 pCell->setQuality(qual2, qbit2, 1); // change quality and qbits for second pmt
993 } else {
994 pCell->setTime(pCell->time1()); // use time from first pmt as cell time
995 pCell->setQuality(qual2, (pCell->qbit1() | TileCell::MASK_BADCH), 1); // change quality flag for second pmt
996 }
997
998 return true;
999
1000 } else {
1001
1002 if (chStatus1.isBadTiming()) {
1003
1004 if (chStatus2.isBadTiming()) {
1005 pCell->setTime(0.0); // time in both pmts is bad - no cell time
1006 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
1007 pCell->setQuality(pCell->qual2(), qbit2, 1); // update qbits for second pmt
1008 } else {
1009 pCell->setTime(pCell->time2()); // use time from second pmt as cell time
1010 }
1011 uint8_t qbit1 = pCell->qbit1() & (~(TileCell::MASK_TIME)); // clear time bit for first pmt
1012 pCell->setQuality(pCell->qual1(), qbit1, 0); // update qbits for first pmt
1013
1014 } else if (chStatus2.isBadTiming()) {
1015
1016 pCell->setTime(pCell->time1()); // use time from first pmt as cell time
1017 uint8_t qbit2 = pCell->qbit2() & (~(TileCell::MASK_TIME)); // clear time bit for second pmt
1018 pCell->setQuality(pCell->qual2(), qbit2, 1); // update qbits for second pmt
1019 }
1020 }
1021
1022 }
1023
1024 return single_PMT_C10;
1025}
1026
1027
1028template<class ITERATOR, class COLLECTION>
1029void TileCellBuilder::build (const EventContext& ctx,
1030 TileDrawerEvtStatusArray& drawerEvtStatus,
1031 VecParams& params,
1032 const ITERATOR & begin,
1033 const ITERATOR & end,
1034 COLLECTION* coll,
1035 TileCellContainer* MBTSCells,
1036 TileCellContainer* E4prCells) const
1037{
1038 // Now retrieve the TileDQstatus
1039 const TileDQstatus* DQstatus = nullptr;
1041 DQstatus = SG::makeHandle (m_DQstatusKey, ctx).get();
1042 }
1043
1044 const TileDCSState* dcsState = m_checkDCS ? SG::ReadCondHandle(m_DCSStateKey, ctx).cptr() : nullptr;
1047
1048 /* zero all counters and sums */
1049 int nTwo = 0;
1050 int nCell = 0;
1051 int nFake = 0;
1052 int nMBTS = 0;
1053 int nE4pr = 0;
1054 int nChan = 0;
1055 float eCh = 0.0;
1056 float eCellTot = 0.0;
1057 float eMBTSTot = 0.0;
1058 float eE4prTot = 0.0;
1059 bool EBdrawerPresent[128];
1060 memset(EBdrawerPresent, 0, sizeof(EBdrawerPresent));
1061 DataPool<TileCell> tileCellsP(5217);
1062 //**
1063 //* Iterate over raw channels, creating new TileCells (or incrementing
1064 //* existing ones). Add each new TileCell to the output collection
1065 //**
1066
1067 std::vector<TileCell*> allCells (m_tileID->cell_hash_max(), nullptr);
1068
1069 for (ITERATOR rawItr = begin; rawItr != end; ++rawItr) {
1070
1071 const TileRawChannel* pChannel = (*rawItr);
1072 HWIdentifier adc_id = pChannel->adc_HWID();
1073 int ros = m_tileHWID->ros(adc_id);
1074 int drawer = m_tileHWID->drawer(adc_id);
1075 int channel = m_tileHWID->channel(adc_id);
1076 int gain = m_tileHWID->adc(adc_id);
1077 if (gain == m_skipGain) {
1078 ATH_MSG_VERBOSE (" skipping adc_id=" << m_tileHWID->to_string(adc_id));
1079 continue; // select only one of two gains in calib runs
1080 }
1081 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
1082 if (channel == 0 && ros > 2) EBdrawerPresent[(ros - 3) * 64 + drawer] = true; // EB drawer appeared in the data
1083
1084 float time = pChannel->uncorrTime(); // take uncorrected time (if available)
1085 float amp = pChannel->amplitude();
1086
1087 TileRawChannelUnit::UNIT oldUnit = params.m_RChUnit;
1088 if (params.m_correctAmplitude && time > m_timeMinThresh && time < m_timeMaxThresh) { // parabolic correction
1089 if (params.m_RChUnit > TileRawChannelUnit::OnlineADCcounts) { // convert from online units to ADC counts
1091 amp = emScale->undoOnlineChannelCalibration(drawerIdx, channel, gain, amp, params.m_RChUnit);
1092
1093 if (amp > m_ampMinThresh) // amp cut in ADC counts
1094 amp *= TileRawChannelBuilder::correctAmp(time,params.m_of2);
1095 } else if (params.m_RChUnit == TileRawChannelUnit::ADCcounts
1096 || params.m_RChUnit == TileRawChannelUnit::OnlineADCcounts) {
1097 if (amp > m_ampMinThresh)
1098 amp *= TileRawChannelBuilder::correctAmp(time,params.m_of2);
1099 } else {
1100 ATH_MSG_ERROR( "Units in raw channel container is " << params.m_RChUnit );
1101 ATH_MSG_ERROR( "But amplitude correction works only with ADC counts " );
1102 ATH_MSG_ERROR( "Please, disable CIS calibration in optimal filter " );
1103 }
1104 }
1105
1106 float qual = pChannel->quality();
1107
1108 // check that time was really reconstructed
1109 bool good_time = (fabs(time) < params.m_maxTimeCorr);
1110 bool non_zero_time = (params.m_RChType == TileFragHash::OptFilterDspCompressed)
1111 ? ((qual > 2.99 && qual < 4.01))
1112 : ((qual > 0.0 || params.m_RChType == TileFragHash::OptFilterDsp));
1113
1114 // new feature in rel 17.2.7 - pedestal keeps information about overflow and underflow
1115 // if there is an underflow, 10000 is added to pedestal value
1116 // if there is an overflow, 20000 is added to pedestal value
1117 // if there is an underflow in all samples, 80000 is added to pedestal value
1118 // if there is an overflow in all samples, 90000 is added to pedestal value
1119 // if there is bad pattern nunber N 100000+N*10000 is added to pedestal value
1120 bool overflow = false;
1121 bool underflow = false;
1122 bool overfit = false;
1123 float ped = pChannel->pedestal();
1124 if (ped > 59500.) { // one of bad patterns
1125 qual = 9999; // mask all bad patterns
1126 } else if (ped > 39500.) { // 40000 for constant value or 50000 for all zeros in disconnexted channel
1127 // nothing to do
1128 } else if (ped > m_ADCmaskValuePlusEps) { // 10000 for underflow or 20000 for overflow or 10000+20000
1129 // NOTE: opt filter can yield values between (-500, 4600) and overlay magic number is 4800 in case of 12-bit ADCs
1130 underflow = ((ped < 10000. + m_ADCmaskValuePlusEps) || (ped > 29500.));
1131 overflow = (ped > 10000. + m_ADCmaskValuePlusEps);
1132 // special flag indicating that fit method was applied for overflow channels
1133 overfit = ( (ped > 20000. + m_ADCmaskValueMinusEps && ped < 29500) || (ped > 30000. + m_ADCmaskValueMinusEps && ped < 39500) );
1134
1135 if (overflow
1136 && gain == TileID::LOWGAIN
1137 && amp > 0
1138 && time > m_timeMinThresh
1139 && time < m_timeMaxThresh) {
1140
1141 qual = fabs(qual);
1142 if (qual > m_qualityCut && qual < 9999.) {
1143 qual = m_qualityCut; // to avoid masking of overflow in low gain
1144 }
1145 }
1146 }
1147
1148 // apply time correction if needed
1149 if (params.m_correctTime && good_time && non_zero_time)
1150 time -= m_tileToolTiming->getSignalPhase(drawerIdx, channel, gain);
1151 else
1152 time = pChannel->time();
1153
1154 ++nChan;
1155 eCh += amp;
1156
1157 int index, pmt;
1158 int channel1 = channel;
1159
1160 if (m_useDemoCabling == 2015 && ros == 4 && drawer == 1) {
1161 int pmt2channel[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1162 26,25,24,29,31,32,27,28,30,35,34,33,38,37,43,44,41,40,39,36,42,47,46,45};
1163 channel1 = pmt2channel[channel];
1164
1165 } else if ( (m_useDemoCabling >= 2016 && m_useDemoCabling <= 2019)
1166 && (ros == 2 && (drawer == 1 || drawer>2)) ) {
1167 int pmt2channel[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1168 26,25,24,29,28,27,32,31,30,35,34,33,38,37,36,41,40,39,44,43,42,47,46,45};
1169 channel1 = pmt2channel[channel];
1170 } else if ( (m_useDemoCabling >= 2018)
1171 && (ros == 4 && drawer>=2) ) {
1172 int pmt2channelEB[48] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,
1173 31,32,30,35, 33,34, 38,37,41,40,39,36, 26,25,24,29,28,27, 44,43,42,47,46,45};
1174 channel1 = pmt2channelEB[channel];
1175 }
1176
1177 Identifier cell_id = m_cabling->h2s_cell_id_index (ros, drawer, channel1, index, pmt);
1178
1179 if (index == -3) { // E4' cells
1180
1181 if (E4prCells) { // do something with them only if the container exists
1182 ++nE4pr;
1183
1184 // convert ADC counts to MeV. like for normal cells
1185 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp, oldUnit
1187
1188 eE4prTot += ener;
1189 unsigned char iqual = iquality(qual);
1190 // for E4' cell qbit use only non_zero_time flag and check that energy is above standatd energy threshold in MeV
1191 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1192 ros, drawer, true, non_zero_time, (fabs(ener) > m_eneForTimeCut)
1193 , overflow, underflow, overfit);
1194 CaloGain::CaloGain cgain = (gain == TileID::HIGHGAIN)
1197
1198 TileCell* pCell = tileCellsP.nextElementPtr();
1199 // no CaloDDE
1200 // Cell ID is set explicitly
1201 pCell->set(NULL, cell_id);
1202 pCell->setEnergy_nonvirt(ener, 0, cgain, 3);
1203 pCell->setTime_nonvirt(time);
1204 pCell->setQual1(iqual);
1205 pCell->setQual2(0);
1206 pCell->setQbit1(qbit);
1207 pCell->setQbit2(0);
1208
1209 if (msgLvl(MSG::VERBOSE)) {
1210 msg(MSG::VERBOSE) << " E4' cell_id=" << m_tileTBID->to_string(cell_id)
1211 << " adc_id=" << m_tileHWID->to_string(adc_id)
1212 << " ene= " << ener
1213 << " amp= " << amp
1214 << " time= " << time
1215 << " qual= " << pChannel->quality()
1216 << " iqual= " << (int) iqual
1217 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1218
1219 if (ped > m_ADCmaskValuePlusEps)
1220 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1221 else
1222 msg(MSG::VERBOSE) << endmsg;
1223 }
1224
1225 if (m_maskBadChannels && maskBadChannel(drawerEvtStatus, DQstatus, dcsState,
1226 *badChannels, pCell, adc_id))
1227 ATH_MSG_VERBOSE ( "cell with id=" << m_tileTBID->to_string(cell_id)
1228 << " bad channel masked, new energy=" << pCell->energy() );
1229
1230 E4prCells->push_back(pCell); // store cell in container
1231
1232 }
1233
1234 } else if (index == -2) { // MBTS cells
1235
1236 if (MBTSCells) { // do something with them only if contaier existst
1237 ++nMBTS;
1238
1239 // convert ADC counts to pCb and not to MeV
1240 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp , oldUnit
1242
1243 eMBTSTot += ener;
1244 unsigned char iqual = iquality(qual);
1245 // for MBTS qbit use AND of good_time and non_zero_time and check that energy is above MBTS energy threshold in pC
1246 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1247 ros, drawer, false, (good_time && non_zero_time),
1248 (fabs(ener) > m_eneForTimeCutMBTS), overflow, underflow, overfit);
1249
1250 CaloGain::CaloGain cgain = (gain == TileID::HIGHGAIN)
1253
1254 TileCell* pCell = tileCellsP.nextElementPtr();
1255 // MBTS CaloDDE
1256 // Cell ID is set explicitly
1257 pCell->set((m_mbtsMgr) ? m_mbtsMgr->get_element(cell_id) : NULL, cell_id);
1258 pCell->setEnergy_nonvirt(ener, 0, cgain, 3);
1259 pCell->setTime_nonvirt(time);
1260 pCell->setQual1(iqual);
1261 pCell->setQual2(0);
1262 pCell->setQbit1(qbit);
1263 pCell->setQbit2(0);
1264
1265 if (msgLvl(MSG::VERBOSE)) {
1266 msg(MSG::VERBOSE) << " MBTS cell_id=" << m_tileTBID->to_string(cell_id)
1267 << " adc_id=" << m_tileHWID->to_string(adc_id)
1268 << " ene= " << ener
1269 << " amp= " << amp
1270 << " time= " << time
1271 << " qual= " << pChannel->quality()
1272 << " iqual= " << (int) iqual
1273 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1274
1275 if (ped > m_ADCmaskValuePlusEps)
1276 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1277 else
1278 msg(MSG::VERBOSE) << endmsg;
1279 }
1280
1281 if (m_maskBadChannels && maskBadChannel(drawerEvtStatus, DQstatus, dcsState,
1282 *badChannels, pCell, adc_id))
1283 ATH_MSG_VERBOSE ( "cell with id=" << m_tileTBID->to_string(cell_id)
1284 << " bad channel masked, new energy=" << pCell->energy() );
1285
1286 MBTSCells->push_back(pCell); // store cell in container
1287
1288 }
1289 } else if (index != -1) { // connected channel
1290
1291 float ener = emScale->calibrateChannel(drawerIdx, channel, gain, amp
1293
1294 eCellTot += ener;
1295
1296 unsigned char iqual = iquality(qual);
1297 // for normal cell qbit use only non_zero_time flag and check that energy is above standatd energy threshold in MeV
1298 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1299 ros, drawer, true, non_zero_time, (fabs(ener) > m_eneForTimeCut)
1300 , overflow, underflow, overfit);
1301
1302
1303 if (m_run2plus && channel == E1_CHANNEL && ros > 2) { // Raw channel -> E1 cell.
1304
1305 int drawer2 = m_cabling->E1_merged_with_run2plus(ros,drawer);
1306 if (drawer2 != 0) { // Raw channel splitted into two E1 cells for Run 2.
1307 int side = (ros == 3) ? 1 : -1;
1308 Identifier cell_id2 = m_tileID->cell_id(TileID::GAPDET, side, drawer2, m_towerE1, TileID::SAMP_E);
1309 int index2 = m_tileID->cell_hash(cell_id2);
1310 TileCell* pCell2 = tileCellsP.nextElementPtr();
1311 ++nCell;
1312 allCells[index2] = pCell2;
1313 const CaloDetDescrElement* dde2 = m_tileMgr->get_cell_element(index2);
1314 pCell2->set(dde2, cell_id2);
1316 int pmt2(0);
1317 ener /= 2.0F;
1318 correctCell(pCell2, 1, pmt2, gain, ener, time, iqual, qbit, 1);
1319
1320 ATH_MSG_DEBUG("E1 cell Id => " << m_tileID->to_string(cell_id)
1321 << " splitted into " << m_tileID->to_string(cell_id2));
1322
1323
1324 }
1325
1326 }
1327
1328 TileCell* pCell = allCells[index];
1329 if (pCell) {
1330 ++nTwo;
1331 correctCell(pCell, 2, pmt, gain, ener, time, iqual, qbit, 0); // correct & merge 2 PMTs in one cell
1332 } else {
1333 ++nCell;
1334 allCells[index] = pCell = tileCellsP.nextElementPtr();
1335 const CaloDetDescrElement* dde = m_tileMgr->get_cell_element(index);
1336 pCell->set(dde, cell_id);
1338 int ch_type = (dde->onl2() == TileHWID::NOT_VALID_HASH) ? 1 : 0;
1339 correctCell(pCell, 1, pmt, gain, ener, time, iqual, qbit, ch_type); // correct & save e,t,q in new cell
1340 }
1341
1342 if (msgLvl(MSG::VERBOSE)) {
1343 float calib1 = (amp != 0) ? ener / amp : 0.0;
1344 msg(MSG::VERBOSE) << " cell_id=" << m_tileID->to_string(cell_id, -2)
1345 << " adc_id=" << m_tileHWID->to_string(adc_id)
1346 << " calib=" << calib1
1347 << " nCell=" << nCell
1348 << " energy=" << ener << " (" << pCell->energy() << ", " << pCell->eneDiff() << ")" << endmsg;
1349
1350 msg(MSG::VERBOSE) << " amp= " << amp
1351 << " time= " << time
1352 << " qual= " << pChannel->quality()
1353 << " iqual= " << (int) iqual
1354 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1355
1356 if (ped > m_ADCmaskValuePlusEps)
1357 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1358 else
1359 msg(MSG::VERBOSE) << endmsg;
1360 }
1361
1362 } else {
1363
1364 if (msgLvl(MSG::VERBOSE)) {
1365
1366 unsigned char iqual = iquality(qual);
1367 unsigned char qbit = qbits(drawerEvtStatus, params.m_RChType,
1368 0, drawer, false, non_zero_time, false, overflow, underflow, overfit); //fake ros number here
1369
1370 msg(MSG::VERBOSE) << " channel with adc_id=" << m_tileHWID->to_string(adc_id)
1371 << " is not connected" << endmsg;
1372
1373 msg(MSG::VERBOSE) << " amp= " << amp
1374 << " time= " << time
1375 << " qual= " << pChannel->quality()
1376 << " iqual= " << (int) iqual
1377 << " qbit = 0x" << MSG::hex << (int) qbit << MSG::dec;
1378
1379 if (ped > m_ADCmaskValuePlusEps)
1380 msg(MSG::VERBOSE) << " err = " << TileRawChannelBuilder::BadPatternName(ped) << endmsg;
1381 else
1382 msg(MSG::VERBOSE) << endmsg;
1383 }
1384 }
1385 if (msgLvl(MSG::VERBOSE)) {
1386 if ((params.m_correctTime && good_time && non_zero_time) || pChannel->sizeTime() > 1) {
1387 msg(MSG::VERBOSE) << " OF_time = " << pChannel->uncorrTime()
1388 << " corr_time = " << time << endmsg;
1389 }
1390 }
1391 }
1392
1393 //**
1394 // Now store all TileCells
1395 //**
1396 for (unsigned int index = 0; index < allCells.size(); ++index) {
1397
1398 TileCell * pCell = allCells[index];
1399
1400 if (pCell) { // cell exists
1401
1403 if (maskBadChannels (drawerEvtStatus, DQstatus, dcsState, *badChannels, pCell))
1404 ATH_MSG_VERBOSE ( "cell with id=" << m_tileID->to_string(pCell->ID(), -2)
1405 << " bad channels masked, new energy=" << pCell->energy() );
1406
1408 || (pCell->energy() > m_eThreshold
1409 && fabs(pCell->timeDiff()) < m_maxTimeDiff
1410 && pCell->time1() < m_maxTime && pCell->time1() > m_minTime
1411 && pCell->time2() < m_maxTime && pCell->time2() > m_minTime
1412 && pCell->qual1() > m_minChi2 && pCell->qual1() < m_maxChi2
1413 && pCell->qual2() > m_minChi2 && pCell->qual2() < m_maxChi2)) {
1414
1415 coll->push_back(pCell); // store cell in container
1416
1417 } else {
1418
1419 //delete pCell; it's dangerous to delete cell, if it's in DataPool
1420
1421 }
1422
1423 allCells[index] = 0; // clear pointer for next event
1424 } else if (m_fakeCrackCells) { // can be true only for full-size container
1425
1426 pCell = tileCellsP.nextElementPtr();
1427 const CaloDetDescrElement* dde = m_tileMgr->get_cell_element(index);
1428 pCell->set(dde, dde->identify());
1429
1430 if (m_tileID->section(pCell->ID()) == TileID::GAPDET) { // missing D4/E3/E4 cell
1431
1432 int ind = m_tileID->module(pCell->ID()) + ((m_tileID->side(pCell->ID()) > 0) ? 0 : 64);
1433 if (EBdrawerPresent[ind]) {
1434 ++nFake;
1435 if (m_tileID->sample(pCell->ID()) == TileID::SAMP_E) {
1436 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, CaloGain::INVALIDGAIN); // reset energy completely, indicate problem putting low gain
1437 pCell->setQuality(0, TileCell::MASK_BADCH, 0); // reset quality flag for first pmt
1438 pCell->setQuality(0, TileCell::MASK_BADCH, 1); // reset quality flag for second pmt
1439 } else {
1440 pCell->setEnergy(0.0, 0.0, TileID::LOWGAIN, TileID::LOWGAIN); // reset energy completely, indicate problem putting low gain
1441 pCell->setQuality(0, 0, 0); // reset quality flag for first pmt
1442 pCell->setQuality(0, 0, 1); // reset quality flag for second pmt
1443 }
1444 pCell->setTime(0.0); // reset time completely
1445
1446 ATH_MSG_VERBOSE ( "adding fake cell with id=" << m_tileID->to_string(pCell->ID(), -2)
1447 << " ene=" << pCell->energy()
1448 << " status=" << (pCell->badcell() ? "bad" : "good") );
1449
1450 coll->push_back(pCell); // store cell in container
1451 }
1452 }
1453 }
1454 }
1455
1456 if (msgLvl(MSG::DEBUG)) {
1457 msg(MSG::DEBUG) << " nChan=" << nChan
1458 << " RawChSum=" << eCh
1459 << " nCell=" << nCell
1460 << " n2=" << nTwo
1461 << " nFake=" << nFake
1462 << " eneTot=" << eCellTot;
1463
1464 if (MBTSCells)
1465 msg(MSG::DEBUG) << " nMBTS=" << nMBTS
1466 << " eMBTS=" << eMBTSTot;
1467 if (E4prCells)
1468 msg(MSG::DEBUG) << " nE4pr=" << nE4pr
1469 << " eE4pr=" << eE4prTot;
1470
1471 msg(MSG::DEBUG) << endmsg;
1472 }
1473}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
Helpers for checking error return status codes and reporting errors.
HWIdentifier id2
SelectAllObjectMT< DCC, OBJECT > SelectAllObject
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
static const InterfaceID IID_ITileCellBuilder("TileCellBuilder", 1, 0)
TileContainer< TileCell > TileCellContainer
Information produced by TileDQstatusAlg (used to be done by TileBeamInfoProvider).
Helper for holding non-const raw data prior to recording in SG.
Container class for CaloCell.
void setHasCalo(const CaloCell_ID::SUBCALO caloNum)
set which calo has been filled.
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
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
void set(const CaloDetDescrElement *caloDDE, const Identifier &ID)
Fast method to change the identity of a cell.
Definition CaloCell.h:511
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.
Identifier identify() const override final
cell identifier
IdentifierHash onl2() const
cell online identifier 2
IdentifierHash onl1() const
cell online identifier 1
a typed memory pool that saves time spent allocation small object.
Definition DataPool.h:63
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
value_type push_back(value_type pElem)
This is a "hash" representation of an Identifier.
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
const_iterator end()
const_iterator begin()
Condition object to keep Tile channel and ADC status.
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
Class holding bad channel problems.
bool isBadTiming() const
bool isBad() const
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
ToolHandle< TileCondToolTiming > m_tileToolTiming
const TileDetDescrManager * m_tileMgr
Pointer to TileDetDescrManager.
SG::ReadHandleKey< TileRawChannelContainer > m_dspRawChannelContainerKey
int m_qualityCut
cut on channel quality (set energy to m_zeroEnergy for them)
virtual ~TileCellBuilder()
Destructor.
float m_timeMaxThresh
correct amplitude is time is below time max threshold
TileDrawerEvtStatus TileDrawerEvtStatusArray[5][64]
status of every drawer
SG::ReadHandleKey< TileDQstatus > m_DQstatusKey
const TileTBID * m_tileTBID
Pointer to TileTBID.
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
float m_timeMinThresh
correct amplitude is time is above time min threshold
void reset(bool fullSizeCont, bool printReset=true)
Method to reset the options of the TileCellContainer.
TileCellBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Contructor.
SG::WriteDecorHandleKey< xAOD::EventInfo > m_EventInfoTileStatusKey
bool maskBadChannel(TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell, HWIdentifier hwid) const
method to check if channels are good or bad.
bool m_mergeChannels
If true, missing raw channels are taken from DSP container.
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
const MbtsDetDescrManager * m_mbtsMgr
Pointer to MbtsDetDescrManager.
const TileInfo * m_tileInfo
bool m_fakeCrackCells
if true=> fake E3/E4 cells added
bool maskBadChannels(TileDrawerEvtStatusArray &drawerEvtStatus, const TileDQstatus *DQstatus, const TileDCSState *dcsState, const TileBadChannels *badChannels, TileCell *pCell) const
unsigned char iquality(float qual) const
bool m_thresholdNotSet
bool variable to check whether some threshold have been set
SG::ReadCondHandleKey< TileDCSState > m_DCSStateKey
Name of TileDCSState object in condition store.
bool m_of2
If true, assume OF2 method for amplitude correction, otherwise - OF1.
const TileCablingService * m_cabling
TileCabling instance.
int m_skipGain
for two-gain calib runs skip one of two gains
float m_eneForTimeCut
keep time for channels with energy above cut
unsigned char qbits(TileDrawerEvtStatusArray &drawerEvtStatus, TileFragHash::TYPE RChType, int ros, int drawer, bool count_over, bool good_time, bool good_ener, bool overflow, bool underflow, bool good_overflowfit) const
method to compute the cell quality bits
const TileHWID * m_tileHWID
Pointer to TileHWID.
virtual StatusCode process(CaloCellContainer *theCellContainer, const EventContext &ctx) const override
method to process all raw channels and store them in container
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
SG::WriteHandleKey< TileCellContainer > m_E4prContainerKey
float m_minEneChan[3]
channel energy thresholds for masking (normal,gap,mbts)
SG::WriteHandleKey< TileCellContainer > m_MBTSContainerKey
void correctCell(TileCell *pCell, int correction, int pmt, int gain, float ener, float time, unsigned char iqual, unsigned char qbit, int ch_type) const
Compute calibrated energy, time, etc.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
static const InterfaceID & interfaceID()
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
float m_zeroEnergy
energy to store in every PMT if both PMT are bad
float m_maxChi2
maximum chi2 for the PMTs in the cels
ToolHandleArray< ITileRawChannelTool > m_noiseFilterTools
void build(const EventContext &ctx, TileDrawerEvtStatusArray &drawerEvtStatus, VecParams &params, const ITERATOR &begin, const ITERATOR &end, COLLECTION *coll, TileCellContainer *MBTSCells, TileCellContainer *E4prCells) const
< method to process raw channels from a given vector and store them in collection
bool m_correctTime
should time be corrected (deltat added from CondDB)
float m_eneForTimeCutMBTS
similar cut for MBTS in pC
virtual StatusCode finalize() override
bool m_correctAmplitude
If true, amplitude is corrected by parabolic function (needed for OF without iterations)
float m_minTime
minimum time for the PMTs in the cels
float m_ampMinThresh
correct amplitude if it's above amplitude threshold (in ADC counts)
std::string m_infoName
bool m_maskBadChannels
if true=> bad channels are masked
float m_maxTimeDiff
maximum time difference between the PMTs in the cell
float m_maxTime
maximum time for the PMTs in the cels
const TileID * m_tileID
Pointer to TileID.
float m_minChi2
minimum chi2 for the PMTs in the cels
virtual StatusCode initialize() override
Initializer.
float m_eThreshold
cell energy threshold to consider the cell
uint8_t qual1(void) const
get quality of first PMT (data member)
Definition TileCell.h:197
void addEnergy(float e, int pmt, int gain)
set energy and gain for one PMT
Definition TileCell.cxx:145
float time1(void) const
get time of first PMT
Definition TileCell.h:192
void setEnergy_nonvirt(float e1, float e2, int gain1, int gain2)
Definition TileCell.h:257
void setQual2(unsigned char qual)
set quality of second PMT
Definition TileCell.h:165
virtual bool badcell(void) const override final
check if whole cell is bad (i.e.
Definition TileCell.h:214
void setTime_nonvirt(float t)
Definition TileCell.h:244
float eneDiff(void) const
all get methods
Definition TileCell.h:182
virtual void setEnergy(float ene) override final
set total energy, reset eneDiff to zero (final override of CaloCell method)
Definition TileCell.cxx:123
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
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
void setQbit1(unsigned char qbit)
set quality bits of first PMT
Definition TileCell.h:168
void setQbit2(unsigned char qbit)
set quality bits of second PMT
Definition TileCell.h:171
void setQuality(unsigned char qual, unsigned char qbit, int pmt)
set quality value and quality bits for one PMT (TileCell specific overloads)
Definition TileCell.h:280
void setQual1(unsigned char qual)
set quality of first PMT
Definition TileCell.h:162
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
virtual void setTime(float t) override final
set cell time, reset timeDiff
Definition TileCell.h:251
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
@ MASK_AMPL
Definition TileCell.h:65
@ MASK_TIME
Definition TileCell.h:67
@ MASK_OVER
Definition TileCell.h:64
@ MASK_ALGO
Definition TileCell.h:62
@ MASK_BADCH
Definition TileCell.h:63
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
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
This class keep detailed status info about one drawer in a given event.
TYPE
initialize
@ EXTBAR_NEG
Definition TileHWID.h:71
@ EXTBAR_POS
Definition TileHWID.h:70
@ NOT_VALID_HASH
Definition TileHWID.h:314
static const char * BadPatternName(float ped)
static double correctAmp(double phase, bool of2=true)
Amplitude correction factor according to the time when using weights for tau=0 without iterations.
float pedestal(void) const
float time(int ind=0) const
float quality(int ind=0) const
int sizeTime() const
float uncorrTime() const
float amplitude(int ind=0) const
uint32_t get_bsflags() const
HWIdentifier adc_HWID(void) const
Definition TileRawData.h:53
@ Tile
The Tile calorimeter.
EventFlagErrorState
States that a given sub-detector could be in.
@ Warning
The sub-detector issued a warning.
@ NotSet
The flag was not set to anything.
@ Error
The sub-detector issued an error.
@ INVALIDGAIN
Definition CaloGain.h:18
@ TILEONEHIGH
Definition CaloGain.h:17
@ TILEONELOW
Definition CaloGain.h:16
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
TileFragHash::TYPE m_RChType
TileRawChannelUnit::UNIT m_RChUnit
MsgStream & msg
Definition testRead.cxx:32