23 #define APP_NAME "BoostedXbbTag"
46 const std::string& recommendations_file,
47 const std::string& boson_type,
48 const std::string& algorithm_name,
50 const std::string& decor_prefix,
53 m_working_point(working_point),
54 m_recommendations_file(recommendations_file),
55 m_boson_type(boson_type),
56 m_algorithm_name(algorithm_name),
57 m_num_bTags(num_bTags),
58 m_decor_prefix(decor_prefix),
62 m_bTagCutCharm(FLT_MIN),
65 m_D2_params(5, FLT_MIN),
66 m_D2_cut_direction(
"None"),
67 m_muonSelectionTool(
new CP::MuonSelectionTool(
"JSSU_MuonSelection")),
68 m_bad_configuration(false),
69 m_isB(
SG::AuxElement::Decorator<
int>(m_decor_prefix+
"m_isB")),
71 m_correctedJetDecor(
SG::AuxElement::Decorator<TLorentzVector>(m_decor_prefix+
"CorrectedJetP4")),
72 m_massWindow(
SG::AuxElement::Decorator<std::pair<
float,
float>>(m_decor_prefix+
"MassWindow")),
73 m_D2Pivot(
SG::AuxElement::Decorator<std::pair<
float, std::string>>(m_decor_prefix+
"m_D2Pivot"))
82 printf(
"<%s>: Attempting to configure with\r\n\t"
83 "Working Point %s\r\n\t"
84 "Recommendations File %s\r\n\t"
86 "Algorithm Name %s\r\n\t"
87 "Debug Output? %s\r\n\t"
88 "Verbose Output? %s\r\n"
89 "=========================================\r\n",
96 printf(
"<%s>: Could not initialize the MuonSelectionTool.\r\n",
APP_NAME);
100 std::set<std::string> validWorkingPoints = {
"tight",
"medium",
"loose",
"veryloose",
"single",
"single_loose",
"single_medium"};
101 if( validWorkingPoints.find(
m_working_point) == validWorkingPoints.end()){
102 printf(
"<%s>: Unknown working point requested.\r\n\tExpected: single, single_loose, single_medium, veryloose, loose, medium, tight\r\n\tGiven: %s\r\n",
APP_NAME,
m_working_point.c_str());
108 std::set<std::string> validBosonTypes = {
"Higgs"};
109 if( validBosonTypes.find(
m_boson_type) == validBosonTypes.end()){
110 printf(
"<%s>: Unknown boson type requested.\r\n\tHiggs\r\n\tGiven: %s\r\n",
APP_NAME,
m_boson_type.c_str());
122 bool found_configuration =
false;
137 printf(
"<%s>: Something is wrong with the recommendations file. Could not open for reading.\r\n",
APP_NAME);
140 if(
m_verbose) printf(
"<%s>: Recommendations file opened for reading.\r\n",
APP_NAME);
143 while( std::getline(f_in,
line) ){
144 if(
line.empty())
continue;
145 if(
line[0] ==
'#')
continue;
151 std::istringstream
ss(
line);
153 std::vector<std::string> lineDetails{std::istream_iterator<std::string>{
ss}, std::istream_iterator<std::string>{}};
154 if(lineDetails.size() != 14)
continue;
160 if(std::stoi(lineDetails[3]) !=
m_num_bTags)
continue;
166 for(
int i=0;
i < 5;
i++)
170 if(
m_verbose) printf(
"<%s>: Found the configuration! We're done reading the file.\r\n",
APP_NAME);
171 found_configuration =
true;
177 if(!found_configuration){
178 printf(
"<%s>: Could not configure the tool. The configuration does not exist in the recommendations file.\r\n",
APP_NAME);
183 std::cout <<
"|=====================================================|" << std::endl;
184 std::cout <<
"| WARNING WARNING WARNING |" << std::endl;
185 std::cout <<
"| WARNING WARNING WARNING |" << std::endl;
186 std::cout <<
"| WARNING WARNING WARNING |" << std::endl;
187 std::cout <<
"| WARNING WARNING WARNING |" << std::endl;
188 std::cout <<
"|-----------------------------------------------------|" << std::endl;
189 std::cout <<
"| |" << std::endl;
190 std::cout <<
"| |" << std::endl;
191 std::cout <<
"| |" << std::endl;
192 std::cout <<
"| BoostedXbbTagger is misconfigured! |" << std::endl;
193 std::cout <<
"| |" << std::endl;
194 std::cout <<
"| |" << std::endl;
195 std::cout <<
"| |" << std::endl;
196 std::cout <<
"|=====================================================|" << std::endl;
198 if(
m_verbose) printf(
"<%s>: BoostedXbbTagger is configured successfuly! Congratulations on such an achievement.\r\n",
APP_NAME);
205 const float size_parameter,
208 bool error_flag(
false);
211 static const std::map<int, std::string> mapAlgorithmType = {
217 static const std::map<int, std::string> mapInputType {
225 static const std::map<int, std::string> mapTransformType {
232 std::string algorithm_name = mapAlgorithmType.at(jet_algorithm)
234 + mapInputType.at(jet_input)
235 + mapTransformType.at(jet_transform);
239 switch(jet_transform){
242 if(
m_debug) printf(
"<%s>: PtFrac is not defined for the input jet.\r\n",
APP_NAME);
246 if(
m_debug) printf(
"<%s>: RClus is not defined for the input jet.\r\n" ,
APP_NAME);
256 if(
m_debug) printf(
"<%s>: RCut is not defined for the input jet.\r\n",
APP_NAME);
260 if(
m_debug) printf(
"<%s>: ZCut is not defined for the input jet.\r\n",
APP_NAME);
270 if(
m_debug) printf(
"<%s>: MuMax is not defined for the input jet.\r\n",
APP_NAME);
274 if(
m_debug) printf(
"<%s>: RClus is not defined for the input jet.\r\n",
APP_NAME);
278 if(
m_debug) printf(
"<%s>: YMin is not defined for the input jet.\r\n" ,
APP_NAME);
282 if(
m_debug) printf(
"<%s>: BDRS is not defined for the input jet.\r\n" ,
APP_NAME);
292 if(
m_debug) printf(
"<%s>: Current value of xAOD::JetTransform::Type is not supported!\r\n",
APP_NAME);
297 return std::pair<bool, std::string>(!error_flag, algorithm_name);
305 if(
m_debug) printf(
"<%s>: BoostedXbbTag has a bad configuration!\r\n",
APP_NAME);
311 if(
m_debug) printf(
"<%s>: AlgorithmType is not defined for the jet.\r\n",
APP_NAME);
315 if(
m_debug) printf(
"<%s>: SizeParameter is not defined for the jet.\r\n",
APP_NAME);
319 if(
m_debug) printf(
"<%s>: InputType is not defined for the jet.\r\n" ,
APP_NAME);
323 if(
m_debug) printf(
"<%s>: TransformType is not defined for the jet.\r\n",
APP_NAME);
327 if(
m_verbose) printf(
"<%s>: Jet has the 4 main properties set.\r\n\t"
328 "AlgorithmType: %d\r\n\t"
329 "Size Parameter: %0.2f\r\n\t"
330 "Input Type: %d\r\n\t"
331 "Transform Type: %d\r\n",
343 if(
m_debug) printf(
"<%s>: Could not determine what jet you are using.\r\n",
APP_NAME);
355 if(
m_debug) printf(
"<%s>: BoostedXbbTag has a bad configuration!\r\n",
APP_NAME);
360 if(
jet.pt()/1.e3 < 250.0 || std::fabs(
jet.eta()) > 2.0){
361 if(
m_verbose) printf(
"<%s>: Jet does not pass basic kinematic selection. pT > 250 GeV, |eta| < 2.0\r\n\tJet Pt: %0.6f GeV\r\n\tJet |eta|: %0.6f\r\n",
APP_NAME,
jet.pt()/1.e3, std::fabs(
jet.eta()));
389 bool pass_mass =
false,
394 std::vector<const xAOD::Jet*> associated_trackJets;
396 bool problemWithParent =
false;
398 if(!
s_parent.isAvailable(
jet)) problemWithParent =
true;
400 if(problemWithParent || !parentEL.
isValid()){
402 if(problemWithParent &&
m_debug) printf(
"Parent decoration does not exist. ");
403 if(!parentEL.
isValid() &&
m_debug) printf(
"Parent link is not valid. ");
416 if(
m_verbose) printf(
"<%s>: No associated track jets found on s_parent jet.\r\n",
APP_NAME);
426 else if(
m_verbose) printf(
"<%s>: Got track jets from parent jet.\r\n",
APP_NAME);
430 for(
const auto& trackJet: associated_trackJets)
431 m_isB(*trackJet) = 0;
434 associated_trackJets.erase(
435 std::remove_if(associated_trackJets.begin(), associated_trackJets.end(), [](
const xAOD::Jet*
jet) ->
bool { return (jet->pt()/1.e3 < 10.0 || fabs(jet->eta()) > 2.5 || jet->numConstituents() < 2); }),
436 associated_trackJets.end());
437 if(associated_trackJets.size() < 2){
442 else if(associated_trackJets.empty()){
449 std::sort(associated_trackJets.begin(), associated_trackJets.end(), [](
const xAOD::IParticle* lhs,
const xAOD::IParticle* rhs) ->
bool { return (lhs->pt() > rhs->pt()); });
451 int num_trackJets_toLookAt =
std::min((
int)associated_trackJets.size(), 2);
452 for(
int i = 0;
i < num_trackJets_toLookAt;
i++){
453 auto& trackJet = associated_trackJets.at(
i);
456 double mv2c10(FLT_MIN);
459 if(
m_verbose) printf(
"<%s>: Could not retrieve the MV2c10 discriminant.\r\n",
APP_NAME);
462 int isBTagged =
static_cast<int>(mv2c10 >
m_bTagCut);
485 m_isB(*trackJet) = isBTagged;
486 num_bTags += isBTagged;
496 std::vector<const xAOD::Muon*> matched_muons;
498 std::vector<const xAOD::Muon*> preselected_muons(muons->
size(),
nullptr);
500 auto it =
std::copy_if(muons->
begin(), muons->
end(), preselected_muons.begin(), [
this](
const xAOD::Muon* muon) ->
bool { return (muon->pt()/1.e3 > 10.0 && m_muonSelectionTool->getQuality(*muon) <= xAOD::Muon::Medium && fabs(muon->eta()) < 2.5); });
502 preselected_muons.resize(
std::distance(preselected_muons.begin(),
it));
503 if(preselected_muons.empty()){
504 if(
m_verbose) printf(
"<%s>: There are no muons that passed the kinematic preselection.\r\n",
APP_NAME);
507 for(
int i = 0;
i < num_trackJets_toLookAt;
i++){
508 auto& trackJet = associated_trackJets.at(
i);
510 if(
m_isB(*trackJet) == 0)
continue;
513 trackJet->getAttribute(
"SizeParameter", maxDR);
515 for(
const auto *
const muon: preselected_muons){
516 float DR( trackJet->p4().DeltaR(muon->p4()) );
517 if(DR > maxDR)
continue;
522 matched_muons.push_back(closest_muon);
528 TLorentzVector corrected_jet =
jet.p4();
529 if(
m_verbose) printf(
"<%s>: There are %d matched muons.\r\n",
APP_NAME, (
int)matched_muons.size());
530 std::vector<ElementLink<xAOD::IParticleContainer> > matched_muons_links;
531 for(
const auto *muon : matched_muons) {
533 muon->parameter(eLoss,xAOD::Muon::EnergyLoss);
534 if(
m_debug) printf(
"<%s>: getELossTLV xAOD::Muon eLoss= %0.2f\r\n",
APP_NAME, eLoss);
535 auto mTLV = muon->p4();
536 double eLossX = eLoss*
sin(mTLV.Theta())*
cos(mTLV.Phi());
537 double eLossY = eLoss*
sin(mTLV.Theta())*
sin(mTLV.Phi());
538 double eLossZ = eLoss*
cos(mTLV.Theta());
539 auto mLoss = TLorentzVector(eLossX,eLossY,eLossZ,eLoss);
540 corrected_jet = corrected_jet + mTLV - mLoss;
543 matched_muons_links.push_back(el_muon);
553 buffer =
"<%s>: Jet %s the mass window cut.\r\n\tMass: %0.6f GeV\r\n\tMass Window: [ %0.6f, %0.6f ]\r\n";
569 if(
m_debug) printf(
"<%s>: D2 wasn't calculated. ECF# variables are not available.\r\n",
APP_NAME);
574 buffer =
"<%s>: Jet %s the D2 cut from %s\r\n\tD2: %0.6f\r\n\tCut: %0.6f\r\n";
586 if(
m_verbose) printf(
"<%s>: No D2 cut has been requested here. The cut direction specified was %s which is not 'LEFT' or 'RIGHT'.\r\n",
APP_NAME,
m_D2_cut_direction.c_str());
591 return static_cast<int>((pass_mass << 2)|(pass_d2 << 1)|(pass_btag << 0));
596 std::vector<const xAOD::Jet*> associated_trackJets;
598 (*
s_parent(
jet))->getAssociatedObjects<xAOD::Jet>(
"GhostAntiKt2TrackJet", associated_trackJets);
601 std::vector<const xAOD::Jet*> bTagged_trackJets;
602 for(
const auto& trackJet: associated_trackJets){
603 if(
m_isB(*trackJet) == 0)
continue;
604 bTagged_trackJets.push_back(trackJet);
606 return bTagged_trackJets;
610 std::vector<const xAOD::Muon*> muons;
613 for(
const auto& muonLink : muonsLink) {
614 if(!muonLink.isValid()) {
615 muons.push_back(
nullptr);
618 muons.push_back(
static_cast<const xAOD::Muon*
>(*muonLink));