ATLAS Offline Software
Loading...
Searching...
No Matches
L1TriggerTowerTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
5// L1TriggerTowerTool.cxx
8
9#include "GaudiKernel/Incident.h"
10#include "GaudiKernel/IIncidentSvc.h"
11#include "GaudiKernel/GaudiException.h"
12
16
27
30
33
36
40
42#include "GaudiKernel/ThreadLocalContext.h"
43
44#include <cstdint>
45#include <tuple>
46
47namespace LVL1
48{
49
50//================ Static Constants ============================================
51
54
55//================ Constructor =================================================
56
58 const std::string& n,
59 const IInterface* p )
60 :
61 AthAlgTool(t,n,p),
62 m_caloMgr(0),
63 m_lvl1Helper(0),
64 m_l1CaloTTIdTools("LVL1::L1CaloTTIdTools/L1CaloTTIdTools", this),
65 m_ttSvc("CaloTriggerTowerService/CaloTriggerTowerService", this),
66 m_mappingTool("", this),
68 m_correctFir(false),
70{
71 declareInterface<IL1TriggerTowerTool>(this);
72
73 declareProperty( "BaselineCorrection", m_correctFir );
74 declareProperty( "L1DynamicPedestalProvider", m_dynamicPedestalProvider );
75}
76
77//================ Destructor =================================================
78
82
83//================ Initialisation =================================================
84
86{
87 m_debug = msgLvl(MSG::VERBOSE); // May want to make this VERBOSE!
88
93
94
95 ATH_CHECK(m_l1CaloTTIdTools.retrieve());
96
97 if(!m_ttSvc.retrieve().isSuccess()) {
98 ATH_MSG_WARNING( "Could not retrieve CaloTriggerTowerService Tool" );
99 } else {
100 ATH_MSG_INFO("Retrieved Tool " << m_ttSvc);
101 }
102
103 StatusCode scID = detStore()->retrieve(m_caloMgr);
104 if (scID.isFailure()) {
105 ATH_MSG_WARNING( "Cannot retrieve m_caloMgr" );
106 } else {
107 m_lvl1Helper = m_caloMgr->getLVL1_ID();
108 }
109
110 if (!m_mappingTool.empty()) {
111 ATH_CHECK( m_mappingTool.retrieve() );
112 }
113
114 // Incident Service:
115 SmartIF<IIncidentSvc> incSvc{service("IncidentSvc")};
116 ATH_CHECK( incSvc.isValid() );
117 incSvc->addListener(this, "BeginRun");
118
119 // Pedestal Correction
120 if (m_correctFir) {
122 ATH_MSG_INFO( "Retrieved L1DynamicPedestalProvider: " << m_dynamicPedestalProvider );
123 }
124
125 ATH_CHECK( m_eventInfoKey.initialize() );
126
127 ATH_CHECK( m_L1MenuKey.initialize() );
128
129 ATH_MSG_INFO( "Initialization completed" );
130
131 return StatusCode::SUCCESS;
132}
133
134//================ Finalisation =================================================
135
137{
138 return StatusCode::SUCCESS;
139}
140
141//================ Reset mapping table at start of run ============================
142
143void L1TriggerTowerTool::handle(const Incident& inc)
144{
145 if (inc.type()=="BeginRun") {
146 ATH_MSG_DEBUG( "Resetting mapping table at start of run" );
147
148 m_idTable.clear();
149 }
150}
151
152//================= Now the actual user calls ===================================
153
156{
157 ATH_MSG_VERBOSE("L1TriggerTowerTool::retrieveConditions");
158
159 // retrieving direct from detector store, requires L1CaloCondAlg to have been scheduled
160 // strategy logic etc is now done inside the L1CaloCondAlg too
161 // so we just need to retrieve three containers (runpars, conditions, disabledchannels) ...
162 bool verbose = msgLvl(MSG::VERBOSE);
163
164 SG::ReadCondHandle <L1CaloRunParametersContainer> rh_rp(m_runParametersContainerKey);
165 CHECK_WITH_CONTEXT(rh_rp.isValid(), "L1TriggerTowerTool");
166 m_runParametersContainer = (*rh_rp);
167 if (verbose) {
168 ATH_MSG_VERBOSE( "Retrieved RunParametersContainer" );
169 rh_rp->dump();
170 }
171
172 if(isRun2()) {
173 SG::ReadCondHandle <L1CaloPprConditionsContainerRun2> rh_c(m_conditionsContainerKeyRun2);
174 CHECK_WITH_CONTEXT(rh_c.isValid(), "L1TriggerTowerTool");
175 m_conditionsContainer = (*rh_c);
176 if (verbose) {
177 ATH_MSG_VERBOSE( "Retrieved ConditionsContainer" );
178 rh_c->dump();
179 }
180 SG::ReadCondHandle <L1CaloPprDisabledChannelContainerRun2> rh_dc(m_disabledChannelContainerKeyRun2);
181 CHECK_WITH_CONTEXT(rh_dc.isValid(), "L1TriggerTowerTool");
183 if (verbose) {
184 ATH_MSG_VERBOSE( "Retrieved DisabledChannelContainer" );
185 rh_dc->dump();
186 }
187 } else {
188 ATH_MSG_ERROR("non-Run2 no longer supported ... requires update to L1CaloCondAlg to create non-Run2 versions of containers");
189 return StatusCode::FAILURE;
190 }
191 return StatusCode::SUCCESS;
192}
193
196void L1TriggerTowerTool::process(const std::vector<int> &digits, double eta, double phi, int layer,
197 std::vector<int> &et, std::vector<int> &bcidResults,
198 std::vector<int> &bcidDecisions, bool useJepLut /* = true */)
199{
201 L1CaloCoolChannelId id = channelID(eta, phi, layer);
202
204 process(digits, id, et, bcidResults, bcidDecisions, useJepLut);
205}
206
207
210void L1TriggerTowerTool::process(const std::vector<int> &digits, const L1CaloCoolChannelId& channelId,
211 std::vector<int> &et, std::vector<int> &bcidResults,
212 std::vector<int> &bcidDecisions, bool useJepLut /* = true */)
213{
214 if (m_debug) {
215 ATH_MSG_VERBOSE( "::process: ==== Entered Process ====" );
216 ATH_MSG_VERBOSE( "::process: digits: ");
217 printVec(digits);
218 ATH_MSG_VERBOSE( " channelID: " << MSG::hex << channelId.id() << MSG::dec );
219 }
220
222 et.clear();
223 bcidResults.clear();
224 bcidDecisions.clear();
225
226 ATH_MSG_VERBOSE( "::process: ---- FIR filter ----" );
227
229 std::vector<int> filter;
230 fir(digits, channelId, filter);
231 std::vector<int> lutInput;
232 dropBits(filter, channelId, lutInput);
233
234 ATH_MSG_VERBOSE( "::process: ---- BCID algorithms ----" );
235
237 bcid(filter, digits, channelId, bcidResults);
238
239 ATH_MSG_VERBOSE( "::process: ---- BCID decisions ----" );
240
242 std::vector<int> decisionRange;
243 bcidDecisionRange(lutInput, digits, channelId, decisionRange);
244 bcidDecision(bcidResults, decisionRange, channelId, bcidDecisions);
245
246 ATH_MSG_VERBOSE( "::process: ---- LUT ET calculation ----" );
247
249 std::vector<int> lutOutput;
250 if(isRun2()) {
251 if(useJepLut) jepLut(lutInput, channelId, lutOutput);
252 else cpLut(lutInput, channelId, lutOutput);
253 } else {
254 lut(lutInput, channelId, lutOutput);
255 }
256
257 ATH_MSG_VERBOSE( "::process: ---- use ET range ----" );
258
261 applyEtRange(lutOutput, decisionRange, channelId, et);
262
263 ATH_MSG_VERBOSE( "::process: ==== Leaving Process ====" );
264}
265
266namespace {
267// helper function to convert vectors of different type
268template <typename DST, typename SRC>
269std::vector<DST> convertVectorType(const std::vector<SRC>& s) {
270 std::vector<DST> d(s.size());
271 std::transform(std::begin(s), std::end(s), std::begin(d),
272 [](SRC v){return static_cast<DST>(v);});
273 return d;
274}
275}
276
278void L1TriggerTowerTool::simulateChannel(const xAOD::TriggerTower& tt, std::vector<int>& outCpLut, std::vector<int>& outJepLut, std::vector<int>& bcidResults, std::vector<int>& bcidDecisions)
279{
280
281 //If we have 80 MHz readout, we need to extract the 40 MHz samples. The central 80 MHz sample is always a 40 MHz sample. We use the cool database (runParameters folder) to understand if we are in 80MHz readout
282
283 unsigned int readoutConfigID = std::cbegin(*m_runParametersContainer)->readoutConfigID();
284
285 if(m_debug){
286 ATH_MSG_VERBOSE("ReadoutConfigID = " << readoutConfigID );
287 }
288
289 std::vector<uint16_t> digits40;
290
291 if(readoutConfigID == 5 or readoutConfigID == 6){
292
293 if(m_debug){
294 ATH_MSG_VERBOSE("80 MHz readout detected, emulating 40 MHz samples");
295 }
296
297 int nSlices = tt.adc().size();
298
299 if((nSlices%4)==3){
300 for (int i=0 ; i < (nSlices-1)/2 ; i++ ){
301 digits40.push_back(tt.adc().at(2*i+1));
302 }
303 }
304 else if((nSlices%4)==1){
305 for (int i=0 ; i <= (nSlices-1)/2 ; i++){
306 digits40.push_back(tt.adc().at(2*i));
307 }
308 }
309
310
311 }else{
312 if(m_debug){
313 ATH_MSG_VERBOSE("40 MHz readout detected");
314 }
315 digits40 = tt.adc();
316 }
317
318 const auto& digits = convertVectorType<int>(digits40);
319
320 L1CaloCoolChannelId channelId {tt.coolId()};
321
322 if (m_debug) {
323 ATH_MSG_VERBOSE( "::simulateChannel: ==== Entered Process ====" );
324 ATH_MSG_VERBOSE( "::simulateChannel: digits: ");
325 printVec(digits);
326 ATH_MSG_VERBOSE( "::simulateChannel: channelID: " << MSG::hex << channelId.id() << MSG::dec );
327 }
328
330 outCpLut.clear();
331 outJepLut.clear();
332 bcidResults.clear();
333 bcidDecisions.clear();
334
336 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- FIR filter ----" );
337 std::vector<int> filter;
338 fir(digits, channelId, filter);
339 if (m_debug) printVec(filter);
340
341
343 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- pedestalCorrection ----" );
344 // the correction is only available for each LUT slice in the read-out (not ADC/Filter slice)
345 // therefore we can only apply it to the #LUT central filter slices
346 const std::size_t nCorr = tt.correctionEnabled().size();
347 const std::size_t filterOffset = filter.size()/2 - nCorr/2;
348 for(std::size_t iCorr = 0; iCorr < nCorr; ++iCorr) {
349 filter[filterOffset + iCorr] -= tt.correction()[iCorr] * tt.correctionEnabled()[iCorr];
350 }
351 if (m_debug) printVec(filter);
352
353 std::vector<int> lutInput;
354 dropBits(filter, channelId, lutInput);
355
356 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- BCID algorithms ----" );
357
359 bcid(filter, digits, channelId, bcidResults);
360
361 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- BCID decisions ----" );
362
364 std::vector<int> decisionRange;
365 bcidDecisionRange(lutInput, digits, channelId, decisionRange);
366 bcidDecision(bcidResults, decisionRange, channelId, bcidDecisions);
367
368 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- LUT ET calculation ----" );
369
371 std::vector<int> cpLutOutput, jepLutOutput;
372 cpLut(lutInput, channelId, cpLutOutput);
373 jepLut(lutInput, channelId, jepLutOutput);
374
375 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ---- use ET range ----" );
376
379 applyEtRange(cpLutOutput, decisionRange, channelId, outCpLut);
380 applyEtRange(jepLutOutput, decisionRange, channelId, outJepLut);
381
382 if (m_debug) ATH_MSG_VERBOSE( "::simulateChannel: ==== Leaving Process ====" );
383}
384
387
388void L1TriggerTowerTool::bcid(const std::vector<int> &filter, const std::vector<int> &digits, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
389{
390 // Get decision flags for the 2 BCID algorithms
391 std::vector<int> peak;
392 peakBcid(filter, channelId, peak);
393 std::vector<int> sat;
394 satBcid(digits, channelId, sat);
395
396 output.clear();
397 output.reserve(sat.size()); // avoid frequent reallocations
398
399 std::vector<int>::iterator itpeak = peak.begin();
400 std::vector<int>::iterator itsat = sat.begin();
401 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
402 output.push_back( (*itpeak<<2) + (*itsat<<1) );
403 }
404 if (m_debug) {
405 ATH_MSG_VERBOSE( "::bcid: bcidResults: ");
406 printVec(output);
407 ATH_MSG_VERBOSE(" ");
408 }
409}
410
413
414void L1TriggerTowerTool::bcid(const std::vector<int> &filter, const std::vector<int> &digits,
415 unsigned int strategy, int satLow, int satHigh, int satLevel, std::vector<int> &output)
416{
417 // Get decision flags for the 2 BCID algorithms
418 std::vector<int> peak;
419 peakBcid(filter, strategy, peak);
420 std::vector<int> sat;
421 satBcid(digits, satLow, satHigh, satLevel, sat);
422
423 output.clear();
424 output.reserve(sat.size()); // avoid frequent reallocations
425
426 std::vector<int>::iterator itpeak = peak.begin();
427 std::vector<int>::iterator itsat = sat.begin();
428 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
429 output.push_back( (*itpeak<<2) + (*itsat<<1) );
430 }
431 if (m_debug) {
432 ATH_MSG_VERBOSE( "::bcid: bcidResults: ");
433 printVec(output);
434 ATH_MSG_VERBOSE(" ");
435 }
436}
437
440
441void L1TriggerTowerTool::bcid(const std::vector<int> &filter, const std::vector<int> &lutInput, const std::vector<int> &digits, int energyLow, int energyHigh, int decisionSource, std::vector<unsigned int> &decisionConditions,
442 unsigned int strategy, int satLow, int satHigh, int satLevel, std::vector<int> &result, std::vector<int> &decision)
443{
444 // Get decision flags for the 2 BCID algorithms
445 std::vector<int> peak;
446 peakBcid(filter, strategy, peak);
447 std::vector<int> sat;
448 satBcid(digits, satLow, satHigh, satLevel, sat);
449
450 result.clear();
451 result.reserve(sat.size()); // avoid frequent reallocations
452 decision.clear();
453
454 std::vector<int>::iterator itpeak = peak.begin();
455 std::vector<int>::iterator itsat = sat.begin();
456 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
457 result.push_back( (*itpeak<<2) + (*itsat<<1) );
458 }
459 if (m_debug) {
460 ATH_MSG_VERBOSE( "::bcid: bcidResults: ");
462 ATH_MSG_VERBOSE(" ");
463 }
464
466 std::vector<int> decisionRange;
467 if (!(decisionSource&0x1)) etRange(digits, energyLow, energyHigh, decisionRange);
468 else etRange(lutInput, energyLow, energyHigh, decisionRange);
469 bcidDecision(result, decisionRange, decisionConditions, decision);
470 if (m_debug) {
471 ATH_MSG_VERBOSE( "::bcid: bcidDecisions: ");
472 printVec(decision);
473 ATH_MSG_VERBOSE(" ");
474 }
475}
476
477namespace { // helper function
478 template<class T>
479 const std::vector<short int>* getFirCoefficients(unsigned int coolId, std::any& C) {
480 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
481 if(!settings) return nullptr;
482 return &(settings->firCoefficients());
483 }
484} // anonymous namespace
485
489void L1TriggerTowerTool::fir(const std::vector<int> &digits, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
490{
492 std::vector<int> firCoeffs;
493 if(m_conditionsContainer.has_value()) {
494 const std::vector<short int>* hwCoeffs;
495 if(isRun2())
496 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
497 else
498 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainer>(channelId.id(), m_conditionsContainer);
499 if(hwCoeffs) {
503 firCoeffs.reserve(hwCoeffs->size()); // avoid frequent reallocations
504 for (int i = hwCoeffs->size()-1; i >= 0; --i) firCoeffs.push_back((*hwCoeffs)[i]);
505
506 } else ATH_MSG_WARNING( "::fir: No L1CaloPprConditions found" );
507 } else ATH_MSG_WARNING( "::fir: No Conditions Container retrieved" );
508
509 if (m_debug) {
510 ATH_MSG_VERBOSE( "::fir: FIR coefficients: ");
511 printVec(firCoeffs);
512 ATH_MSG_VERBOSE(" ");
513 }
514
515 fir(digits, firCoeffs, output);
516}
517
522void L1TriggerTowerTool::fir(const std::vector<int> &digits, const std::vector<int> &firCoeffs, std::vector<int> &output)
523{
524 output.clear();
525 output.reserve(digits.size()); // avoid frequent reallocations
528 int firstFIR = -1;
529 int lastFIR = 0;
530 for (unsigned int i = 0; i < firCoeffs.size(); ++i) {
531 if (firstFIR < 0 && firCoeffs[i] != 0) firstFIR = i;
532 if (firCoeffs[i] != 0) lastFIR = i;
533 }
534 if (firstFIR < 0) firstFIR = lastFIR + 1;
535
536 for (int i = 0; i < (int)digits.size(); i++) {
537 int sum = 0;
539 if (i >= 2-firstFIR && i < (int)digits.size()+2-lastFIR) {
540 for (int j = firstFIR; j <= lastFIR; ++j) {
541 sum += digits[i+j-2]*firCoeffs[j];
542 }
543 }
544 if (sum < 0) sum = 0;
545 output.push_back(sum);
546 }
547 if (m_debug) {
548 ATH_MSG_VERBOSE( "::fir: output: ");
549 printVec(output);
550 ATH_MSG_VERBOSE(" ");
551 }
552}
553
554namespace {
555 template<typename T>
556 unsigned int getStrategy(std::any& C) {
557 return std::any_cast<T*>(C)->peakFinderCond();
558 }
559}
560
562void L1TriggerTowerTool::peakBcid(const std::vector<int> &fir, const L1CaloCoolChannelId& /*channelId*/, std::vector<int> &output)
563{
564 unsigned int strategy = 0;
565 if(m_conditionsContainer.has_value()) {
566 if(isRun2())
567 strategy = getStrategy<L1CaloPprConditionsContainerRun2>(m_conditionsContainer);
568 else
569 strategy = getStrategy<L1CaloPprConditionsContainer>(m_conditionsContainer);
570 } else ATH_MSG_WARNING( "::peakBcid: No Conditions Container retrieved" );
571
572 ATH_MSG_VERBOSE( "::peakBcid: peak-finder strategy: " << strategy );
573
574 peakBcid(fir, strategy, output);
575}
576
578void L1TriggerTowerTool::peakBcid(const std::vector<int> &fir, unsigned int strategy, std::vector<int> &output)
579{
580 output.clear();
581 output.reserve(fir.size()); // avoid frequent reallocations
582
583 for (unsigned int i = 0; i < fir.size(); i++) {
584 int result = 0;
586 if (i > 0 && i < fir.size()-1) {
588 if (strategy&0x1) {
589 if ( (fir[i-1]<fir[i]) && (fir[i+1]<fir[i]) ) result = 1;
590 } else {
591 if ( (fir[i-1]<fir[i]) && (fir[i+1]<=fir[i]) ) result = 1;
592 }
593 }
594 output.push_back(result);
595 }
596 if (m_debug) {
597 ATH_MSG_VERBOSE( "::peakBcid: output: ");
598 printVec(output);
599 ATH_MSG_VERBOSE(" ");
600 }
601}
602
603namespace { // helper function
604 template<class T>
605 std::tuple<bool, int, int, int> getSaturation(unsigned int coolId, std::any& C) {
606 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
607 if(!settings) return std::make_tuple(false, 0, 0, 0);
608 return std::make_tuple(true, settings->satBcidLevel(), settings->satBcidThreshLow(),
609 settings->satBcidThreshHigh());
610 }
611} // anonymous namespace
612
614void L1TriggerTowerTool::satBcid(const std::vector<int> &digits, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
615{
616 int satLevel = 0;
617 int satLow = 0;
618 int satHigh = 0;
619 if (m_conditionsContainer.has_value()) {
620 bool available = false;
621 if(isRun2())
622 std::tie(available, satLevel, satLow, satHigh) = getSaturation<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
623 else
624 std::tie(available, satLevel, satLow, satHigh) = getSaturation<L1CaloPprConditionsContainer>(channelId.id(), m_conditionsContainer);
625 if(!available) ATH_MSG_WARNING( "::satBcid: No L1CaloPprConditions found" );
626 } else ATH_MSG_WARNING( "::satBcid: No Conditions Container retrieved" );
627
628 ATH_MSG_VERBOSE( "::satBcid: satLevel: " << satLevel
629 << " satLow: " << satLow
630 << " satHigh: " << satHigh );
631
632 satBcid(digits, satLow, satHigh, satLevel, output);
633}
634
636
637void L1TriggerTowerTool::satBcid(const std::vector<int> &digits, int satLow, int satHigh, int satLevel, std::vector<int> &output)
638{
639 output.clear();
640 output.reserve(digits.size()); // avoid frequent reallocations
641
642 bool enabled = true;
643 int flag[2] = {0,0};
644
645 for (unsigned int i = 0; i<digits.size(); i++) {
646 // Algorithm can set flag for following sample. So here we
647 // propagate such flags into the current sample.
648 flag[0] = flag[1];
649 flag[1] = 0;
650
651 if (digits[i]>=satLevel) { // do we have saturation?
652 if (enabled && i>1) { // is algorithm active?
653 bool low = (digits[i-2]>satLow);
654 bool high = (digits[i-1]>satHigh);
655 if (high) { // flag current or next sample?
656 if (low) {
657 flag[0] = 1;
658 }
659 else {
660 flag[1] = 1;
661 }
662 }
663 else {
664 flag[1] = 1;
665 }
666 }
667 enabled = false; // after first saturation, disable algorithm
668 }
669 else {
670 enabled = true; // unsaturated sample reenables algorithm
671 }
672 output.push_back(flag[0]);
673 }
674 if (m_debug) {
675 ATH_MSG_VERBOSE( "::satBcid: output: ");
676 printVec(output);
677 ATH_MSG_VERBOSE(" ");
678 }
679}
680
682namespace {
683 template<typename T>
684 unsigned int getDecisionSource(std::any& C) {
685 return std::any_cast<T*>(C)->decisionSource();
686 }
687}
688
689void L1TriggerTowerTool::bcidDecisionRange(const std::vector<int>& lutInput, const std::vector<int>& digits, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
690{
691 int decisionSource = 0;
692 if (m_conditionsContainer.has_value()) {
693 if(isRun2()) decisionSource = getDecisionSource<L1CaloPprConditionsContainerRun2>(m_conditionsContainer);
694 else decisionSource = getDecisionSource<L1CaloPprConditionsContainer>(m_conditionsContainer);
695
696 } else ATH_MSG_WARNING( "::bcidDecisionRange: No Conditions Container retrieved" );
697
698 if (!(decisionSource&0x1)) etRange(digits, channelId, output);
699 else etRange(lutInput, channelId, output);
700 if (m_debug) {
701 ATH_MSG_VERBOSE( "::bcidDecisionRange: decisionSource: " << decisionSource);
702 ATH_MSG_VERBOSE( " output: ");
703 printVec(output);
704 ATH_MSG_VERBOSE(" ");
705 }
706}
707
709namespace { // helper function
710 template<class T>
711 std::tuple<unsigned int, unsigned int, unsigned int> getBcidDecision(std::any& C) {
712 auto CC = std::any_cast<T*>(C);
713 return std::make_tuple(CC->bcidDecision1(), CC->bcidDecision2(), CC->bcidDecision3());
714 }
715} // anonymous namespace
716void L1TriggerTowerTool::bcidDecision(const std::vector<int> &bcidResults, const std::vector<int> &range, const L1CaloCoolChannelId& /*channelId*/, std::vector<int> &output)
717{
718 unsigned int decision1 = 0;
719 unsigned int decision2 = 0;
720 unsigned int decision3 = 0;
721 if(m_conditionsContainer.has_value()) {
722 if(isRun2())
723 std::tie(decision1, decision2, decision3) = getBcidDecision<L1CaloPprConditionsContainerRun2>(m_conditionsContainer);
724 else
725 std::tie(decision1, decision2, decision3) = getBcidDecision<L1CaloPprConditionsContainer>(m_conditionsContainer);
726 } else ATH_MSG_WARNING( "::bcidDecision: No Conditions Container retrieved" );
727
728 // Reverse the order! (see elog 97082 9/06/10)
729 std::vector<unsigned int> mask = { decision3, decision2, decision1 };
730
731 ATH_MSG_VERBOSE( "::bcidDecision: masks: " << MSG::hex
732 << decision3 << " " << decision2 << " " << decision1 << MSG::dec );
733
734 bcidDecision(bcidResults, range, mask, output);
735}
736
738
739void L1TriggerTowerTool::bcidDecision(const std::vector<int> &bcidResults, const std::vector<int> &range, const std::vector<unsigned int> &mask, std::vector<int> &output)
740{
741 output.clear();
742 output.reserve(bcidResults.size()); // avoid frequent reallocations
743
744 std::vector<int>::const_iterator itBcid = bcidResults.begin();
745 std::vector<int>::const_iterator itRange = range.begin();
746 int nRange = mask.size();
747
748 for ( ; itBcid != bcidResults.end() && itRange != range.end(); ++itBcid, ++itRange) {
749 if ((*itRange) < nRange && (mask[*itRange]&(0x1<<*itBcid))) output.push_back(1);
750 else output.push_back(0);
751 }
752 if (m_debug) {
753 ATH_MSG_VERBOSE( "::bcidDecision: output: ");
754 printVec(output);
755 ATH_MSG_VERBOSE(" ");
756 }
757}
758
760void L1TriggerTowerTool::lut(const std::vector<int> &fir, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
761{
762 int strategy = 0;
763 int offset = 0;
764 int slope = 0;
765 int cut = 0;
766 int ped = 0;
767
768 if(isRun2()) {
769 // assert instead ?!
770 ATH_MSG_WARNING("::lut: Run-2 data - behaviour undefined!");
771 }
772
773 if(m_conditionsContainer.has_value()) {
774 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainer*>(m_conditionsContainer);
775 const L1CaloPprConditions* settings = conditionsContainer->pprConditions(channelId.id());
776 if (settings) {
777 strategy = settings->lutStrategy();
778 offset = settings->lutOffset();
779 slope = settings->lutSlope();
780 cut = settings->lutNoiseCut();
781 ped = settings->pedValue();
782 } else ATH_MSG_WARNING( "::lut: No L1CaloPprConditions found" );
783 } else ATH_MSG_WARNING( "::lut: No Conditions Container retrieved" );
784
785 ATH_MSG_VERBOSE( "::lut: LUT strategy/offset/slope/cut/ped: "
786 << strategy << " " << offset << " " << slope << " " << cut << " " << ped << " " );
787
788 unsigned int noiseCut = 0;
789 bool disabled = disabledChannel(channelId, noiseCut);
790 if (noiseCut > 0) cut = noiseCut;
791
792 lut(fir, slope, offset, cut, ped, strategy, disabled, output);
793}
794
795// TODO implement scale
796void L1TriggerTowerTool::cpLut(const std::vector<int> &fir, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
797{
798 int startBit = 0;
799 int strategy = 0;
800 int offset = 0;
801 double offsetReal = 0;
802 int slope = 0;
803 int cut = 0;
804 unsigned short scale = 0;
805 double pedMean = 0;
806 int ped = 0;
807 int hwCoeffSum = 0;
808 const std::vector<short int>* hwCoeffs;
809
810 if(!isRun2()) {
811 // assert instead ?!
812 ATH_MSG_WARNING("::cpLut: Run-1 data - behaviour undefined!");
813 }
814
815 if(m_conditionsContainer.has_value()) {
816 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainerRun2*>(m_conditionsContainer);
817 const L1CaloPprConditionsRun2* settings = conditionsContainer->pprConditions(channelId.id());
818 if (settings) {
819 startBit = settings->firStartBit();
820 strategy = settings->lutCpStrategy();
821 slope = settings->lutCpSlope();
822 cut = settings->lutCpNoiseCut();
823 scale = settings->lutCpScale();
824 ped = settings->pedValue();
825 pedMean = settings->pedMean();
826
827 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
828
829 for (unsigned int i = 0; i < hwCoeffs->size(); i++){
830 hwCoeffSum += hwCoeffs->at(i);
831 }
832
833 if (strategy == 0){
834 offsetReal = pedMean * hwCoeffSum / pow(2.,startBit);
835 }
836 else{
837 offsetReal = pedMean * hwCoeffSum * slope / pow(2.,startBit) - slope/2.;
838 }
839 offset = static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
840
841 ATH_MSG_VERBOSE( "::cpLut: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
842 << offset << " " << strategy << " " << " " << pedMean << " " << hwCoeffSum << " " << startBit << " " << slope );
843
844 } else ATH_MSG_WARNING( "::cpLut: No L1CaloPprConditions found" );
845 } else ATH_MSG_WARNING( "::cpLut: No Conditions Container retrieved" );
846
847 ATH_MSG_VERBOSE( "::cpLut: LUT strategy/offset/slope/cut/ped: "
848 << strategy << " " << offset << " " << slope << " " << cut << " " << ped << " " );
849
850 unsigned int noiseCut = 0;
851 bool disabled = disabledChannel(channelId, noiseCut);
852 if (noiseCut > 0) cut = noiseCut;
853 if(strategy == 2) {
854 // take the global scale into account - translate strategy to 1 for Run-1 compatible treatment
855 lut(fir, scale*slope, scale*offset, scale*cut, ped, 1, disabled, output);
856 } else if(strategy == 1 || strategy == 0){
857 lut(fir, slope, offset, cut, ped, strategy, disabled, output);
858 } else ATH_MSG_WARNING(" ::cpLut: Unknown stragegy: " << strategy);
859}
860
861void L1TriggerTowerTool::jepLut(const std::vector<int> &fir, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
862{
863 int startBit = 0;
864 int strategy = 0;
865 int offset = 0;
866 double offsetReal = 0;
867 int slope = 0;
868 int cut = 0;
869 unsigned short scale_db = 0;
870 unsigned short scale_menu = 0;
871 int ped = 0;
872 double pedMean = 0;
873 int hwCoeffSum = 0;
874 const std::vector<short int>* hwCoeffs;
875 short par1 = 0;
876 short par2 = 0;
877 short par3 = 0;
878 short par4 = 0;
879
880 if(!isRun2()) {
881 // assert instead ?!
882 ATH_MSG_WARNING("::jepLut: Run-1 data - behaviour undefined!");
883 }
884
885 if(m_conditionsContainer.has_value()) {
886 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainerRun2*>(m_conditionsContainer);
887 const L1CaloPprConditionsRun2* settings = conditionsContainer->pprConditions(channelId.id());
888 if (settings) {
889 startBit = settings->firStartBit();
890 strategy = settings->lutJepStrategy();
891 slope = settings->lutJepSlope();
892 cut = settings->lutJepNoiseCut();
893 ped = settings->pedValue();
894 pedMean = settings->pedMean();
895 scale_db = settings->lutJepScale();
896
897 auto l1Menu = SG::makeHandle( m_L1MenuKey );
898 scale_menu = l1Menu->thrExtraInfo().JET().jetScale(); // Retrieve scale param from menu
899 if (strategy == 3) {
900 par1 = settings->lutJepPar1();
901 par2 = settings->lutJepPar2();
902 par3 = settings->lutJepPar3();
903 par4 = settings->lutJepPar4();
904 }
905
906 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
907
908 for (unsigned int i = 0; i < hwCoeffs->size(); i++){
909 hwCoeffSum += hwCoeffs->at(i);
910 }
911
912 if (strategy == 0){
913 offsetReal = pedMean * hwCoeffSum / pow(2.,startBit);
914 }
915 else{
916 offsetReal = pedMean * hwCoeffSum * slope / pow(2.,startBit) - slope/2.;
917 }
918 offset = static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
919
920 ATH_MSG_VERBOSE( "::jepLut: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
921 << offset << " " << strategy << " " << " " << pedMean << " " << hwCoeffSum << " " << startBit << " " << slope );
922
923 } else ATH_MSG_WARNING( "::jepLut: No L1CaloPprConditions found" );
924 } else ATH_MSG_WARNING( "::jepLut: No Conditions Container retrieved" );
925
926 ATH_MSG_VERBOSE( "::jepLut: LUT strategy/offset/slope/cut/ped: "
927 << strategy << " " << offset << " " << slope << " " << cut << " " << ped << " " );
928
929 unsigned int noiseCut = 0;
930 bool disabled = disabledChannel(channelId, noiseCut);
931 if (noiseCut > 0) cut = noiseCut;
932
933 if(strategy == 3) {
934 nonLinearLut(fir, slope, offset, cut, scale_db, par1, par2, par3, par4, disabled, output);
935 }
936 else if(strategy == 2) {
937 // take the global scale into account - translate strategy to 1 for Run-1 compatible treatment
938 lut(fir, scale_menu*slope, scale_menu*offset, scale_menu*cut, ped, 1, disabled, output);
939 }else if(strategy == 1 || strategy == 0) {
940 lut(fir, slope, offset, cut, ped, strategy, disabled, output);
941 } else ATH_MSG_WARNING(" ::jepLut: Unknown stragegy: " << strategy);
942}
943
945
946void L1TriggerTowerTool::lut(const std::vector<int> &fir, int slope, int offset, int cut, int /*ped*/, int strategy, bool disabled, std::vector<int> &output)
947{
948 output.clear();
949 output.reserve(fir.size()); // avoid frequent reallocations
950
951 std::vector<int>::const_iterator it = fir.begin();
952 for ( ; it != fir.end(); ++it) {
953 int out = 0;
954 if (!disabled) {
955 if (strategy == 0 && (*it) >= offset+cut) { // Original scheme
956 out = (((*it)-offset)*slope + 2048)>>12;
957 } else if (strategy == 1 && (*it)*slope >= offset+cut) { // New scheme
958 out = ((*it)*slope - offset + 2048)>>12;
959 }
960 if (out < 0) out = 0;
961 if (out > s_saturationValue) out = s_saturationValue;
962 }
963 output.push_back(out);
964 }
965 if (m_debug) {
966 ATH_MSG_VERBOSE( "::lut: output: ");
967 printVec(output);
968 ATH_MSG_VERBOSE(" ");
969 }
970}
971
972void L1TriggerTowerTool::nonLinearLut(const std::vector<int> &fir, int slope, int offset, int cut, int scale, short par1, short par2, short par3, short par4, bool disabled, std::vector<int> &output)
973{
974 output.clear();
975 output.reserve(fir.size()); // avoid frequent reallocations
976
977 std::vector<int>::const_iterator it = fir.begin();
978 for ( ; it != fir.end(); ++it) {
979 int out = 0;
980 if (!disabled) {
981 // turn shorts into double
982 double nll_slope = 0.001 * scale;
983 double nll_offset = 0.001 * par1;
984 double nll_ampl = 0.001 * par2;
985 double nll_expo = 0.;
986 if(par3) {
987 nll_expo = -1. / (4096 * 0.001*par3);
988 } else {
989 nll_ampl = 0.;
990 }
991 double nll_noise = 0.001 * par4;
992
993 // noise cut
994 if ((*it) * slope < offset + nll_noise * cut) {
995 output.push_back(0);
996 continue;
997 }
998 // actual calculation
999 out = int((((int)(2048 + nll_slope * ((*it) * slope - offset)))>>12) + nll_offset + nll_ampl * std::exp(nll_expo * ((*it) * slope - offset)));
1000
1001 if(out > s_saturationValue) out = s_saturationValue;
1002 if(out < 0) out = 0;
1003 }
1004 output.push_back(out);
1005 }
1006 if (m_debug) {
1007 ATH_MSG_VERBOSE( "::nonLinearLut: output: ");
1008 printVec(output);
1009 ATH_MSG_VERBOSE(" ");
1010 }
1011}
1012
1014
1015void L1TriggerTowerTool::applyEtRange(const std::vector<int>& lut, const std::vector<int>& range, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
1016{
1017 bool disabled = disabledChannel(channelId);
1018 std::vector<int>::const_iterator itlut = lut.begin();
1019 std::vector<int>::const_iterator itrange = range.begin();
1020 while ( itlut != lut.end() && itrange != range.end() ) {
1021 if (!disabled && satOverride((*itrange), channelId)) output.push_back(s_saturationValue);
1022 else output.push_back(*itlut);
1023 ++itlut;
1024 ++itrange;
1025 }
1026 if (m_debug) {
1027 ATH_MSG_VERBOSE( "::applyEtRange: output: ");
1028 printVec(output);
1029 ATH_MSG_VERBOSE(" ");
1030 }
1031}
1032
1034namespace { // helper function
1035 template<class T>
1036 std::tuple<bool, int, int> getBcidEnergyRange(unsigned int coolId, std::any& C) {
1037 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
1038 if(!settings) return std::make_tuple(false, 0, 0);
1039 return std::make_tuple(true, settings->bcidEnergyRangeLow(), settings->bcidEnergyRangeHigh());
1040 }
1041} // anonymous namespace
1042
1043void L1TriggerTowerTool::etRange(const std::vector<int> &et, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
1044{
1045 int energyLow = 0;
1046 int energyHigh = 0;
1047 if (m_conditionsContainer.has_value()) {
1048 bool available = false;
1049 if(isRun2())
1050 std::tie(available, energyLow, energyHigh) = getBcidEnergyRange<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
1051 else
1052 std::tie(available, energyLow, energyHigh) = getBcidEnergyRange<L1CaloPprConditionsContainer>(channelId.id(), m_conditionsContainer);
1053
1054 if(!available) ATH_MSG_WARNING("::etRange: No L1CaloPprConditions found");
1055 } else ATH_MSG_WARNING("::etRange: No Conditions Container retrieved");
1056
1057 ATH_MSG_VERBOSE( "::etRange: energyLow: " << energyLow
1058 << " energyHigh: " << energyHigh);
1059
1060 etRange(et, energyLow, energyHigh, output);
1061}
1062
1064
1065void L1TriggerTowerTool::etRange(const std::vector<int> &et, int energyLow, int energyHigh, std::vector<int> &output)
1066{
1067 output.clear();
1068 output.reserve(et.size()); // avoid frequent reallocations
1069 for (std::vector<int>::const_iterator it = et.begin(); it != et.end(); ++it) {
1070 if ((*it) <= energyLow) output.push_back(0);
1071 else if ((*it) <= energyHigh) output.push_back(1);
1072 else output.push_back(2);
1073 }
1074 if (m_debug) {
1075 ATH_MSG_VERBOSE( "::etRange: output: ");
1076 printVec(output);
1077 ATH_MSG_VERBOSE(" ");
1078 }
1079}
1080
1082namespace { // helper function
1083 template<class T>
1084 std::tuple<bool, int> getFirStartBit(unsigned int coolId, std::any& C) {
1085 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
1086 if(!settings) return std::make_tuple(false, 0);
1087 return std::make_tuple(true, settings->firStartBit());
1088 }
1089} // anonymous namespace
1090
1091void L1TriggerTowerTool::dropBits(const std::vector<int> &fir, const L1CaloCoolChannelId& channelId, std::vector<int> &output)
1092{
1093 unsigned int start = 0;
1094 if(m_conditionsContainer.has_value()) {
1095 bool available = false;
1096 if(isRun2())
1097 std::tie(available, start) = getFirStartBit<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
1098 else
1099 std::tie(available, start) = getFirStartBit<L1CaloPprConditionsContainer>(channelId.id(), m_conditionsContainer);
1100 if(!available)ATH_MSG_WARNING( "::dropBits: No L1CaloPprConditions found" );
1101 } else ATH_MSG_WARNING( "::dropBits: No Conditions Container retrieved" );
1102
1103 ATH_MSG_VERBOSE( "::dropBits: firStartBit: " << start );
1104
1105 dropBits(fir, start, output);
1106}
1107
1109
1110void L1TriggerTowerTool::dropBits(const std::vector<int> &fir, unsigned int start, std::vector<int> &output)
1111{
1112 output.clear();
1113 output.reserve(fir.size()); // avoid frequent reallocations
1114
1116 unsigned int mask = (0x3ff<<start);
1117
1119 int max = 1<<(10+start);
1120
1121 for (std::vector<int>::const_iterator it = fir.begin(); it != fir.end(); ++it) {
1122 if ((*it)>=max) output.push_back(0x3ff);
1123 else output.push_back(((*it)&mask)>>start);
1124 }
1125 if (m_debug) {
1126 ATH_MSG_VERBOSE( "::dropBits: output: ");
1127 printVec(output);
1128 ATH_MSG_VERBOSE(" ");
1129 }
1130}
1131
1133void L1TriggerTowerTool::firParams(const L1CaloCoolChannelId& channelId, std::vector<int> &firCoeffs)
1134{
1136 firCoeffs.clear();
1137 if(m_conditionsContainer.has_value()) {
1138 const std::vector<short int>* hwCoeffs = nullptr;
1139 if(isRun2())
1140 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
1141 else
1142 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainer>(channelId.id(), m_conditionsContainer);
1143
1144 if(hwCoeffs) {
1148 firCoeffs.reserve(hwCoeffs->size()); // avoid frequent reallocations
1149 for (int i = hwCoeffs->size()-1; i >= 0; --i) firCoeffs.push_back((*hwCoeffs)[i]);
1150
1151 } else ATH_MSG_WARNING( "::firParams: No L1CaloPprConditions found" );
1152 } else ATH_MSG_WARNING( "::firParams: No Conditions Container retrieved" );
1153
1154 if (m_debug) {
1155 ATH_MSG_VERBOSE( "::fir: FIR coefficients: ");
1156 printVec(firCoeffs);
1157 ATH_MSG_VERBOSE(" ");
1158 }
1159}
1160
1162void L1TriggerTowerTool::bcidParams(const L1CaloCoolChannelId& channelId, int &energyLow, int &energyHigh, int &decisionSource, std::vector<unsigned int> &decisionConditions,
1163 unsigned int &peakFinderStrategy, int &satLow, int &satHigh, int &satLevel)
1164{
1165 energyLow = 0;
1166 energyHigh = 0;
1167 decisionSource = 0;
1168 decisionConditions.clear();
1169 peakFinderStrategy = 0;
1170 satLevel = 0;
1171 satLow = 0;
1172 satHigh = 0;
1173
1174 if(m_conditionsContainer.has_value()) {
1175 using std::get;
1176 std::tuple<unsigned int, unsigned int, unsigned int> bcidDecision;
1177 std::tuple<bool, int, int> bcidEnergyRange;
1178 std::tuple<bool, int, int, int> saturation;
1179 if(isRun2()) {
1181 bcidDecision = getBcidDecision<Cont>(m_conditionsContainer);
1182 peakFinderStrategy = getStrategy<Cont>(m_conditionsContainer);
1183 decisionSource = getDecisionSource<Cont>(m_conditionsContainer);
1184 bcidEnergyRange = getBcidEnergyRange<Cont>(channelId.id(), m_conditionsContainer);
1185 saturation = getSaturation<Cont>(channelId.id(), m_conditionsContainer);
1186 } else {
1187 using Cont = L1CaloPprConditionsContainer;
1188 bcidDecision = getBcidDecision<Cont>(m_conditionsContainer);
1189 peakFinderStrategy = getStrategy<Cont>(m_conditionsContainer);
1190 decisionSource = getDecisionSource<Cont>(m_conditionsContainer);
1191 bcidEnergyRange = getBcidEnergyRange<Cont>(channelId.id(), m_conditionsContainer);
1192 saturation = getSaturation<Cont>(channelId.id(), m_conditionsContainer);
1193 }
1194
1195 decisionConditions = { get<2>(bcidDecision),
1197 get<0>(bcidDecision) }; // reverse order
1198 if(get<0>(bcidEnergyRange)) {
1199 std::tie(std::ignore, energyLow, energyHigh) = bcidEnergyRange;
1200 } else ATH_MSG_WARNING( "::bcidParams: No BcidEnergyRange found" );
1201
1202 if(get<0>(saturation)) {
1203 std::tie(std::ignore, satLevel, satLow, satHigh) = saturation;
1204 } else ATH_MSG_WARNING( "::bcidParams: No Saturation found" );
1205 } else ATH_MSG_WARNING( "::bcid:Params No Conditions Container retrieved" );
1206
1207 ATH_MSG_VERBOSE( "::bcidParams: satLevel: " << satLevel
1208 << " satLow: " << satLow << " satHigh: " << satHigh << endmsg
1209 << " energyLow: " << energyLow << " energyHigh: " << energyHigh << endmsg
1210 << " decisionSource: " << decisionSource << " peakFinderStrategy: "
1211 << peakFinderStrategy );
1212
1213}
1214
1216void L1TriggerTowerTool::lutParams(const L1CaloCoolChannelId& channelId, int &startBit, int &slope, int &offset, int &cut, int &pedValue, float &pedMean, int &strategy, bool &disabled)
1217{
1218 startBit = 0;
1219 strategy = 0;
1220 offset = 0;
1221 slope = 0;
1222 cut = 0;
1223 pedValue = 0;
1224 pedMean = 0.;
1225 disabled = true;
1226
1227 if(isRun2()) {
1228 // assert instead ?!
1229 ATH_MSG_WARNING("::lutParams: Run-2 data - behaviour undefined!");
1230 }
1231
1232 if(m_conditionsContainer.has_value()) {
1233 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainer*>(m_conditionsContainer);
1234
1235 const L1CaloPprConditions* settings = conditionsContainer->pprConditions(channelId.id());
1236 if (settings) {
1237 startBit = settings->firStartBit();
1238 strategy = settings->lutStrategy();
1239 offset = settings->lutOffset();
1240 slope = settings->lutSlope();
1241 cut = settings->lutNoiseCut();
1242 pedValue = settings->pedValue();
1243 pedMean = settings->pedMean();
1244 } else ATH_MSG_WARNING( "::lutParams: No L1CaloPprConditions found" );
1245 } else ATH_MSG_WARNING( "::lutParams: No Conditions Container retrieved" );
1246
1247 ATH_MSG_VERBOSE( "::lutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1248 << startBit << " " << strategy << " " << offset << " " << slope << " " << cut << " " << pedValue << " " << pedMean );
1249 unsigned int noiseCut = 0;
1250 disabled = disabledChannel(channelId, noiseCut);
1251 if (noiseCut > 0) cut = noiseCut;
1252}
1253
1254void L1TriggerTowerTool::cpLutParams(const L1CaloCoolChannelId& channelId, int& startBit, int& slope, int& offset, int& cut, int& pedValue, float& pedMean, int& strategy, bool& disabled)
1255{
1256 startBit = 0;
1257 strategy = 0;
1258 offset = 0;
1259 double offsetReal = 0;
1260 slope = 0;
1261 cut = 0;
1262 pedValue = 0;
1263 pedMean = 0.;
1264 disabled = true;
1265 int hwCoeffSum = 0;
1266 const std::vector<short int>* hwCoeffs;
1267
1268 if(!isRun2()) {
1269 // assert instead ?!
1270 ATH_MSG_WARNING("::cpLutParams: Run-1 data - behaviour undefined!");
1271 }
1272
1273 if(m_conditionsContainer.has_value()) {
1274 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainerRun2*>(m_conditionsContainer);
1275
1276 const L1CaloPprConditionsRun2* settings = conditionsContainer->pprConditions(channelId.id());
1277 if(settings) {
1278 startBit = settings->firStartBit();
1279 strategy = settings->lutCpStrategy();
1280 slope = settings->lutCpSlope();
1281 cut = settings->lutCpNoiseCut();
1282 pedValue = settings->pedValue();
1283 pedMean = settings->pedMean();
1284
1285 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
1286 for (unsigned int i = 0; i < hwCoeffs->size(); i++){
1287 hwCoeffSum += hwCoeffs->at(i);
1288 }
1289
1290 if (strategy == 0){
1291 offsetReal = pedMean * hwCoeffSum / pow(2.,startBit);
1292 }
1293 else{
1294 offsetReal = pedMean * hwCoeffSum * slope / pow(2.,startBit) - slope/2.;
1295 }
1296 offset = static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
1297
1298 ATH_MSG_VERBOSE( "::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1299 << offset << " " << strategy << " " << " " << pedMean << " " << hwCoeffSum << " " << startBit << " " << slope );
1300
1301 } else ATH_MSG_WARNING( "::cpLutParams: No L1CaloPprConditions found" );
1302 } else ATH_MSG_WARNING( "::cpLutParams: No Conditions Container retrieved" );
1303
1304 ATH_MSG_VERBOSE( "::cpLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1305 << startBit << " " << strategy << " " << offset << " " << slope << " " << cut << " " << pedValue << " " << pedMean );
1306 unsigned int noiseCut = 0;
1307 disabled = disabledChannel(channelId, noiseCut);
1308 if (noiseCut > 0) cut = noiseCut;
1309}
1310
1311void L1TriggerTowerTool::jepLutParams(const L1CaloCoolChannelId& channelId, int& startBit, int& slope, int& offset, int& cut, int& pedValue, float& pedMean, int& strategy, bool& disabled)
1312{
1313 startBit = 0;
1314 strategy = 0;
1315 offset = 0;
1316 double offsetReal = 0;
1317 slope = 0;
1318 cut = 0;
1319 pedValue = 0;
1320 pedMean = 0.;
1321 disabled = true;
1322 int hwCoeffSum = 0;
1323 const std::vector<short int>* hwCoeffs;
1324
1325 if(!isRun2()) {
1326 // assert instead ?!
1327 ATH_MSG_WARNING("::jepLutParams: Run-1 data - behaviour undefined!");
1328 }
1329
1330 if(m_conditionsContainer.has_value()) {
1331 auto conditionsContainer = std::any_cast<L1CaloPprConditionsContainerRun2*>(m_conditionsContainer);
1332
1333 const L1CaloPprConditionsRun2* settings = conditionsContainer->pprConditions(channelId.id());
1334 if(settings) {
1335 startBit = settings->firStartBit();
1336 strategy = settings->lutJepStrategy();
1337 slope = settings->lutJepSlope();
1338 cut = settings->lutJepNoiseCut();
1339 pedValue = settings->pedValue();
1340 pedMean = settings->pedMean();
1341
1342 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(channelId.id(), m_conditionsContainer);
1343
1344 for (unsigned int i = 0; i < hwCoeffs->size(); i++){
1345 hwCoeffSum += hwCoeffs->at(i);
1346 }
1347
1348 if (strategy == 0){
1349 offsetReal = pedMean * hwCoeffSum / pow(2.,startBit);
1350 }
1351 else{
1352 offsetReal = pedMean * hwCoeffSum * slope / pow(2.,startBit) - slope/2.;
1353 }
1354 offset = static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
1355
1356 ATH_MSG_VERBOSE( "::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1357 << offset << " " << strategy << " " << " " << pedMean << " " << hwCoeffSum << " " << startBit << " " << slope );
1358
1359 } else ATH_MSG_WARNING( "::jepLutParams: No L1CaloPprConditions found" );
1360 } else ATH_MSG_WARNING( "::jepLutParams: No Conditions Container retrieved" );
1361
1362 ATH_MSG_VERBOSE( "::jepLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1363 << startBit << " " << strategy << " " << offset << " " << slope << " " << cut << " " << pedValue << " " << pedMean );
1364 unsigned int noiseCut = 0;
1365 disabled = disabledChannel(channelId, noiseCut);
1366 if (noiseCut > 0) cut = noiseCut;
1367}
1368
1370
1372{
1373 Identifier id(0);
1375 int pos_neg_z = m_l1CaloTTIdTools->pos_neg_z(eta);
1376 int region = m_l1CaloTTIdTools->regionIndex(eta);
1377 int ieta = m_l1CaloTTIdTools->etaIndex(eta);
1378 int iphi = m_l1CaloTTIdTools->phiIndex(eta, phi);
1379
1380 id = m_lvl1Helper->tower_id(pos_neg_z, layer, region, ieta, iphi);
1381 }
1382 return id;
1383}
1384
1386
1388{
1389 HWIdentifier hwId(0);
1390 if (m_ttSvc) {
1391 try { hwId = m_ttSvc->createTTChannelID(id, false); }
1392 catch (const CaloID_Exception&) { hwId = HWIdentifier(0); }
1393 }
1394 return hwId;
1395}
1396
1398
1400{
1401 Identifier id = identifier(eta, phi, layer);
1402 return hwIdentifier(id);
1403}
1404
1406
1408{
1409 // Use direct lookup table if possible
1410 const double absEta = fabs(eta);
1411 int index = 0;
1412 if (absEta < 2.5) {
1413 const int etaBin = 10.*absEta;
1414 const int phiBin = phi*(32/M_PI);
1415 index = (etaBin<<6) + phiBin;
1416 } else if (absEta < 3.2) {
1417 const int etaBin = 5.*(absEta - 2.5);
1418 const int phiBin = phi*(16./M_PI);
1419 index = 1600 + (etaBin<<5) + phiBin;
1420 } else {
1421 const int etaBin = (absEta - 3.2)*(1./0.425);
1422 const int phiBin = phi*(8./M_PI);
1423 index = 1728 + (etaBin<<4) + phiBin;
1424 }
1425 if (eta < 0.) index += 1792;
1426 if (layer > 0) index += 3584;
1427 if (index >= s_maxTowers) return L1CaloCoolChannelId(0);
1428 if (m_idTable.empty()) {
1429 m_idTable.reserve(s_maxTowers);
1430 m_idTable.assign(s_maxTowers, 0);
1431 }
1432 if (m_idTable[index] == 0) {
1433 Identifier id = identifier(eta, phi, layer);
1434 L1CaloCoolChannelId coolID = channelID(id);
1435 m_idTable[index] = coolID.id();
1436 }
1438}
1439
1441
1443{
1444 L1CaloCoolChannelId coolId(0);
1445 if (m_ttSvc) {
1446 try {
1447 HWIdentifier hwId = hwIdentifier(id);
1448 coolId = m_ttSvc->createL1CoolChannelId(hwId);
1449 }
1450 catch (const CaloID_Exception&) { coolId = L1CaloCoolChannelId(0); }
1451 }
1452 return coolId;
1453}
1454
1456namespace { // helper function
1457 template<class T>
1458 std::tuple<bool, bool, bool> getSatOverride(std::any& C) {
1459 auto CC = std::any_cast<T*>(C);
1460 return std::make_tuple(CC->satOverride1(), CC->satOverride2(), CC->satOverride3());
1461 }
1462} // anonymous namespace
1463
1464bool L1TriggerTowerTool::satOverride(int range, const L1CaloCoolChannelId& /*channelId*/)
1465{
1466 bool override = false;
1467 if(m_conditionsContainer.has_value()) {
1468 std::tuple<bool, bool, bool> satOverride;
1469 if(isRun2())
1470 satOverride = getSatOverride<L1CaloPprConditionsContainerRun2>(m_conditionsContainer);
1471 else
1472 satOverride = getSatOverride<L1CaloPprConditionsContainer>(m_conditionsContainer);
1473 // NB Reverse order as for bcidDecision1/2/3
1474 if (range == 0) override = std::get<2>(satOverride);
1475 if (range == 1) override = std::get<1>(satOverride);
1476 if (range == 2) override = std::get<0>(satOverride);
1477 } else ATH_MSG_WARNING( "::satOverride: No Conditions Container retrieved" );
1478
1479 ATH_MSG_VERBOSE( "::satOverride: range " << range
1480 << " has saturation override flag " << override );
1481
1482 return override;
1483}
1484
1486
1488{
1489 unsigned int noiseCut = 0;
1490 return disabledChannel(channelId, noiseCut);
1491}
1492
1494bool L1TriggerTowerTool::disabledChannel(const L1CaloCoolChannelId& channelId, unsigned int& noiseCut)
1495{
1496 bool isDisabled = false;
1497 noiseCut = 0;
1498 if(m_disabledChannelContainer.has_value()) {
1499 const L1CaloPprDisabledChannel* disabledChan = nullptr;
1500 if(isRun2()) disabledChan = std::any_cast<L1CaloPprDisabledChannelContainerRun2*>(m_disabledChannelContainer)->pprDisabledChannel(channelId.id());
1501 else disabledChan = std::any_cast<L1CaloPprDisabledChannelContainer*>(m_disabledChannelContainer)->pprDisabledChannel(channelId.id());
1502
1503 if (disabledChan) {
1504 if (!disabledChan->disabledBits()) {
1505 ChanCalibErrorCode calibError(disabledChan->calibErrorCode());
1506 if (calibError.chanValid()) {
1507 ChanDeadErrorCode deadError(disabledChan->deadErrorCode());
1508 if (deadError.chanValid()) noiseCut = disabledChan->noiseCut();
1509 //else isDisabled = true;
1510 } //else isDisabled = true;
1511 } else isDisabled = true;
1512
1513 ATH_MSG_VERBOSE( MSG::hex
1514 << "::disabledChannel: calibErrorCode: " << (disabledChan->calibErrorCode()).errorCode()
1515 << " deadErrorCode: " << (disabledChan->deadErrorCode()).errorCode()
1516 << " noiseCut: " << disabledChan->noiseCut()
1517 << " disabledBits: " << disabledChan->disabledBits()
1518 << MSG::dec );
1519
1520 } else {
1521 ATH_MSG_VERBOSE( "::disabledChannel: No L1CaloPprDisabledChannel found" );
1522 }
1523 } else {
1524 ATH_MSG_WARNING( "::disabledChannel: No DisabledChannel Container retrieved" );
1525 }
1526 if (isDisabled && m_debug) ATH_MSG_VERBOSE( "::disabledChannel: Channel is disabled" );
1527
1528 return isDisabled;
1529}
1530
1532
1534{
1535 m_debug = (debug && msgLvl(MSG::VERBOSE));
1536}
1537
1540
1541double L1TriggerTowerTool::FCalTTeta(double nominalEta, double /*phi*/, int layer)
1542{
1543 double eta = nominalEta;
1544 float abseta = fabs(eta);
1545 if (abseta<3.2) return eta; // If called for non-FCAL TT return input value
1546 if (layer == 0) {
1547 int sign = ((eta > 0) ? 1 : -1);
1548 if (abseta < 3.6) eta = 3.15 * sign;
1549 else if (abseta < 4.0) eta = 3.33 * sign;
1550 else if (abseta < 4.5) eta = 3.72 * sign;
1551 else eta = 4.41 * sign;
1552 }
1553 else if (eta > 0) {
1554 if (abseta < 3.6) eta = 3.36;
1555 else if (abseta < 4.0) eta = 3.45;
1556 else if (abseta < 4.5) eta = 4.17;
1557 else eta = 4.19;
1558 }
1559 else {
1560 if (abseta < 3.6) eta = -3.45;
1561 else if (abseta < 4.0) eta = -3.36;
1562 else if (abseta < 4.5) eta = -4.19;
1563 else eta = -4.17;
1564 }
1565 return eta;
1566}
1567
1571
1573{
1574 if ( !m_mappingTool.isValid() ) {
1575 throw GaudiException("No mapping tool configured",
1576 "L1TriggerTowerTool::FCalTTeta", StatusCode::FAILURE);
1577 }
1578
1580 unsigned int crate = channelId.crate();
1581 unsigned int module = channelId.module();
1582 unsigned int mcm = channelId.subModule();
1583 unsigned int pin = channelId.channel();
1584 int channel = pin*16 + mcm;
1585
1587 double eta;
1588 double phi;
1589 int layer;
1590 if(!m_mappingTool->mapping(crate, module, channel, eta, phi, layer)) {
1591 ATH_MSG_WARNING("::FCalTTeta: could not map 0x" << std::hex << channelId.id() << std::dec);
1592 }
1593
1595 return FCalTTeta(eta, phi, layer);
1596}
1597
1599template <typename T>
1600void L1TriggerTowerTool::printVec(const std::vector<T>& vec)
1601{
1602 if (m_debug) {
1603 if (vec.empty()) ATH_MSG_VERBOSE( " empty ");
1604 else {
1605 for(auto v : vec) {
1606 ATH_MSG_VERBOSE( v << " ");
1607 }
1608 }
1609 }
1610}
1611
1613{
1614 //method to load the FineTimeReferences Folder from COOL or an sqlite file (needs to be included in the job options)
1615 //implementation very similar to L1TriggerTowerTool::retrieveConditions
1616 //calling this method outside of fillHistograms() can result in Errors
1617
1618 // this method new requires L1CalCondAlg to be scheduled
1619 m_dbFineTimeRefsTowers = nullptr;
1620 bool verbose = msgLvl(MSG::VERBOSE);
1621 SG::ReadCondHandle <L1CaloPpmFineTimeRefsContainer> rh(m_dbFineTimeRefsTowersKey);
1622 CHECK_WITH_CONTEXT(rh.isValid(), "L1TriggerTowerTool");
1623 m_dbFineTimeRefsTowers = (*rh);
1624 if (verbose) {
1625 ATH_MSG_VERBOSE( "Retrieved FineTimeReferences Container" );
1626 rh->dump();
1627 }
1628 return StatusCode::SUCCESS;
1629}
1630
1631std::pair<double, double> L1TriggerTowerTool::refValues(const L1CaloCoolChannelId& channelId)
1632{
1633 //method returning the fine time reference and calibration value
1634 //the fineTimeReference folder has to be loaded first using the method L1TriggerTowerTool::loadFTRefs
1635 double reference = 0;
1636 double calib = 0;
1637
1639 const L1CaloPpmFineTimeRefs* ftref = m_dbFineTimeRefsTowers->ppmFineTimeRefs(channelId.id());
1640 if (ftref) {
1641 FineTimeErrorCode errorCode(ftref->errorCode());
1642// if (errorCode.chanValid()) { //this should be changed at some point, at the moment the error code is ignored
1643 reference = ftref->refValue();
1644 calib = ftref->calibValue();
1645// }
1646
1647 ATH_MSG_VERBOSE( MSG::hex
1648 << "::refValues: errorCode: " << (ftref->errorCode()).errorCode()
1649 << MSG::dec << " reference: " << ftref->refValue() << " calib: " << ftref->calibValue() );
1650
1651 } else {
1652 ATH_MSG_VERBOSE( "::refValue: No FineTimeRefsTowers found" );
1653 }
1654 } else {
1655 ATH_MSG_VERBOSE( "::refValue: No FineTimeRefs Container retrieved" );
1656 }
1657
1658 return std::make_pair(reference, calib);
1659}
1660
1661void L1TriggerTowerTool::pedestalCorrection(std::vector<int>& firInOut, int firPed, int iElement, int layer, int bcid, float mu, std::vector<int_least16_t>& correctionOut) {
1662 unsigned nFIR = firInOut.size();
1663 correctionOut.assign(nFIR, 0u);
1664
1665 if(!m_correctFir) return;
1666
1667 // apply the pedestal correction
1668 for(unsigned i = 0; i != nFIR; ++i) {
1669 correctionOut[i] = (m_dynamicPedestalProvider->dynamicPedestal(iElement, layer, firPed, bcid + i - nFIR/2, mu) - firPed);
1670 firInOut[i] -= correctionOut[i];
1671
1672 if(firInOut[i] < 0) firInOut[i] = 0;
1673 }
1674
1675 if(m_debug) {
1676 ATH_MSG_VERBOSE( "::pedestalCorrection(BCID=" << bcid << ", mu = " << mu << "): ");
1677 printVec(correctionOut);
1678 ATH_MSG_VERBOSE(" ");
1679 }
1680}
1681
1683{
1684 const EventContext& ctx = Gaudi::Hive::currentContext();
1685 if (ctx.eventID().run_number() >= 253377) return true;
1686
1688 if (eventInfo->eventType (xAOD::EventInfo::IS_SIMULATION)) return true;
1689 return false;
1690}
1691
1692} // end of namespace
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#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)
std::vector< size_t > vec
#define CHECK_WITH_CONTEXT(...)
Evaluate an expression and check for errors, with an explicitly specified context name.
const bool debug
Handle class for reading from StoreGate.
int sign(int a)
constexpr int pow(int base, int exp) noexcept
#define max(a, b)
Definition cfImp.cxx:41
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
Exception class for Calo Identifiers.
ChanCalibErrorCode class for L1Calo error codes Adapted from /LVL1/l1calo/coolL1Calo/coolL1Calo/ChanE...
bool chanValid() const
Checks if channel is valid, ie.
ChanDeadErrorCode class for L1Calo error codes Adapted from /LVL1/l1calo/coolL1Calo/coolL1Calo/ChanDe...
FineTimeErrorCode class for L1Calo error codes.
Encapsulates the ID of one channel of conditions data in COOL, ie the ID of a row in a table.
unsigned int id() const
FineTimeErrorCode errorCode(void) const
double calibValue(void) const
double refValue(void) const
Container of L1CaloPprConditions objects, inherit from the abstract base class AbstractL1CaloConditio...
Container of L1CaloPprConditions objects, inherit from the abstract base class AbstractL1CaloConditio...
Transient conditions class for objects defined by the online framework and retrieved from COOL for th...
unsigned short lutJepSlope() const
unsigned short lutCpStrategy() const
unsigned short lutCpSlope() const
unsigned short lutCpNoiseCut() const
unsigned short lutCpScale() const
unsigned short firStartBit() const
unsigned short lutJepStrategy() const
unsigned short lutJepScale() const
unsigned short lutJepNoiseCut() const
Transient conditions class for objects defined by the online framework and retrieved from COOL.
unsigned short lutStrategy() const
unsigned short lutSlope() const
unsigned short firStartBit() const
unsigned int pedValue() const
unsigned short lutOffset() const
unsigned short lutNoiseCut() const
Transient conditions class for objects defined by the online framework and retrieved from COOL.
ChanCalibErrorCode calibErrorCode(void) const
ChanDeadErrorCode deadErrorCode(void) const
SG::ReadCondHandleKey< L1CaloRunParametersContainer > m_runParametersContainerKey
L1Calo conditions.
ToolHandle< LVL1::IL1CaloMappingTool > m_mappingTool
and mappings
virtual Identifier identifier(double eta, double phi, int layer)
Return offline identifier for given tower coordinates.
SG::ReadCondHandleKey< L1CaloPpmFineTimeRefsContainer > m_dbFineTimeRefsTowersKey
virtual void setDebug(bool debug)
Finer control of debug printing.
virtual void cpLutParams(const L1CaloCoolChannelId &channelId, int &startBit, int &slope, int &offset, int &cut, int &pedValue, float &pedMean, int &strategy, bool &disabled)
L1TriggerTowerTool(const std::string &, const std::string &, const IInterface *)
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
virtual StatusCode initialize()
standard Athena-Algorithm method
const CaloIdManager * m_caloMgr
Id managers.
virtual bool disabledChannel(const L1CaloCoolChannelId &channelId)
Check for disabled channel.
const L1CaloRunParametersContainer * m_runParametersContainer
ToolHandle< LVL1::IL1DynamicPedestalProvider > m_dynamicPedestalProvider
SG::ReadCondHandleKey< L1CaloPprConditionsContainerRun2 > m_conditionsContainerKeyRun2
void printVec(const std::vector< T > &vec)
Print a vector to debug.
virtual std::pair< double, double > refValues(const L1CaloCoolChannelId &channelId)
virtual void dropBits(const std::vector< int > &fir, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
virtual void jepLut(const std::vector< int > &fir, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
virtual void firParams(const L1CaloCoolChannelId &channelId, std::vector< int > &firCoeffs)
Return FIR filter parameters for a channel.
virtual void bcidParams(const L1CaloCoolChannelId &channelId, int &energyLow, int &energyHigh, int &decisionSource, std::vector< unsigned int > &decisionConditions, unsigned int &peakFinderStrategy, int &satLow, int &satHigh, int &satLevel)
Return BCID parameters for a channel.
ToolHandle< LVL1::IL1CaloTTIdTools > m_l1CaloTTIdTools
virtual StatusCode retrieveConditions()
Retrieve pointers to the L1Calo conditions containers.
virtual void lut(const std::vector< int > &fir, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
LUT simulation: pedestal subtraction, energy calibration and threshold.
virtual double FCalTTeta(const L1CaloCoolChannelId &channelId)
Return median eta of trigger tower from L1CaloCoolChannelId.
virtual void handle(const Incident &)
catch begRun
virtual L1CaloCoolChannelId channelID(double eta, double phi, int layer)
Return Cool channel identifier for given tower coordinates.
SG::ReadHandleKey< TrigConf::L1Menu > m_L1MenuKey
virtual void simulateChannel(const xAOD::TriggerTower &tt, std::vector< int > &outCpLut, std::vector< int > &outJepLut, std::vector< int > &bcidResults, std::vector< int > &bcidDecisions)
All-in-one routine - give it the TT identifier, and it returns the results.
virtual void satBcid(const std::vector< int > &digits, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
Saturated pulse BCID.
virtual void fir(const std::vector< int > &digits, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
This FIR simulation produces a vector of same length as digit vector, with peak positions correspondi...
virtual void process(const std::vector< int > &digits, double eta, double phi, int layer, std::vector< int > &et, std::vector< int > &bcidResults, std::vector< int > &bcidDecisions, bool useJepLut=true)
Take in vector of ADC digits, return PPrASIC results.
virtual void peakBcid(const std::vector< int > &fir, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
Peak finder BCID.
ToolHandle< CaloTriggerTowerService > m_ttSvc
bool m_correctFir
Baseline correction Tool.
virtual StatusCode loadFTRefs()
virtual void applyEtRange(const std::vector< int > &lut, const std::vector< int > &range, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
Use ET range to return appropriate ET value Do not test BCID here, since no guarantee enough ADC samp...
virtual HWIdentifier hwIdentifier(const Identifier &id)
Return online identifier for given offline identifier.
virtual void nonLinearLut(const std::vector< int > &fir, int slope, int offset, int cut, int scale, short par1, short par2, short par3, short par4, bool disabled, std::vector< int > &output)
SG::ReadCondHandleKey< L1CaloPprDisabledChannelContainerRun2 > m_disabledChannelContainerKeyRun2
virtual bool satOverride(int range, const L1CaloCoolChannelId &channelId)
virtual void bcidDecision(const std::vector< int > &bcidResults, const std::vector< int > &range, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
virtual void bcid(const std::vector< int > &fir, const std::vector< int > &digits, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
Evaluate both peak-finder and saturated BCID algorithms and return vector of predicted BCID result wo...
virtual void jepLutParams(const L1CaloCoolChannelId &channelId, int &startBit, int &slope, int &offset, int &cut, int &pedValue, float &pedMean, int &strategy, bool &disabled)
virtual void cpLut(const std::vector< int > &fir, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
virtual void bcidDecisionRange(const std::vector< int > &lutInput, const std::vector< int > &digits, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
virtual void pedestalCorrection(std::vector< int > &firInOut, int firPed, int iElement, int layer, int bcid, float mu, std::vector< int_least16_t > &correctionOut)
std::vector< unsigned int > m_idTable
Mapping lookup table.
static const int s_saturationValue
Parameters.
virtual StatusCode finalize()
standard Athena-Algorithm method
virtual void lutParams(const L1CaloCoolChannelId &channelId, int &startBit, int &slope, int &offset, int &cut, int &pedValue, float &pedMean, int &strategy, bool &disabled)
Return LUT parameters for a channel.
const CaloLVL1_ID * m_lvl1Helper
and tools for computing identifiers
virtual void etRange(const std::vector< int > &et, const L1CaloCoolChannelId &channelId, std::vector< int > &output)
const L1CaloPpmFineTimeRefsContainer * m_dbFineTimeRefsTowers
For the fine time monitoring.
virtual ~L1TriggerTowerTool()
default destructor
@ IS_SIMULATION
true: simulation, false: data
const std::string process
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
bool verbose
Definition hcg.cxx:73
struct color C
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
TriggerTower_v2 TriggerTower
Define the latest version of the TriggerTower class.
Extra patterns decribing particle interation process.