ATLAS Offline Software
Loading...
Searching...
No Matches
TileRawChannelBuilder.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
12
13// Atlas includes
17
18// Gaudi includes
19#include "GaudiKernel/ThreadLocalContext.h"
20
21
22static const InterfaceID IID_ITileRawChannelBuilder("TileRawChannelBuilder", 1, 0);
23
27
28
33
37
41
45
50 , const std::string& name, const IInterface* parent)
51 : AthAlgTool(type, name, parent)
53 , m_rChUnit(TileRawChannelUnit::ADCcounts)
54 , m_bsflags(0)
55 , m_tileID(nullptr)
56 , m_tileHWID(nullptr)
57 , m_trigType(0)
58 , m_idophys(false)
59 , m_idolas(false)
60 , m_idoped(false)
61 , m_idocis(false)
62 , m_cischan(-1)
63 , m_capdaq(100)
64 , m_evtCounter(0)
65 , m_chCounter(0)
66 , m_nChL(0)
67 , m_nChH(0)
68 , m_RChSumL(0.0)
69 , m_RChSumH(0.0)
71 , m_tileInfo(nullptr)
72{
74 memset(m_error, 0, sizeof(m_error));
75
76 declareProperty("calibrateEnergy", m_calibrateEnergy = false);
77 declareProperty("correctTime", m_correctTime = false);
78 declareProperty("AmpMinForAmpCorrection", m_ampMinThresh = 15.0);
79 declareProperty("TimeMinForAmpCorrection", m_timeMinThresh = -12.5);
80 declareProperty("TimeMaxForAmpCorrection", m_timeMaxThresh = 12.5);
81 declareProperty("RunType", m_runType = 0);
82 declareProperty("DataPoolSize", m_dataPoollSize = -1);
83 declareProperty("UseDSPCorrection", m_useDSP = true);
84 declareProperty("TileInfoName", m_infoName = "TileInfo");
85 declareProperty("FirstSample",m_firstSample = 0);
86
87}
88
94
99
100 ATH_MSG_INFO( "TileRawChannelBuilder::initialize()" );
101
103 m_idophys = ((m_trigType == 0) || (m_trigType == 1));
104 m_idolas = ((m_trigType == 2) || (m_trigType == 3));
105 m_idoped = ((m_trigType == 4) || (m_trigType == 5));
106 m_idocis = ((m_trigType == 8) || (m_trigType == 9));
107 m_cischan = -1;
108 m_capdaq = 0;
109 m_chCounter = 0;
110 m_evtCounter = 0;
111 m_rawChannelCnt = nullptr;
112 m_nChL = m_nChH = 0;
113 m_RChSumL = m_RChSumH = 0.0;
114 m_evtCounter = -1;
115 // retrieve TileID helpers and TileIfno from det store
116 ATH_CHECK( detStore()->retrieve(m_tileID, "TileID") );
117 ATH_CHECK( detStore()->retrieve(m_tileHWID, "TileHWID") );
118
119 ATH_CHECK( detStore()->retrieve(m_tileInfo, m_infoName) );
120 m_i_ADCmax = m_tileInfo->ADCmax();
125 m_ADCmaskValueMinusEps = m_tileInfo->ADCmaskValue() - 0.01; // indicates channels which were masked in background dataset
126
127 // access tools and store them
128 ATH_CHECK( m_noiseFilterTools.retrieve() );
129 ATH_MSG_DEBUG( "Successfully retrieve NoiseFilterTools: " << m_noiseFilterTools );
130
132 ATH_MSG_DEBUG( "Obsolete calibrateEnergy flag is set to True in jobOptions - disabling it" );
133 m_calibrateEnergy = false;
134 }
135
136 // check if we want to keep ADC counts or convert them to pCb
139
140 // if unit is not pCb, but already MeV one can use method TileRawChannelContainer::set_unit()
141 // later to declare that
142
143 // 8 upper bits of bsflags:
144 // UUPPSTTT
145 // 31,30 - units
146 // 29,28 - pulse type = 3 for offline reco
147 // 27 - 7(=0) or 9(=1) samples
148 // 24,25,26 - TileFragHash::TYPE - OF algorithm type
149 int nsamp = (m_tileInfo->NdigitSamples() > 7) ? 1 : 0;
150 m_bsflags = (m_rChUnit << 30) | (3 << 28) | (nsamp << 27) | (m_rChType << 24);
151
152 // bits 12-15 - various options
153 if (m_correctTime) m_bsflags |= 0x1000;
154
155 if (msgLvl(MSG::DEBUG)) {
156 msg(MSG::DEBUG) << "TileRawChannelBuilder created, storing rc in '"
157 << m_rawChannelContainerKey.key() << "'" << endmsg;
158 msg(MSG::DEBUG) << " calibrate energy = " << m_calibrateEnergy << endmsg;
159 msg(MSG::DEBUG) << " correct time = " << m_correctTime << endmsg;
160 msg(MSG::DEBUG) << " run type = " << m_runType << endmsg;
161 }
162
163 if (m_dataPoollSize < 0) m_dataPoollSize = m_tileHWID->channel_hash_max();
164
165 ATH_CHECK( m_cablingSvc.retrieve());
166
167 m_cabling = m_cablingSvc->cablingService();
168 if (!m_cabling) {
169 ATH_MSG_ERROR( "Unable to retrieve TileCablingService" );
170 return StatusCode::FAILURE;
171 }
172
174
175 int runPeriod = m_cabling->runPeriod();
176 std::ostringstream os;
177 if (runPeriod==3) {
178 if ( m_demoFragIDs.empty() ) {
179 std::vector<int> v = { 0x10d }; // LBA14 is demonstrator in RUN3
180 m_demoFragIDs = v;
181 }
182 os << " in RUN3";
183 }
184
185 if ( !m_demoFragIDs.empty() ) {
187 os << " (frag IDs):";
188 for (int fragID : m_demoFragIDs) {
189 if (fragID>0)
190 os << " 0x" << std::hex << fragID << std::dec;
191 else
192 os << " " << fragID;
193 }
194 ATH_MSG_INFO("Enable special treatment for demonstrator modules" << os.str());
195 }
196
197 if (m_calibrateEnergy) {
198 ATH_CHECK( m_tileToolEmscale.retrieve() );
199 } else {
200 m_tileToolEmscale.disable();
201 }
202
203 if (m_correctTime) {
204 ATH_CHECK( m_tileToolTiming.retrieve() );
205 } else {
206 m_tileToolTiming.disable();
207 }
208
210 ATH_CHECK( m_tileIdTransforms.retrieve() );
211 } else {
212 m_tileIdTransforms.disable();
213 }
214
217
218 if (m_useDSP && !m_DSPContainerKey.key().empty()) {
219 ATH_CHECK( m_DSPContainerKey.initialize() );
220 }
221 else {
223 }
224
225 return StatusCode::SUCCESS;
226}
227
229 ATH_MSG_INFO( "Finalizing" );
230 return StatusCode::SUCCESS;
231}
232
233StatusCode TileRawChannelBuilder::createContainer(const EventContext& ctx) {
234 initLog(ctx);
235
236 // create TRC container
237 m_rawChannelCnt = std::make_unique<TileMutableRawChannelContainer>(true, m_rChType, m_rChUnit, SG::VIEW_ELEMENTS);
238 ATH_CHECK( m_rawChannelCnt->status() );
239 m_rawChannelCnt->set_bsflags(m_bsflags);
240
241 ATH_MSG_DEBUG( "Created TileRawChannelContainer '" << m_rawChannelContainerKey.key() << "'" );
242
243 return StatusCode::SUCCESS;
244}
245
246void TileRawChannelBuilder::initLog(const EventContext& ctx) {
247
248 const TileDQstatus* DQstatus = SG::makeHandle (m_DQstatusKey, ctx).get();
249
250 // update only if there is new event
251 if (m_evtCounter != ctx.evt()) {
252
253 m_evtCounter = ctx.evt();
254 if (m_runType != 0) m_trigType = m_runType;
255 else m_trigType = DQstatus->trigType();
256
257 if (0 == m_trigType) {
258 m_idophys = (DQstatus->calibMode() == 0);
259 m_idolas = false;
260 m_idoped = false;
261 m_idocis = (DQstatus->calibMode() == 1);
262 } else {
263 m_idophys = (m_trigType <= 1);
264 m_idolas = ((m_trigType == 2) || (m_trigType == 3));
265 m_idoped = ((m_trigType == 4) || (m_trigType == 5));
266 m_idocis = ((m_trigType == 8) || (m_trigType == 9));
267 }
268
269 const unsigned int *cispar = DQstatus->cispar();
270 if (0 == cispar[7]) { // if capdaq not set, it can't be CIS event
271 if (m_idocis) { // cis flag was set incorrectly, change to ped
272 m_idoped = true;
273 m_idocis = false;
274 }
275 m_capdaq = 0.0;
276 } else {
277 m_capdaq = (cispar[7] < 10) ? 5.2 : 100.0;
278 }
279 m_cischan = cispar[8] - 1; // channel where CIS is fired (-1 = all channels)
280
281 ATH_MSG_DEBUG( "Trig type is " << m_trigType
282 << "; dophys is " << ((m_idophys) ? "true" : "false")
283 << "; dolas is " << ((m_idolas) ? "true" : "false")
284 << "; doped is " << ((m_idoped) ? "true" : "false")
285 << "; docis is " << ((m_idocis) ? "true" : "false")
286 << "; capacitor is " << m_capdaq
287 << "; cis chan is " << m_cischan );
288 }
289}
290
291TileRawChannel* TileRawChannelBuilder::rawChannel(const TileDigits* digits, const EventContext& /*ctx*/) {
292 ++m_chCounter;
293 ATH_MSG_WARNING( "Default constructor for rawChannel!" );
294 DataPool<TileRawChannel> tileRchPool (100);
295 TileRawChannel *rawCh = tileRchPool.nextElementPtr();
296 rawCh->assign (digits->adc_HWID(), 0.0, 0.0, 0.0);
297 return rawCh;
298}
299
300void TileRawChannelBuilder::fill_drawer_errors(const EventContext& ctx,
301 const TileDigitsCollection* coll)
302{
303 const TileDQstatus* DQstatus = SG::makeHandle (m_DQstatusKey, ctx).get();
304
305 int frag = coll->identify();
306 int ros = (frag >> 8);
307 int drawer = (frag & 0xff);
308
309 m_lastDrawer = frag;
310
311 memset(m_error, 0, sizeof(m_error));
312 int dmuerr[MAX_DMUS] = {0};
313 int nch = 0;
314 bool bigain = DQstatus->isBiGain();
315 if (!bigain) { // in bigain runs we don't have DQ status fragment
316 for (int ch = 0; ch < MAX_CHANNELS; ch += 3) {
317 if (!DQstatus->isAdcDQgood(ros, drawer, ch, 0)) {
318 m_error[ch + 2] = m_error[ch + 1] = m_error[ch] = -3;
319 dmuerr[ch / 3] = 3;
320 nch += 3;
321 }
322 }
323 }
324 if (nch == MAX_CHANNELS) { // all bad - nothing to do
325 m_badDrawer = true;
326 ATH_MSG_VERBOSE( "Drawer 0x" << MSG::hex << frag << MSG::dec
327 << " is bad - skipping bad patterns check " );
328 return;
329 } else {
330 m_badDrawer = false;
331 ATH_MSG_VERBOSE( "Drawer 0x" << MSG::hex << frag << MSG::dec
332 << " looking for bad patterns in digits" );
333 }
334
335 float mindig, maxdig;
336 int nchbad[2] = { 0, 0 };
337
338 // Iterate over all digits in this collection
340 TileDigitsCollection::const_iterator lastDigit = coll->end();
341
342 for (; digitItr != lastDigit; ++digitItr) {
343 const TileDigits * pDigits = (*digitItr);
344 HWIdentifier adcId = pDigits->adc_HWID();
345 int channel = m_tileHWID->channel(adcId);
346 int gain = m_tileHWID->adc(adcId);
347
348 if (m_error[channel]) {
349 ATH_MSG_VERBOSE( "BadCh " << ros
350 << "/" << drawer
351 << "/" << channel
352 << "/" << gain << " BAD DQ STATUS ");
353
354 } else {
355
356 int err = CorruptedData(ros, drawer, channel, gain, pDigits->samples(), mindig, maxdig, m_ADCmaxMinusEps, m_ADCmaskValueMinusEps);
357
358 if (err) {
359
360 m_error[channel] = err;
361 if (err > -5) {
362 ++dmuerr[channel / 3];
363 ++nchbad[channel / 24];
364 }
365
366 if (msgLvl(MSG::VERBOSE)) {
367
368 msg(MSG::VERBOSE) << "BadCh " << ros
369 << "/" << drawer
370 << "/" << channel
371 << "/" << gain;
372 if (err < -5) msg(MSG::VERBOSE) << " Warning " << err;
373 else msg(MSG::VERBOSE) << " Error " << err;
374 if (mindig > m_ADCmaskValueMinusEps) msg(MSG::VERBOSE) << " BADDQ";
375 if (maxdig > m_ADCmaxMinusEps) msg(MSG::VERBOSE) << " Overflow";
376 if (mindig < 0.1) msg(MSG::VERBOSE) << " Underflow";
377 if (err < 0) msg(MSG::VERBOSE) << " Const";
378
379 msg(MSG::VERBOSE) << " samp=";
380 std::vector<float> digits = pDigits->samples();
381 for (unsigned int i = 0; i < digits.size(); ++i) {
382 msg(MSG::VERBOSE) << " " << digits[i];
383 }
384 msg(MSG::VERBOSE) << endmsg;
385 }
386
387 } else {
388 if (mindig < 0.01) err += 1;
389 if (maxdig > m_ADCmaxMinusEps) err += 2;
390 if (err) m_error[channel] = err - 10;
391 }
392 }
393 }
394
395 // check if we want to mask half a drawer
396 // in this case set error = -4 for channels which were good before
397
398 int ndmubad[2] = { 0, 0 };
399 int dmu = 0;
400 for (; dmu < MAX_DMUS / 2; ++dmu) { // first half
401 if (dmuerr[dmu] > 1)
402 ++ndmubad[0]; // count DMUs with at least two bad channels
403 }
404 for (; dmu < MAX_DMUS; ++dmu) { // second half
405 if (dmuerr[dmu] > 1)
406 ++ndmubad[1]; // count DMUs with at least two bad channels
407 }
408
409 int ndmulimit[2] = { 3, 3 }; // max number of bad DMUs when half-drawer is not yet masked
410 // if 4 DMUs will be bad - mask whole half-drawer
411 if (frag > 0x2ff) { // if extended barrel
412 if (frag == 0x30e || frag == 0x411)
413 ndmulimit[0] = 4; // in EB special one DMU is always bad (missing)
414 ndmulimit[1] = 5; // in second half of EB 4 DMUs ara always bad (missing)
415 // only if 7 DMUs are bad, mask whole half-drawer
416 }
417
418 bool printall = true;
419 for (int p = 0; p < 2; ++p) {
420 if (ndmubad[p] > ndmulimit[p] && nchbad[p] > 0) {
421 if (msgLvl(MSG::VERBOSE)) {
422 msg(MSG::VERBOSE) << "Drawer 0x" << MSG::hex << frag << MSG::dec
423 << " masking whole " << ((p) ? "second" : "first")
424 << " half" << endmsg;
425 if (printall) {
426 msg(MSG::VERBOSE) << "nDMuErr ";
427 for (int d = 0; d < MAX_DMUS; ++d) {
428 msg(MSG::VERBOSE) << " " << dmuerr[d];
429 }
430 msg(MSG::VERBOSE) << " total " << ndmubad[p] << " errors" << endmsg;
431
432 msg(MSG::VERBOSE) << "ChErr ";
433 int ch = 0;
434 while (ch < MAX_CHANNELS-2) {
435 msg(MSG::VERBOSE) << " " << m_error[ch++];
436 msg(MSG::VERBOSE) << " " << m_error[ch++];
437 msg(MSG::VERBOSE) << " " << m_error[ch++];
438 msg(MSG::VERBOSE) << " ";
439 }
440
441 msg(MSG::VERBOSE) << " total " << nchbad[p]
442 << " bad patterns" << endmsg;
443 printall = false;
444 }
445 }
446 int ch = (p) ? MAX_CHANNELS / 2 : 0;
447 int chmax = (p) ? MAX_CHANNELS : MAX_CHANNELS / 2;
448 for (; ch < chmax; ++ch) {
449 if (m_error[ch] == 0 || m_error[ch] < -5) { // channel was good before
450 m_error[ch] = -4;
451 }
452 }
453 }
454 }
455
456}
457
459 static const char * const errname[26] = {
460 "-10 - good signal",
461 "-9 - underflow",
462 "-8 - overflow",
463 "-7 - underflow and overflow",
464 "-6 - constant signal",
465 "-5 - disconnected channel",
466 "-4 - half a drawer masked",
467 "-3 - bad DQ status",
468 "-2 - underflow in all samples",
469 "-1 - overflow in all samples",
470 "0 - unknown error",
471 "1 - jump from zero to saturation",
472 "2 - samples with zeros",
473 "3 - at least two saturated. others - close to pedestal",
474 "4 - two distinct levels with at least 2 samples each",
475 "5 - pedestal with jump up in one sample",
476 "6 - pedestal with jump down in one sample",
477 "7 - signal with jump up in one sample",
478 "8 - signal with jump down in one sample",
479 "9 - base line above threshold in low gain",
480 "10 - jump down in first sample in low gain",
481 "11 - jump down in last sample in low gain",
482 "12 - jump up in one sample above const",
483 "13 - jump down in one sample below const",
484 "14 - unrecoverable timing jump",
485 "15 - unknown error"
486 };
487
488 return errname[std::min(25, std::max(0, int((ped + 500) * 1e-4)))];
489}
490
491
492StatusCode TileRawChannelBuilder::build(const TileDigitsCollection* coll, const EventContext& ctx)
493{
494
495 int frag = coll->identify();
496
497 // make sure that error array is up-to-date
498 if (frag != m_lastDrawer && m_notUpgradeCabling) {
499 fill_drawer_errors(ctx, coll);
500 }
501
502 // Iterate over all digits in this collection
504 TileDigitsCollection::const_iterator lastDigit = coll->end();
505
506 for (; digitItr != lastDigit; ++digitItr) {
507
508 TileRawChannel* rch = rawChannel((*digitItr), ctx);
509
511
512 int err = m_error[m_tileHWID->channel(rch->adc_HWID())];
513
514 if (err) {
515 if (err == -8 || err == -7) m_overflows.push_back(std::make_pair(rch, (*digitItr)));
516 float ped = rch->pedestal() + 100000 + 10000 * err;
517 rch->setPedestal(ped);
518 if (msgLvl(MSG::VERBOSE) && !m_badDrawer) {
519 if (err < -5) {
520 msg(MSG::VERBOSE) << "BadCh " << m_tileHWID->to_string(rch->adc_HWID())
521 << " warning = " << BadPatternName(ped) << endmsg;
522 } else {
523 msg(MSG::VERBOSE) << "BadCh " << m_tileHWID->to_string(rch->adc_HWID())
524 << " error = " << BadPatternName(ped) << endmsg;
525 }
526 }
527 }
528
529 }
530
531 ATH_CHECK( m_rawChannelCnt->push_back (rch) );
532 }
533
534 IdentifierHash hash = m_rawChannelCnt->hashFunc().hash(coll->identify());
535 TileRawChannelCollection* rawChannelCollection = m_rawChannelCnt->indexFindPtr(hash);
536 rawChannelCollection->setLvl1Id(coll->getLvl1Id());
537 rawChannelCollection->setLvl1Type(coll->getLvl1Type());
538 rawChannelCollection->setDetEvType(coll->getDetEvType());
539 rawChannelCollection->setRODBCID(coll->getRODBCID());
540
541 return StatusCode::SUCCESS;
542}
543
544StatusCode TileRawChannelBuilder::commitContainer(const EventContext& ctx)
545{
546
547 const TileDQstatus* DQstatus = SG::makeHandle (m_DQstatusKey, ctx).get();
548
549 ToolHandleArray<ITileRawChannelTool>::iterator itrTool = m_noiseFilterTools.begin();
550 ToolHandleArray<ITileRawChannelTool>::iterator endTool = m_noiseFilterTools.end();
551
552 if ( m_useDSP && !m_DSPContainerKey.key().empty() &&
553 (DQstatus->incompleteDigits() || m_chCounter<12288) && itrTool!=endTool )
554 {
555 const TileRawChannelContainer * dspCnt = SG::makeHandle (m_DSPContainerKey, ctx).get();
556 ATH_MSG_DEBUG( "Incomplete container - use noise filter corrections from DSP container" );
557
558 uint32_t bsFlags = dspCnt->get_bsflags();
559 std::vector<IdentifierHash> hashes = m_rawChannelCnt->GetAllCurrentHashes();
560 std::vector<IdentifierHash> dspHashes = dspCnt->GetAllCurrentHashes();
561 if (bsFlags == 0) {
562 ATH_MSG_WARNING("Problem in applying noise corrections: DSP container ("
563 << m_DSPContainerKey.key() << ") seems to be emtpy!");
564 } else if (hashes != dspHashes) {
565 ATH_MSG_ERROR( " Error in applying noise corrections; "
566 "hash vectors do not match.");
567 } else {
568 // Go through all TileRawChannelCollections
569 for (IdentifierHash hash : hashes) {
570 TileRawChannelCollection* coll = m_rawChannelCnt->indexFindPtr (hash);
571 const TileRawChannelCollection* dcoll = dspCnt->indexFindPtr (hash);
572
573 if (coll->identify() != dcoll->identify()) {
574
575 ATH_MSG_ERROR( " Error in applying noise corrections " << MSG::hex
576 << " collection IDs 0x" << coll->identify() << " and 0x" << dcoll->identify()
577 << " do not match " << MSG::dec );
578 break;
579 }
580
581 // iterate over all channels in a collection
584
585 for (TileRawChannel* rch : *coll) {
586 HWIdentifier adc_id = rch->adc_HWID();
587 while (dspItr != dspLast && adc_id != (*dspItr)->adc_HWID()) {
588 ++dspItr;
589 }
590 if (dspItr != dspLast) {
591 float corr = (*dspItr)->pedestal();
592 ATH_MSG_VERBOSE( "Ch "<<m_tileHWID->to_string(adc_id)
593 <<" amp " << rch->amplitude() << " ped " << rch->pedestal()
594 << " corr " << corr );
595 if (corr<10000.) {
596 rch->setAmplitude (rch->amplitude() - corr); // just baseline shift
597 rch->setPedestal (rch->pedestal() + corr); // just baseline shift
598 } else {
599 float ped = rch->pedestal();
600 if (corr > ped) {
601 rch->setPedestal (fmod(ped,10000.) + int(corr)/10000 * 10000); // changing error status
602 ATH_MSG_VERBOSE( "New error status in ped "<<rch->pedestal());
603 }
604 }
605 } else {
606 ATH_MSG_WARNING(" Problem in applying noise corrections "
607 << " can not find channel in DSP container with HWID "
608 << m_tileHWID->to_string(adc_id) );
609 dspItr = dcoll->begin();
610 }
611 }
612 }
613 }
614
615 } else {
616
617 for (ToolHandle<ITileRawChannelTool>& noiseFilterTool : m_noiseFilterTools) {
618 if (noiseFilterTool->process(*m_rawChannelCnt.get(), ctx).isFailure()) {
619 ATH_MSG_ERROR( " Error status returned from noise filter " );
620 } else {
621 ATH_MSG_DEBUG( "Noise filter applied to the container" );
622 }
623 }
624
625 }
626
627 ATH_MSG_DEBUG( " nCh=" << m_chCounter
628 << " nChH/L=" << m_nChH << "/" << m_nChL
629 << " RChSumH/L=" << m_RChSumH << "/" << m_RChSumL );
630
632 ATH_CHECK( rawChannelsContainer.record(std::move(m_rawChannelCnt)) );
633
634 endLog();
635
636 return StatusCode::SUCCESS;
637}
638
640 m_chCounter = 0;
641 m_nChL = m_nChH = 0;
642 m_RChSumL = m_RChSumH = 0.0;
643
644}
645
646double TileRawChannelBuilder::correctAmp(double phase, bool of2) {
647
648 double corr = 1.0;
649 if (of2) {
650 // estimation from Belen for rel 14.0.0
651 /*double a,b,c;
652 if(fabs(phase)<5.){
653 a=0.137; b=0.0877; c=0.0865;
654 }else{
655 a=0.565; b=0.116; c=0.0751;
656 }
657 corr=(1+(a+b*phase+c*phase*phase)/100.);
658 */
659
660 // estimation from Vakhtang for rel 14.4.0
661 /*double k = (phase < 0.0 ? 0.0009400 : 0.0010160);
662 corr = (1.0 + k * phase * phase);
663 */
664
665 // Parabolic correction from Tigran
666 double a1,a2,b,c;
667 a1 = phase < 0.0 ? 0.000940774 : 0.00102111;
668 a2 = phase < 0.0 ? 0.000759051 : 0.000689625;
669 b = phase < 0.0 ? -2.0 * 7.0 * (a1 - a2) : 2.0 * 12.5 * (a1 - a2);
670 c = phase < 0.0 ? 1.0 - 7.0 * 7.0 * (a1-a2) : 1.0 - 12.5 * 12.5 * (a1-a2);
671 if (phase < 12.5 && phase > -7.0) corr = a1 * phase * phase + 1.0;
672 else corr = phase * ( a2 * phase + b) + c;
673
674
675 } else {
676 /*double a,b,c;
677 if(phase<0){
678 a=1.0002942; b=0.0003528; c=0.0005241;
679 }else{
680 a=1.0001841; b=-0.0004182; c=0.0006167;
681 }
682 corr = a + phase * ( b + c * phase);
683 */
684
685 /*double k = (phase < 0.0 ? 0.0005241 : 0.0006167);
686 corr = (1.0 + k * phase * phase);
687 */
688
689 // 4th degree polynomial correction from Tigran
690 double k1 = (phase < 0.0 ? -0.0000326707:0.000380336);
691 double k2 = (phase < 0.0 ? -0.000560962:-0.000670487);
692 double k3 = (phase < 0.0 ? -0.00000807869:0.00000501773);
693 double k4 = (phase < 0.0 ? -0.000000145008:0.0000000584647);
694
695 corr = 1.0 / (1.0 + (k1 + (k2 + (k3 + k4 *phase)*phase)*phase)*phase);
696
697
698 }
699
700 return corr;
701}
702
703
704// Time correction for shifted pulses by Tigran
705double TileRawChannelBuilder::correctTime(double phase, bool of2) {
706
707 double correction = 0.0;
708
709 if (of2) {
710 if(phase < 0) {
711 correction = (-0.00695743 + (0.0020673 - (0.0002976 + 0.00000361305 * phase) * phase) * phase) * phase;
712 } else {
713 correction = (0.0130013 + (0.00128769 + (-0.000550218 + 0.00000755344 * phase) * phase) * phase) * phase;
714 }
715 }
716 // OF1 does not need correction
717
718 return correction;
719}
720
721
722
723int TileRawChannelBuilder::CorruptedData(int ros, int drawer, int channel, int gain,
724 const std::vector<float> & digits, float &dmin, float &dmax, float ADCmaxMinusEps, float ADCmaskValueMinusEps) {
725 bool eb = (ros > 2);
726 bool ebsp = ((ros == 3 && drawer == 14) || (ros == 4 && drawer == 17));
727 bool empty = ((eb && ((channel > 23 && channel < 30) || channel > 41)) || (ebsp && channel < 3));
728 bool not_gap = !(empty || (eb && (channel == 0 || channel == 1 || channel == 12 || channel == 13))
729 || (ebsp && (channel == 18 || channel == 19)));
730
731 const float epsilon = 4.1; // allow +/- 2 counts fluctuations around const value
732 const float delta[4] = { 29.9, 29.9, 49.9, 99.9 }; // jump levels between constLG, constHG, non-constLG, non-constHG
733 const float level1 = 99.9; // jump from this level to m_i_ADCmax is bad
734 const float level2 = 149.9; // base line at this level in low gain is bad
735 const float narrowLevel[2] = { 29.9, 49.9 }; // minimal amplitude for narrow pulses
736 const float delt = std::min(std::min(std::min(delta[0], delta[1]), std::min(delta[2], delta[3])),
737 std::min(narrowLevel[0], narrowLevel[1]));
738 const float secondMaxLevel = 0.3;
739
740 int error = 0;
741
742 unsigned int nSamp = digits.size();
743 if (nSamp) {
744 dmin = dmax = digits[0];
745 unsigned int pmin = 0;
746 unsigned int pmax = 0;
747 unsigned int nzero = (dmin < 0.01) ? 1 : 0;
748 unsigned int nover = (dmax > ADCmaxMinusEps) ? 1 : 0;
749
750 for (unsigned int i = 1; i < nSamp; ++i) {
751 float dig = digits[i];
752 if (dig > dmax) {
753 dmax = dig;
754 pmax = i;
755 } else if (dig < dmin) {
756 dmin = dig;
757 pmin = i;
758 }
759 if (dig < 0.01) ++nzero;
760 else if (dig > ADCmaxMinusEps) ++nover;
761 }
762
763 float dmaxmin = dmax - dmin;
764 //std::cout << " ros " << ros << " drawer " << drawer << " channel " << channel << " not_gap " << not_gap << " nzero " << nzero << " nover " << nover << std::endl;
765
766 if (dmin > ADCmaxMinusEps) { // overflow in all samples
767 error = (dmin > ADCmaskValueMinusEps) ? -3 : -1; // dmin=m_tileInfo->ADCmaskValue() - masking in overlay job (set in TileDigitsMaker)
768
769 } else if (dmax < 0.01) { // underflow in all samples
770 error = (empty) ? -5 : -2; // set different type of errors for exsiting and non-existing channels
771
772 } else if (dmaxmin < 0.01) { // constant value in all samples
773 error = -6;
774
775 } else if (nzero && nover) { // jump from zero to saturation
776 error = 1;
777
778 } else if ((nzero && (not_gap || empty)) || nzero > 1) { // one sample at zero in normal channel
779 error = 2; // or 2 samples at zero in gap/crack/MBTS
780
781 } else if (gain == 0 && dmin > level2) { // baseline above threshold in low gain is bad
782 error = 9;
783
784 } else if (dmaxmin > delt) { // check that max-min is above minimal allowed jump
785
786 float abovemin = dmax;
787 float belowmax = dmin;
788 unsigned int nmin = 0;
789 unsigned int nmax = 0;
790 for (unsigned int i = 0; i < nSamp; ++i) {
791 float smp = digits[i];
792 if (smp - dmin < epsilon) {
793 ++nmin;
794 }
795 if (dmax - smp < epsilon) {
796 ++nmax;
797 }
798 if (smp < abovemin && smp > dmin) {
799 abovemin = smp;
800 }
801 if (smp > belowmax && smp < dmax) {
802 belowmax = smp;
803 }
804 }
805 // more than two different values - shift index by 2, i.e. use thresholds for non-const levels
806 int gainInd = (abovemin != dmax || belowmax != dmin) ? gain + 2 : gain;
807 bool big_jump = (dmaxmin > delta[gainInd]);
808 bool max_in_middle = (pmax > 0 && pmax < nSamp - 1);
809 bool min_in_middle = (pmin > 0 && pmin < nSamp - 1);
810
811 if (nover > 1 && belowmax < level1) { // at least two saturated. others - close to pedestal
812 error = 3;
813 } else if (nmax + nmin == nSamp && big_jump) {
814 if (nmax > 1 && nmin > 1) { // at least 2 samples at two distinct levels
815 error = 4;
816 } else if (nmax == 1) {
817 if (max_in_middle) { // jump up in one sample, but not at the edge
818 error = 5;
819 }
820 } else if (nmin == 1) { // jump down in one sample
821 error = 6;
822 }
823 }
824 if (error == 0 && dmaxmin > narrowLevel[gain]) {
825 float secondMax = dmaxmin * secondMaxLevel;
826 float dminPlus = dmin + secondMax;
827 float dmaxMinus = dmax - secondMax;
828 if (not_gap) { // jumps above two (or one) neighbour samples
829 if (max_in_middle && std::max(digits[pmax - 1], digits[pmax + 1]) < dminPlus) {
830 error = 7; // jump up in one sample in the middle, which is much higher than two neighbours
831 } else if (min_in_middle && std::min(digits[pmin - 1], digits[pmin + 1]) > dmaxMinus) {
832 error = 8; // jump down in one sample, which is much lower than two neighbours
833 } else if (big_jump && gain == 0) { // check first and last sample only in low gain
834 if (pmin == 0 && digits[1] > dmax - secondMax) {
835 error = 10; // jump down in first sample. which is much lower than next one
836 } else if (pmin == nSamp - 1 && digits[pmin - 1] > dmax - secondMax) {
837 error = 11; // jump down in last sample. which is much lower than previous one
838 }
839 }
840 }
841 if (!error && big_jump) { // jumps above all samples
842 if ((max_in_middle || gain == 0) && nmax == 1 && belowmax < dminPlus) {
843 error = 12; // jump up in one sample in the middle, which is much higher than all others
844 } else if ((min_in_middle || gain == 0) && nmin == 1 && abovemin > dmaxMinus) {
845 error = 13; // jump down in one sample, which is much lower than all others (
846 }
847 }
848 }
849 }
850
851 } else {
852 dmin = dmax = 0.0;
853 }
854
855 return error;
856}
#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)
Helpers for checking error return status codes and reporting errors.
const int nmax(200)
Handle class for recording to StoreGate.
static const InterfaceID IID_ITileRawChannelBuilder("TileRawChannelBuilder", 1, 0)
std::vector< std::pair< TileRawChannel *, const TileDigits * > > Overflows_t
static const Attributes_t empty
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
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...
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
virtual std::vector< IdentifierHash > GetAllCurrentHashes() const override final
Returns a collection of all hashes availiable in this IDC.
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
This is a "hash" representation of an Identifier.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
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
int trigType() const
Trigger type.
uint32_t calibMode() const
Calibration mode.
bool incompleteDigits() const
A few extra items (from TileBeamInfoProvider).
const uint32_t * cispar() const
CIS parameters.
bool isBiGain() const
returns gain mode of run
const std::vector< float > & samples() const
Definition TileDigits.h:58
Hash table for Tile fragments (==drawers ==collections in StoreGate)
virtual StatusCode finalize()
ToolHandle< TileCondToolTiming > m_tileToolTiming
Overflows_t & getOverflowedChannels(void)
static const char * BadPatternName(float ped)
TileRawChannelUnit::UNIT m_rChUnit
StatusCode build(const TileDigitsCollection *collection, const EventContext &ctx)
static const InterfaceID & interfaceID()
AlgTool InterfaceID.
float m_timeMinThresh
correct amplitude is time is above time min threshold
std::unique_ptr< TileMutableRawChannelContainer > m_rawChannelCnt
SG::ReadHandleKey< TileDQstatus > m_DQstatusKey
static double correctTime(double phase, bool of2=true)
Time correction factor.
virtual ~TileRawChannelBuilder()
Destructor.
float m_ADCmaskValueMinusEps
indicates channels which were masked in background dataset
SG::ReadHandleKey< TileRawChannelContainer > m_DSPContainerKey
float m_ampMinThresh
correct amplitude if it's above amplitude threshold (in ADC counts)
virtual StatusCode createContainer(const EventContext &ctx)
Create container in SG with name given by parameter (m_rawChannelContainerKey)
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
float m_timeMaxThresh
correct amplitude is time is below time max threshold
static int CorruptedData(int ros, int drawer, int channel, int gain, const std::vector< float > &digits, float &dmin, float &dmax, float ADCmaxMinusEps, float ADCmaskValueMinusEps)
ToolHandle< TileCondIdTransforms > m_tileIdTransforms
void fill_drawer_errors(const EventContext &ctx, const TileDigitsCollection *collection)
std::string getTileRawChannelContainerID(void)
virtual StatusCode commitContainer(const EventContext &ctx)
Commit RawChannelContiner in SG and make const.
static double correctAmp(double phase, bool of2=true)
Amplitude correction factor according to the time when using weights for tau=0 without iterations.
const TileCablingService * m_cabling
TileCabling instance.
virtual TileRawChannel * rawChannel(const TileDigits *digits, const EventContext &ctx)
Builder virtual method to be implemented by subclasses.
void initLog(const EventContext &ctx)
ToolHandleArray< ITileRawChannelTool > m_noiseFilterTools
virtual StatusCode initialize()
Initializer.
ToolHandle< TileCondToolEmscale > m_tileToolEmscale
SG::WriteHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
Gaudi::Property< std::vector< int > > m_demoFragIDs
TileRawChannelBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
void assign(const HWIdentifier &id, float amplitude, float time, float quality, float ped=0.0)
float pedestal(void) const
void setPedestal(float ped)
uint32_t getLvl1Type() const
Getter for level1 type.
uint32_t getDetEvType() const
Getter for detector event type.
void setLvl1Type(uint32_t lvl1Type)
Setter for level1 type from ROD header.
void setLvl1Id(uint32_t lvl1Id)
Setter for level1 id from ROD header.
void setRODBCID(uint32_t rodBCID)
Setter for BCID from ROD header.
void setDetEvType(uint32_t detEvType)
Setter for detector event type from ROD header.
uint32_t getLvl1Id() const
Getter for level1 id.
uint32_t getRODBCID() const
Getter for BCID from.
uint32_t get_bsflags() const
HWIdentifier adc_HWID(void) const
Definition TileRawData.h:53
@ 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())
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.