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;
58 for (
size_t i = 0; i <
m_L1_items.size(); ++i){
62 std::regex
re(R
"(([\w\d_-]+)\[x(\d+)\])");
64 std::sregex_iterator end;
65 std::vector<size_t> triggerPositions;
69 std::smatch
match = *iter;
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(
"|");
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;
161 ATH_MSG_DEBUG(
"Item being analyzed: " << beforeCTP_triggers[i]);
162 for(
const auto & connName : l1menu->connectorNames() ) {
163 auto & conn = l1menu->connector(connName);
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();
173 definition.
clock = tl.clock();
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);
234 for (
size_t i = 0; i <
m_L1_items.size(); ++i){
247 for (
size_t i = 1; i <=
m_L1_items.size(); ++i){
263 return StatusCode::SUCCESS;
269 uint32_t resultValue = 999;
272 std::vector<uint32_t>result_vector(2,0);
275 long long topoWordPrint =
result->topoWord64();
276 std::bitset<64> wordPrint(topoWordPrint);
277 if (
result->connectionId() != definition.
conID)
continue;
279 std::vector<uint32_t> connectorWords(4);
280 unsigned int bitWidth =
result->bitWidth();
281 long long topoWord64 =
result->topoWord64();
282 std::bitset<64> word(topoWord64);
286 long long topoWord =
result->topoWord();
287 std::bitset<32> word(topoWord);
289 long long topoWordOverflow =
result->topoWordOverflow();
291 std::bitset<32> wordRes(topoWord);
292 std::bitset<32> wordOver(topoWordOverflow);
293 word = wordRes | wordOver;
295 connectorWords[
result->clock()] =
static_cast<uint32_t
>(word.to_ullong());
300 long long topoWord64Overflow =
result->topoWord64Overflow();
302 std::bitset<64> wordRes(topoWord64);
303 std::bitset<64> wordOver(topoWord64Overflow);
304 word = wordRes | wordOver;
307 connectorWords[2*
result->clock() + 0] =
static_cast<uint32_t
>(word.to_ullong());
308 connectorWords[2*
result->clock() + 1] =
static_cast<uint32_t
>(word.to_ullong() >> 32);
313 unsigned int startOffset = 0;
315 if (
result->connectionId() == 5 ||
result->connectionId() == 7){
320 resultValue =
extractResult(connectorWords, definition, startOffset);
321 result_vector[
result->clock()] = resultValue;
324 if ((result_vector[0]>1)||(result_vector[1]>1)){
325 if (result_vector[0]>1) resultValue = result_vector[0];
326 if (result_vector[1]>1) resultValue = result_vector[1];
328 resultValue = result_vector[0] || result_vector[1];
344 unsigned int startindex = definition.
flatindex + startOffset;
345 unsigned int endindex = startindex + definition.
nBit - 1;
346 unsigned int firstWord = startindex / 32;
347 unsigned int lastWord = endindex / 32;
348 unsigned int nBitAdded = 0;
351 if ((firstWord>1) | (lastWord>1)){
352 firstWord = firstWord%3;
353 lastWord = lastWord%3;
356 std::vector<uint32_t>result_vec(lastWord,0);
359 for (
unsigned int wordIndex=firstWord; wordIndex <= lastWord; wordIndex++) {
360 unsigned int startPosInWord = (wordIndex == firstWord) ? (startindex % 32) : 0 ;
361 unsigned int endPosInWord = (wordIndex == lastWord) ? (endindex % 32) : 31;
363 mask = ( ( 1u<< (endPosInWord+1) ) - 1 );
364 word = connectorContents[wordIndex] & mask;
365 word >>= startPosInWord;
366 result |= word << nBitAdded;
367 nBitAdded += endPosInWord - startPosInWord + 1;
368 result_vec.push_back(
result);
370 if (result_vec.size()>1){
371 result = result_vec[0] || result_vec[1];
384 const std::vector<uint32_t> l1Triggers = trigDecision->
tbp();
388 ATH_MSG_FATAL(
"Could not retrieve L1Topo EDM Container from the Simulation.");
389 return StatusCode::FAILURE;
392 std::vector<std::string> l1Items_vector;
394 std::vector<uint32_t> resultValue(l1Items_vector.size(), 0);
399 std::map<std::string, bool> beforeCTP_result_Map;
407 ATH_MSG_DEBUG(
"Decision from the decoder first (L1TopoResultsContainer): " << resultValue[i]);
412 ATH_MSG_DEBUG(
"Decision from the decoder (L1TopoResultsContainer): " << resultValue[i]);
419 while (pos < mult_item.size() && std::isdigit(mult_item[pos])) {
422 std::string leading_number = mult_item.substr(0, pos);
423 std::string item_name = mult_item.substr(pos);
426 if (item_name == l1Items_vector[i]) {
427 if (leading_number <= std::to_string(resultValue[i])) {
428 if (resultValue[i] >= 1){
429 beforeCTP_result_Map[mult_item] =
true;
441 std::map<std::string, bool> L1_result_Map;
442 std::vector<bool> isPassed_L1item;
445 const std::string& key =
pair.first;
447 if (info.triggers.empty())
continue;
449 std::vector<bool> triggerResults;
450 std::vector<std::string> newTriggers;
452 std::vector<std::string> muTriggers;
453 std::vector<size_t> muIndices;
455 for (
size_t i = 0; i < info.triggers.size(); ++i) {
456 if (info.triggers[i].find(
"MU") != std::string::npos && info.triggers[i].find(
"TOPO") == std::string::npos) {
457 muTriggers.push_back(info.triggers[i]);
458 muIndices.push_back(i);
462 std::map<size_t, bool> customResults;
464 if (!muTriggers.empty()) {
465 std::string muCombinedName =
"L1";
466 for (
const auto& trig : muTriggers) {
468 while (start < trig.size() && std::isdigit(trig[start])) ++start;
469 std::string mult = trig.substr(0, start);
470 std::string name = trig.substr(start);
471 if (mult.empty() || mult ==
"1") {
472 muCombinedName +=
"_" + name;
474 muCombinedName +=
"_" + mult + name;
480 double weight = it->second->getTotalPrescaleWeight();
481 for (
size_t idx : muIndices) {
482 customResults[idx] =
static_cast<bool>(weight);
485 std::cerr <<
" [Warning] Combined MU not found: " << muCombinedName << std::endl;
486 for (
size_t idx : muIndices) {
487 customResults[idx] =
false;
492 for (
size_t i = 0; i < info.triggers.size(); ++i) {
494 const std::string& trig = info.triggers[i];
496 if (customResults.count(i)) {
497 result = customResults[i];
498 newTriggers.push_back(
"<<MU>>");
500 auto it = beforeCTP_result_Map.find(trig);
501 if (it != beforeCTP_result_Map.end()) {
504 std::cerr <<
" [Warning] Trigger not found in beforeCTP_result_Map: " << trig << std::endl;
507 newTriggers.push_back(trig);
509 triggerResults.push_back(
result);
512 bool finalResult = triggerResults[0];
513 for (
size_t i = 1; i < triggerResults.size(); ++i) {
514 const std::string& op = info.operations[i - 1];
516 finalResult &= triggerResults[i];
517 }
else if (op ==
"|") {
518 finalResult |= triggerResults[i];
520 std::cerr <<
" [Warning] Unknown operation: " << op << std::endl;
524 L1_result_Map[key] = finalResult;
525 isPassed_L1item.push_back(finalResult);
531 for (
const auto&
pair : L1_result_Map) {
549 bool flag = (isPassed_L1item[i] && isPassed_L1item[j]);
563 std::vector<std::string> triggerNames;
565 triggerNames.push_back(key);
568 const size_t nTriggers = triggerNames.size();
570 for (
size_t i = 0; i < nTriggers; ++i) {
571 for (
size_t j = 0; j < nTriggers; ++j) {
572 double w_i =
getTriggerMap().at(triggerNames[i])->getTotalPrescaleWeight();
573 double w_j =
getTriggerMap().at(triggerNames[j])->getTotalPrescaleWeight();
574 double weight_result_tdt = w_i * w_j;
585 return StatusCode::SUCCESS;
593 std::vector<std::string> triggerNames;
595 triggerNames.push_back(key);
598 const size_t nTriggers = triggerNames.size();
607 for (
size_t i = 0; i < nTriggers; ++i) {
608 for (
size_t j = 0; j < nTriggers; ++j) {
635 auto it = std::find(triggerNames.begin(), triggerNames.end(), name);
636 if (it == triggerNames.end()) {
637 std::cerr <<
"Trigger not found in TDT: " << name << std::endl;
640 size_t idxTDT = std::distance(triggerNames.begin(), it);
644 if (original != tdt) {
648 auto jt = std::find(triggerNames.begin(), triggerNames.end(),
m_RCM_nameOrder[j]);
649 if (jt == triggerNames.end())
continue;
650 size_t jTDT = std::distance(triggerNames.begin(), jt);
659 ATH_MSG_DEBUG(
"Trigger rates replaced from TDT: " << name <<
", TDT rate: " << tdt <<
", RCM rate: " << original);
676 double denom = AB * (
A + B - AB);
677 if (AB == 0 || (
A + B - AB) == 0 || denom == 0) {
683 double topoScore = (
A * B) / denom;
686 double dfdA = (B * (
A + B - AB) -
A * B) / (AB *
pow(
A + B - AB, 2));
687 double dfdB = (
A * (
A + B - AB) -
A * B) / (AB *
pow(
A + B - AB, 2));
688 double dfdAB = -(
A + B - 2 * AB) / (
pow(AB, 2) *
pow(
A + B - AB, 2));
689 double sigma2 =
pow(dfdA * sigma_A, 2)
690 +
pow(dfdB * sigma_B, 2)
691 +
pow(dfdAB * sigma_AB, 2);
712 return StatusCode::SUCCESS;
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ALWAYS(x)
constexpr int pow(int base, int exp) noexcept
const ServiceHandle< StoreGateSvc > & detStore() const
const ServiceHandle< ITHistSvc > & histSvc() const
The standard THistSvc (for writing histograms and TTrees and more to a root file) Returns (kind of) a...
virtual StatusCode ratesInitialize() override
To be implemented by the user.
std::vector< std::string > m_L1_items
L1TopoRatesCalculator(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::TrigDecision > m_trigDecisionKey
std::vector< std::vector< double > > m_rates_matrix
Gaudi::Property< std::vector< std::string > > m_userDefinedDefinitions
Gaudi::Property< float > m_lumi
SG::ReadHandleKey< xAOD::L1TopoSimResultsContainer > m_l1topoKey
std::vector< double > m_EB_weight
virtual StatusCode initialize() override
Get the trigger decision tool and set up global groups.
std::map< std::string, TriggerInfo > m_triggerMap
TH2D * m_countsMatrixHist
std::vector< ResultDefinition > m_definitions
std::vector< std::string > m_RCM_nameOrder
std::vector< std::string > m_L1_item_definitions
virtual StatusCode ratesExecute() override
To be implemented by the user.
std::vector< std::vector< double > > m_count_matrix
std::vector< std::vector< double > > m_L1TopoScore_matrix
std::vector< std::vector< double > > m_counts_matrix_TDT
uint32_t extractResult(const std::vector< uint32_t > &connectorContents, const L1TopoRatesCalculator::ResultDefinition &definition, unsigned int startOffset)
TH2D * m_L1TopoScoreMatrixHist
virtual StatusCode ratesFinalize() override
To be implemented by the user.
std::vector< std::vector< double > > m_rates_matrix2_TDT
Gaudi::Property< std::vector< std::string > > m_userDefinedNames
std::vector< std::vector< double > > m_rates_matrix_TDT
Gaudi::Property< std::vector< std::string > > m_L1_items_json
std::vector< std::string > m_beforeCTP_triggers
uint32_t L1TopoSimResultsContainer_decoder(const L1TopoRatesCalculator::ResultDefinition &definition, SG::ReadHandle< xAOD::L1TopoSimResultsContainer > &cont)
std::vector< std::vector< double > > m_rates_matrix2
std::vector< std::string > m_beforeCTP_triggers_mult
std::vector< std::vector< double > > m_L1TopoScore_errors
std::vector< double > m_denominator
std::unordered_map< std::string, std::string > m_userDefinedMap
RatesAnalysisAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_doHistograms
double m_ratesDenominator
How much walltime is seen by the algorithm.
const std::unordered_map< std::string, std::unique_ptr< RatesTrigger > > & getTriggerMap() const
WeightingValuesSummary_t m_weightingValues
Possible weighting & lumi extrapolation values for the current event.
virtual StatusCode initialize()
Get the trigger decision tool and set up global groups.
void setTargetLumi(const double lumi)
Set the target instantaneous luminosity.
StatusCode addExisting(const std::string &pattern)
Register some existing triggers based on wild-card match, e.g.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
L1 threshold configuration.
const std::vector< uint32_t > & tbp() const
Get the Trigger Before Prescale bits.
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
bool match(std::string s1, std::string s2)
match the individual directories of two strings
std::string label(const std::string &format, int i)
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
L1TopoSimResultsContainer_v1 L1TopoSimResultsContainer
TrigDecision_v1 TrigDecision
Define the latest version of the trigger decision class.
L1TopoSimResults_v1 L1TopoSimResults
Define the latest version of the L1TopoSimResults class.
hold the test vectors and ease the comparison