37 #include "GaudiKernel/IIncidentSvc.h"
42 #include "GaudiKernel/ThreadLocalContext.h"
44 #include "CLHEP/Random/RandGaussZiggurat.h"
45 #include "CLHEP/Random/Randomize.h"
46 #include "CLHEP/Random/RandomEngine.h"
54 #include <sys/types.h>
55 #include <unordered_map>
62 template <
typename MSG,
typename T>
63 void printVec(
MSG&
msg,
const std::vector<T>&
v) {
67 template <
typename MSG,
typename T, std::
size_t N>
68 void printVec(
MSG&
msg,
const std::array<T, N>&
v) {
72 constexpr
static int ADCMAX = 1023;
73 constexpr
static int SATURATIONVALUE = 255;
83 m_rngSvc(
"AthRNGSvc",
name),
85 m_mappingTool(
"LVL1::PpmMappingTool/PpmMappingTool", this),
86 m_bstowertool(
"LVL1BS__TrigT1CaloDataAccessV2/TrigT1CaloDataAccessV2", this),
90 m_TileToMeV(s_MEV/4.1),
92 m_isDataReprocessing(false),
93 m_doOverlay(false), m_isReco(false)
133 for(
unsigned int i = 0;
i < 25;
i++) {
145 m_sinThetaHash[ (
unsigned int)(32 + (0.5*0.425)*10.) ] = 1.0/cosh(3.2 + 0.5*0.425);
146 m_sinThetaHash[ (
unsigned int)(32 + (1.5*0.425)*10.) ] = 1.0/cosh(3.2 + 1.5*0.425);
147 m_sinThetaHash[ (
unsigned int)(32 + (2.5*0.425)*10.) ] = 1.0/cosh(3.2 + 2.5*0.425);
148 m_sinThetaHash[ (
unsigned int)(32 + (3.5*0.425)*10.) ] = 1.0/cosh(3.2 + 3.5*0.425);
166 return StatusCode::FAILURE;
172 incSvc->addListener(
this,
"BeginRun");
208 return StatusCode::SUCCESS;
215 if(inc.type() !=
"BeginRun")
return;
222 }
catch(
const std::out_of_range&) {
223 ATH_MSG_DEBUG(
"No Legacy triggers in menu, using default scales");
239 throw std::runtime_error(
"Overlay no longer supported in Run2TriggerTowerMaker");
279 ATH_MSG_WARNING(
"Could not determine if input file is data or simulation. Will assume simulation.");
285 ATH_MSG_INFO(
"Detected data reprocessing. Will take pedestal correction values from input trigger towers.");
294 ATH_MSG_INFO(
"L1Calo overlay job - setting m_isDataReprocessing to false");
302 return StatusCode::SUCCESS;
328 ATH_MSG_ERROR(
"Could not retrieve channel 0 PprChanDefaults folder. Aborting ...");
329 throw std::runtime_error(
"Run2TriggerTowerMaker: channel 0 of PprChanDefaults not accesible");
333 const EventContext& ctx = Gaudi::Hive::currentContext();
353 ATH_MSG_ERROR(
"Unsupported Cell Type!!!!!!");
return StatusCode::FAILURE;
360 const float mu = muDecor(0);
371 return StatusCode::SUCCESS;
377 if (!
db)
return false;
378 if (
db->errorCode() > 0 ||
db->noiseCut() > 0)
return true;
384 if (!
db)
return false;
385 if (
db->disabledBits() > 0)
return true;
393 if (!isDead && !isDisabled)
return true;
402 overlayDataTTs->setStore( &overlayDataTTsAux );
406 std::unordered_map<uint32_t,xAOD::TriggerTower*> overlayMap;
410 char decor_ttNotUsedInOverlay = 0;
411 char decor_ttUsedInOverlay = 1;
413 for (
auto tt:*overlayDataTTs) {
416 decor(*
tt) = decor_ttNotUsedInOverlay;
417 overlayMap.insert( std::make_pair(
tt->coolId() ,
tt ) );
422 bool findSizeOfPrimaryLUT(
true);
423 unsigned int sizeOfPrimaryLUT(0);
430 if (findSizeOfPrimaryLUT) {
431 findSizeOfPrimaryLUT =
false;
432 sizeOfPrimaryLUT =
tt->lut_cp().size();
433 peakOfPrimary =
tt->peak();
437 Itr
match = overlayMap.find(
tt->coolId() );
438 if (
match != overlayMap.end()) {
443 decor(*
match->second) = decor_ttUsedInOverlay;
449 for (Itr
i=overlayMap.begin();
i!=overlayMap.end();++
i) {
451 if (decor(*
tt) == decor_ttNotUsedInOverlay) {
453 std::vector<uint8_t> overlay_lut_cp(sizeOfPrimaryLUT,0.);
454 std::vector<uint8_t> overlay_lut_jep(sizeOfPrimaryLUT,0.);
457 overlay_lut_cp.at(peakOfPrimary) =
tt->cpET();
458 overlay_lut_jep.at(peakOfPrimary) =
tt->jepET();
461 tt->setPeak( peakOfPrimary );
462 tt->setLut_cp( overlay_lut_cp );
463 tt->setLut_jep( overlay_lut_jep );
471 return StatusCode::SUCCESS;
482 ATH_MSG_ERROR(
"Cannot find signal DB for tower 0x"<<std::hex<<sigTT->
coolId()<<std::dec<<
" Aborting...");
483 return StatusCode::FAILURE;
487 ATH_MSG_ERROR(
"Cannot find overlay DB for tower 0x"<<std::hex<<ovTT->
coolId()<<std::dec<<
" Aborting...");
488 return StatusCode::FAILURE;
495 std::vector<int> normOverlayDigits;
499 std::vector<int> sigLutIn,ovLutIn;
504 std::vector<int> lutOut_cp,lutOut_jep;
510 std::size_t peak = lutOut_jep.size()/2;
511 std::vector<uint_least8_t> etResultVectorCp {
uint8_t(lutOut_cp[peak]) };
512 std::vector<uint_least8_t> etResultVectorJep {
uint8_t(lutOut_jep[peak]) };
514 sigTT->
setLut_cp(std::move(etResultVectorCp));
515 sigTT->
setLut_jep(std::move(etResultVectorJep));
517 return StatusCode::SUCCESS;
523 ATH_MSG_ERROR(
"Cannot process calcLutOutCP as lutCpStrategy > 2");
524 return StatusCode::FAILURE;
528 double sigSlope = sigScale * sigDB->
lutCpSlope();
529 double sigOffset = sigScale * sigDB->
lutCpOffset();
532 double ovSlope = ovScale * ovDB->
lutCpSlope();
536 calcCombinedLUT(sigLutIn,sigSlope,sigOffset,ovLutIn,ovSlope,ovOffset,ovNoiseCut,output);
538 return StatusCode::SUCCESS;
544 ATH_MSG_ERROR(
"Cannot process calcLutOutJEP as lutJepStrategy > 2");
545 return StatusCode::FAILURE;
557 calcCombinedLUT(sigLutIn,sigSlope,sigOffset,ovLutIn,ovSlope,ovOffset,ovNoiseCut,output);
559 return StatusCode::SUCCESS;
563 const std::vector<int>& ovIN,
const int ovSlope,
const int ovOffset,
const int ovNoiseCut,std::vector<int>& output)
573 output.reserve(sigIN.size());
575 for (
unsigned int i=0;
i<sigIN.size();++
i) {
580 int outSig =
signal*sigSlope - sigOffset;
581 int outOv =
overlay*ovSlope - ovOffset;
582 int outTmp = outSig + outOv;
585 if (outTmp >= ovNoiseCut) {
586 out = (outSig + outOv + 2048)>>12;
593 output.push_back(
out );
602 std::vector<int> fir;
604 {
db->firCoeff5(),
db->firCoeff4(),
db->firCoeff3(),
db->firCoeff2(),
db->firCoeff1()},
608 int pedCorrectionStrategy =
db->lutCpStrategy();
612 if (pedCorrectionStrategy == 1) {
616 int firPed = (
db->firCoeff5() +
db->firCoeff4() +
db->firCoeff3() +
617 db->firCoeff2() +
db->firCoeff1()) *
int(
db->pedMean() + 0.5);
628 if (pedCorrectionStrategy == 2) {
642 m_TTtool->dropBits(fir,
db->firStartBit(), output);
644 return StatusCode::SUCCESS;
656 if (sigDigits.size() == ovDigits.size()) {
657 for (
auto x:ovDigits) normDigits.push_back(
x );
661 if (sigDigits.size() > ovDigits.size()) {
662 unsigned int pad = (sigDigits.size() - ovDigits.size()) / 2;
663 for (
unsigned int x=0;
x<pad;++
x) normDigits.push_back( 32 );
664 for (
auto x:ovDigits) normDigits.push_back(
x );
665 for (
unsigned int x=0;
x<pad;++
x) normDigits.push_back( 32 );
670 if (sigDigits.size() < ovDigits.size()) {
671 unsigned int offset = (ovDigits.size() - sigDigits.size()) / 2;
672 for (
unsigned int x=0;
x<sigDigits.size();++
x) {
674 normDigits.push_back( ovDigits[
pos] );
689 return StatusCode::SUCCESS;
698 ATH_MSG_ERROR(
"Tower with coolId 0x"<<std::hex<<tower->
coolId()<<std::dec<<
" Not in database! Aborting ...");
699 return StatusCode::FAILURE;
703 int pedCorrectionStrategy(0);
717 std::vector<int> fir;
734 if (pedCorrectionStrategy == 1) {
750 if (pedCorrectionStrategy == 2) {
768 std::vector<int> lutIn;
772 std::vector<int> lutOut_cp;
795 std::vector<int> lutOut_jep;
818 std::vector<int> BCIDOut;
833 std::size_t peak = lutOut_jep.size()/2;
834 std::vector<uint_least8_t> etResultVectorCp {
uint8_t(lutOut_cp[peak]) };
837 std::vector<uint_least8_t> etResultVectorJep {
uint8_t(lutOut_jep[peak]) };
851 std::array<int, 3> bcidDecision {
857 std::array<int, 3> satOverride {
863 if((bcidDecision[
range]) & (0
x1 << (BCIDOut[BCIDOut.size()/2]))) {
864 if((satOverride[
range]) & 0
x1) {
866 etResultVectorCp[0] = SATURATIONVALUE;
867 etResultVectorJep[0] = SATURATIONVALUE;
871 etResultVectorCp[0] = 0;
872 etResultVectorJep[0] = 0;
878 tower->
setLut_cp(std::move(etResultVectorCp));
879 tower->
setLut_jep(std::move(etResultVectorJep));
902 return StatusCode::SUCCESS;
917 return tt->cpET() == 0 && tt->jepET() == 0;
933 return StatusCode::SUCCESS;
959 [
this](
const xAOD::TriggerTower*
tt){return !IsGoodTower(tt,m_deadChannelsContainer,m_disabledTowersContainer);}),
962 return StatusCode::SUCCESS;
973 sc1 = StatusCode::FAILURE;
980 sc2 = StatusCode::FAILURE;
988 sc3 = StatusCode::FAILURE;
992 (sc2==StatusCode::FAILURE) ||
993 (sc3==StatusCode::FAILURE))) {
995 <<
"Found Em LArTTL1 : "<<sc1 <<
endmsg
996 <<
"Found Had LArTTL1 : "<<sc2 <<
endmsg
997 <<
"Found TileTTL1 : "<<sc3<<
endmsg
999 return StatusCode::FAILURE;
1003 if(sc1 == StatusCode::SUCCESS) {
1006 if(sc2 == StatusCode::SUCCESS) {
1009 if(sc3 == StatusCode::SUCCESS) {
1021 [
this](
const xAOD::TriggerTower*
tt){return !IsGoodTower(tt,m_deadChannelsContainer,m_disabledTowersContainer);}),
1024 return StatusCode::SUCCESS;
1032 ATH_MSG_VERBOSE(
"Looking at retrieved tower number "<<towerNumber++<<
" ***********");
1043 std::vector<float> tower_amps = tower->samples();
1056 amps[
i] = tower_amps[j];
1066 t->setCoolId(coolId.
id());
1078 ATH_MSG_VERBOSE(
"Looking at retrieved tower number "<<towerNumber++<<
" ***********");
1091 unsigned Ieta =
unsigned(fabs(tower_eta)*10.0);
1093 ATH_MSG_WARNING(
"TileTTL1 with invalid index for m_sinThetaHash: Ieta = " << Ieta);
1099 std::vector<float> tower_amps = tower->fsamples();
1108 for(
int i = 0;
i < 7;
i++) {
1124 t->setCoolId(
channelId(tower_eta, tower_phi, 1).
id());
1125 t->setEta(tower_eta);
1126 t->setPhi(tower_phi);
1145 tower->setAdcPeak(digits.size()/2);
1154 double ped = chanCalib->pedMean();
1157 double adcCal = (
m_gainCorr > 0.) ? CLHEP::RandGaussZiggurat::shoot(rndmADCs, 1.,
m_gainCorr) : 1.;
1159 std::vector<int> digits;
1164 double adcNoise = (
m_adcVar > 0.) ? CLHEP::RandGaussZiggurat::shoot(rndmADCs,0.,
m_adcVar) : 0.;
1169 digits.push_back(
digit);
1176 if(
et < bcidEnergyRangeLow)
return 0;
1177 if(
et < bcidEnergyRangeHigh)
return 1;
1183 int region = l1id->
region(
id);
1184 int ieta = l1id->
eta(
id);
1187 double gran[4] = {0.1, 0.2, 0.1, 0.425};
1188 double offset[4] = {0., 2.5, 3.1, 3.2};
1191 if(region>=0 && region<=3) {
1206 double phiMax = l1id->
phi_max(regId);
1207 int iphi = l1id->
phi(
id);
1208 double phi = (iphi+0.5)*2*
M_PI/(phiMax+1);
1229 constexpr
static int NELEMENTS = 33;
1231 float shiftedEta = feta + 4.9;
1233 if(fabs(shiftedEta*10.0 - (
uint)(
eta+1)) < 0.01)
eta++;
1234 if(fabs(shiftedEta) < 0.01)
eta = 0;
1236 constexpr
int nBins = 16;
1237 constexpr
uint map[
nBins] = {2,6,10,14,17,19,21,23,75,77,79,80,83,87,91,95};
1239 if(
eta > 23 &&
eta < 74) {
1244 if(
i < 8) element =
i;
1245 else element =
i + 50;
1250 if (
layer == 1 && (element == 0 || element == 64)) element = 1;
1251 else if (
layer == 1 && (element == 1 || element == 65)) element = 0;
1252 else if (
layer == 1 && (element == 2 || element == 62)) element = 3;
1253 else if (
layer == 1 && (element == 3 || element == 63)) element = 2;
1254 else if (element > 32) element = 65-element;
1257 element = NELEMENTS-element-1;
1270 double nll_slope = 0.001 *
scale;
1271 double nll_offset = 0.001 * par1;
1272 double nll_ampl = 0.001 * par2;
1273 double nll_expo = 0.;
1275 nll_expo = -1. / (4096 * 0.001*par3);
1279 double nll_noise = 0.001 * par4;
1282 if (lutin * slope <
offset + nll_noise * noiseCut) {
1287 int output =
int((((
int)(2048 + nll_slope * (lutin * slope -
offset)))>>12) + nll_offset + nll_ampl *
std::exp(nll_expo * (lutin * slope -
offset)));
1288 if(output >= 255)
return 255;
1289 if(output < 0)
return 0;