10 #include "GaudiKernel/ITHistSvc.h"
11 #include <nlohmann/json.hpp>
37 const std::string& L1name = L1item.name();
38 if (L1name == L1_item){
39 const std::string& L1definition = L1item.definition();
47 ATH_MSG_DEBUG(
"Warning: L1 item '" << L1_item <<
"' not found in the L1 menu!");
57 std::map<std::string, TriggerInfo> triggerMap;
64 std::sregex_iterator end;
65 std::vector<size_t> triggerPositions;
70 std::string triggerName =
match.str(1);
71 std::string triggerCount =
match.str(2);
72 info.triggers.push_back(triggerCount + triggerName);
75 triggerPositions.push_back(
match.position(0) +
match.length(0));
80 for (
size_t j = 0; j < triggerPositions.size(); ++j) {
81 size_t pos = triggerPositions[j];
86 [](
unsigned char c) { return std::isspace(c); }),
90 if (
part.find(
"&") != std::string::npos) {
91 info.operations.push_back(
"&");
92 }
else if (
part.find(
"|") != std::string::npos) {
93 info.operations.push_back(
"|");
100 lastPart.erase(std::remove_if(lastPart.begin(), lastPart.end(),
101 [](
unsigned char c) {
return std::isspace(
c); }),
108 for (
const auto& pair : triggerMap) {
110 for (
size_t i = 0;
i < pair.second.triggers.size(); ++
i) {
112 if (
i < pair.second.operations.size()) {
120 std::vector<std::string> beforeCTP_triggers;
121 std::vector<std::string> beforeCTP_triggers_mult;
123 for (
const auto& pair : triggerMap) {
124 for (
size_t i = 0;
i < pair.second.triggers.size(); ++
i) {
125 beforeCTP_triggers_mult.push_back(pair.second.triggers[
i]);
126 size_t pos_number = 0;
127 while (pos_number < (pair.second.triggers[
i]).size() && std::isdigit((pair.second.triggers[
i])[pos_number])) {
130 beforeCTP_triggers.push_back((pair.second.triggers[
i]).substr(pos_number));
134 std::unordered_set<std::string> seen_mult;
135 std::vector<std::string> beforeCTP_triggers_mult_unique;
137 for (
const auto& str_mult : beforeCTP_triggers_mult) {
138 auto [
it, inserted] = seen_mult.insert(str_mult);
140 beforeCTP_triggers_mult_unique.push_back(str_mult);
144 std::sort(beforeCTP_triggers.begin(), beforeCTP_triggers.end());
145 auto beforeCTP_triggers_unique = std::unique(beforeCTP_triggers.begin(), beforeCTP_triggers.end());
146 beforeCTP_triggers.erase(beforeCTP_triggers_unique, beforeCTP_triggers.end());
153 for (
size_t i = 0;
i < beforeCTP_triggers.size(); ++
i){
154 ATH_MSG_DEBUG(
"Filling L1menu parameters from item: " << beforeCTP_triggers[
i]);
157 definition.
clock = 0;
162 for(
const auto & connName :
l1menu->connectorNames() ) {
164 for(
auto &
tl :
conn.triggerLines() ) {
166 if ((connName ==
"Topo2El") || (connName ==
"Topo3El")){
167 for (
size_t fpga = 0; fpga < 2; ++fpga){
168 for (
size_t clock = 0; clock < 2; ++clock){
169 for (
auto &
tl :
conn.triggerLines(fpga,clock)){
170 if (
tl.name() == beforeCTP_triggers[
i]){
172 definition.
nBit =
tl.nbits();
174 if (connName ==
"Topo2El") definition.
conID = 2;
175 if (connName ==
"Topo3El") definition.
conID = 3;
184 if (
tl.name() == beforeCTP_triggers[
i]){
186 definition.
nBit =
tl.nbits();
187 definition.
clock = 0;
188 if (connName ==
"Topo1Opt0") definition.
conID = 4;
189 if (connName ==
"Topo1Opt1") definition.
conID = 5;
190 if (connName ==
"Topo1Opt2") definition.
conID = 6;
191 if (connName ==
"Topo1Opt3") definition.
conID = 7;
202 return StatusCode::SUCCESS;
209 ATH_MSG_DEBUG(
"################## Registering rates matrix:");
210 m_ratesMatrixHist =
new TH2D(
"rates_matrix",
"L1item Rates matrix",150,-3,3,150,-3,3);
211 m_countsMatrixHist =
new TH2D(
"counts_matrix",
"L1item Counts matrix",150,-3,3,150,-3,3);
229 std::set<std::string> triggerGroup {
"RATE_SingleElectron"};
233 std::vector<double> vector_zeros(
m_L1_items.size(), 0);
262 return StatusCode::SUCCESS;
271 std::vector<uint32_t>result_vector(2,0);
274 long long topoWordPrint =
result->topoWord64();
275 std::bitset<64> wordPrint(topoWordPrint);
276 if (
result->connectionId() != definition.
conID)
continue;
278 std::vector<uint32_t> connectorWords(4);
288 long long topoWordOverflow =
result->topoWordOverflow();
291 std::bitset<32> wordOver(topoWordOverflow);
292 word = wordRes | wordOver;
294 connectorWords[
result->clock()] =
static_cast<uint32_t>(word.to_ullong());
299 long long topoWord64Overflow =
result->topoWord64Overflow();
302 std::bitset<64> wordOver(topoWord64Overflow);
303 word = wordRes | wordOver;
306 connectorWords[2*
result->clock() + 0] =
static_cast<uint32_t>(word.to_ullong());
307 connectorWords[2*
result->clock() + 1] =
static_cast<uint32_t>(word.to_ullong() >> 32);
312 unsigned int startOffset = 0;
314 if (
result->connectionId() == 5 ||
result->connectionId() == 7){
319 resultValue =
extractResult(connectorWords, definition, startOffset);
320 result_vector[
result->clock()] = resultValue;
323 if ((result_vector[0]>1)||(result_vector[1]>1)){
324 if (result_vector[0]>1) resultValue = result_vector[0];
325 if (result_vector[1]>1) resultValue = result_vector[1];
327 resultValue = result_vector[0] || result_vector[1];
343 unsigned int startindex = definition.
flatindex + startOffset;
344 unsigned int endindex = startindex + definition.
nBit - 1;
345 unsigned int firstWord = startindex / 32;
346 unsigned int lastWord = endindex / 32;
347 unsigned int nBitAdded = 0;
350 if ((firstWord>1) | (lastWord>1)){
351 firstWord = firstWord%3;
352 lastWord = lastWord%3;
355 std::vector<uint32_t>result_vec(lastWord,0);
358 for (
unsigned int wordIndex=firstWord; wordIndex <= lastWord; wordIndex++) {
359 unsigned int startPosInWord = (wordIndex == firstWord) ? (startindex % 32) : 0 ;
360 unsigned int endPosInWord = (wordIndex == lastWord) ? (endindex % 32) : 31;
362 mask = ( ( 1
u<< (endPosInWord+1) ) - 1 );
363 word = connectorContents[wordIndex] &
mask;
364 word >>= startPosInWord;
365 result |= word << nBitAdded;
366 nBitAdded += endPosInWord - startPosInWord + 1;
367 result_vec.push_back(
result);
369 if (result_vec.size()>1){
370 result = result_vec[0] || result_vec[1];
383 const std::vector<uint32_t>
l1Triggers = trigDecision->
tbp();
387 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
388 return StatusCode::FAILURE;
391 std::vector<std::string> l1Items_vector;
393 std::vector<uint32_t> resultValue(l1Items_vector.size(), 0);
398 std::map<std::string, bool> beforeCTP_result_Map;
406 ATH_MSG_DEBUG(
"Decision from the decoder first (L1TopoResultsContainer): " << resultValue[
i]);
411 ATH_MSG_DEBUG(
"Decision from the decoder (L1TopoResultsContainer): " << resultValue[
i]);
418 while (
pos < mult_item.size() && std::isdigit(mult_item[
pos])) {
421 std::string leading_number = mult_item.substr(0,
pos);
422 std::string item_name = mult_item.substr(
pos);
425 if (item_name == l1Items_vector[
i]) {
427 if (resultValue[
i] >= 1){
428 beforeCTP_result_Map[mult_item] =
true;
440 std::map<std::string, bool> L1_result_Map;
441 std::vector<bool> isPassed_L1item;
444 const std::string&
key = pair.first;
446 if (
info.triggers.empty())
continue;
448 std::vector<bool> triggerResults;
449 std::vector<std::string> newTriggers;
451 std::vector<std::string> muTriggers;
452 std::vector<size_t> muIndices;
454 for (
size_t i = 0;
i <
info.triggers.size(); ++
i) {
455 if (
info.triggers[
i].find(
"MU") != std::string::npos &&
info.triggers[
i].find(
"TOPO") == std::string::npos) {
456 muTriggers.push_back(
info.triggers[
i]);
457 muIndices.push_back(
i);
461 std::map<size_t, bool> customResults;
463 if (!muTriggers.empty()) {
464 std::string muCombinedName =
"L1";
465 for (
const auto& trig : muTriggers) {
468 std::string mult = trig.substr(0,
start);
470 if (mult.empty() || mult ==
"1") {
471 muCombinedName +=
"_" +
name;
473 muCombinedName +=
"_" + mult +
name;
479 double weight =
it->second->getTotalPrescaleWeight();
480 for (
size_t idx : muIndices) {
481 customResults[
idx] =
static_cast<bool>(
weight);
484 std::cerr <<
" [Warning] Combined MU not found: " << muCombinedName << std::endl;
485 for (
size_t idx : muIndices) {
486 customResults[
idx] =
false;
491 for (
size_t i = 0;
i <
info.triggers.size(); ++
i) {
493 const std::string& trig =
info.triggers[
i];
495 if (customResults.count(
i)) {
497 newTriggers.push_back(
"<<MU>>");
499 auto it = beforeCTP_result_Map.find(trig);
500 if (
it != beforeCTP_result_Map.end()) {
503 std::cerr <<
" [Warning] Trigger not found in beforeCTP_result_Map: " << trig << std::endl;
506 newTriggers.push_back(trig);
508 triggerResults.push_back(
result);
511 bool finalResult = triggerResults[0];
512 for (
size_t i = 1;
i < triggerResults.size(); ++
i) {
513 const std::string& op =
info.operations[
i - 1];
515 finalResult &= triggerResults[
i];
516 }
else if (op ==
"|") {
517 finalResult |= triggerResults[
i];
519 std::cerr <<
" [Warning] Unknown operation: " << op << std::endl;
523 L1_result_Map[
key] = finalResult;
524 isPassed_L1item.push_back(finalResult);
530 for (
const auto& pair : L1_result_Map) {
531 const std::string&
label = pair.first;
548 bool flag = (isPassed_L1item[
i] && isPassed_L1item[j]);
562 std::vector<std::string> triggerNames;
564 triggerNames.push_back(
key);
567 const size_t nTriggers = triggerNames.size();
569 for (
size_t i = 0;
i < nTriggers; ++
i) {
570 for (
size_t j = 0; j < nTriggers; ++j) {
571 double w_i =
getTriggerMap().at(triggerNames[
i])->getTotalPrescaleWeight();
572 double w_j =
getTriggerMap().at(triggerNames[j])->getTotalPrescaleWeight();
573 double weight_result_tdt = w_i * w_j;
583 return StatusCode::SUCCESS;
591 std::vector<std::string> triggerNames;
593 triggerNames.push_back(
key);
596 const size_t nTriggers = triggerNames.size();
605 for (
size_t i = 0;
i < nTriggers; ++
i) {
606 for (
size_t j = 0; j < nTriggers; ++j) {
612 const std::string&
label = pair.first;
634 if (
it == triggerNames.end()) {
635 std::cerr <<
"Trigger not found in TDT: " <<
name << std::endl;
642 if (original !=
tdt) {
647 if (jt == triggerNames.end())
continue;
655 ATH_MSG_DEBUG(
"Trigger rates replaced from TDT: " <<
name <<
", TDT rate: " <<
tdt <<
", RCM rate: " << original);
673 double denom = AB * (
A +
B - AB);
674 if (AB == 0 || (
A +
B - AB) == 0 ||
denom == 0) {
680 double topoScore = (
A *
B) /
denom;
683 double dfdA = (
B * (
A +
B - AB) -
A *
B) / (AB *
pow(
A +
B - AB, 2));
684 double dfdB = (
A * (
A +
B - AB) -
A *
B) / (AB *
pow(
A +
B - AB, 2));
685 double dfdAB = -
A *
B * (
A +
B) / (
pow(AB, 2) *
pow(
A +
B - AB, 2));
687 double sigma2 =
pow(dfdA * sigma_A, 2)
688 +
pow(dfdB * sigma_B, 2)
689 +
pow(dfdAB * sigma_AB, 2);
710 return StatusCode::SUCCESS;