8 #include "GaudiKernel/Incident.h"
9 #include "GaudiKernel/IIncidentSvc.h"
10 #include "GaudiKernel/GaudiException.h"
23 #include "GaudiKernel/ThreadLocalContext.h"
46 m_l1CaloTTIdTools(
"LVL1::L1CaloTTIdTools/L1CaloTTIdTools", this),
47 m_ttSvc(
"CaloTriggerTowerService/CaloTriggerTowerService", this),
48 m_mappingTool(
"", this),
50 m_dynamicPedestalProvider(
"", this)
52 declareInterface<IL1TriggerTowerToolRun3>(
this);
75 if(!
m_ttSvc.retrieve().isSuccess()) {
82 if (scID.isFailure()) {
93 SmartIF<IIncidentSvc> incSvc{service(
"IncidentSvc")};
95 incSvc->addListener(
this,
"BeginRun");
112 return StatusCode::SUCCESS;
119 return StatusCode::SUCCESS;
126 if (inc.type()==
"BeginRun") {
138 std::vector<int> &
et, std::vector<int> &bcidResults,
139 std::vector<int> &bcidDecisions,
bool useJepLut )
145 process(digits,
id,
et, bcidResults, bcidDecisions, useJepLut);
152 std::vector<int> &
et, std::vector<int> &bcidResults,
153 std::vector<int> &bcidDecisions,
bool useJepLut )
164 bcidDecisions.clear();
171 std::vector<int> lutInput;
182 std::vector<int> decisionRange;
184 bcidDecision(bcidResults, decisionRange, bcidDecisions);
189 std::vector<int> lutOutput;
205 template <
typename DST,
typename SRC>
206 std::vector<DST> convertVectorType(
const std::vector<SRC>&
s) {
207 std::vector<DST>
d(
s.size());
209 [](SRC
v){
return static_cast<DST
>(
v);});
221 ATH_MSG_DEBUG(
"RunParameters:: readoutConfigID " << readoutConfigID);
223 std::vector<uint16_t> digits40;
225 if(readoutConfigID == 5 or readoutConfigID == 6){
228 ATH_MSG_DEBUG(
"::simulateChannel: 80 MHz readout detected, emulating 40 MHz samples");
230 int nSlices =
tt.adc().size();
233 for (
int i=0 ;
i < (nSlices-1)/2 ;
i++ ){
234 digits40.push_back(
tt.adc().at(2*
i+1));
237 else if((nSlices%4)==1){
238 for (
int i=0 ;
i <= (nSlices-1)/2 ;
i++){
239 digits40.push_back(
tt.adc().at(2*
i));
249 const auto& digits = convertVectorType<int>(digits40);
253 ATH_MSG_DEBUG(
"::simulateChannel: ==== Entered Process ====" );
262 bcidDecisions.clear();
271 ATH_MSG_DEBUG(
"::simulateChannel: ---- pedestalCorrection ----" );
274 const std::size_t nCorr =
tt.correctionEnabled().size();
275 const std::size_t filterOffset =
filter.size()/2 - nCorr/2;
276 for(std::size_t iCorr = 0; iCorr < nCorr; ++iCorr) {
277 filter[filterOffset + iCorr] -=
tt.correction()[iCorr] *
tt.correctionEnabled()[iCorr];
283 std::vector<int> lutInput;
286 ATH_MSG_DEBUG(
"::simulateChannel: ---- BCID algorithms ---- ");
293 std::vector<int> decisionRange;
295 bcidDecision(bcidResults, decisionRange, bcidDecisions);
297 ATH_MSG_DEBUG(
"::simulateChannel: bcidDecisionRange " << decisionRange);
298 ATH_MSG_DEBUG(
"::simulateChannel: bcidDecisions " << bcidDecisions);
302 ATH_MSG_DEBUG(
"::simulateChannel: ---- LUT ET calculation ----" );
305 std::vector<int> cpLutOutput, jepLutOutput;
310 ATH_MSG_DEBUG(
"::simulateChannel: jepLut " << jepLutOutput);
312 ATH_MSG_DEBUG(
"::simulateChannel: ---- use ET range ----" );
319 ATH_MSG_DEBUG(
"::simulateChannel: cpLut applyETRange " << outCpLut);
320 ATH_MSG_DEBUG(
"::simulateChannel: jepLut applyETRange " << outJepLut);
323 ATH_MSG_DEBUG(
"::simulateChannel: ==== Leaving Process ====" );
332 std::vector<int> peak;
334 std::vector<int> sat;
338 output.reserve(sat.size());
342 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
343 output.push_back( (*itpeak<<2) + (*itsat<<1) );
354 unsigned int strategy,
int satLow,
int satHigh,
int satLevel, std::vector<int> &output)
const
357 std::vector<int> peak;
359 std::vector<int> sat;
360 satBcid(digits, satLow, satHigh, satLevel, sat);
363 output.reserve(sat.size());
367 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
368 output.push_back( (*itpeak<<2) + (*itsat<<1) );
377 void L1TriggerTowerToolRun3::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,
378 unsigned int strategy,
int satLow,
int satHigh,
int satLevel, std::vector<int> &
result, std::vector<int> &decision)
const
381 std::vector<int> peak;
383 std::vector<int> sat;
384 satBcid(digits, satLow, satHigh, satLevel, sat);
387 result.reserve(sat.size());
392 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
393 result.push_back( (*itpeak<<2) + (*itsat<<1) );
401 std::vector<int> decisionRange;
402 if (!(decisionSource&0
x1))
etRange(digits, energyLow, energyHigh, decisionRange);
403 else etRange(lutInput, energyLow, energyHigh, decisionRange);
413 if(!settings)
return nullptr;
414 return &(settings->firCoefficients());
427 std::vector<int> firCoeffs;
429 const std::vector<short int>* hwCoeffs;
430 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
435 firCoeffs.reserve(hwCoeffs->size());
437 firCoeffs.push_back(
i);
445 fir(digits, firCoeffs, output);
455 output.reserve(digits.size());
460 for (
unsigned int i = 0;
i < firCoeffs.size(); ++
i) {
461 if (firstFIR < 0 && firCoeffs[
i] != 0) firstFIR =
i;
462 if (firCoeffs[
i] != 0) lastFIR =
i;
464 if (firstFIR < 0) firstFIR = lastFIR + 1;
466 for (
int i = 0;
i < (
int)digits.size();
i++) {
469 if (
i >= 2-firstFIR &&
i < (
int)digits.size()+2-lastFIR) {
470 for (
int j = firstFIR; j <= lastFIR; ++j) {
471 sum += digits[
i+j-2]*firCoeffs[j];
475 output.push_back(
sum);
497 strategy = getStrategy<L1CaloPprConditionsContainerRun2>( pprConditionsRun2);
498 }
else ATH_MSG_WARNING(
"::peakBcid: No Conditions Container retrieved" );
509 output.reserve(
fir.size());
511 for (
unsigned int i = 0;
i <
fir.size();
i++) {
514 if (
i > 0 &&
i <
fir.size()-1) {
534 if(!settings)
return std::make_tuple(
false, 0, 0, 0);
535 return std::make_tuple(
true, settings->satBcidLevel(), settings->satBcidThreshLow(),
536 settings->satBcidThreshHigh());
549 bool available =
false;
550 std::tie(available, satLevel, satLow, satHigh) = getSaturation<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
551 if(!available)
ATH_MSG_WARNING(
"::satBcid: No L1CaloPprConditions found" );
552 }
else ATH_MSG_WARNING(
"::satBcid: No Conditions Container retrieved" );
555 <<
" satLow: " << satLow
556 <<
" satHigh: " << satHigh );
558 satBcid(digits, satLow, satHigh, satLevel, output);
566 output.reserve(digits.size());
571 for (
unsigned int i = 0;
i<digits.size();
i++) {
577 if (digits[
i]>=satLevel) {
578 if (enabled &&
i>1) {
579 bool low = (digits[
i-2]>satLow);
580 bool high = (digits[
i-1]>satHigh);
598 output.push_back(
flag[0]);
615 int decisionSource = 0;
619 decisionSource = getDecisionSource<L1CaloPprConditionsContainerRun2>(pprConditionsRun2);
621 }
else ATH_MSG_WARNING(
"::bcidDecisionRange: No Conditions Container retrieved" );
626 ATH_MSG_DEBUG(
"::bcidDecisionRange: decisionSource: " << decisionSource);
641 unsigned int decision1 = 0;
642 unsigned int decision2 = 0;
643 unsigned int decision3 = 0;
647 std::tie(decision1, decision2, decision3) = getBcidDecision<L1CaloPprConditionsContainerRun2>(pprConditionsRun2);
648 }
else ATH_MSG_WARNING(
"::bcidDecision: No Conditions Container retrieved" );
651 std::vector<unsigned int>
mask = { decision3, decision2, decision1 };
654 << decision3 <<
" " << decision2 <<
" " << decision1 << MSG::dec );
664 output.reserve(bcidResults.size());
666 std::vector<int>::const_iterator itBcid = bcidResults.begin();
667 std::vector<int>::const_iterator itRange =
range.begin();
668 int nRange =
mask.size();
670 for ( ; itBcid != bcidResults.end() && itRange !=
range.end(); ++itBcid, ++itRange) {
671 if ((*itRange) < nRange && (
mask[*itRange]&(0
x1<<*itBcid))) output.push_back(1);
672 else output.push_back(0);
688 unsigned short scale_menu = 0;
691 const std::vector<short int>* hwCoeffs;
695 const EventContext& ctx = Gaudi::Hive::currentContext();
701 strategy = settings->lutCpStrategy();
702 slope = settings->lutCpSlope();
703 cut = settings->lutCpNoiseCut();
704 pedMean = settings->pedMean();
706 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
709 scale_menu = l1Menu->thrExtraInfo().EM().emScale();
711 for(
auto &
coeffs : *hwCoeffs) {
718 }
else ATH_MSG_WARNING(
"::cpLut: No Conditions Container retrieved" );
720 ATH_MSG_DEBUG(
"::cpLut: strategy/scale/offset/slope/cut/pedMean/firCoeffSum/startBit: "
721 <<
strategy <<
"/" << scale_menu <<
"/" <<
offset <<
"/" << slope <<
"/" <<
cut <<
"/" << pedMean <<
"/" << hwCoeffSum <<
"/" << startBit );
723 unsigned int noiseCut = 0;
725 if (noiseCut > 0)
cut = noiseCut;
751 unsigned short scale_db = 0;
752 unsigned short scale_menu = 0;
755 const std::vector<short int>* hwCoeffs;
768 const EventContext& ctx = Gaudi::Hive::currentContext();
774 strategy = settings->lutJepStrategy();
775 slope = settings->lutJepSlope();
776 cut = settings->lutJepNoiseCut();
777 pedMean = settings->pedMean();
778 scale_db = settings->lutJepScale();
781 scale_menu = l1Menu->thrExtraInfo().JET().jetScale();
784 par1 = settings->lutJepPar1();
785 par2 = settings->lutJepPar2();
786 par3 = settings->lutJepPar3();
787 par4 = settings->lutJepPar4();
790 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
792 for(
auto &
coeffs : *hwCoeffs) {
799 }
else ATH_MSG_WARNING(
"::jepLut: No Conditions Container retrieved" );
801 ATH_MSG_DEBUG(
"::jepLut: strategy/scale/offset/slope/cut/pedMean/firCoeffSum/startBit: "
802 <<
strategy <<
"/" << scale_menu <<
"/" <<
offset <<
"/" << slope <<
"/" <<
cut <<
"/" << pedMean <<
"/" << hwCoeffSum <<
"/" << startBit );
804 unsigned int noiseCut = 0;
806 if (noiseCut > 0)
cut = noiseCut;
809 nonLinearLut(
fir, slope,
offset,
cut, scale_db, par1, par2, par3, par4,
disabled, output);
837 output.reserve(
fir.size());
839 const int reScale = 2;
840 for(
auto it :
fir) {
851 out = (
it*slope*reScale -
offset*reScale + 2048)>>12;
856 output.push_back(
out);
863 void L1TriggerTowerToolRun3::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)
const
866 output.reserve(
fir.size());
869 for(
auto it :
fir) {
873 double nll_slope = 0.001 *
scale;
874 double nll_offset = 0.001 * par1;
875 double nll_ampl = 0.001 * par2;
876 double nll_expo = 0.;
878 nll_expo = -1. / (4096 * 0.001*par3);
882 double nll_noise = 0.001 * par4;
895 output.push_back(
out);
906 std::vector<int>::const_iterator itlut =
lut.begin();
907 std::vector<int>::const_iterator itrange =
range.begin();
908 while ( itlut !=
lut.end() && itrange !=
range.end() ) {
910 else output.push_back(*itlut);
924 if(!settings)
return std::make_tuple(
false, 0, 0);
925 return std::make_tuple(
true, settings->bcidEnergyRangeLow(), settings->bcidEnergyRangeHigh());
938 bool available =
false;
939 std::tie(available, energyLow, energyHigh) = getBcidEnergyRange<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
940 if(!available)
ATH_MSG_WARNING(
"::etRange: No L1CaloPprConditions found");
941 }
else ATH_MSG_WARNING(
"::etRange: No Conditions Container retrieved");
944 <<
" energyHigh: " << energyHigh);
946 etRange(
et, energyLow, energyHigh, output);
954 output.reserve(
et.size());
956 if (
it <= energyLow) output.push_back(0);
957 else if (
it <= energyHigh) output.push_back(1);
958 else output.push_back(2);
971 if(!settings)
return std::make_tuple(
false, 0);
972 return std::make_tuple(
true, settings->firStartBit());
978 unsigned int start = 0;
982 bool available =
false;
983 std::tie(available,
start) = getFirStartBit<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
984 if(!available)
ATH_MSG_WARNING(
"::dropBits: No L1CaloPprConditions found" );
985 }
else ATH_MSG_WARNING(
"::dropBits: No Conditions Container retrieved" );
997 output.reserve(
fir.size());
1005 for(
auto it :
fir) {
1006 if (
it>=
max) output.push_back(0x3ff);
1020 const std::vector<short int>* hwCoeffs =
nullptr;
1021 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2 );
1027 firCoeffs.reserve(hwCoeffs->size());
1028 for (
int i = hwCoeffs->size()-1;
i >= 0; --
i) firCoeffs.push_back((*hwCoeffs)[
i]);
1030 }
else ATH_MSG_WARNING(
"::firParams: No L1CaloPprConditions found" );
1031 }
else ATH_MSG_WARNING(
"::firParams: No Conditions Container retrieved" );
1040 unsigned int &peakFinderStrategy,
int &satLow,
int &satHigh,
int &satLevel)
const
1045 decisionConditions.clear();
1046 peakFinderStrategy = 0;
1055 std::tuple<unsigned int, unsigned int, unsigned int>
bcidDecision;
1056 std::tuple<bool, int, int> bcidEnergyRange;
1057 std::tuple<bool, int, int, int> saturation;
1060 bcidDecision = getBcidDecision<Cont>(pprConditionsRun2);
1061 peakFinderStrategy = getStrategy<Cont>(pprConditionsRun2);
1062 decisionSource = getDecisionSource<Cont>(pprConditionsRun2);
1063 bcidEnergyRange = getBcidEnergyRange<Cont>(
channelId.id(), pprConditionsRun2);
1064 saturation = getSaturation<Cont>(
channelId.id(), pprConditionsRun2);
1070 if(get<0>(bcidEnergyRange)) {
1071 std::tie(
std::ignore, energyLow, energyHigh) = bcidEnergyRange;
1074 if(get<0>(saturation)) {
1075 std::tie(
std::ignore, satLevel, satLow, satHigh) = saturation;
1077 }
else ATH_MSG_WARNING(
"::bcid:Params No Conditions Container retrieved" );
1080 <<
" satLow: " << satLow <<
" satHigh: " << satHigh <<
endmsg
1081 <<
" energyLow: " << energyLow <<
" energyHigh: " << energyHigh <<
endmsg
1082 <<
" decisionSource: " << decisionSource <<
" peakFinderStrategy: "
1083 << peakFinderStrategy );
1098 const std::vector<short int>* hwCoeffs;
1112 strategy = settings->lutCpStrategy();
1113 slope = settings->lutCpSlope();
1114 cut = settings->lutCpNoiseCut();
1115 pedValue = settings->pedValue();
1116 pedMean = settings->pedMean();
1118 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(), pprConditionsRun2);
1120 for(
auto &
coeffs : *hwCoeffs) {
1126 ATH_MSG_VERBOSE(
"::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1127 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
1129 }
else ATH_MSG_WARNING(
"::cpLutParams: No L1CaloPprConditions found" );
1130 }
else ATH_MSG_WARNING(
"::cpLutParams: No Conditions Container retrieved" );
1132 ATH_MSG_VERBOSE(
"::cpLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1133 << startBit <<
" " <<
strategy <<
" " <<
offset <<
" " << slope <<
" " <<
cut <<
" " << pedValue <<
" " << pedMean );
1134 unsigned int noiseCut = 0;
1136 if (noiseCut > 0)
cut = noiseCut;
1150 const std::vector<short int>* hwCoeffs;
1162 strategy = settings->lutJepStrategy();
1163 slope = settings->lutJepSlope();
1164 cut = settings->lutJepNoiseCut();
1165 pedValue = settings->pedValue();
1166 pedMean = settings->pedMean();
1168 hwCoeffs = getFirCoefficients<L1CaloPprConditionsContainerRun2>(
channelId.id(),pprConditionsRun2);
1170 for(
auto &
coeffs : *hwCoeffs) {
1176 ATH_MSG_VERBOSE(
"::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1177 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
1179 }
else ATH_MSG_WARNING(
"::jepLutParams: No L1CaloPprConditions found" );
1180 }
else ATH_MSG_WARNING(
"::jepLutParams: No Conditions Container retrieved" );
1182 ATH_MSG_VERBOSE(
"::jepLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1183 << startBit <<
" " <<
strategy <<
" " <<
offset <<
" " << slope <<
" " <<
cut <<
" " << pedValue <<
" " << pedMean );
1184 unsigned int noiseCut = 0;
1186 if (noiseCut > 0)
cut = noiseCut;
1211 try { hwId =
m_ttSvc->createTTChannelID(
id,
false); }
1236 }
else if (
absEta < 3.2) {
1268 coolId =
m_ttSvc->createL1CoolChannelId(hwId);
1288 bool override =
false;
1291 satOverride = getSatOverride<L1CaloPprConditionsContainerRun2>(pprConditionsRun2);
1296 }
else ATH_MSG_WARNING(
"::satOverride: No Conditions Container retrieved" );
1299 <<
" has saturation override flag " <<
override );
1308 unsigned int noiseCut = 0;
1317 bool isDisabled =
false;
1324 if (!disabledChan->disabledBits()) {
1328 if (deadError.
chanValid()) noiseCut = disabledChan->noiseCut();
1331 }
else isDisabled =
true;
1334 <<
"::disabledChannel: calibErrorCode: " << (disabledChan->calibErrorCode()).errorCode()
1335 <<
" deadErrorCode: " << (disabledChan->deadErrorCode()).errorCode()
1336 <<
" noiseCut: " << disabledChan->noiseCut()
1337 <<
" disabledBits: " << disabledChan->disabledBits()
1341 ATH_MSG_DEBUG(
"::disabledChannel: No L1CaloPprDisabledChannel found" );
1344 ATH_MSG_WARNING(
"::disabledChannel: No DisabledChannel Container retrieved" );
1346 if (isDisabled)
ATH_MSG_DEBUG(
"::disabledChannel: Channel is disabled" );
1358 float abseta = std::abs(
eta);
1359 if (abseta<3.2)
return eta;
1361 int sign = ((
eta > 0) ? 1 : -1);
1362 if (abseta < 3.6)
eta = 3.15 *
sign;
1363 else if (abseta < 4.0)
eta = 3.33 *
sign;
1364 else if (abseta < 4.5)
eta = 3.72 *
sign;
1368 if (abseta < 3.6)
eta = 3.36;
1369 else if (abseta < 4.0)
eta = 3.45;
1370 else if (abseta < 4.5)
eta = 4.17;
1374 if (abseta < 3.6)
eta = -3.45;
1375 else if (abseta < 4.0)
eta = -3.36;
1376 else if (abseta < 4.5)
eta = -4.19;
1389 throw GaudiException(
"No mapping tool configured",
1390 "L1TriggerTowerToolRun3::FCalTTeta", StatusCode::FAILURE);
1396 unsigned int mcm =
channelId.subModule();
1432 <<
"::refValues: errorCode: " << (ftref->
errorCode()).errorCode()
1433 << MSG::dec <<
" reference: " << ftref->
refValue() <<
" calib: " << ftref->
calibValue() );
1446 unsigned nFIR = firInOut.size();
1447 correctionOut.assign(nFIR, 0
u);
1452 for(
unsigned i = 0;
i != nFIR; ++
i) {
1454 firInOut[
i] -= correctionOut[
i];
1456 if(firInOut[
i] < 0) firInOut[
i] = 0;
1459 ATH_MSG_DEBUG(
"::pedestalCorrection(BCID=" <<
bcid <<
", mu = " <<
mu <<
"): " << correctionOut);
1465 const EventContext& ctx = Gaudi::Hive::currentContext();
1466 if (ctx.eventID().run_number() >= 253377)
return true;
1473 unsigned int L1TriggerTowerToolRun3::getLutOffset(
const double &pedMean,
const unsigned int &firStartBit,
const std::vector<short int> &firCoeff,
const unsigned int &lutSlope,
const unsigned int &lutStrategy)
const
1475 unsigned int lutOffset = 0;
1477 long long int lutOffsetLong = 0;
1478 long long int lutSlopeLong = lutSlope;
1479 long long int firStartBitLong = firStartBit;
1480 long long int pedMeanLong = std::lround(pedMean * 10000.);
1481 long long int firCoeffSum = 0;
1483 for (
unsigned int i=0;
i<firCoeff.size();
i++) {
1484 firCoeffSum += firCoeff.at(
i);
1487 if ( lutStrategy == 0 ) {
1488 lutOffsetLong = ((pedMeanLong*firCoeffSum) >> firStartBitLong);
1491 lutOffsetLong = ((pedMeanLong*firCoeffSum*lutSlopeLong) >> firStartBitLong) - ((lutSlopeLong * 10000) >> 1);
1494 lutOffsetLong = (lutOffsetLong + (10000-1))/10000;
1495 lutOffset =
static_cast<unsigned int>( lutOffsetLong < 0 ? 0 : lutOffsetLong );
1503 if (
sc.isFailure()) {