Skip to content

Commit

Permalink
Merge pull request #11502 from cms-btv-pog/JetFlavorFixes_from-CMSSW_…
Browse files Browse the repository at this point in the history
…7_5_3

Flavor bugfix in jetTools.py (75X)
  • Loading branch information
davidlange6 committed Nov 10, 2015
2 parents 4900c4c + 58c7c4c commit a078f9b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 23 deletions.
10 changes: 6 additions & 4 deletions PhysicsTools/JetExamples/test/printJetFlavourInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@
subjets = cms.InputTag("ak8PFJetsPruned", "SubJets"),
bHadrons = cms.InputTag("selectedHadronsAndPartons","bHadrons"),
cHadrons = cms.InputTag("selectedHadronsAndPartons","cHadrons"),
partons = cms.InputTag("selectedHadronsAndPartons","partons"),
partons = cms.InputTag("selectedHadronsAndPartons","algorithmicPartons"),
leptons = cms.InputTag("selectedHadronsAndPartons","leptons"),
jetAlgorithm = cms.string("AntiKt"),
rParam = cms.double(0.8),
ghostRescaling = cms.double(1e-18),
hadronFlavourHasPriority = cms.bool(True)
hadronFlavourHasPriority = cms.bool(False)
)

process.printEventAK8PFJets = cms.EDAnalyzer("printJetFlavourInfo",
Expand Down Expand Up @@ -109,11 +110,12 @@
subjets = cms.InputTag("caHEPTopTagJets", "caTopSubJets"),
bHadrons = cms.InputTag("selectedHadronsAndPartons","bHadrons"),
cHadrons = cms.InputTag("selectedHadronsAndPartons","cHadrons"),
partons = cms.InputTag("selectedHadronsAndPartons","partons"),
partons = cms.InputTag("selectedHadronsAndPartons","algorithmicPartons"),
leptons = cms.InputTag("selectedHadronsAndPartons","leptons"),
jetAlgorithm = cms.string("CambridgeAachen"),
rParam = cms.double(1.5),
ghostRescaling = cms.double(1e-18),
hadronFlavourHasPriority = cms.bool(True)
hadronFlavourHasPriority = cms.bool(False)
)

process.printEventCA15PFJets = cms.EDAnalyzer("printJetFlavourInfo",
Expand Down
24 changes: 13 additions & 11 deletions PhysicsTools/JetMCAlgos/plugins/JetFlavourClustering.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* \brief Clusters hadrons, partons, and jet contituents to determine the jet flavour
*
* This producer clusters hadrons, partons and jet contituents to determine the jet flavour. The jet flavour information
* is stored in the event as an AssociationVector which associates an object of type JetFlavorInfo to each of the jets.
* is stored in the event as an AssociationVector which associates an object of type JetFlavourInfo to each of the jets.
*
* The producer takes as input jets and hadron and partons selected by the HadronAndPartonSelector producer. The hadron
* and parton four-momenta are rescaled by a very small number (default rescale factor is 10e-18) which turns them into
Expand All @@ -30,38 +30,40 @@
* - jet is considered a c jet if there is at least one c and no b "ghost" partons clustered inside it (partonFlavour = 4)
*
* - jet is considered a light-flavour jet if there are light-flavour and no b or c "ghost" partons clustered inside it.
* The jet is assigned the flavour of the hardest light-flavour "ghost" parton clustered inside it (partonFlavour = 1,2,3, or 21)
* The jet is assigned the flavour of the hardest light-flavour "ghost" parton clustered inside it (partonFlavour = 1, 2, 3, or 21)
*
* - jet has an undefined flavour if there are no "ghost" partons clustered inside it (partonFlavour = 0)
*
* In rare instances a conflict between the hadron- and parton-based flavours can occur. In such cases it is possible to
* keep both flavours or to give priority to the hadron-based flavour. This is controlled by the 'hadronFlavourHasPriority'
* switch which is enabled by default. The priority is given to the hadron-based flavour as follows:
* switch. The priority is given to the hadron-based flavour as follows:
*
* - if hadronFlavour==0 && (partonFlavour==4 || partonFlavour==5): partonFlavour is set to the flavour of the hardest
* light-flavour parton clustered inside the jet if such parton exists. Otherwise, the parton flavour is left undefined
*
* - if hadronFlavour!=0 && hadronFlavour!=partonFlavour: partonFlavour is set equal to hadronFlavour
*
* The producer is also capable of assigning the flavor to subjets of fat jets, in which case it produces an additional
* AssociationVector providing the flavour information for subjets. In order to assign the flavor to subjets, three input
* The producer is also capable of assigning the flavour to subjets of fat jets, in which case it produces an additional
* AssociationVector providing the flavour information for subjets. In order to assign the flavour to subjets, three input
* jet collections are required:
*
* - jets, in this case represented by fat jets
*
* - groomed jets, which is a collection of fat jets from which the subjets are derived
* - groomed jets, which is a collection of fat jets from which the subjets are derived (e.g. pruned, filtered, soft drop, top-tagged, etc. jets)
*
* - subjets, derived from the groomed fat jets
*
* The "ghost" hadrons and partons clustered inside a fat jet are assigned to the closest subjet in the rapidity-phi
* space. Once hadrons and partons have been assigned to subjets, the subjet flavor is determined in the same way as for
* space. Once hadrons and partons have been assigned to subjets, the subjet flavour is determined in the same way as for
* jets. The reason for requiring three jet collections as input in order to determine the subjet flavour is to avoid
* possible inconsistencies between the fat jet and subjet flavours (such as a non-b fat jet having a b subjet and vice
* versa) as well as the fact that reclustering the constituents of groomed fat jets will generally result in a jet
* collection different from the input groomed fat jets.
* versa) as well as the fact that re-clustering the constituents of groomed fat jets will generally result in a jet
* collection different from the input groomed fat jets. Also note that "ghost" particles generally cannot be clustered
* inside subjets in the same way this is done for fat jets. This is because some of the jet grooming techniques could
* reject such very soft particle. So instead, the "ghost" particles are assigned to the closest subjet.
*
* In addition, "ghost" leptons can also be clustered inside jets but they are not used in any way to determine the jet
* flavor. This functionality is disabled by default.
* Finally, "ghost" leptons can also be clustered inside jets but they are not used in any way to determine the jet
* flavour. This functionality is optional and is potentially useful to identify jets from hadronic taus.
*
* For more details, please refer to
* https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideBTagMCTools
Expand Down
20 changes: 15 additions & 5 deletions PhysicsTools/JetMCAlgos/src/Pythia8PartonSelector.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

/**
* This is a Pythia8-specific parton selector that selects all status==71 or 72 partons. An explanation of
* the particle status codes returned by Pythia8 can be found in Pythia8 online manual
* (http://home.thep.lu.se/~torbjorn/pythia81html/ParticleProperties.html).
* This is a Pythia8-specific parton selector that selects all partons that don't have other partons as daughters, i.e., partons
* from the end of the parton showering sequence. An explanation of the particle status codes returned by Pythia8 can be found in
* Pythia8 online manual (http://home.thep.lu.se/~torbjorn/pythia81html/ParticleProperties.html).
*/

#include "PhysicsTools/JetMCAlgos/interface/Pythia8PartonSelector.h"
Expand All @@ -25,10 +25,20 @@ Pythia8PartonSelector::run(const edm::Handle<reco::GenParticleCollection> & part
for(reco::GenParticleCollection::const_iterator it = particles->begin(); it != particles->end(); ++it)
{
int status = it->status();
if( !(status==71 || status==72) ) continue; // only accept status==71 or 72 particles
if( status==1 ) continue; // skip stable particles
if( status==2 ) continue; // skip decayed Standard Model hadrons and leptons
if( !CandMCTagUtils::isParton( *it ) ) continue; // skip particle if not a parton

partons->push_back( reco::GenParticleRef( particles, it - particles->begin() ) );
// check if the parton has other partons as daughters
int nparton_daughters = 0;
for(unsigned i=0; i<it->numberOfDaughters(); ++i)
{
if( CandMCTagUtils::isParton( *(it->daughter(i)) ) )
++nparton_daughters;
}

if( nparton_daughters==0 )
partons->push_back( reco::GenParticleRef( particles, it - particles->begin() ) );
}

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"keep abs(pdgId) == 23 || abs(pdgId) == 24 || abs(pdgId) == 25 || abs(pdgId) == 6 || abs(pdgId) == 37 ", # keep VIP(articles)s
"keep abs(pdgId) == 310 && abs(eta) < 2.5 && pt > 1 ", # keep K0
# keep heavy flavour quarks for parton-based jet flavour
"keep (4 <= abs(pdgId) <= 5) & (status = 2 || status = 11 || status = 71 || status = 72)",
"keep (4 <= abs(pdgId) <= 5)",
# keep light-flavour quarks and gluons for parton-based jet flavour
"keep (1 <= abs(pdgId) <= 3 || pdgId = 21) & (status = 2 || status = 11 || status = 71 || status = 72) && pt>5",
# keep b and c hadrons for hadron-based jet flavour
Expand Down
4 changes: 2 additions & 2 deletions PhysicsTools/PatAlgos/python/tools/jetTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def toolCode(self, process):
_newPatJetFlavourAssociation.rParam=rParam
_newPatJetFlavourAssociation.bHadrons=cms.InputTag("patJetPartons"+postfix,"bHadrons")
_newPatJetFlavourAssociation.cHadrons=cms.InputTag("patJetPartons"+postfix,"cHadrons")
_newPatJetFlavourAssociation.partons=cms.InputTag("patJetPartons"+postfix,"physicsPartons")
_newPatJetFlavourAssociation.partons=cms.InputTag("patJetPartons"+postfix,"algorithmicPartons")
_newPatJetFlavourAssociation.leptons=cms.InputTag("patJetPartons"+postfix,"leptons")
else :
setattr(process, 'patJetFlavourAssociation'+_labelName+postfix,
Expand All @@ -328,7 +328,7 @@ def toolCode(self, process):
rParam=rParam,
bHadrons = cms.InputTag("patJetPartons"+postfix,"bHadrons"),
cHadrons = cms.InputTag("patJetPartons"+postfix,"cHadrons"),
partons = cms.InputTag("patJetPartons"+postfix,"physicsPartons"),
partons = cms.InputTag("patJetPartons"+postfix,"algorithmicPartons"),
leptons = cms.InputTag("patJetPartons"+postfix,"leptons")
)
)
Expand Down

0 comments on commit a078f9b

Please sign in to comment.