24 std::vector<size_t> bitsetIndices(
const std::bitset<N>& bits) {
27 for (
size_t i=0;
i<bits.size(); ++
i) {
100 auto & conn2EL =
l1menu->connector(
"Topo2El");
101 auto & conn3EL =
l1menu->connector(
"Topo3El");
103 auto & connOpt0 =
l1menu->connector(
"Topo1Opt0");
104 auto & connOpt1 =
l1menu->connector(
"Topo1Opt1");
105 auto & connOpt2 =
l1menu->connector(
"Topo1Opt2");
106 auto & connOpt3 =
l1menu->connector(
"Topo1Opt3");
114 auto & tlopt0 = connOpt0.triggerLines();
115 auto & tlopt1 = connOpt1.triggerLines();
116 auto & tlopt2 = connOpt2.triggerLines();
117 auto & tlopt3 = connOpt3.triggerLines();
119 long unsigned int size_tlopt0 = tlopt0.size();
120 long unsigned int size_tlopt1 = tlopt1.size();
121 long unsigned int size_tlopt2 = tlopt2.size();
122 long unsigned int size_tlopt3 = tlopt3.size();
124 long unsigned int total_size_opt = size_tlopt0+size_tlopt1+size_tlopt2+size_tlopt3;
132 auto & tl2a0 = conn2EL.triggerLines(0, 0);
133 auto & tl2a1 = conn2EL.triggerLines(0, 1);
134 long unsigned int size_tl2a0 = tl2a0.size();
135 long unsigned int size_tl2a1 = tl2a1.size();
137 auto & tl2b0 = conn2EL.triggerLines(1, 0);
138 auto & tl2b1 = conn2EL.triggerLines(1, 1);
139 long unsigned int size_tl2b0 = tl2b0.size();
140 long unsigned int size_tl2b1 = tl2b1.size();
142 auto & tl3a0 = conn3EL.triggerLines(0, 0);
143 auto & tl3a1 = conn3EL.triggerLines(0, 1);
144 long unsigned int size_tl3a0 = tl3a0.size();
145 long unsigned int size_tl3a1 = tl3a1.size();
147 auto & tl3b0 = conn3EL.triggerLines(1, 0);
148 auto & tl3b1 = conn3EL.triggerLines(1, 1);
149 long unsigned int size_tl3b0 = tl3b0.size();
150 long unsigned int size_tl3b1 = tl3b1.size();
152 for (
size_t i = 0;
i < 16; ++
i) {
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) {
183 for (
size_t j = 0; j < total_size_opt; ++j) {
191 for (
int j =0; j<128;j++){
211 return StatusCode::SUCCESS;
219 ATH_CHECK(errorFlagsCont.
record(std::make_unique<xAOD::TrigCompositeContainer>(),
220 std::make_unique<xAOD::TrigCompositeAuxContainer>()));
231 std::vector<uint8_t> failedMonFunctions;
232 std::vector<std::vector<unsigned>> multWeightsSim;
233 std::vector<std::vector<unsigned>> multWeightsHdw;
237 ATH_MSG_DEBUG(
"Executed doHWMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
238 if (
sc.isFailure()) {
239 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMon));
245 ATH_MSG_DEBUG(
"Executed doHWMonCTP: " << (
sc.isFailure() ?
"failed" :
"ok"));
246 if (
sc.isFailure()) {
247 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doHwMonCTP));
253 ATH_MSG_DEBUG(
"Executed doSimMon: " << (
sc.isFailure() ?
"failed" :
"ok"));
254 if (
sc.isFailure()) {
255 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doSimMon));
261 ATH_MSG_DEBUG(
"Executed doComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
262 if (
sc.isFailure()) {
263 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doComp));
269 ATH_MSG_DEBUG(
"Executed doMultComp: " << (
sc.isFailure() ?
"failed" :
"ok"));
270 if (
sc.isFailure()) {
271 failedMonFunctions.push_back(
static_cast<uint8_t>(MonFunction::doMultComp));
278 return StatusCode::SUCCESS;
287 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
288 return StatusCode::FAILURE;
296 std::unordered_map<unsigned,std::bitset<s_nTopoCTPOutputs>> multWeightsMap;
297 for(
const auto l1topo_dec : * cont){
298 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() );
300 if (l1topo_dec->bitWidth() == 32) {
301 std::vector<unsigned> topoword;
302 std::vector<unsigned> topowordOverflow;
303 for(
unsigned int i=0;
i<32; ++
i) {
305 if ((l1topo_dec->topoWord() &
mask) !=0) {
306 if (l1topo_dec->connectionId()==2 || l1topo_dec->connectionId()==3) {
307 topoword.push_back(32*l1topo_dec->clock()+
i);
308 uint32_t pos = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==2 ? 0 : 2))+
i;
311 if (l1topo_dec->connectionId()==22 || l1topo_dec->connectionId()==23) {
312 uint32_t pos_ambiguity = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==22 ? 0 : 2))+
i;
316 if ((l1topo_dec->topoWordOverflow() &
mask) !=0) {
317 topowordOverflow.push_back(32*l1topo_dec->clock()+
i);
318 uint32_t pus = 32*(l1topo_dec->clock()+(l1topo_dec->connectionId()==12 ? 0 : 2))+
i;
322 std::string
name =
"CableElec_";
327 else if (l1topo_dec->bitWidth() == 64) {
328 for (
size_t i=0;
i<64;
i++) {
329 unsigned index =
i+l1topo_dec->clock()*64;
331 if ((l1topo_dec->topoWord64() &
mask) !=0) {
332 multWeightsMap[
static_cast<unsigned>(l1topo_dec->connectionId() - 4)].
set(
index);
337 ATH_MSG_DEBUG(
"Unknown Bit-length: " << l1topo_dec->bitWidth() );
338 return StatusCode::FAILURE;
343 std::vector<unsigned> vecCount, vecIndices;
347 for (
size_t i=0;
i<startbit.second;
i++){
348 if (multWeightsMap[
key][startbit.first+
i]) {
352 vecCount.push_back(
count);
356 multWeights.push_back(vecCount);
363 std::vector<size_t> triggerBitIndicesSim = bitsetIndices(triggerBitsSim);
364 std::vector<size_t> overflowBitIndicesSim = bitsetIndices(overflowBitsSim);
365 std::vector<size_t> ambiguityBitIndicesSim = bitsetIndices(ambiguityBitsSim);
373 return StatusCode::SUCCESS;
380 if (!ctpRdo.isValid()) {
381 ATH_MSG_DEBUG(
"Failed to retrieve CTP_RDO object (converted from CTP DAQ ROB) with key \""
383 return StatusCode::FAILURE;
388 ctp.setRDO(ctpRdo.cptr());
389 const uint32_t l1aPos = ctpRdo->getL1AcceptBunchPosition();
390 if (l1aPos >=
ctp.getBunchCrossings().size()) {
391 ATH_MSG_DEBUG(
"CTP_RDO gave invalid l1aPos. Skipping CTP hardware comparison");
392 return StatusCode::FAILURE;
394 ATH_MSG_DEBUG(
"CTP l1aPos, size: " << l1aPos <<
", " <<
ctp.getBunchCrossings().size());
395 const CTP_BC& ctpL1a =
ctp.getBunchCrossings().at(l1aPos);
399 static constexpr
size_t ctpTBPSize{512};
400 const std::bitset<ctpTBPSize>& tbp = ctpL1a.
getTBP();
407 {triggerBitsCtp[
i] =
false;}
410 std::vector<size_t> triggerBitIndicesCtp = bitsetIndices(triggerBitsCtp);
414 return StatusCode::SUCCESS;
421 ATH_MSG_WARNING(
"Could not retrieve L1Topo RAW Data Container from the BS data.");
422 return StatusCode::FAILURE;
430 std::unique_ptr<L1Topo::L1TopoResult> l1topoResult = std::make_unique<L1Topo::L1TopoResult>(*cont);
433 return StatusCode::FAILURE;
438 enum class MonFunction :
uint8_t {doRODct, doRODpc, doRODhc, doRODpe, doRODlm, doRODhm, doRODpt};
439 std::vector<uint8_t> rodErrors;
440 if (l1topoResult->
getROD(0)->ct() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODct)); }
441 if (l1topoResult->
getROD(0)->pc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpc)); }
442 if (l1topoResult->
getROD(0)->hc() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhc)); }
443 if (l1topoResult->
getROD(0)->pe() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpe)); }
444 if (l1topoResult->
getROD(0)->lm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODlm)); }
445 if (l1topoResult->
getROD(0)->hm() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODhm)); }
446 if (l1topoResult->
getROD(0)->pt() != 0) { rodErrors.push_back(
static_cast<uint8_t>(MonFunction::doRODpt)); }
452 unsigned topoNumber = l1topoResult->
getFPGA(
i)->topoNumber();
453 unsigned fpgaNumber = l1topoResult->
getFPGA(
i)->fpgaNumber();
456 auto mon_fpga_labels =
Monitored::Scalar(
"FPGA_Labels", (topoNumber*2)-fpgaNumber-1);
458 if (l1topoResult->
getFPGA(
i)->ct() != 0) {
462 if (l1topoResult->
getFPGA(
i)->sm() != 0) {
466 if (l1topoResult->
getFPGA(
i)->pe() != 0) {
470 if (l1topoResult->
getFPGA(
i)->lm() != 0) {
474 if (l1topoResult->
getFPGA(
i)->hm() != 0) {
478 if (l1topoResult->
getFPGA(
i)->pt() != 0) {
485 std::vector<unsigned> topo1Opt0,topo1Opt1,topo1Opt2,topo1Opt3;
486 std::vector<unsigned> topo1Opt0Indices,topo1Opt1Indices,topo1Opt2Indices,topo1Opt3Indices;
491 for (
size_t i=0;
i<startbit.second;
i++){
496 topo1Opt0.push_back(
count);
497 topo1Opt0Indices.push_back(
indices);
503 for (
size_t i=0;
i<startbit.second;
i++){
508 topo1Opt1.push_back(
count);
509 topo1Opt1Indices.push_back(
indices);
515 for (
size_t i=0;
i<startbit.second;
i++){
520 topo1Opt2.push_back(
count);
521 topo1Opt2Indices.push_back(
indices);
527 for (
size_t i=0;
i<startbit.second;
i++){
532 topo1Opt3.push_back(
count);
533 topo1Opt3Indices.push_back(
indices);
540 multWeights.push_back(topo1Opt0);
545 multWeights.push_back(topo1Opt1);
550 multWeights.push_back(topo1Opt2);
555 multWeights.push_back(topo1Opt3);
561 const std::vector<size_t> triggerBitIndicesHdw = bitsetIndices(triggerBits);
562 const std::vector<size_t> overflowBitIndicesHdw = bitsetIndices(overflowBits);
572 return StatusCode::SUCCESS;
577 ATH_MSG_DEBUG(
"Simulation bits not set. Skipping simulation to hardware comparison");
578 return StatusCode::FAILURE;
581 std::bitset<s_nTopoCTPOutputs> triggerBitsSim = decisionBits.
triggerBitsSim.value();
582 std::bitset<s_nTopoCTPOutputs> triggerBitsHdw;
585 {triggerBitsHdw = decisionBits.
triggerBits.value();}
589 ATH_MSG_DEBUG(
"Hardware bits not set. Skipping simulation to hardware comparison");
590 return StatusCode::FAILURE;
593 std::bitset<s_nTopoCTPOutputs> triggerBitsSimNotHdw = triggerBitsSim & (~triggerBitsHdw);
594 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwNotSim = triggerBitsHdw & (~triggerBitsSim);
595 std::bitset<s_nTopoCTPOutputs> triggerBitsHdwSim = triggerBitsHdw & triggerBitsSim;
596 std::bitset<s_nTopoCTPOutputs> triggerBitsAny = triggerBitsHdw | triggerBitsSim;
598 std::bitset<s_nTopoCTPOutputs>& overflowBitsSim = decisionBits.
overflowBitsSim.value();
599 std::bitset<s_nTopoCTPOutputs>& overflowBitsHdw = decisionBits.
overflowBits.value();
600 std::bitset<s_nTopoCTPOutputs> overflowBitsSimNotHdw = overflowBitsSim & (~overflowBitsHdw);
601 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwNotSim = overflowBitsHdw & (~overflowBitsSim);
602 std::bitset<s_nTopoCTPOutputs> overflowBitsHdwSim = overflowBitsHdw & overflowBitsSim;
603 std::bitset<s_nTopoCTPOutputs> overflowBitsAny = overflowBitsHdw | overflowBitsSim;
605 std::bitset<s_nTopoCTPOutputs>& ambiguityBitsSim = decisionBits.
ambiguityBitsSim.value();
606 std::bitset<s_nTopoCTPOutputs> ambiguitySimANDHdw = ambiguityBitsSim & triggerBitsHdwSim;
607 std::bitset<s_nTopoCTPOutputs> ambiguityMismatch = ambiguityBitsSim & (triggerBitsSimNotHdw | triggerBitsHdwNotSim);
609 std::vector<size_t> triggerBitIndicesSimNotHdw = bitsetIndices(triggerBitsSimNotHdw);
610 std::vector<size_t> triggerBitIndicesHdwNotSim = bitsetIndices(triggerBitsHdwNotSim);
611 std::vector<size_t> ambiguitySimANDHdwBitIndices = bitsetIndices(ambiguitySimANDHdw);
612 std::vector<size_t> ambiguityMismatchBitIndices = bitsetIndices(ambiguityMismatch);
615 auto monAmbiguitySimANDHdw =
Monitored::Collection(
"Ambiguity_SimANDHdwDecisions", ambiguitySimANDHdwBitIndices);
616 auto monAmbiguityMismatch =
Monitored::Collection(
"Ambiguity_DecisionMismatches", ambiguityMismatchBitIndices);
621 float rate_overflow=0;
627 for (
size_t i=0;
i<4;
i++) {
636 for (
size_t j=0;j<32;j++) {
638 if (ambiguityBitsSim[32*
i+j] == 0) {
639 mon_trig =
static_cast<unsigned>(j);
640 mon_trig_allboards =
static_cast<unsigned>(32*
i+j);
641 if (overflowBitsHdw[32*
i+j] == 1 || overflowBitsSim[32*
i+j] == 1) {
731 return StatusCode::SUCCESS;
735 if (multWeightsSim.size() == 0 or multWeightsHdw.size() == 0) {
736 ATH_MSG_DEBUG(
"Multiplicities not set, skipping multiplicities comparison");
737 return StatusCode::FAILURE;
743 int AccumulatedPosition=0;
744 for (
size_t i=0;
i<multWeightsSim.size();
i++) {
747 for (
size_t k=0;
k<multWeightsSim[
i].size();
k++) {
752 if (monMultSim < monMultHdw) {mon_match = 0; mon_matchVsLumi_DQ = 1;}
753 if (monMultSim > monMultHdw) {mon_match = 1; mon_matchVsLumi_DQ = 1;}
754 if (monMultSim == monMultHdw){mon_match = 2; mon_matchVsLumi_DQ = 0;}
755 mon_multiplicity =
static_cast<unsigned>(
k);
756 mon_multiplicity_allboards =
static_cast<unsigned>(
k+AccumulatedPosition);
762 AccumulatedPosition=AccumulatedPosition+multWeightsSim[
i].size();
764 return StatusCode::SUCCESS;
769 std::vector<std::vector<std::pair<unsigned,unsigned>>> startbit_vec;
770 std::vector<std::string> connNames =
l1menu.connectorNames();
771 for(
const std::string connName : {
"Topo1Opt0",
"Topo1Opt1",
"Topo1Opt2",
"Topo1Opt3"}) {
772 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
775 std::vector<std::pair<unsigned,unsigned>> startbit;
776 for(
auto &
t1 :
l1menu.connector(connName).triggerLines()) {
777 startbit.push_back(std::make_pair(
t1.startbit(),
t1.nbits()));
779 startbit_vec.push_back(startbit);
788 std::vector<std::string> connNames =
l1menu.connectorNames();
790 for(
const std::string connName : {
"Topo2El",
"Topo3El"}) {
791 if(
find(connNames.begin(), connNames.end(), connName) == connNames.end() ) {
794 for(
uint fpga : {0,1}) {
795 for(
uint clock : {0,1}) {
796 for(
auto &
tl :
l1menu.connector(connName).triggerLines(fpga,clock)) {
797 uint flatIndex =
tl.flatindex() + 64 * (connName ==
"Topo3El");
798 labelsTopoEl[flatIndex] =
tl.name();
804 ATH_MSG_DEBUG(
"Obtaining CTPIds for Phase1 L1Topo Monitoring");
807 std::string definition =
item.definition();
808 if (definition.substr(0,5) ==
"TOPO_" &&
809 definition.find(
' ') == std::string::npos) {
810 std::string trigger = definition.substr(0, definition.find(
'['));
811 auto pos =
std::find(labelsTopoEl.begin(),labelsTopoEl.end(),trigger);
812 if (
pos != labelsTopoEl.end()) {
813 ATH_MSG_DEBUG(
"Found one CTP; ,CTPId: " <<
item.ctpId() <<
" ,Name: " <<
item.name() <<
" ,Definition: " << definition);
824 errorFlags.
setDetail(
"hasTrivialFlag",
true);