22 const std::string&
name,
40 m_dl2 = std::make_unique<FlavorTagDiscriminants::DL2HighLevel>(
"BTagging/20210519r22/dl1d/antikt4empflow/network.json",
44 return StatusCode::SUCCESS;
55 const EmulContext& emulCtx)
const
62 return isPassed(*(itr->second.get()), emulCtx);
84 for (
const auto& is_chainPart_PFlow :
chain.is_PFlow() ) {
85 if ( not is_chainPart_PFlow ) {
86 ATH_MSG_ERROR(
"Only PFlow jets are supported at this moment" );
98 const int shared_idx =
chain.shared_idx();
99 const std::vector<int>& jet_multiplicity =
chain.jet_multiplicity();
100 const std::vector<std::string>& chainPartName =
chain.chainPartName();
101 const std::vector<TrigBtagEmulationJet>& pflow_jets =
m_manager_PFlow_cnt->getJets(emulCtx);
103 int nChainParts =
static_cast<int>( jet_multiplicity.size() );
111 std::vector<std::string> chainPartNames_leg1(chainPartName.begin(), chainPartName.begin() + shared_idx);
112 std::vector<int> multiplicities_leg1(jet_multiplicity.begin(), jet_multiplicity.begin() + shared_idx);
113 std::vector<std::string> chainPartNames_leg2(chainPartName.begin() + shared_idx, chainPartName.end());
114 std::vector<int> multiplicities_leg2(jet_multiplicity.begin() + shared_idx, jet_multiplicity.end());
122 std::vector<std::string> chainPartNames(chainPartName.begin(), chainPartName.end());
123 std::vector<int>
multiplicities(jet_multiplicity.begin(), jet_multiplicity.end());
132 const std::vector<TrigBtagEmulationJet>& preselJets)
const
134 const std::vector<std::string>& jet_presel =
chain.jet_presel();
135 if (jet_presel.size() == 0)
return true;
137 int presel_multiplicity = 1;
138 double presel_ptcut = 0.;
139 double presel_eta_min = 0.;
140 double presel_eta_max = 0.;
143 if( preselJets.size() == 1 ) {
145 const std::string presel_part = jet_presel[0];
146 int preseljets_passed = 0;
148 parse_preselection(presel_part, presel_multiplicity, presel_ptcut, presel_eta_min, presel_eta_max);
150 for(
const auto& preseljet: preselJets ) {
152 presel_eta_min < std::fabs(preseljet.eta()) && std::fabs(preseljet.eta()) < presel_eta_max) {
162 if(preseljets_passed >= presel_multiplicity) {
170 std::vector<std::vector<bool>> chainPart_passedjets(jet_presel.size());
171 size_t chainPart_passedjets_lenmax = 0;
174 for(
size_t chainPart_idx = 0; chainPart_idx < chainPart_passedjets.size(); chainPart_idx++) {
175 parse_preselection(jet_presel[chainPart_idx], presel_multiplicity, presel_ptcut, presel_eta_min, presel_eta_max);
178 for (
const auto& preseljet : preselJets ) {
180 presel_eta_min < std::fabs(preseljet.eta()) && std::fabs(preseljet.eta()) < presel_eta_max) {
182 chainPart_passedjets[chainPart_idx].push_back(
true);
185 chainPart_passedjets[chainPart_idx].push_back(
false);
190 if(chainPart_passedjets[chainPart_idx].
size() > chainPart_passedjets_lenmax) {
191 chainPart_passedjets_lenmax = chainPart_passedjets[chainPart_idx].size();
198 for(
auto& chainPart_passedjets_row : chainPart_passedjets ) {
200 while(chainPart_passedjets_row.size() < chainPart_passedjets_lenmax) {
201 chainPart_passedjets_row.push_back(
false);
212 const std::vector<TrigBtagEmulationJet>& preselJets)
const
214 const std::string& dijetmass =
chain.dijetmass();
215 if ( dijetmass ==
"None")
return true;
217 double dijet_mass = 0.;
218 double dijet_minjetpt = 0.;
219 double dijet_dphi = -1.;
220 double dijet_deta = -1.;
224 for(
const auto& jet1: preselJets ) {
229 for(
const auto& jet2: preselJets ) {
234 double mass = (jet1.p4() + jet2.p4()).M();
235 double adphi = std::abs(jet1.p4().DeltaPhi(jet2.p4()));
236 double adeta = std::abs(jet1.eta() - jet2.eta());
239 (dijet_dphi < 0 || adphi < dijet_dphi) &&
240 (dijet_deta < 0 || adeta > dijet_deta) ) {
252 int& presel_multiplicity,
253 double& presel_ptcut,
254 double& presel_eta_min,
255 double& presel_eta_max)
const
257 char presel_etarange =
'?';
259 presel_multiplicity = 1;
260 int tokenizer_offset = 0;
261 if(
'0' <= presel_part[0] && presel_part[0] <=
'9') {
262 presel_multiplicity = (presel_part[0] -
'0');
263 tokenizer_offset = 1;
265 presel_etarange = presel_part[tokenizer_offset];
266 presel_ptcut =
static_cast<double>( std::stoi(&presel_part[1 +tokenizer_offset]) );
268 switch(presel_etarange) {
270 presel_eta_max = 3.2;
273 presel_eta_max = 4.9;
276 presel_eta_max = 2.4;
279 presel_eta_min = 3.2;
280 presel_eta_max = 4.9;
283 ATH_MSG_ERROR(
"Unknown eta range in jet preselection cut." );
290 double& dijet_minjetpt,
292 double& dijet_deta)
const
301 dijet_mass =
static_cast<double>( std::stoi(dijetmass) );
302 dijet_minjetpt =
static_cast<double>( std::stoi(dijetmass.substr(dijetmass.find(
"j") +1)) );
304 if(dijetmass.find(
"dphi") != std::string::npos) {
305 dijet_dphi =
static_cast<double>( (std::stoi(dijetmass.substr(dijetmass.find(
"dphi") + 4)))) / 1
e2 ;
308 if(dijetmass.find(
"deta") != std::string::npos) {
309 std::string deta_str = dijetmass.substr(dijetmass.find(
"deta") -6);
310 dijet_deta =
static_cast<double>( (std::stoi(dijetmass.substr(dijetmass.find(
"x") +1)))) / 1
e2;
313 ATH_MSG_DEBUG(
"DijetMass parsing result: " << dijetmass <<
" ->"
314 <<
" m:" << dijet_mass
315 <<
" j:" << dijet_minjetpt
316 <<
" dphi:" << dijet_dphi
317 <<
" deta:" << dijet_deta);
321 const std::vector<std::string>& chainPartNames,
325 std::vector<bool> chainPart_subset_passed;
327 auto chainPartName_it = chainPartNames.begin();
328 for(
const auto& chainPart_passedjets: chainPart_jet_matrix) {
329 std::string passedJets =
"";
330 passedJets.reserve(chainPart_passedjets.size());
331 for(
bool pass: chainPart_passedjets) {
332 passedJets += pass ?
'1' :
'0';
333 passedJets += !(passedJets.size() % 5) ?
" " :
"";
338 if(chainPart_jet_matrix.size() == 1) {
340 chainPart_subset_passed.push_back(
false);
342 for(
bool pass: chainPart_jet_matrix[0]) {
346 chainPart_subset_passed.back() =
true;
362 for (
int subset_bits = 1; subset_bits < (1 << chainPart_jet_matrix.size()); ++subset_bits) {
363 std::bitset<32> subset(subset_bits);
364 std::vector<bool> subset_passedJets(chainPart_jet_matrix[0].
size(),
false);
365 int njets_required_subset = 0;
367 std::string subset_str =
"";
368 for(
size_t chainPart_idx = 0; chainPart_idx < chainPart_jet_matrix.size(); ++chainPart_idx) {
369 if(subset[chainPart_idx]) {
373 for(
size_t jet_idx = 0; jet_idx < chainPart_jet_matrix[chainPart_idx].size(); ++jet_idx) {
374 if(chainPart_jet_matrix[chainPart_idx][jet_idx]) {
375 subset_passedJets[jet_idx] =
true;
381 int njets_passed_subset = 0;
382 for(
bool pass: subset_passedJets) {
384 njets_passed_subset++;
388 ATH_MSG_DEBUG(
"Subset {" << subset_str <<
"} requires " << njets_required_subset <<
" jets, and has " << njets_passed_subset <<
" jets passed." );
390 if(njets_passed_subset < njets_required_subset) {
391 chainPart_subset_passed.push_back(
false);
395 chainPart_subset_passed.push_back(
true);
401 if(chainPart_subset_passed.size() ==
static_cast<size_t>(1 << chainPart_jet_matrix.size()) -1 &&
402 !chainPart_subset_passed.empty()) {
404 res = chainPart_subset_passed.back();
407 ATH_MSG_DEBUG( chainPart_subset_passed.size() <<
" out of " << (1 << chainPart_jet_matrix.size()) -1 <<
" chain part subsets checked" );
414 const std::vector<TrigBtagEmulationJet>&
jets,
418 const std::vector<double>& jet_pt_vec =
chain.jet_pt();
419 const std::vector<double>& jet_eta_min_vec =
chain.jet_eta_min();
420 const std::vector<double>& jet_eta_max_vec =
chain.jet_eta_max();
421 const std::vector<double>& jvt_vec =
chain.jvt();
422 const std::vector<std::string>& tagger_vec =
chain.tagger();
423 const std::vector<std::string>& chainPartName_vec =
chain.chainPartName();
425 std::vector<std::vector<bool>> chainPart_passedjets(idx_end - idx_begin);
427 for(
size_t chainPart_idx = 0; chainPart_idx < chainPart_passedjets.size(); chainPart_idx++) {
428 double jet_pt = jet_pt_vec[chainPart_idx +idx_begin];
429 double jet_eta_min = jet_eta_min_vec[chainPart_idx +idx_begin];
430 double jet_eta_max = jet_eta_max_vec[chainPart_idx +idx_begin];
431 double jvtcut = jvt_vec[chainPart_idx +idx_begin];
432 std::string tagger = tagger_vec[chainPart_idx +idx_begin];
434 ATH_MSG_DEBUG(
">-- " << chainPartName_vec[chainPart_idx +idx_begin] <<
":" );
435 for(
const auto&
jet :
jets ) {
436 float jvt =
jet.jvt();
437 bool passedJvt = jvt > jvtcut ||
439 std::fabs(
jet.eta()) > 2.5;
441 if (tagger ==
"ewTagger") tagger =
"newTagger";
444 if(
jet.pt() > jet_pt &&
445 std::fabs(
jet.eta()) > jet_eta_min &&
446 std::fabs(
jet.eta()) < jet_eta_max &&
448 ((tagger !=
"") ? is_bjet :
true) ) {
450 chainPart_passedjets[chainPart_idx].push_back(
true);
453 chainPart_passedjets[chainPart_idx].push_back(
false);
457 <<
", eta:" <<
jet.eta()
459 << ((tagger !=
"") ?
", btag:" :
"") << ((tagger !=
"") ? (is_bjet?
"Y":
"N") :
"")
460 <<
", pass:" << (chainPart_passedjets[chainPart_idx].back()?
"Y":
"N")
465 return chainPart_passedjets;
473 EmulContext *emulCtx =
new EmulContext();
494 EmulContext& emulCtx)
const
496 const EventContext& ctx = Gaudi::Hive::currentContext();
499 const std::string& jetContainerName =
manager.jetContainerName();
500 const unsigned int jetSize =
manager.getJets(emulCtx).size();
502 ATH_MSG_DEBUG(
"Size of input containers ['" << jetContainerName <<
"'] :"
503 <<
" jet=" << jetSize);
505 return StatusCode::SUCCESS;
510 std::vector<std::string> listOfTriggers =
m_trigDec->getChainGroup( inputChain )->getListOfTriggers();
511 if ( listOfTriggers.empty() ) {
512 ATH_MSG_ERROR(
"Input Chain ('" << inputChain <<
"') is not in the list of available triggers: {" <<
m_trigDec->getListOfTriggers(
".*") <<
"}" );
513 return StatusCode::FAILURE;
516 ATH_MSG_DEBUG(
"Triggers in configured ChainGroup " << inputChain <<
":" );
517 for (
const auto& cname: listOfTriggers) {
521 return StatusCode::SUCCESS;
525 const std::vector<std::string>& definition)
528 ATH_MSG_ERROR(
"Chain " << triggerName <<
" has already been added in the Emulation List.");
529 return StatusCode::FAILURE;
531 auto chain = std::make_unique<TrigBtagEmulationChain>( triggerName, definition );
532 chain->setLevel(msgLevel());
535 return StatusCode::SUCCESS;
539 const std::string& btagger)
const
541 if (btagger.empty())
return false;
542 if (btagger ==
"offperf")
return true;
547 double workingPoint = itr->second;
550 if( btagger.substr(0, 4) ==
"dl1r" ) {
551 res =
jet.satisfy(
"DL1r", workingPoint);
552 }
else if( btagger.substr(0, 4) ==
"dl1d" ) {
553 res =
jet.satisfy(
"DL1d20211216", workingPoint);
554 }
else if( btagger ==
"newTagger" ) {
556 if (not btag)
return false;
557 m_dl2->decorate(*btag);
559 res =
jet.satisfy(
"DL1dEMUL", workingPoint);