24 std::vector<size_t> bitsetIndices(
const std::bitset<N>& bits) {
27 for (
size_t i=0;
i<bits.size(); ++
i) {
106 auto & conn2EL =
l1menu->connector(
"Topo2El");
107 auto & conn3EL =
l1menu->connector(
"Topo3El");
109 auto & connOpt0 =
l1menu->connector(
"Topo1Opt0");
110 auto & connOpt1 =
l1menu->connector(
"Topo1Opt1");
111 auto & connOpt2 =
l1menu->connector(
"Topo1Opt2");
112 auto & connOpt3 =
l1menu->connector(
"Topo1Opt3");
120 auto & tlopt0 = connOpt0.triggerLines();
121 auto & tlopt1 = connOpt1.triggerLines();
122 auto & tlopt2 = connOpt2.triggerLines();
123 auto & tlopt3 = connOpt3.triggerLines();
125 long unsigned int size_tlopt0 = tlopt0.size();
126 long unsigned int size_tlopt1 = tlopt1.size();
127 long unsigned int size_tlopt2 = tlopt2.size();
128 long unsigned int size_tlopt3 = tlopt3.size();
130 long unsigned int total_size_opt = size_tlopt0+size_tlopt1+size_tlopt2+size_tlopt3;
138 auto & tl2a0 = conn2EL.triggerLines(0, 0);
139 auto & tl2a1 = conn2EL.triggerLines(0, 1);
140 long unsigned int size_tl2a0 = tl2a0.size();
141 long unsigned int size_tl2a1 = tl2a1.size();
143 auto & tl2b0 = conn2EL.triggerLines(1, 0);
144 auto & tl2b1 = conn2EL.triggerLines(1, 1);
145 long unsigned int size_tl2b0 = tl2b0.size();
146 long unsigned int size_tl2b1 = tl2b1.size();
148 auto & tl3a0 = conn3EL.triggerLines(0, 0);
149 auto & tl3a1 = conn3EL.triggerLines(0, 1);
150 long unsigned int size_tl3a0 = tl3a0.size();
151 long unsigned int size_tl3a1 = tl3a1.size();
153 auto & tl3b0 = conn3EL.triggerLines(1, 0);
154 auto & tl3b1 = conn3EL.triggerLines(1, 1);
155 long unsigned int size_tl3b0 = tl3b0.size();
156 long unsigned int size_tl3b1 = tl3b1.size();
158 for (
size_t i = 0;
i < 16; ++
i) {
165 for (
size_t i = 0;
i < 16; ++
i) {
172 for (
size_t i = 0;
i < 16; ++
i) {
179 for (
size_t i = 0;
i < 16; ++
i) {
189 for (
size_t j = 0; j < total_size_opt; ++j) {
197 for (
int j =0; j<128;j++){
217 return StatusCode::SUCCESS;
225 ATH_CHECK(errorFlagsCont.
record(std::make_unique<xAOD::TrigCompositeContainer>(),
226 std::make_unique<xAOD::TrigCompositeAuxContainer>()));
237 std::vector<uint8_t> failedMonFunctions;
238 std::vector<std::vector<unsigned>> multWeightsSim;
239 std::vector<std::vector<unsigned>> multWeightsHdw;
243 ATH_MSG_DEBUG(
"Executed doHWMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
244 if (
sc.isFailure()) {
245 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMon));
251 ATH_MSG_DEBUG(
"Executed doHWMonCTP: " << (
sc.isFailure() ?
"failed" :
"ok"));
252 if (
sc.isFailure()) {
253 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMonCTP));
259 ATH_MSG_DEBUG(
"Executed doSimMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
260 if (
sc.isFailure()) {
261 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doSimMon));
267 ATH_MSG_DEBUG(
"Executed doComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
268 if (
sc.isFailure()) {
269 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doComp));
275 ATH_MSG_DEBUG(
"Executed doMultComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
276 if (
sc.isFailure()) {
277 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doMultComp));
284 return StatusCode::SUCCESS;
293 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
294 return StatusCode::FAILURE;
302 std::unordered_map<unsigned,std::bitset<s_nTopoCTPOutputs>> multWeightsMap;
303 for(
const auto l1topo_dec : * cont){
304 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() );
306 if (l1topo_dec->bitWidth() == 32) {
307 std::vector<unsigned> topoword;
308 std::vector<unsigned> topowordOverflow;
309 for(
unsigned int i=0;
i<32; ++
i) {
311 if ((l1topo_dec->topoWord() &
mask) !=0) {
312 if (l1topo_dec->connectionId()==2 || l1topo_dec->connectionId()==3) {
313 topoword.push_back(32*l1topo_dec->clock()+
i);
314 uint32_t pos = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==2 ? 0 : 2))+
i;
317 if (l1topo_dec->connectionId()==22 || l1topo_dec->connectionId()==23) {
318 uint32_t pos_ambiguity = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==22 ? 0 : 2))+
i;
322 if ((l1topo_dec->topoWordOverflow() &
mask) !=0) {
323 topowordOverflow.push_back(32*l1topo_dec->clock()+
i);
324 uint32_t pus = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==12 ? 0 : 2))+
i;
328 std::string
name =
"CableElec_";
333 else if (l1topo_dec->bitWidth() == 64) {
334 for (
size_t i=0;
i<64;
i++) {
335 unsigned index =
i+l1topo_dec->clock()*64;
337 if ((l1topo_dec->topoWord64() &
mask) !=0) {
338 multWeightsMap[
static_cast<unsigned>(l1topo_dec->connectionId() - 4)].
set(
index);
343 ATH_MSG_DEBUG(
"Unknown Bit-length: " << l1topo_dec->bitWidth() );
344 return StatusCode::FAILURE;
349 std::vector<unsigned> vecCount, vecIndices;
353 for (
size_t i=0;
i<startbit.second;
i++){
354 if (multWeightsMap[
key][startbit.first+
i]) {
358 vecCount.push_back(
count);
362 multWeights.push_back(vecCount);
369 std::vector<size_t> triggerBitIndicesSim = bitsetIndices(triggerBitsSim);
370 std::vector<size_t> overflowBitIndicesSim = bitsetIndices(overflowBitsSim);
371 std::vector<size_t> ambiguityBitIndicesSim = bitsetIndices(ambiguityBitsSim);
379 return StatusCode::SUCCESS;
386 if (!ctpRdo.isValid()) {
387 ATH_MSG_DEBUG(
"Failed to retrieve CTP_RDO object (converted from CTP DAQ ROB) with key \""
389 return StatusCode::FAILURE;
394 ctp.setRDO(ctpRdo.cptr());
395 const uint32_t l1aPos = ctpRdo->getL1AcceptBunchPosition();
396 if (l1aPos >=
ctp.getBunchCrossings().size()) {
397 ATH_MSG_DEBUG(
"CTP_RDO gave invalid l1aPos. Skipping CTP hardware comparison");
398 return StatusCode::FAILURE;
400 ATH_MSG_DEBUG(
"CTP l1aPos, size: " << l1aPos <<
", " <<
ctp.getBunchCrossings().size());
401 const CTP_BC& ctpL1a =
ctp.getBunchCrossings().at(l1aPos);
405 static constexpr
size_t ctpTBPSize{512};
406 const std::bitset<ctpTBPSize>& tbp = ctpL1a.
getTBP();
413 {triggerBitsCtp[
i] =
false;}
416 std::vector<size_t> triggerBitIndicesCtp = bitsetIndices(triggerBitsCtp);
420 return StatusCode::SUCCESS;
427 ATH_MSG_WARNING(
"Could not retrieve L1Topo RAW Data Container from the BS data.");
428 return StatusCode::FAILURE;
436 std::unique_ptr<L1Topo::L1TopoResult> l1topoResult = std::make_unique<L1Topo::L1TopoResult>(*cont);
439 return StatusCode::FAILURE;
444 enum class MonFunction :
uint8_t {doRODct, doRODpc, doRODhc, doRODpe, doRODlm, doRODhm, doRODpt};
445 std::vector<uint8_t> rodErrors;
446 if (l1topoResult->
getROD(0)->ct() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODct)); }
447 if (l1topoResult->
getROD(0)->pc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpc)); }
448 if (l1topoResult->
getROD(0)->hc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhc)); }
449 if (l1topoResult->
getROD(0)->pe() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpe)); }
450 if (l1topoResult->
getROD(0)->lm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODlm)); }
451 if (l1topoResult->
getROD(0)->hm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhm)); }
452 if (l1topoResult->
getROD(0)->pt() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpt)); }
458 unsigned topoNumber = l1topoResult->
getFPGA(
i)->topoNumber();
459 unsigned fpgaNumber = l1topoResult->
getFPGA(
i)->fpgaNumber();
462 auto mon_fpga_labels =
Monitored::Scalar(
"FPGA_Labels", (topoNumber*2)-fpgaNumber-1);
464 if (l1topoResult->
getFPGA(
i)->ct() != 0) {
468 if (l1topoResult->
getFPGA(
i)->sm() != 0) {
472 if (l1topoResult->
getFPGA(
i)->pe() != 0) {
476 if (l1topoResult->
getFPGA(
i)->lm() != 0) {
480 if (l1topoResult->
getFPGA(
i)->hm() != 0) {
484 if (l1topoResult->
getFPGA(
i)->pt() != 0) {
491 std::vector<unsigned> topo1Opt0,topo1Opt1,topo1Opt2,topo1Opt3;
492 std::vector<unsigned> topo1Opt0Indices,topo1Opt1Indices,topo1Opt2Indices,topo1Opt3Indices;
497 for (
size_t i=0;
i<startbit.second;
i++){
502 topo1Opt0.push_back(
count);
503 topo1Opt0Indices.push_back(
indices);
509 for (
size_t i=0;
i<startbit.second;
i++){
514 topo1Opt1.push_back(
count);
515 topo1Opt1Indices.push_back(
indices);
521 for (
size_t i=0;
i<startbit.second;
i++){
526 topo1Opt2.push_back(
count);
527 topo1Opt2Indices.push_back(
indices);
533 for (
size_t i=0;
i<startbit.second;
i++){
538 topo1Opt3.push_back(
count);
539 topo1Opt3Indices.push_back(
indices);
546 multWeights.push_back(topo1Opt0);
551 multWeights.push_back(topo1Opt1);
556 multWeights.push_back(topo1Opt2);
561 multWeights.push_back(topo1Opt3);
567 const std::vector<size_t> triggerBitIndicesHdw = bitsetIndices(triggerBits);
568 const std::vector<size_t> overflowBitIndicesHdw = bitsetIndices(overflowBits);
578 return StatusCode::SUCCESS;
583 ATH_MSG_DEBUG(
"Simulation bits not set. Skipping simulation to hardware comparison");
584 return StatusCode::FAILURE;
587 std::bitset<s_nTopoCTPOutputs> triggerBitsSim = decisionBits.
triggerBitsSim.value();
588 std::bitset<s_nTopoCTPOutputs> triggerBitsHdw;
591 {triggerBitsHdw = decisionBits.
triggerBits.value();}
595 ATH_MSG_DEBUG(
"Hardware bits not set. Skipping simulation to hardware comparison");
596 return StatusCode::FAILURE;
599 std::bitset<s_nTopoCTPOutputs> triggerBitsSimNotHdw = triggerBitsSim & (~triggerBitsHdw);
600 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwNotSim = triggerBitsHdw & (~triggerBitsSim);
601 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwSim = triggerBitsHdw & triggerBitsSim;
602 std::bitset<s_nTopoCTPOutputs> triggerBitsAny = triggerBitsHdw | triggerBitsSim;
604 std::bitset<s_nTopoCTPOutputs>& overflowBitsSim = decisionBits.
overflowBitsSim.value();
605 std::bitset<s_nTopoCTPOutputs>& overflowBitsHdw = decisionBits.
overflowBits.value();
606 std::bitset<s_nTopoCTPOutputs> overflowBitsSimNotHdw = overflowBitsSim & (~overflowBitsHdw);
607 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwNotSim = overflowBitsHdw & (~overflowBitsSim);
608 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwSim = overflowBitsHdw & overflowBitsSim;
609 std::bitset<s_nTopoCTPOutputs> overflowBitsAny = overflowBitsHdw | overflowBitsSim;
611 std::bitset<s_nTopoCTPOutputs>& ambiguityBitsSim = decisionBits.
ambiguityBitsSim.value();
612 std::bitset<s_nTopoCTPOutputs> ambiguitySimANDHdw = ambiguityBitsSim & triggerBitsHdwSim;
613 std::bitset<s_nTopoCTPOutputs> ambiguityMismatch = ambiguityBitsSim & (triggerBitsSimNotHdw | triggerBitsHdwNotSim);
615 std::vector<size_t> triggerBitIndicesSimNotHdw = bitsetIndices(triggerBitsSimNotHdw);
616 std::vector<size_t> triggerBitIndicesHdwNotSim = bitsetIndices(triggerBitsHdwNotSim);
617 std::vector<size_t> ambiguitySimANDHdwBitIndices = bitsetIndices(ambiguitySimANDHdw);
618 std::vector<size_t> ambiguityMismatchBitIndices = bitsetIndices(ambiguityMismatch);
621 auto monAmbiguitySimANDHdw =
Monitored::Collection(
"Ambiguity_SimANDHdwDecisions", ambiguitySimANDHdwBitIndices);
622 auto monAmbiguityMismatch =
Monitored::Collection(
"Ambiguity_DecisionMismatches", ambiguityMismatchBitIndices);
627 float rate_overflow=0;
633 for (
size_t i=0;
i<4;
i++) {
642 for (
size_t j=0;j<32;j++) {
644 if (ambiguityBitsSim[32*
i+j] == 0) {
645 mon_trig =
static_cast<unsigned>(j);
646 mon_trig_allboards =
static_cast<unsigned>(32*
i+j);
647 if (overflowBitsHdw[32*
i+j] == 1 || overflowBitsSim[32*
i+j] == 1) {
739 return StatusCode::SUCCESS;
743 if (multWeightsSim.size() == 0 or multWeightsHdw.size() == 0) {
744 ATH_MSG_DEBUG(
"Multiplicities not set, skipping multiplicities comparison");
745 return StatusCode::FAILURE;
751 int AccumulatedPosition=0;
752 for (
size_t i=0;
i<multWeightsSim.size();
i++) {
755 for (
size_t k=0;
k<multWeightsSim[
i].size();
k++) {
760 if (monMultSim < monMultHdw) {mon_mult = 0; mon_multVsLumi_DQ = 1;}
761 if (monMultSim > monMultHdw) {mon_mult = 1; mon_multVsLumi_DQ = 1;}
762 if (monMultSim == monMultHdw){mon_mult = 2; mon_multVsLumi_DQ = 0;}
763 mon_multiplicity =
static_cast<unsigned>(
k);
764 mon_multiplicity_allboards =
static_cast<unsigned>(
k+AccumulatedPosition);
770 AccumulatedPosition=AccumulatedPosition+multWeightsSim[
i].size();
772 return StatusCode::SUCCESS;
777 std::vector<std::vector<std::pair<unsigned,unsigned>>> startbit_vec;
778 std::vector<std::string> connNames =
l1menu.connectorNames();
779 for(
const std::string connName : {
"Topo1Opt0",
"Topo1Opt1",
"Topo1Opt2",
"Topo1Opt3"}) {
780 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
783 std::vector<std::pair<unsigned,unsigned>> startbit;
784 for(
auto &
t1 :
l1menu.connector(connName).triggerLines()) {
785 startbit.push_back(std::make_pair(
t1.startbit(),
t1.nbits()));
787 startbit_vec.push_back(startbit);
796 std::vector<std::string> connNames =
l1menu.connectorNames();
798 for(
const std::string connName : {
"Topo2El",
"Topo3El"}) {
799 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
802 for(
uint fpga : {0,1}) {
803 for(
uint clock : {0,1}) {
804 for(
auto &
tl :
l1menu.connector(connName).triggerLines(fpga,clock)) {
805 uint flatIndex =
tl.flatindex() + 64 * (connName ==
"Topo3El");
806 labelsTopoEl[flatIndex] =
tl.name();
812 ATH_MSG_DEBUG(
"Obtaining CTPIds for Phase1 L1Topo Monitoring");
815 std::string definition =
item.definition();
816 if (definition.substr(0,5) ==
"TOPO_" &&
817 definition.find(
' ') == std::string::npos) {
818 std::string trigger = definition.substr(0, definition.find(
'['));
819 auto pos =
std::find(labelsTopoEl.begin(),labelsTopoEl.end(),trigger);
820 if (
pos != labelsTopoEl.end()) {
821 ATH_MSG_DEBUG(
"Found one CTP; ,CTPId: " <<
item.ctpId() <<
" ,Name: " <<
item.name() <<
" ,Definition: " << definition);
832 errorFlags.
setDetail(
"hasTrivialFlag",
true);