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)
134 for(
unsigned int i = 0;
i < 25;
i++) {
146 m_sinThetaHash[ (
unsigned int)(32 + (0.5*0.425)*10.) ] = 1.0/cosh(3.2 + 0.5*0.425);
147 m_sinThetaHash[ (
unsigned int)(32 + (1.5*0.425)*10.) ] = 1.0/cosh(3.2 + 1.5*0.425);
148 m_sinThetaHash[ (
unsigned int)(32 + (2.5*0.425)*10.) ] = 1.0/cosh(3.2 + 2.5*0.425);
149 m_sinThetaHash[ (
unsigned int)(32 + (3.5*0.425)*10.) ] = 1.0/cosh(3.2 + 3.5*0.425);
167 return StatusCode::FAILURE;
173 incSvc->addListener(
this,
"BeginRun");
209 return StatusCode::SUCCESS;
216 if(inc.type() !=
"BeginRun")
return;
223 }
catch(
const std::out_of_range&) {
224 ATH_MSG_DEBUG(
"No Legacy triggers in menu, using default scales");
240 throw std::runtime_error(
"Overlay no longer supported in Run2TriggerTowerMaker");
280 ATH_MSG_WARNING(
"Could not determine if input file is data or simulation. Will assume simulation.");
286 ATH_MSG_INFO(
"Detected data reprocessing. Will take pedestal correction values from input trigger towers.");
295 ATH_MSG_INFO(
"L1Calo overlay job - setting m_isDataReprocessing to false");
303 return StatusCode::SUCCESS;
329 ATH_MSG_ERROR(
"Could not retrieve channel 0 PprChanDefaults folder. Aborting ...");
330 throw std::runtime_error(
"Run2TriggerTowerMaker: channel 0 of PprChanDefaults not accesible");
334 const EventContext& ctx = Gaudi::Hive::currentContext();
354 ATH_MSG_ERROR(
"Unsupported Cell Type!!!!!!");
return StatusCode::FAILURE;
361 const float mu = muDecor(0);
372 return StatusCode::SUCCESS;
378 if (!
db)
return false;
379 if (
db->errorCode() > 0 ||
db->noiseCut() > 0)
return true;
385 if (!
db)
return false;
386 if (
db->disabledBits() > 0)
return true;
394 if (!isDead && !isDisabled)
return true;
403 overlayDataTTs->setStore( &overlayDataTTsAux );
407 std::unordered_map<uint32_t,xAOD::TriggerTower*> overlayMap;
411 char decor_ttNotUsedInOverlay = 0;
412 char decor_ttUsedInOverlay = 1;
414 for (
auto tt:*overlayDataTTs) {
417 decor(*
tt) = decor_ttNotUsedInOverlay;
418 overlayMap.insert( std::make_pair(
tt->coolId() ,
tt ) );
423 bool findSizeOfPrimaryLUT(
true);
424 unsigned int sizeOfPrimaryLUT(0);
431 if (findSizeOfPrimaryLUT) {
432 findSizeOfPrimaryLUT =
false;
433 sizeOfPrimaryLUT =
tt->lut_cp().size();
434 peakOfPrimary =
tt->peak();
438 Itr
match = overlayMap.find(
tt->coolId() );
439 if (
match != overlayMap.end()) {
444 decor(*
match->second) = decor_ttUsedInOverlay;
450 for (Itr
i=overlayMap.begin();
i!=overlayMap.end();++
i) {
452 if (decor(*
tt) == decor_ttNotUsedInOverlay) {
454 std::vector<uint8_t> overlay_lut_cp(sizeOfPrimaryLUT,0.);
455 std::vector<uint8_t> overlay_lut_jep(sizeOfPrimaryLUT,0.);
458 overlay_lut_cp.at(peakOfPrimary) =
tt->cpET();
459 overlay_lut_jep.at(peakOfPrimary) =
tt->jepET();
462 tt->setPeak( peakOfPrimary );
463 tt->setLut_cp( overlay_lut_cp );
464 tt->setLut_jep( overlay_lut_jep );
472 return StatusCode::SUCCESS;
483 ATH_MSG_ERROR(
"Cannot find signal DB for tower 0x"<<std::hex<<sigTT->
coolId()<<std::dec<<
" Aborting...");
484 return StatusCode::FAILURE;
488 ATH_MSG_ERROR(
"Cannot find overlay DB for tower 0x"<<std::hex<<ovTT->
coolId()<<std::dec<<
" Aborting...");
489 return StatusCode::FAILURE;
496 std::vector<int> normOverlayDigits;
500 std::vector<int> sigLutIn,ovLutIn;
505 std::vector<int> lutOut_cp,lutOut_jep;
511 std::size_t peak = lutOut_jep.size()/2;
512 std::vector<uint_least8_t> etResultVectorCp {
uint8_t(lutOut_cp[peak]) };
513 std::vector<uint_least8_t> etResultVectorJep {
uint8_t(lutOut_jep[peak]) };
515 sigTT->
setLut_cp(std::move(etResultVectorCp));
516 sigTT->
setLut_jep(std::move(etResultVectorJep));
518 return StatusCode::SUCCESS;
524 ATH_MSG_ERROR(
"Cannot process calcLutOutCP as lutCpStrategy > 2");
525 return StatusCode::FAILURE;
529 double sigSlope = sigScale * sigDB->
lutCpSlope();
530 double sigOffset = sigScale * sigDB->
lutCpOffset();
533 double ovSlope = ovScale * ovDB->
lutCpSlope();
537 calcCombinedLUT(sigLutIn,sigSlope,sigOffset,ovLutIn,ovSlope,ovOffset,ovNoiseCut,output);
539 return StatusCode::SUCCESS;
545 ATH_MSG_ERROR(
"Cannot process calcLutOutJEP as lutJepStrategy > 2");
546 return StatusCode::FAILURE;
558 calcCombinedLUT(sigLutIn,sigSlope,sigOffset,ovLutIn,ovSlope,ovOffset,ovNoiseCut,output);
560 return StatusCode::SUCCESS;
564 const std::vector<int>& ovIN,
const int ovSlope,
const int ovOffset,
const int ovNoiseCut,std::vector<int>& output)
574 output.reserve(sigIN.size());
576 for (
unsigned int i=0;
i<sigIN.size();++
i) {
581 int outSig =
signal*sigSlope - sigOffset;
582 int outOv =
overlay*ovSlope - ovOffset;
583 int outTmp = outSig + outOv;
586 if (outTmp >= ovNoiseCut) {
587 out = (outSig + outOv + 2048)>>12;
594 output.push_back(
out );
603 std::vector<int> fir;
605 {
db->firCoeff5(),
db->firCoeff4(),
db->firCoeff3(),
db->firCoeff2(),
db->firCoeff1()},
609 int pedCorrectionStrategy =
db->lutCpStrategy();
613 if (pedCorrectionStrategy == 1) {
617 int firPed = (
db->firCoeff5() +
db->firCoeff4() +
db->firCoeff3() +
618 db->firCoeff2() +
db->firCoeff1()) *
int(
db->pedMean() + 0.5);
629 if (pedCorrectionStrategy == 2) {
643 m_TTtool->dropBits(fir,
db->firStartBit(), output);
645 return StatusCode::SUCCESS;
657 if (sigDigits.size() == ovDigits.size()) {
658 for (
auto x:ovDigits) normDigits.push_back(
x );
662 if (sigDigits.size() > ovDigits.size()) {
663 unsigned int pad = (sigDigits.size() - ovDigits.size()) / 2;
664 for (
unsigned int x=0;
x<pad;++
x) normDigits.push_back( 32 );
665 for (
auto x:ovDigits) normDigits.push_back(
x );
666 for (
unsigned int x=0;
x<pad;++
x) normDigits.push_back( 32 );
671 if (sigDigits.size() < ovDigits.size()) {
672 unsigned int offset = (ovDigits.size() - sigDigits.size()) / 2;
673 for (
unsigned int x=0;
x<sigDigits.size();++
x) {
675 normDigits.push_back( ovDigits[
pos] );
690 return StatusCode::SUCCESS;
699 ATH_MSG_ERROR(
"Tower with coolId 0x"<<std::hex<<tower->
coolId()<<std::dec<<
" Not in database! Aborting ...");
700 return StatusCode::FAILURE;
704 int pedCorrectionStrategy(0);
718 std::vector<int> fir;
735 if (pedCorrectionStrategy == 1) {
751 if (pedCorrectionStrategy == 2) {
769 std::vector<int> lutIn;
773 std::vector<int> lutOut_cp;
796 std::vector<int> lutOut_jep;
819 std::vector<int> BCIDOut;
834 std::size_t peak = lutOut_jep.size()/2;
835 std::vector<uint_least8_t> etResultVectorCp {
uint8_t(lutOut_cp[peak]) };
838 std::vector<uint_least8_t> etResultVectorJep {
uint8_t(lutOut_jep[peak]) };
852 std::array<int, 3> bcidDecision {
858 std::array<int, 3> satOverride {
864 if((bcidDecision[
range]) & (0
x1 << (BCIDOut[BCIDOut.size()/2]))) {
865 if((satOverride[
range]) & 0
x1) {
867 etResultVectorCp[0] = SATURATIONVALUE;
868 etResultVectorJep[0] = SATURATIONVALUE;
872 etResultVectorCp[0] = 0;
873 etResultVectorJep[0] = 0;
879 tower->
setLut_cp(std::move(etResultVectorCp));
880 tower->
setLut_jep(std::move(etResultVectorJep));
903 return StatusCode::SUCCESS;
918 return tt->cpET() == 0 && tt->jepET() == 0;
934 return StatusCode::SUCCESS;
960 [
this](
const xAOD::TriggerTower*
tt){return !IsGoodTower(tt,m_deadChannelsContainer,m_disabledTowersContainer);}),
963 return StatusCode::SUCCESS;
974 sc1 = StatusCode::FAILURE;
981 sc2 = StatusCode::FAILURE;
989 sc3 = StatusCode::FAILURE;
993 (sc2==StatusCode::FAILURE) ||
994 (sc3==StatusCode::FAILURE))) {
996 <<
"Found Em LArTTL1 : "<<sc1 <<
endmsg
997 <<
"Found Had LArTTL1 : "<<sc2 <<
endmsg
998 <<
"Found TileTTL1 : "<<sc3<<
endmsg
1000 return StatusCode::FAILURE;
1004 if(sc1 == StatusCode::SUCCESS) {
1007 if(sc2 == StatusCode::SUCCESS) {
1010 if(sc3 == StatusCode::SUCCESS) {
1022 [
this](
const xAOD::TriggerTower*
tt){return !IsGoodTower(tt,m_deadChannelsContainer,m_disabledTowersContainer);}),
1025 return StatusCode::SUCCESS;
1033 ATH_MSG_VERBOSE(
"Looking at retrieved tower number "<<towerNumber++<<
" ***********");
1044 std::vector<float> tower_amps = tower->samples();
1057 amps[
i] = tower_amps[j];
1067 t->setCoolId(coolId.
id());
1079 ATH_MSG_VERBOSE(
"Looking at retrieved tower number "<<towerNumber++<<
" ***********");
1092 unsigned Ieta =
unsigned(fabs(tower_eta)*10.0);
1094 ATH_MSG_WARNING(
"TileTTL1 with invalid index for m_sinThetaHash: Ieta = " << Ieta);
1100 std::vector<float> tower_amps = tower->fsamples();
1109 for(
int i = 0;
i < 7;
i++) {
1125 t->setCoolId(
channelId(tower_eta, tower_phi, 1).
id());
1126 t->setEta(tower_eta);
1127 t->setPhi(tower_phi);
1146 tower->setAdcPeak(digits.size()/2);
1155 double ped = chanCalib->pedMean();
1158 double adcCal = (
m_gainCorr > 0.) ? CLHEP::RandGaussZiggurat::shoot(rndmADCs, 1.,
m_gainCorr) : 1.;
1160 std::vector<int> digits;
1165 double adcNoise = (
m_adcVar > 0.) ? CLHEP::RandGaussZiggurat::shoot(rndmADCs,0.,
m_adcVar) : 0.;
1170 digits.push_back(
digit);
1177 if(
et < bcidEnergyRangeLow)
return 0;
1178 if(
et < bcidEnergyRangeHigh)
return 1;
1184 int region = l1id->
region(
id);
1185 int ieta = l1id->
eta(
id);
1188 double gran[4] = {0.1, 0.2, 0.1, 0.425};
1189 double offset[4] = {0., 2.5, 3.1, 3.2};
1192 if(region>=0 && region<=3) {
1193 eta =
sign* (((ieta+0.5) * gran[region]) +
offset[region]);
1207 double phiMax = l1id->
phi_max(regId);
1208 int iphi = l1id->
phi(
id);
1209 double phi = (iphi+0.5)*2*
M_PI/(phiMax+1);
1230 constexpr
static int NELEMENTS = 33;
1232 float shiftedEta = feta + 4.9;
1233 uint eta = (
uint)floor(shiftedEta*10.0);
1234 if(fabs(shiftedEta*10.0 - (
uint)(eta+1)) < 0.01) eta++;
1235 if(fabs(shiftedEta) < 0.01) eta = 0;
1237 constexpr
int nBins = 16;
1238 constexpr
uint map[
nBins] = {2,6,10,14,17,19,21,23,75,77,79,80,83,87,91,95};
1240 if(eta > 23 && eta < 74) {
1245 if(
i < 8) element =
i;
1246 else element =
i + 50;
1251 if (
layer == 1 && (element == 0 || element == 64)) element = 1;
1252 else if (
layer == 1 && (element == 1 || element == 65)) element = 0;
1253 else if (
layer == 1 && (element == 2 || element == 62)) element = 3;
1254 else if (
layer == 1 && (element == 3 || element == 63)) element = 2;
1255 else if (element > 32) element = 65-element;
1258 element = NELEMENTS-element-1;
1271 double nll_slope = 0.001 *
scale;
1272 double nll_offset = 0.001 * par1;
1273 double nll_ampl = 0.001 * par2;
1274 double nll_expo = 0.;
1276 nll_expo = -1. / (4096 * 0.001*par3);
1280 double nll_noise = 0.001 * par4;
1283 if (lutin * slope <
offset + nll_noise * noiseCut) {
1288 int output =
int((((
int)(2048 + nll_slope * (lutin * slope -
offset)))>>12) + nll_offset + nll_ampl *
std::exp(nll_expo * (lutin * slope -
offset)));
1289 if(output >= 255)
return 255;
1290 if(output < 0)
return 0;