25 std::vector<size_t> bitsetIndices(
const std::bitset<N>& bits) {
28 for (
size_t i=0;
i<bits.size(); ++
i) {
107 auto & conn2EL =
l1menu->connector(
"Topo2El");
108 auto & conn3EL =
l1menu->connector(
"Topo3El");
110 auto & connOpt0 =
l1menu->connector(
"Topo1Opt0");
111 auto & connOpt1 =
l1menu->connector(
"Topo1Opt1");
112 auto & connOpt2 =
l1menu->connector(
"Topo1Opt2");
113 auto & connOpt3 =
l1menu->connector(
"Topo1Opt3");
121 auto & tlopt0 = connOpt0.triggerLines();
122 auto & tlopt1 = connOpt1.triggerLines();
123 auto & tlopt2 = connOpt2.triggerLines();
124 auto & tlopt3 = connOpt3.triggerLines();
126 long unsigned int size_tlopt0 = tlopt0.size();
127 long unsigned int size_tlopt1 = tlopt1.size();
128 long unsigned int size_tlopt2 = tlopt2.size();
129 long unsigned int size_tlopt3 = tlopt3.size();
131 long unsigned int total_size_opt = size_tlopt0+size_tlopt1+size_tlopt2+size_tlopt3;
139 auto & tl2a0 = conn2EL.triggerLines(0, 0);
140 auto & tl2a1 = conn2EL.triggerLines(0, 1);
141 long unsigned int size_tl2a0 = tl2a0.size();
142 long unsigned int size_tl2a1 = tl2a1.size();
144 auto & tl2b0 = conn2EL.triggerLines(1, 0);
145 auto & tl2b1 = conn2EL.triggerLines(1, 1);
146 long unsigned int size_tl2b0 = tl2b0.size();
147 long unsigned int size_tl2b1 = tl2b1.size();
149 auto & tl3a0 = conn3EL.triggerLines(0, 0);
150 auto & tl3a1 = conn3EL.triggerLines(0, 1);
151 long unsigned int size_tl3a0 = tl3a0.size();
152 long unsigned int size_tl3a1 = tl3a1.size();
154 auto & tl3b0 = conn3EL.triggerLines(1, 0);
155 auto & tl3b1 = conn3EL.triggerLines(1, 1);
156 long unsigned int size_tl3b0 = tl3b0.size();
157 long unsigned int size_tl3b1 = tl3b1.size();
159 for (
size_t i = 0;
i < 16; ++
i) {
166 for (
size_t i = 0;
i < 16; ++
i) {
173 for (
size_t i = 0;
i < 16; ++
i) {
180 for (
size_t i = 0;
i < 16; ++
i) {
190 for (
size_t j = 0; j < total_size_opt; ++j) {
198 for (
int j =0; j<128;j++){
218 return StatusCode::SUCCESS;
226 ATH_CHECK(errorFlagsCont.
record(std::make_unique<xAOD::TrigCompositeContainer>(),
227 std::make_unique<xAOD::TrigCompositeAuxContainer>()));
238 std::vector<uint8_t> failedMonFunctions;
239 std::vector<std::vector<unsigned>> multWeightsSim;
240 std::vector<std::vector<unsigned>> multWeightsHdw;
244 ATH_MSG_DEBUG(
"Executed doHWMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
245 if (
sc.isFailure()) {
246 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMon));
252 ATH_MSG_DEBUG(
"Executed doHWMonCTP: " << (
sc.isFailure() ?
"failed" :
"ok"));
253 if (
sc.isFailure()) {
254 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMonCTP));
260 ATH_MSG_DEBUG(
"Executed doSimMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
261 if (
sc.isFailure()) {
262 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doSimMon));
268 ATH_MSG_DEBUG(
"Executed doComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
269 if (
sc.isFailure()) {
270 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doComp));
276 ATH_MSG_DEBUG(
"Executed doMultComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
277 if (
sc.isFailure()) {
278 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doMultComp));
285 return StatusCode::SUCCESS;
294 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
295 return StatusCode::FAILURE;
303 std::unordered_map<unsigned,std::bitset<s_nTopoCTPOutputs>> multWeightsMap;
304 for(
const auto l1topo_dec : * cont){
305 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() );
307 if (l1topo_dec->bitWidth() == 32) {
308 std::vector<unsigned> topoword;
309 std::vector<unsigned> topowordOverflow;
310 for(
unsigned int i=0;
i<32; ++
i) {
312 if ((l1topo_dec->topoWord() &
mask) !=0) {
313 if (l1topo_dec->connectionId()==2 || l1topo_dec->connectionId()==3) {
314 topoword.push_back(32*l1topo_dec->clock()+
i);
315 uint32_t pos = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==2 ? 0 : 2))+
i;
318 if (l1topo_dec->connectionId()==22 || l1topo_dec->connectionId()==23) {
319 uint32_t pos_ambiguity = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==22 ? 0 : 2))+
i;
323 if ((l1topo_dec->topoWordOverflow() &
mask) !=0) {
324 topowordOverflow.push_back(32*l1topo_dec->clock()+
i);
325 uint32_t pus = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==12 ? 0 : 2))+
i;
329 std::string
name =
"CableElec_";
334 else if (l1topo_dec->bitWidth() == 64) {
335 for (
size_t i=0;
i<64;
i++) {
336 unsigned index =
i+l1topo_dec->clock()*64;
338 if ((l1topo_dec->topoWord64() &
mask) !=0) {
339 multWeightsMap[
static_cast<unsigned>(l1topo_dec->connectionId() - 4)].
set(
index);
344 ATH_MSG_DEBUG(
"Unknown Bit-length: " << l1topo_dec->bitWidth() );
345 return StatusCode::FAILURE;
350 std::vector<unsigned> vecCount, vecIndices;
354 for (
size_t i=0;
i<startbit.second;
i++){
355 if (multWeightsMap[
key][startbit.first+
i]) {
359 vecCount.push_back(
count);
363 multWeights.push_back(vecCount);
370 std::vector<size_t> triggerBitIndicesSim = bitsetIndices(triggerBitsSim);
371 std::vector<size_t> overflowBitIndicesSim = bitsetIndices(overflowBitsSim);
372 std::vector<size_t> ambiguityBitIndicesSim = bitsetIndices(ambiguityBitsSim);
380 return StatusCode::SUCCESS;
387 if (!ctpRdo.isValid()) {
388 ATH_MSG_DEBUG(
"Failed to retrieve CTP_RDO object (converted from CTP DAQ ROB) with key \""
390 return StatusCode::FAILURE;
395 ctp.setRDO(ctpRdo.cptr());
396 const uint32_t l1aPos = ctpRdo->getL1AcceptBunchPosition();
397 if (l1aPos >=
ctp.getBunchCrossings().size()) {
398 ATH_MSG_DEBUG(
"CTP_RDO gave invalid l1aPos. Skipping CTP hardware comparison");
399 return StatusCode::FAILURE;
401 ATH_MSG_DEBUG(
"CTP l1aPos, size: " << l1aPos <<
", " <<
ctp.getBunchCrossings().size());
402 const CTP_BC& ctpL1a =
ctp.getBunchCrossings().at(l1aPos);
406 static constexpr
size_t ctpTBPSize{512};
407 const std::bitset<ctpTBPSize>& tbp = ctpL1a.
getTBP();
414 {triggerBitsCtp[
i] =
false;}
417 std::vector<size_t> triggerBitIndicesCtp = bitsetIndices(triggerBitsCtp);
421 return StatusCode::SUCCESS;
428 ATH_MSG_WARNING(
"Could not retrieve L1Topo RAW Data Container from the BS data.");
429 return StatusCode::FAILURE;
437 std::unique_ptr<L1Topo::L1TopoResult> l1topoResult = std::make_unique<L1Topo::L1TopoResult>(*cont);
440 return StatusCode::FAILURE;
445 enum class MonFunction :
uint8_t {doRODct, doRODpc, doRODhc, doRODpe, doRODlm, doRODhm, doRODpt};
446 std::vector<uint8_t> rodErrors;
447 if (l1topoResult->
getROD(0)->ct() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODct)); }
448 if (l1topoResult->
getROD(0)->pc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpc)); }
449 if (l1topoResult->
getROD(0)->hc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhc)); }
450 if (l1topoResult->
getROD(0)->pe() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpe)); }
451 if (l1topoResult->
getROD(0)->lm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODlm)); }
452 if (l1topoResult->
getROD(0)->hm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhm)); }
453 if (l1topoResult->
getROD(0)->pt() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpt)); }
459 unsigned topoNumber = l1topoResult->
getFPGA(
i)->topoNumber();
460 unsigned fpgaNumber = l1topoResult->
getFPGA(
i)->fpgaNumber();
463 auto mon_fpga_labels =
Monitored::Scalar(
"FPGA_Labels", (topoNumber*2)-fpgaNumber-1);
465 if (l1topoResult->
getFPGA(
i)->ct() != 0) {
469 if (l1topoResult->
getFPGA(
i)->sm() != 0) {
473 if (l1topoResult->
getFPGA(
i)->pe() != 0) {
477 if (l1topoResult->
getFPGA(
i)->lm() != 0) {
481 if (l1topoResult->
getFPGA(
i)->hm() != 0) {
485 if (l1topoResult->
getFPGA(
i)->pt() != 0) {
492 std::vector<unsigned> topo1Opt0,topo1Opt1,topo1Opt2,topo1Opt3;
493 std::vector<unsigned> topo1Opt0Indices,topo1Opt1Indices,topo1Opt2Indices,topo1Opt3Indices;
498 for (
size_t i=0;
i<startbit.second;
i++){
503 topo1Opt0.push_back(
count);
504 topo1Opt0Indices.push_back(
indices);
510 for (
size_t i=0;
i<startbit.second;
i++){
515 topo1Opt1.push_back(
count);
516 topo1Opt1Indices.push_back(
indices);
522 for (
size_t i=0;
i<startbit.second;
i++){
527 topo1Opt2.push_back(
count);
528 topo1Opt2Indices.push_back(
indices);
534 for (
size_t i=0;
i<startbit.second;
i++){
539 topo1Opt3.push_back(
count);
540 topo1Opt3Indices.push_back(
indices);
547 multWeights.push_back(topo1Opt0);
552 multWeights.push_back(topo1Opt1);
557 multWeights.push_back(topo1Opt2);
562 multWeights.push_back(topo1Opt3);
568 const std::vector<size_t> triggerBitIndicesHdw = bitsetIndices(triggerBits);
569 const std::vector<size_t> overflowBitIndicesHdw = bitsetIndices(overflowBits);
579 return StatusCode::SUCCESS;
584 ATH_MSG_DEBUG(
"Simulation bits not set. Skipping simulation to hardware comparison");
585 return StatusCode::FAILURE;
588 std::bitset<s_nTopoCTPOutputs> triggerBitsSim = decisionBits.
triggerBitsSim.value();
589 std::bitset<s_nTopoCTPOutputs> triggerBitsHdw;
592 {triggerBitsHdw = decisionBits.
triggerBits.value();}
596 ATH_MSG_DEBUG(
"Hardware bits not set. Skipping simulation to hardware comparison");
597 return StatusCode::FAILURE;
600 std::bitset<s_nTopoCTPOutputs> triggerBitsSimNotHdw = triggerBitsSim & (~triggerBitsHdw);
601 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwNotSim = triggerBitsHdw & (~triggerBitsSim);
602 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwSim = triggerBitsHdw & triggerBitsSim;
603 std::bitset<s_nTopoCTPOutputs> triggerBitsAny = triggerBitsHdw | triggerBitsSim;
605 std::bitset<s_nTopoCTPOutputs>& overflowBitsSim = decisionBits.
overflowBitsSim.value();
606 std::bitset<s_nTopoCTPOutputs>& overflowBitsHdw = decisionBits.
overflowBits.value();
607 std::bitset<s_nTopoCTPOutputs> overflowBitsSimNotHdw = overflowBitsSim & (~overflowBitsHdw);
608 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwNotSim = overflowBitsHdw & (~overflowBitsSim);
609 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwSim = overflowBitsHdw & overflowBitsSim;
610 std::bitset<s_nTopoCTPOutputs> overflowBitsAny = overflowBitsHdw | overflowBitsSim;
612 std::bitset<s_nTopoCTPOutputs>& ambiguityBitsSim = decisionBits.
ambiguityBitsSim.value();
613 std::bitset<s_nTopoCTPOutputs> ambiguitySimANDHdw = ambiguityBitsSim & triggerBitsHdwSim;
614 std::bitset<s_nTopoCTPOutputs> ambiguityMismatch = ambiguityBitsSim & (triggerBitsSimNotHdw | triggerBitsHdwNotSim);
616 std::vector<size_t> triggerBitIndicesSimNotHdw = bitsetIndices(triggerBitsSimNotHdw);
617 std::vector<size_t> triggerBitIndicesHdwNotSim = bitsetIndices(triggerBitsHdwNotSim);
618 std::vector<size_t> ambiguitySimANDHdwBitIndices = bitsetIndices(ambiguitySimANDHdw);
619 std::vector<size_t> ambiguityMismatchBitIndices = bitsetIndices(ambiguityMismatch);
622 auto monAmbiguitySimANDHdw =
Monitored::Collection(
"Ambiguity_SimANDHdwDecisions", ambiguitySimANDHdwBitIndices);
623 auto monAmbiguityMismatch =
Monitored::Collection(
"Ambiguity_DecisionMismatches", ambiguityMismatchBitIndices);
628 float rate_overflow=0;
634 for (
size_t i=0;
i<4;
i++) {
643 for (
size_t j=0;j<32;j++) {
645 if (ambiguityBitsSim[32*
i+j] == 0) {
646 mon_trig =
static_cast<unsigned>(j);
647 mon_trig_allboards =
static_cast<unsigned>(32*
i+j);
648 if (overflowBitsHdw[32*
i+j] == 1 || overflowBitsSim[32*
i+j] == 1) {
740 return StatusCode::SUCCESS;
744 if (multWeightsSim.size() == 0 or multWeightsHdw.size() == 0) {
745 ATH_MSG_DEBUG(
"Multiplicities not set, skipping multiplicities comparison");
746 return StatusCode::FAILURE;
752 int AccumulatedPosition=0;
753 for (
size_t i=0;
i<multWeightsSim.size();
i++) {
756 for (
size_t k=0;
k<multWeightsSim[
i].size();
k++) {
761 if (monMultSim < monMultHdw) {mon_mult = 0; mon_multVsLumi_DQ = 1;}
762 if (monMultSim > monMultHdw) {mon_mult = 1; mon_multVsLumi_DQ = 1;}
763 if (monMultSim == monMultHdw){mon_mult = 2; mon_multVsLumi_DQ = 0;}
764 mon_multiplicity =
static_cast<unsigned>(
k);
765 mon_multiplicity_allboards =
static_cast<unsigned>(
k+AccumulatedPosition);
771 AccumulatedPosition=AccumulatedPosition+multWeightsSim[
i].size();
773 return StatusCode::SUCCESS;
778 std::vector<std::vector<std::pair<unsigned,unsigned>>> startbit_vec;
779 std::vector<std::string> connNames =
l1menu.connectorNames();
780 for(
const std::string connName : {
"Topo1Opt0",
"Topo1Opt1",
"Topo1Opt2",
"Topo1Opt3"}) {
781 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
784 std::vector<std::pair<unsigned,unsigned>> startbit;
785 for(
auto &
t1 :
l1menu.connector(connName).triggerLines()) {
786 startbit.push_back(std::make_pair(
t1.startbit(),
t1.nbits()));
788 startbit_vec.push_back(startbit);
797 std::vector<std::string> connNames =
l1menu.connectorNames();
799 for(
const std::string connName : {
"Topo2El",
"Topo3El"}) {
800 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
803 for(
uint fpga : {0,1}) {
804 for(
uint clock : {0,1}) {
805 for(
auto &
tl :
l1menu.connector(connName).triggerLines(fpga,clock)) {
806 uint flatIndex =
tl.flatindex() + 64 * (connName ==
"Topo3El");
807 labelsTopoEl[flatIndex] =
tl.name();
813 ATH_MSG_DEBUG(
"Obtaining CTPIds for Phase1 L1Topo Monitoring");
816 std::string definition =
item.definition();
817 if (definition.substr(0,5) ==
"TOPO_" &&
818 definition.find(
' ') == std::string::npos) {
819 std::string trigger = definition.substr(0, definition.find(
'['));
820 auto pos =
std::find(labelsTopoEl.begin(),labelsTopoEl.end(),trigger);
821 if (
pos != labelsTopoEl.end()) {
822 ATH_MSG_DEBUG(
"Found one CTP; ,CTPId: " <<
item.ctpId() <<
" ,Name: " <<
item.name() <<
" ,Definition: " << definition);
833 errorFlags.
setDetail(
"hasTrivialFlag",
true);