24 std::vector<size_t> bitsetIndices(
const std::bitset<N>& bits) {
27 for (
size_t i=0;
i<bits.size(); ++
i) {
109 return StatusCode::SUCCESS;
117 ATH_CHECK(errorFlagsCont.
record(std::make_unique<xAOD::TrigCompositeContainer>(),
118 std::make_unique<xAOD::TrigCompositeAuxContainer>()));
129 std::vector<uint8_t> failedMonFunctions;
130 std::vector<std::vector<unsigned>> multWeightsSim;
131 std::vector<std::vector<unsigned>> multWeightsHdw;
136 ATH_MSG_DEBUG(
"Executed doHWMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
137 if (
sc.isFailure()) {
138 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMon));
144 ATH_MSG_DEBUG(
"Executed doHWMonCTP: " << (
sc.isFailure() ?
"failed" :
"ok"));
145 if (
sc.isFailure()) {
146 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMonCTP));
152 ATH_MSG_DEBUG(
"Executed doSimMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
153 if (
sc.isFailure()) {
154 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doSimMon));
160 ATH_MSG_DEBUG(
"Executed doComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
161 if (
sc.isFailure()) {
162 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doComp));
168 ATH_MSG_DEBUG(
"Executed doMultComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
169 if (
sc.isFailure()) {
170 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doMultComp));
177 return StatusCode::SUCCESS;
186 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
187 return StatusCode::FAILURE;
195 std::unordered_map<unsigned,std::bitset<s_nTopoCTPOutputs>> multWeightsMap;
196 for(
const auto l1topo_dec : * cont){
197 ATH_MSG_DEBUG(
"Reading L1Topo EDM:: Connection ID: " << l1topo_dec->connectionId() <<
" Clock: " << l1topo_dec->clock() <<
" Bit-length: " << l1topo_dec->bitWidth() <<
" Word: " << l1topo_dec->topoWord() <<
" Word64: " << l1topo_dec->topoWord64() );
199 if (l1topo_dec->bitWidth() == 32) {
200 std::vector<unsigned> topoword;
201 std::vector<unsigned> topowordOverflow;
202 for(
unsigned int i=0;
i<32; ++
i) {
204 if ((l1topo_dec->topoWord() &
mask) !=0) {
205 if (l1topo_dec->connectionId()==2 || l1topo_dec->connectionId()==3) {
206 topoword.push_back(32*l1topo_dec->clock()+
i);
207 uint32_t pos = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==2 ? 0 : 2))+
i;
210 if (l1topo_dec->connectionId()==22 || l1topo_dec->connectionId()==23) {
211 uint32_t pos_ambiguity = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==22 ? 0 : 2))+
i;
215 if ((l1topo_dec->topoWordOverflow() &
mask) !=0) {
216 topowordOverflow.push_back(32*l1topo_dec->clock()+
i);
217 uint32_t pus = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==12 ? 0 : 2))+
i;
221 std::string
name =
"CableElec_";
226 else if (l1topo_dec->bitWidth() == 64) {
227 for (
size_t i=0;
i<64;
i++) {
228 unsigned index =
i+l1topo_dec->clock()*64;
230 if ((l1topo_dec->topoWord64() &
mask) !=0) {
231 multWeightsMap[
static_cast<unsigned>(l1topo_dec->connectionId() - 4)].
set(
index);
236 ATH_MSG_DEBUG(
"Unknown Bit-length: " << l1topo_dec->bitWidth() );
237 return StatusCode::FAILURE;
242 std::vector<unsigned> vecCount, vecIndices;
246 for (
size_t i=0;
i<startbit.second;
i++){
247 if (multWeightsMap[
key][startbit.first+
i]) {
251 vecCount.push_back(
count);
255 multWeights.push_back(vecCount);
262 std::vector<size_t> triggerBitIndicesSim = bitsetIndices(triggerBitsSim);
263 std::vector<size_t> overflowBitIndicesSim = bitsetIndices(overflowBitsSim);
264 std::vector<size_t> ambiguityBitIndicesSim = bitsetIndices(ambiguityBitsSim);
272 return StatusCode::SUCCESS;
279 if (!ctpRdo.isValid()) {
280 ATH_MSG_DEBUG(
"Failed to retrieve CTP_RDO object (converted from CTP DAQ ROB) with key \""
282 return StatusCode::FAILURE;
287 ctp.setRDO(ctpRdo.cptr());
288 const uint32_t l1aPos = ctpRdo->getL1AcceptBunchPosition();
289 if (l1aPos >=
ctp.getBunchCrossings().size()) {
290 ATH_MSG_DEBUG(
"CTP_RDO gave invalid l1aPos. Skipping CTP hardware comparison");
291 return StatusCode::FAILURE;
293 ATH_MSG_DEBUG(
"CTP l1aPos, size: " << l1aPos <<
", " <<
ctp.getBunchCrossings().size());
294 const CTP_BC& ctpL1a =
ctp.getBunchCrossings().at(l1aPos);
298 static constexpr
size_t ctpTBPSize{512};
299 const std::bitset<ctpTBPSize>& tbp = ctpL1a.
getTBP();
306 {triggerBitsCtp[
i] =
false;}
309 std::vector<size_t> triggerBitIndicesCtp = bitsetIndices(triggerBitsCtp);
313 return StatusCode::SUCCESS;
320 ATH_MSG_WARNING(
"Could not retrieve L1Topo RAW Data Container from the BS data.");
321 return StatusCode::FAILURE;
329 std::unique_ptr<L1Topo::L1TopoResult> l1topoResult = std::make_unique<L1Topo::L1TopoResult>(*cont);
332 return StatusCode::FAILURE;
337 enum class MonFunction :
uint8_t {doRODct, doRODpc, doRODhc, doRODpe, doRODlm, doRODhm, doRODpt};
338 std::vector<uint8_t> rodErrors;
339 if (l1topoResult->
getROD(0)->ct() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODct)); }
340 if (l1topoResult->
getROD(0)->pc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpc)); }
341 if (l1topoResult->
getROD(0)->hc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhc)); }
342 if (l1topoResult->
getROD(0)->pe() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpe)); }
343 if (l1topoResult->
getROD(0)->lm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODlm)); }
344 if (l1topoResult->
getROD(0)->hm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhm)); }
345 if (l1topoResult->
getROD(0)->pt() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpt)); }
351 unsigned topoNumber = l1topoResult->
getFPGA(
i)->topoNumber();
352 unsigned fpgaNumber = l1topoResult->
getFPGA(
i)->fpgaNumber();
355 auto mon_fpga_labels =
Monitored::Scalar(
"FPGA_Labels", (topoNumber*2)-fpgaNumber-1);
357 if (l1topoResult->
getFPGA(
i)->ct() != 0) {
361 if (l1topoResult->
getFPGA(
i)->sm() != 0) {
365 if (l1topoResult->
getFPGA(
i)->pe() != 0) {
369 if (l1topoResult->
getFPGA(
i)->lm() != 0) {
373 if (l1topoResult->
getFPGA(
i)->hm() != 0) {
377 if (l1topoResult->
getFPGA(
i)->pt() != 0) {
384 std::vector<unsigned> topo1Opt0,topo1Opt1,topo1Opt2,topo1Opt3;
385 std::vector<unsigned> topo1Opt0Indices,topo1Opt1Indices,topo1Opt2Indices,topo1Opt3Indices;
390 for (
size_t i=0;
i<startbit.second;
i++){
395 topo1Opt0.push_back(
count);
396 topo1Opt0Indices.push_back(
indices);
402 for (
size_t i=0;
i<startbit.second;
i++){
407 topo1Opt1.push_back(
count);
408 topo1Opt1Indices.push_back(
indices);
414 for (
size_t i=0;
i<startbit.second;
i++){
419 topo1Opt2.push_back(
count);
420 topo1Opt2Indices.push_back(
indices);
426 for (
size_t i=0;
i<startbit.second;
i++){
431 topo1Opt3.push_back(
count);
432 topo1Opt3Indices.push_back(
indices);
439 multWeights.push_back(topo1Opt0);
444 multWeights.push_back(topo1Opt1);
449 multWeights.push_back(topo1Opt2);
454 multWeights.push_back(topo1Opt3);
460 const std::vector<size_t> triggerBitIndicesHdw = bitsetIndices(triggerBits);
461 const std::vector<size_t> overflowBitIndicesHdw = bitsetIndices(overflowBits);
471 return StatusCode::SUCCESS;
476 ATH_MSG_DEBUG(
"Simulation bits not set. Skipping simulation to hardware comparison");
477 return StatusCode::FAILURE;
480 std::bitset<s_nTopoCTPOutputs> triggerBitsSim = decisionBits.
triggerBitsSim.value();
481 std::bitset<s_nTopoCTPOutputs> triggerBitsHdw;
484 {triggerBitsHdw = decisionBits.
triggerBits.value();}
488 ATH_MSG_DEBUG(
"Hardware bits not set. Skipping simulation to hardware comparison");
489 return StatusCode::FAILURE;
492 std::bitset<s_nTopoCTPOutputs> triggerBitsSimNotHdw = triggerBitsSim & (~triggerBitsHdw);
493 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwNotSim = triggerBitsHdw & (~triggerBitsSim);
494 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwSim = triggerBitsHdw & triggerBitsSim;
495 std::bitset<s_nTopoCTPOutputs> triggerBitsAny = triggerBitsHdw | triggerBitsSim;
497 std::bitset<s_nTopoCTPOutputs>& overflowBitsSim = decisionBits.
overflowBitsSim.value();
498 std::bitset<s_nTopoCTPOutputs>& overflowBitsHdw = decisionBits.
overflowBits.value();
499 std::bitset<s_nTopoCTPOutputs> overflowBitsSimNotHdw = overflowBitsSim & (~overflowBitsHdw);
500 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwNotSim = overflowBitsHdw & (~overflowBitsSim);
501 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwSim = overflowBitsHdw & overflowBitsSim;
502 std::bitset<s_nTopoCTPOutputs> overflowBitsAny = overflowBitsHdw | overflowBitsSim;
504 std::bitset<s_nTopoCTPOutputs>& ambiguityBitsSim = decisionBits.
ambiguityBitsSim.value();
505 std::bitset<s_nTopoCTPOutputs> ambiguitySimANDHdw = ambiguityBitsSim & triggerBitsHdwSim;
506 std::bitset<s_nTopoCTPOutputs> ambiguityMismatch = ambiguityBitsSim & (triggerBitsSimNotHdw | triggerBitsHdwNotSim);
508 std::vector<size_t> triggerBitIndicesSimNotHdw = bitsetIndices(triggerBitsSimNotHdw);
509 std::vector<size_t> triggerBitIndicesHdwNotSim = bitsetIndices(triggerBitsHdwNotSim);
510 std::vector<size_t> ambiguitySimANDHdwBitIndices = bitsetIndices(ambiguitySimANDHdw);
511 std::vector<size_t> ambiguityMismatchBitIndices = bitsetIndices(ambiguityMismatch);
514 auto monAmbiguitySimANDHdw =
Monitored::Collection(
"Ambiguity_SimANDHdwDecisions", ambiguitySimANDHdwBitIndices);
515 auto monAmbiguityMismatch =
Monitored::Collection(
"Ambiguity_DecisionMismatches", ambiguityMismatchBitIndices);
520 float rate_overflow=0;
521 for (
size_t i=0;
i<4;
i++) {
526 for (
size_t j=0;j<32;j++) {
527 if (ambiguityBitsSim[32*
i+j] == 0) {
528 mon_trig =
static_cast<unsigned>(j);
529 if (overflowBitsHdw[32*
i+j] == 1 || overflowBitsSim[32*
i+j] == 1) {
604 return StatusCode::SUCCESS;
608 if (multWeightsSim.size() == 0 or multWeightsHdw.size() == 0) {
609 ATH_MSG_DEBUG(
"Multiplicities not set, skipping multiplicities comparison");
610 return StatusCode::FAILURE;
613 for (
size_t i=0;
i<multWeightsSim.size();
i++) {
616 for (
size_t k=0;
k<multWeightsSim[
i].size();
k++) {
621 if (monMultSim < monMultHdw) mon_match = 0;
622 if (monMultSim > monMultHdw) mon_match = 1;
623 if (monMultSim == monMultHdw) mon_match = 2;
624 mon_multiplicity =
static_cast<unsigned>(
k);
628 return StatusCode::SUCCESS;
633 std::vector<std::vector<std::pair<unsigned,unsigned>>> startbit_vec;
634 std::vector<std::string> connNames =
l1menu.connectorNames();
635 for(
const std::string connName : {
"Topo1Opt0",
"Topo1Opt1",
"Topo1Opt2",
"Topo1Opt3"}) {
636 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
639 std::vector<std::pair<unsigned,unsigned>> startbit;
640 for(
auto &
t1 :
l1menu.connector(connName).triggerLines()) {
641 startbit.push_back(std::make_pair(
t1.startbit(),
t1.nbits()));
643 startbit_vec.push_back(startbit);
652 std::vector<std::string> connNames =
l1menu.connectorNames();
654 for(
const std::string connName : {
"Topo2El",
"Topo3El"}) {
655 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
658 for(
uint fpga : {0,1}) {
659 for(
uint clock : {0,1}) {
660 for(
auto &
tl :
l1menu.connector(connName).triggerLines(fpga,clock)) {
661 uint flatIndex =
tl.flatindex() + 64 * (connName ==
"Topo3El");
662 labelsTopoEl[flatIndex] =
tl.name();
668 ATH_MSG_DEBUG(
"Obtaining CTPIds for Phase1 L1Topo Monitoring");
671 std::string definition =
item.definition();
672 if (definition.substr(0,5) ==
"TOPO_" &&
673 definition.find(
' ') == std::string::npos) {
674 std::string trigger = definition.substr(0, definition.find(
'['));
675 auto pos =
std::find(labelsTopoEl.begin(),labelsTopoEl.end(),trigger);
676 if (
pos != labelsTopoEl.end()) {
677 ATH_MSG_DEBUG(
"Found one CTP; ,CTPId: " <<
item.ctpId() <<
" ,Name: " <<
item.name() <<
" ,Definition: " << definition);
688 errorFlags.
setDetail(
"hasTrivialFlag",
true);