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,
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);
97 m_bad_configuration |= true;
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());
103 m_bad_configuration |= true;
105 if(m_verbose) printf(
"<%s>: Valid working point requested.\r\n", APP_NAME);
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());
111 m_bad_configuration |= true;
113 if(m_verbose) printf(
"<%s>: Valid boson type requested.\r\n", APP_NAME);
122 bool found_configuration =
false;
128 printf(
"<%s>: Recommendations file could not be found.\r\n\tGiven: %s\r\n", APP_NAME, m_recommendations_file.c_str());
129 m_bad_configuration |= true;
131 if(m_verbose) printf(
"<%s>: Recommendations file was found.\r\n", APP_NAME);
135 f_in.open(m_recommendations_file, std::ios::in);
137 printf(
"<%s>: Something is wrong with the recommendations file. Could not open for reading.\r\n", APP_NAME);
138 m_bad_configuration |= true;
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;
156 if(m_verbose) printf(
"<%s>: Reading in line\r\n\t'%s'\r\n", APP_NAME, line.c_str());
157 if(lineDetails[0] != m_boson_type) continue;
158 if(lineDetails[1] != m_working_point) continue;
159 if(lineDetails[2] != m_algorithm_name) continue;
160 if(std::stoi(lineDetails[3]) != m_num_bTags) continue;
162 m_bTagCut = std::stof(lineDetails[4]);
163 m_bTagCutCharm = std::stof(lineDetails[5]);
164 m_massMin = std::stof(lineDetails[6]);
165 m_massMax = std::stof(lineDetails[7]);
166 for(int i=0; i < 5; i++)
167 m_D2_params[i] = std::stof(lineDetails[i+8]);
168 m_D2_cut_direction = lineDetails[13];
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);
179 m_bad_configuration |=
true;
182 if(m_bad_configuration){
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)
233 + std::to_string(
static_cast<int>(size_parameter*10))
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);
251 algorithm_name +=
"F" + std::to_string(
static_cast<int>(
s_PtFrac(
jet)*100))
252 +
"R" + std::to_string(
static_cast<int>(
s_RClus(
jet)*100));
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);
265 algorithm_name +=
"R" + std::to_string(
static_cast<int>(
s_RCut(
jet)*100))
266 +
"Z" + std::to_string(
static_cast<int>(
s_ZCut(
jet)*100));
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);
287 algorithm_name +=
"M" + std::to_string(
static_cast<int>(
s_MuMax(
jet)*100))
288 +
"R" + std::to_string(
static_cast<int>(
s_RClus(
jet)*100))
289 +
"Y" + std::to_string(
static_cast<int>(
s_YMin(
jet)*100));
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()){
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));
std::pair< std::vector< unsigned int >, bool > res
DataVector< IParticle > IParticleContainer
std::string PathResolverFindXMLFile(const std::string &logical_file_name)
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
bool isValid() const
Test to see if the link can be dereferenced.
const SG::AuxElement::Decorator< TLorentzVector > m_correctedJetDecor
static const SG::AuxElement::ConstAccessor< int > s_TransformType
std::string m_algorithm_name
std::vector< const xAOD::Muon * > get_matched_muons(const xAOD::Jet &jet) const
std::vector< float > m_D2_params
std::vector< const xAOD::Jet * > get_bTagged_trackJets(const xAOD::Jet &jet) const
static const SG::AuxElement::ConstAccessor< float > s_RClus
TLorentzVector get_correctedJet_TLV(const xAOD::Jet &jet) const
static const SG::AuxElement::ConstAccessor< ElementLink< xAOD::JetContainer > > s_parent
std::string m_D2_cut_direction
static const SG::AuxElement::ConstAccessor< float > s_RCut
static const SG::AuxElement::ConstAccessor< float > s_SizeParameter
std::pair< bool, std::string > get_algorithm_name(const xAOD::Jet &jet, const xAOD::JetAlgorithmType::ID jet_algorithm, const float size_parameter, const xAOD::JetInput::Type jet_input, const xAOD::JetTransform::Type jet_transform) const
static const SG::AuxElement::ConstAccessor< float > s_ECF2
static const SG::AuxElement::ConstAccessor< int > s_InputType
std::string m_working_point
std::pair< float, std::string > get_D2_pivot(const xAOD::Jet &jet) const
static const SG::AuxElement::ConstAccessor< float > s_PtFrac
const SG::AuxElement::Decorator< std::pair< float, float > > m_massWindow
static const SG::AuxElement::ConstAccessor< char > s_BDRS
const SG::AuxElement::Decorator< int > m_isB
static const SG::AuxElement::ConstAccessor< int > s_AlgorithmType
std::unique_ptr< CP::MuonSelectionTool > m_muonSelectionTool
const SG::AuxElement::Decorator< std::vector< ElementLink< xAOD::IParticleContainer > > > m_matchedMuonsLink
std::string m_decor_prefix
const SG::AuxElement::Decorator< std::pair< float, std::string > > m_D2Pivot
int result(const xAOD::Jet &jet, const xAOD::MuonContainer *muons) const
static const SG::AuxElement::ConstAccessor< float > s_MuMax
static const SG::AuxElement::ConstAccessor< float > s_ZCut
std::string m_recommendations_file
static const SG::AuxElement::ConstAccessor< float > s_ECF3
static const SG::AuxElement::ConstAccessor< float > s_D2
BoostedXbbTag(const std::string &working_point="medium", const std::string &recommendations_file="JetSubStructureUtils/data/config_13TeV_Htagging_MC15c_77WP_20160522.dat", const std::string &boson_type="Higgs", const std::string &algorithm_name="AK10LCTRIMF5R20", int num_bTags=2, const std::string &decor_prefix="", bool debug=false, bool verbose=false)
std::pair< float, float > get_mass_window(const xAOD::Jet &jet) const
static const SG::AuxElement::ConstAccessor< float > s_YMin
static const SG::AuxElement::ConstAccessor< float > s_ECF1
SG::ConstAccessor< T, ALLOC > ConstAccessor
bool MVx_discriminant(const std::string &taggername, double &value) const
Class providing the definition of the 4-vector interface.
std::vector< const T * > getAssociatedObjects(const std::string &name) const
get associated objects as a vector<object> this compact form throws an exception if the object is not...
Select isolated Photons, Electrons and Muons.
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.
const BTagging * getBTagging(const SG::AuxElement &part)
Access the default xAOD::BTagging object associated to an object.
ID
//////////////////////////////////////// JetAlgorithmType::ID defines most common physics jet finding...
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Jet_v1 Jet
Definition of the current "jet version".
BTagging_v1 BTagging
Definition of the current "BTagging version".
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".