9 #include "GaudiKernel/Incident.h"
10 #include "GaudiKernel/IIncidentSvc.h"
11 #include "GaudiKernel/GaudiException.h"
43 #include "GaudiKernel/ThreadLocalContext.h"
65 m_l1CaloTTIdTools(
"LVL1::L1CaloTTIdTools/L1CaloTTIdTools", this),
66 m_ttSvc(
"CaloTriggerTowerService/CaloTriggerTowerService", this),
67 m_mappingTool(
"", this),
68 m_l1CondSvc(
"L1CaloCondSvc",
n),
69 m_dbFineTimeRefsTowers(0),
71 m_dynamicPedestalProvider(
"", this)
73 declareInterface<IL1TriggerTowerTool>(
this);
95 if(!
m_ttSvc.retrieve().isSuccess()) {
102 if (scID.isFailure()) {
113 IIncidentSvc* incSvc = 0;
114 if (service(
"IncidentSvc", incSvc).isFailure()) {
118 incSvc->addListener(
this,
"BeginRun");
133 return StatusCode::SUCCESS;
140 return StatusCode::SUCCESS;
147 if (inc.type()==
"BeginRun") {
162 return StatusCode::SUCCESS;
165 template<
class T,
class FolderMap>
170 return StatusCode::SUCCESS;
189 return StatusCode::FAILURE;
195 return StatusCode::FAILURE;
199 std::string timingRegime = std::cbegin(*m_derivedRunParsContainer)->timingRegime();
205 if (
it.timingRegime() == timingRegime){
210 std::map<L1CaloPprConditionsContainerRun2::eCoolFolders, std::string>
211 coolFoldersKeysMap = {
214 "/TRIGGER/L1Calo/V2/Configuration/PprChanDefaults"
220 =
"/TRIGGER/L1Calo/V2/Calibration/" + timingRegime +
"/PprChanCalib";
223 "/TRIGGER/L1Calo/V2/Calibration/" + timingRegime +
"/PprChanCommon";
225 "/TRIGGER/L1Calo/V2/Calibration/" + timingRegime +
"/PprChan" +
strategy;
228 CHECK(retrieveGenericWithFolders<L1CaloPprConditionsContainerRun2>(
268 return StatusCode::FAILURE;
271 return StatusCode::SUCCESS;
277 std::vector<int> &
et, std::vector<int> &bcidResults,
278 std::vector<int> &bcidDecisions,
bool useJepLut )
284 process(digits,
id,
et, bcidResults, bcidDecisions, useJepLut);
291 std::vector<int> &
et, std::vector<int> &bcidResults,
292 std::vector<int> &bcidDecisions,
bool useJepLut )
304 bcidDecisions.clear();
311 std::vector<int> lutInput;
322 std::vector<int> decisionRange;
329 std::vector<int> lutOutput;
348 template <
typename DST,
typename SRC>
349 std::vector<DST> convertVectorType(
const std::vector<SRC>&
s) {
350 std::vector<DST>
d(
s.size());
352 [](SRC
v){
return static_cast<DST
>(
v);});
363 unsigned int readoutConfigID = std::cbegin(*m_runParametersContainer)->readoutConfigID();
369 std::vector<uint16_t> digits40;
371 if(readoutConfigID == 5 or readoutConfigID == 6){
377 int nSlices =
tt.adc().size();
380 for (
int i=0 ;
i < (nSlices-1)/2 ;
i++ ){
381 digits40.push_back(
tt.adc().at(2*
i+1));
384 else if((nSlices%4)==1){
385 for (
int i=0 ;
i <= (nSlices-1)/2 ;
i++){
386 digits40.push_back(
tt.adc().at(2*
i));
398 const auto& digits = convertVectorType<int>(digits40);
413 bcidDecisions.clear();
426 const std::size_t nCorr =
tt.correctionEnabled().size();
427 const std::size_t filterOffset =
filter.size()/2 - nCorr/2;
428 for(std::size_t iCorr = 0; iCorr < nCorr; ++iCorr) {
429 filter[filterOffset + iCorr] -=
tt.correction()[iCorr] *
tt.correctionEnabled()[iCorr];
433 std::vector<int> lutInput;
444 std::vector<int> decisionRange;
451 std::vector<int> cpLutOutput, jepLutOutput;
471 std::vector<int> peak;
473 std::vector<int> sat;
477 output.reserve(sat.size());
481 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
482 output.push_back( (*itpeak<<2) + (*itsat<<1) );
495 unsigned int strategy,
int satLow,
int satHigh,
int satLevel, std::vector<int> &
output)
498 std::vector<int> peak;
500 std::vector<int> sat;
501 satBcid(digits, satLow, satHigh, satLevel, sat);
504 output.reserve(sat.size());
508 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
509 output.push_back( (*itpeak<<2) + (*itsat<<1) );
521 void 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,
522 unsigned int strategy,
int satLow,
int satHigh,
int satLevel, std::vector<int> &
result, std::vector<int> &decision)
525 std::vector<int> peak;
527 std::vector<int> sat;
528 satBcid(digits, satLow, satHigh, satLevel, sat);
531 result.reserve(sat.size());
536 for ( ; itpeak!=peak.end() && itsat!=sat.end(); ++itpeak, ++itsat ) {
537 result.push_back( (*itpeak<<2) + (*itsat<<1) );
546 std::vector<int> decisionRange;
547 if (!(decisionSource&0
x1))
etRange(digits, energyLow, energyHigh, decisionRange);
548 else etRange(lutInput, energyLow, energyHigh, decisionRange);
559 const std::vector<short int>* getFirCoefficients(
unsigned int coolId, std::any& C) {
560 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
561 if(!settings)
return nullptr;
562 return &(settings->firCoefficients());
572 std::vector<int> firCoeffs;
574 const std::vector<short int>* hwCoeffs;
583 firCoeffs.reserve(hwCoeffs->size());
584 for (
int i = hwCoeffs->size()-1;
i >= 0; --
i) firCoeffs.push_back((*hwCoeffs)[
i]);
605 output.reserve(digits.size());
610 for (
unsigned int i = 0;
i < firCoeffs.size(); ++
i) {
611 if (firstFIR < 0 && firCoeffs[
i] != 0) firstFIR =
i;
612 if (firCoeffs[
i] != 0) lastFIR =
i;
614 if (firstFIR < 0) firstFIR = lastFIR + 1;
616 for (
int i = 0;
i < (
int)digits.size();
i++) {
619 if (
i >= 2-firstFIR &&
i < (
int)digits.size()+2-lastFIR) {
620 for (
int j = firstFIR; j <= lastFIR; ++j) {
621 sum += digits[
i+j-2]*firCoeffs[j];
636 unsigned int getStrategy(std::any& C) {
637 return std::any_cast<T*>(C)->peakFinderCond();
650 }
else ATH_MSG_WARNING(
"::peakBcid: No Conditions Container retrieved" );
663 for (
unsigned int i = 0;
i <
fir.size();
i++) {
666 if (
i > 0 &&
i <
fir.size()-1) {
685 std::tuple<bool, int, int, int> getSaturation(
unsigned int coolId, std::any& C) {
686 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
687 if(!settings)
return std::make_tuple(
false, 0, 0, 0);
688 return std::make_tuple(
true, settings->satBcidLevel(), settings->satBcidThreshLow(),
689 settings->satBcidThreshHigh());
700 bool available =
false;
705 if(!available)
ATH_MSG_WARNING(
"::satBcid: No L1CaloPprConditions found" );
706 }
else ATH_MSG_WARNING(
"::satBcid: No Conditions Container retrieved" );
709 <<
" satLow: " << satLow
710 <<
" satHigh: " << satHigh );
720 output.reserve(digits.size());
725 for (
unsigned int i = 0;
i<digits.size();
i++) {
731 if (digits[
i]>=satLevel) {
732 if (enabled &&
i>1) {
733 bool low = (digits[
i-2]>satLow);
734 bool high = (digits[
i-1]>satHigh);
764 unsigned int getDecisionSource(std::any& C) {
765 return std::any_cast<T*>(C)->decisionSource();
771 int decisionSource = 0;
776 }
else ATH_MSG_WARNING(
"::bcidDecisionRange: No Conditions Container retrieved" );
781 ATH_MSG_VERBOSE(
"::bcidDecisionRange: decisionSource: " << decisionSource);
791 std::tuple<unsigned int, unsigned int, unsigned int> getBcidDecision(std::any& C) {
792 auto CC = std::any_cast<T*>(C);
793 return std::make_tuple(
CC->bcidDecision1(),
CC->bcidDecision2(),
CC->bcidDecision3());
798 unsigned int decision1 = 0;
799 unsigned int decision2 = 0;
800 unsigned int decision3 = 0;
803 std::tie(decision1, decision2, decision3) = getBcidDecision<L1CaloPprConditionsContainerRun2>(
m_conditionsContainer);
805 std::tie(decision1, decision2, decision3) = getBcidDecision<L1CaloPprConditionsContainer>(
m_conditionsContainer);
806 }
else ATH_MSG_WARNING(
"::bcidDecision: No Conditions Container retrieved" );
809 std::vector<unsigned int>
mask = { decision3, decision2, decision1 };
812 << decision3 <<
" " << decision2 <<
" " << decision1 << MSG::dec );
822 output.reserve(bcidResults.size());
824 std::vector<int>::const_iterator itBcid = bcidResults.begin();
825 std::vector<int>::const_iterator itRange =
range.begin();
826 int nRange =
mask.size();
828 for ( ; itBcid != bcidResults.end() && itRange !=
range.end(); ++itBcid, ++itRange) {
829 if ((*itRange) < nRange && (
mask[*itRange]&(0
x1<<*itBcid)))
output.push_back(1);
868 unsigned int noiseCut = 0;
870 if (noiseCut > 0)
cut = noiseCut;
881 double offsetReal = 0;
884 unsigned short scale = 0;
888 const std::vector<short int>* hwCoeffs;
909 for (
unsigned int i = 0;
i < hwCoeffs->size();
i++){
910 hwCoeffSum += hwCoeffs->at(
i);
914 offsetReal = pedMean * hwCoeffSum /
pow(2.,startBit);
917 offsetReal = pedMean * hwCoeffSum * slope /
pow(2.,startBit) - slope/2.;
919 offset =
static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
921 ATH_MSG_VERBOSE(
"::cpLut: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
922 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
925 }
else ATH_MSG_WARNING(
"::cpLut: No Conditions Container retrieved" );
930 unsigned int noiseCut = 0;
932 if (noiseCut > 0)
cut = noiseCut;
946 double offsetReal = 0;
949 unsigned short scale_db = 0;
950 unsigned short scale_menu = 0;
954 const std::vector<short int>* hwCoeffs;
978 scale_menu = l1Menu->thrExtraInfo().JET().jetScale();
988 for (
unsigned int i = 0;
i < hwCoeffs->size();
i++){
989 hwCoeffSum += hwCoeffs->at(
i);
993 offsetReal = pedMean * hwCoeffSum /
pow(2.,startBit);
996 offsetReal = pedMean * hwCoeffSum * slope /
pow(2.,startBit) - slope/2.;
998 offset =
static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
1000 ATH_MSG_VERBOSE(
"::jepLut: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1001 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
1004 }
else ATH_MSG_WARNING(
"::jepLut: No Conditions Container retrieved" );
1009 unsigned int noiseCut = 0;
1011 if (noiseCut > 0)
cut = noiseCut;
1014 nonLinearLut(
fir, slope,
offset,
cut, scale_db, par1, par2, par3, par4,
disabled,
output);
1031 std::vector<int>::const_iterator
it =
fir.begin();
1032 for ( ;
it !=
fir.end(); ++
it) {
1036 out = (((*it)-
offset)*slope + 2048)>>12;
1038 out = ((*it)*slope -
offset + 2048)>>12;
1052 void 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)
1057 std::vector<int>::const_iterator
it =
fir.begin();
1058 for ( ;
it !=
fir.end(); ++
it) {
1062 double nll_slope = 0.001 *
scale;
1063 double nll_offset = 0.001 * par1;
1064 double nll_ampl = 0.001 * par2;
1065 double nll_expo = 0.;
1067 nll_expo = -1. / (4096 * 0.001*par3);
1071 double nll_noise = 0.001 * par4;
1098 std::vector<int>::const_iterator itlut =
lut.begin();
1099 std::vector<int>::const_iterator itrange =
range.begin();
1100 while ( itlut !=
lut.end() && itrange !=
range.end() ) {
1102 else output.push_back(*itlut);
1116 std::tuple<bool, int, int> getBcidEnergyRange(
unsigned int coolId, std::any& C) {
1117 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
1118 if(!settings)
return std::make_tuple(
false, 0, 0);
1119 return std::make_tuple(
true, settings->bcidEnergyRangeLow(), settings->bcidEnergyRangeHigh());
1128 bool available =
false;
1134 if(!available)
ATH_MSG_WARNING(
"::etRange: No L1CaloPprConditions found");
1135 }
else ATH_MSG_WARNING(
"::etRange: No Conditions Container retrieved");
1138 <<
" energyHigh: " << energyHigh);
1149 for (std::vector<int>::const_iterator
it =
et.begin();
it !=
et.end(); ++
it) {
1150 if ((*
it) <= energyLow)
output.push_back(0);
1151 else if ((*
it) <= energyHigh)
output.push_back(1);
1152 else output.push_back(2);
1164 std::tuple<bool, int> getFirStartBit(
unsigned int coolId, std::any& C) {
1165 auto settings = std::any_cast<T*>(C)->pprConditions(coolId);
1166 if(!settings)
return std::make_tuple(
false, 0);
1167 return std::make_tuple(
true, settings->firStartBit());
1173 unsigned int start = 0;
1175 bool available =
false;
1180 if(!available)
ATH_MSG_WARNING(
"::dropBits: No L1CaloPprConditions found" );
1181 }
else ATH_MSG_WARNING(
"::dropBits: No Conditions Container retrieved" );
1201 for (std::vector<int>::const_iterator
it =
fir.begin();
it !=
fir.end(); ++
it) {
1218 const std::vector<short int>* hwCoeffs =
nullptr;
1228 firCoeffs.reserve(hwCoeffs->size());
1229 for (
int i = hwCoeffs->size()-1;
i >= 0; --
i) firCoeffs.push_back((*hwCoeffs)[
i]);
1231 }
else ATH_MSG_WARNING(
"::firParams: No L1CaloPprConditions found" );
1232 }
else ATH_MSG_WARNING(
"::firParams: No Conditions Container retrieved" );
1243 unsigned int &peakFinderStrategy,
int &satLow,
int &satHigh,
int &satLevel)
1248 decisionConditions.clear();
1249 peakFinderStrategy = 0;
1256 std::tuple<unsigned int, unsigned int, unsigned int>
bcidDecision;
1257 std::tuple<bool, int, int> bcidEnergyRange;
1258 std::tuple<bool, int, int, int> saturation;
1278 if(get<0>(bcidEnergyRange)) {
1279 std::tie(
std::ignore, energyLow, energyHigh) = bcidEnergyRange;
1282 if(get<0>(saturation)) {
1283 std::tie(
std::ignore, satLevel, satLow, satHigh) = saturation;
1285 }
else ATH_MSG_WARNING(
"::bcid:Params No Conditions Container retrieved" );
1288 <<
" satLow: " << satLow <<
" satHigh: " << satHigh <<
endmsg
1289 <<
" energyLow: " << energyLow <<
" energyHigh: " << energyHigh <<
endmsg
1290 <<
" decisionSource: " << decisionSource <<
" peakFinderStrategy: "
1291 << peakFinderStrategy );
1323 pedMean = settings->
pedMean();
1324 }
else ATH_MSG_WARNING(
"::lutParams: No L1CaloPprConditions found" );
1325 }
else ATH_MSG_WARNING(
"::lutParams: No Conditions Container retrieved" );
1327 ATH_MSG_VERBOSE(
"::lutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1328 << startBit <<
" " <<
strategy <<
" " <<
offset <<
" " << slope <<
" " <<
cut <<
" " << pedValue <<
" " << pedMean );
1329 unsigned int noiseCut = 0;
1331 if (noiseCut > 0)
cut = noiseCut;
1339 double offsetReal = 0;
1346 const std::vector<short int>* hwCoeffs;
1363 pedMean = settings->
pedMean();
1366 for (
unsigned int i = 0;
i < hwCoeffs->size();
i++){
1367 hwCoeffSum += hwCoeffs->at(
i);
1371 offsetReal = pedMean * hwCoeffSum /
pow(2.,startBit);
1374 offsetReal = pedMean * hwCoeffSum * slope /
pow(2.,startBit) - slope/2.;
1376 offset =
static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
1378 ATH_MSG_VERBOSE(
"::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1379 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
1381 }
else ATH_MSG_WARNING(
"::cpLutParams: No L1CaloPprConditions found" );
1382 }
else ATH_MSG_WARNING(
"::cpLutParams: No Conditions Container retrieved" );
1384 ATH_MSG_VERBOSE(
"::cpLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1385 << startBit <<
" " <<
strategy <<
" " <<
offset <<
" " << slope <<
" " <<
cut <<
" " << pedValue <<
" " << pedMean );
1386 unsigned int noiseCut = 0;
1388 if (noiseCut > 0)
cut = noiseCut;
1396 double offsetReal = 0;
1403 const std::vector<short int>* hwCoeffs;
1420 pedMean = settings->
pedMean();
1424 for (
unsigned int i = 0;
i < hwCoeffs->size();
i++){
1425 hwCoeffSum += hwCoeffs->at(
i);
1429 offsetReal = pedMean * hwCoeffSum /
pow(2.,startBit);
1432 offsetReal = pedMean * hwCoeffSum * slope /
pow(2.,startBit) - slope/2.;
1434 offset =
static_cast<unsigned short>( offsetReal < 0. ? 0 : offsetReal + 0.5 );
1436 ATH_MSG_VERBOSE(
"::jepLutParams: Offset: offset/strategy/pedMean/firCoeffSum/startBit/slope: "
1437 <<
offset <<
" " <<
strategy <<
" " <<
" " << pedMean <<
" " << hwCoeffSum <<
" " << startBit <<
" " << slope );
1439 }
else ATH_MSG_WARNING(
"::jepLutParams: No L1CaloPprConditions found" );
1440 }
else ATH_MSG_WARNING(
"::jepLutParams: No Conditions Container retrieved" );
1442 ATH_MSG_VERBOSE(
"::jepLutParams: LUT startBit/strategy/offset/slope/cut/pedValue/pedMean: "
1443 << startBit <<
" " <<
strategy <<
" " <<
offset <<
" " << slope <<
" " <<
cut <<
" " << pedValue <<
" " << pedMean );
1444 unsigned int noiseCut = 0;
1446 if (noiseCut > 0)
cut = noiseCut;
1471 try { hwId =
m_ttSvc->createTTChannelID(
id,
false); }
1496 }
else if (
absEta < 3.2) {
1528 coolId =
m_ttSvc->createL1CoolChannelId(hwId);
1538 std::tuple<bool, bool, bool> getSatOverride(std::any& C) {
1539 auto CC = std::any_cast<T*>(C);
1540 return std::make_tuple(
CC->satOverride1(),
CC->satOverride2(),
CC->satOverride3());
1546 bool override =
false;
1557 }
else ATH_MSG_WARNING(
"::satOverride: No Conditions Container retrieved" );
1560 <<
" has saturation override flag " <<
override );
1569 unsigned int noiseCut = 0;
1576 bool isDisabled =
false;
1591 }
else isDisabled =
true;
1594 <<
"::disabledChannel: calibErrorCode: " << (disabledChan->
calibErrorCode()).errorCode()
1595 <<
" deadErrorCode: " << (disabledChan->
deadErrorCode()).errorCode()
1596 <<
" noiseCut: " << disabledChan->
noiseCut()
1601 ATH_MSG_VERBOSE(
"::disabledChannel: No L1CaloPprDisabledChannel found" );
1604 ATH_MSG_WARNING(
"::disabledChannel: No DisabledChannel Container retrieved" );
1624 float abseta = fabs(
eta);
1625 if (abseta<3.2)
return eta;
1627 int sign = ((
eta > 0) ? 1 : -1);
1628 if (abseta < 3.6)
eta = 3.15 *
sign;
1629 else if (abseta < 4.0)
eta = 3.33 *
sign;
1630 else if (abseta < 4.5)
eta = 3.72 *
sign;
1634 if (abseta < 3.6)
eta = 3.36;
1635 else if (abseta < 4.0)
eta = 3.45;
1636 else if (abseta < 4.5)
eta = 4.17;
1640 if (abseta < 3.6)
eta = -3.45;
1641 else if (abseta < 4.0)
eta = -3.36;
1642 else if (abseta < 4.5)
eta = -4.19;
1655 throw GaudiException(
"No mapping tool configured",
1656 "L1TriggerTowerTool::FCalTTeta", StatusCode::FAILURE);
1662 unsigned int mcm =
channelId.subModule();
1679 template <
typename T>
1706 if (
sc.isFailure()) {
1714 ATH_MSG_WARNING(
"Could not retrieve FineTimeReferences, as Conditon Service not present" );
1715 return StatusCode::FAILURE;
1718 return StatusCode::SUCCESS;
1738 <<
"::refValues: errorCode: " << (ftref->
errorCode()).errorCode()
1739 << MSG::dec <<
" reference: " << ftref->
refValue() <<
" calib: " << ftref->
calibValue() );
1752 unsigned nFIR = firInOut.size();
1753 correctionOut.assign(nFIR, 0
u);
1758 for(
unsigned i = 0;
i != nFIR; ++
i) {
1760 firInOut[
i] -= correctionOut[
i];
1762 if(firInOut[
i] < 0) firInOut[
i] = 0;
1774 const EventContext& ctx = Gaudi::Hive::currentContext();
1775 if (ctx.eventID().run_number() >= 253377)
return true;