CMS 3D CMS Logo

List of all members | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
GenHFHadronMatcher Class Reference

Finds the origin of each heavy flavour hadron and associated jets to it. More...

#include <GenHFHadronMatcher.cc>

Inheritance diagram for GenHFHadronMatcher:
edm::global::EDProducer<> edm::global::EDProducerBase edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Public Member Functions

 GenHFHadronMatcher (const edm::ParameterSet &)
 
 ~GenHFHadronMatcher () override
 
- Public Member Functions inherited from edm::global::EDProducer<>
 EDProducer ()=default
 
bool hasAbilityToProduceInLumis () const final
 
bool hasAbilityToProduceInRuns () const final
 
bool wantsGlobalLuminosityBlocks () const final
 
bool wantsGlobalRuns () const final
 
bool wantsStreamLuminosityBlocks () const final
 
bool wantsStreamRuns () const final
 
- Public Member Functions inherited from edm::global::EDProducerBase
 EDProducerBase ()
 
ModuleDescription const & moduleDescription () const
 
 ~EDProducerBase () override
 
- Public Member Functions inherited from edm::ProducerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
std::vector< edm::ProductResolverIndex > const & indiciesForPutProducts (BranchType iBranchType) const
 
 ProducerBase ()
 
std::vector< edm::ProductResolverIndex > const & putTokenIndexToProductResolverIndex () const
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
std::function< void(BranchDescription const &)> registrationCallback () const
 used by the fwk to register list of products More...
 
void resolvePutIndicies (BranchType iBranchType, ModuleToResolverIndicies const &iIndicies, std::string const &moduleLabel)
 
 ~ProducerBase () noexcept(false) override
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
void convertCurrentProcessAlias (std::string const &processName)
 Convert "@currentProcess" in InputTag process names to the actual current process name. More...
 
 EDConsumerBase ()
 
 EDConsumerBase (EDConsumerBase const &)=delete
 
 EDConsumerBase (EDConsumerBase &&)=default
 
ESProxyIndex const * esGetTokenIndices (edm::Transition iTrans) const
 
ProductResolverIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
 
std::vector< ProductResolverIndexAndSkipBit > const & itemsToGetFrom (BranchType iType) const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesWhoseProductsAreConsumed (std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
 
EDConsumerBase const & operator= (EDConsumerBase const &)=delete
 
EDConsumerBaseoperator= (EDConsumerBase &&)=default
 
bool registeredToConsume (ProductResolverIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
ProductResolverIndexAndSkipBit uncheckedIndexFrom (EDGetToken) const
 
void updateLookup (BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
 
void updateLookup (eventsetup::ESRecordsToProxyIndices const &)
 
virtual ~EDConsumerBase () noexcept(false)
 

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)
 description of the run-time parameters More...
 
- Static Public Member Functions inherited from edm::global::EDProducerBase
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 

Private Member Functions

int analyzeMothers (const reco::Candidate *thisParticle, int &topDaughterQId, int &topBarDaughterQId, std::vector< const reco::Candidate * > &hadMothers, std::vector< std::vector< int > > &hadMothersIndices, std::set< const reco::Candidate * > *analyzedParticles, const int prevPartIndex) const
 do a recursive search for the mother particles until the b-quark is found or the absolute mother is found More...
 
bool checkForLoop (std::vector< const reco::Candidate * > &particleChain, const reco::Candidate *particle) const
 
std::vector< int > findHadronJets (const reco::GenParticleCollection *genParticles, const reco::JetFlavourInfoMatchingCollection *jetFlavourInfos, std::vector< int > &hadIndex, std::vector< reco::GenParticle > &hadMothersGenPart, std::vector< std::vector< int > > &hadMothersIndices, std::vector< int > &hadLeptonIndex, std::vector< int > &hadLeptonHadIndex, std::vector< int > &hadLeptonViaTau, std::vector< int > &hadFlavour, std::vector< int > &hadFromTopWeakDecay, std::vector< int > &hadBHadronId) const
 identify the jets that contain b-hadrons More...
 
int findInMothers (int idx, std::vector< int > &mothChains, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose) const
 helper function to find indices of particles with particular pdgId and status from the list of mothers of a given particle More...
 
bool fixExtraSameFlavours (const unsigned int hadId, const std::vector< int > &hadIndices, const std::vector< reco::GenParticle > &hadMothers, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< int > &isFromTopWeakDecay, const std::vector< std::vector< int > > &LastQuarkIds, const std::vector< std::vector< int > > &LastQuarkMotherIds, std::vector< int > &lastQuarkIndices, std::vector< int > &hadronFlavour, std::set< int > &checkedHadronIds, const int lastQuarkIndex) const
 
int flavourSign (const int pdgId) const
 Sign of the flavour (matter/antimatter) More...
 
std::string getParticleName (int id) const
 
bool hasHadronDaughter (const int flavour, const reco::Candidate *thisParticle) const
 Check if the particle has bHadron among daughters. More...
 
int idInList (std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle) const
 Check if the cpecified particle is already in the list of particles. More...
 
int idInList (std::vector< int > list, const int value) const
 
bool isBaryonPdgId (const int flavour, const int pdgId) const
 Check the pdgId if it represents a baryon of particular flavour. More...
 
bool isHadron (const int flavour, const reco::Candidate *thisParticle) const
 Check the pdgId of a given particle if it is a hadron. More...
 
bool isHadronPdgId (const int flavour, const int pdgId) const
 Check the pdgId if it represents a hadron of particular flavour. More...
 
bool isMesonPdgId (const int flavour, const int pdgId) const
 Check the pdgId if it represents a meson of particular flavour. More...
 
bool isNeutralPdg (int pdgId) const
 Check whether a given pdgId represents neutral particle. More...
 
void produce (edm::StreamID, edm::Event &, const edm::EventSetup &) const override
 
bool putMotherIndex (std::vector< std::vector< int > > &hadMothersIndices, int partIndex, int mothIndex) const
 puts mother index to the list of mothers of particle, if it isn't there already More...
 

Private Attributes

const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
 
const int flavour_
 
const std::string flavourStr_
 
const edm::EDPutTokenT< std::vector< int > > flavourToken_
 
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
 
const edm::EDGetTokenT< reco::GenParticleCollectiongenParticlesToken_
 
const edm::EDPutTokenT< std::vector< int > > indexToken_
 
const edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollectionjetFlavourInfosToken_
 
const edm::EDPutTokenT< std::vector< int > > jetIndexToken_
 
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
 
const edm::EDPutTokenT< std::vector< int > > leptonIndexToken_
 
const edm::EDPutTokenT< std::vector< int > > leptonViaTauToken_
 
const bool noBBbarResonances_
 
const bool onlyJetClusteredHadrons_
 
const edm::EDPutTokenT< std::vector< std::vector< int > > > plusMothersIndicesToken_
 
const edm::EDPutTokenT< std::vector< reco::GenParticle > > plusMothersToken_
 

Additional Inherited Members

- Public Types inherited from edm::global::EDProducerBase
typedef EDProducerBase ModuleType
 
- Public Types inherited from edm::ProducerBase
using ModuleToResolverIndicies = std::unordered_multimap< std::string, std::tuple< edm::TypeID const *, const char *, edm::ProductResolverIndex >>
 
typedef ProductRegistryHelper::TypeLabelList TypeLabelList
 
- Public Types inherited from edm::EDConsumerBase
typedef ProductLabels Labels
 
- Protected Member Functions inherited from edm::EDConsumerBase
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > consumes (edm::InputTag const &tag)
 
EDGetToken consumes (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken consumes (TypeToGet const &id, edm::InputTag const &tag)
 
ConsumesCollector consumesCollector ()
 Use a ConsumesCollector to gather consumes information from helper functions. More...
 
template<typename ProductType , BranchType B = InEvent>
void consumesMany ()
 
void consumesMany (const TypeToGet &id)
 
template<BranchType B>
void consumesMany (const TypeToGet &id)
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes ()
 
template<typename ESProduct , typename ESRecord , Transition Tr = Transition::Event>
auto esConsumes (ESInputTag const &tag)
 
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > mayConsume (edm::InputTag const &tag)
 
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 

Detailed Description

Finds the origin of each heavy flavour hadron and associated jets to it.

Starting from each consituent of each jet, tracks back in chain to find heavy flavour hadrons. From each hadron traces back until finds the b quark and its mother. For each hadron identifies the jet to which it was injected as a ghost hadron.

The description of the run-time parameters can be found at fillDescriptions()

The description of the products can be found at GenHFHadronMatcher()

Definition at line 56 of file GenHFHadronMatcher.cc.

Constructor & Destructor Documentation

GenHFHadronMatcher::GenHFHadronMatcher ( const edm::ParameterSet cfg)
explicit

Definition at line 152 of file GenHFHadronMatcher.cc.

References funct::abs(), bHadronIdToken_, looper::cfg, flavour_, flavourStr_, flavourToken_, fromTopWeakDecayToken_, edm::ParameterSet::getParameter(), indexToken_, jetIndexToken_, leptonHadronIndexToken_, leptonIndexToken_, leptonViaTauToken_, noBBbarResonances_, onlyJetClusteredHadrons_, plusMothersIndicesToken_, and plusMothersToken_.

152  :
153 genParticlesToken_(consumes<reco::GenParticleCollection>(cfg.getParameter<edm::InputTag>("genParticles"))),
154 jetFlavourInfosToken_(consumes<reco::JetFlavourInfoMatchingCollection>(cfg.getParameter<edm::InputTag>("jetFlavourInfos"))),
155 flavour_{std::abs(cfg.getParameter<int> ( "flavour" ))},
156 noBBbarResonances_{cfg.getParameter<bool> ( "noBBbarResonances" )},
157 onlyJetClusteredHadrons_{cfg.getParameter<bool> ( "onlyJetClusteredHadrons" )},
158 flavourStr_{flavourName(flavour_)},
159 plusMothersToken_{produces< std::vector<reco::GenParticle> > ( "gen"+flavourStr_+"HadPlusMothers" )}, // All mothers in all decay chains above any hadron of specified flavour
160 plusMothersIndicesToken_{produces< std::vector< std::vector<int> > > ( "gen"+flavourStr_+"HadPlusMothersIndices" )}, // Indices of mothers of each hadMother
161 indexToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadIndex" )}, // Index of hadron in the vector of hadMothers
162 flavourToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadFlavour" )}, // PdgId of the first non-b(c) quark mother with sign corresponding to hadron charge
163 jetIndexToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadJetIndex" )}, // Index of genJet matched to each hadron by jet clustering algorithm
164 leptonIndexToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonIndex" )}, // Index of lepton found among the hadron decay products in the list of mothers
165 leptonHadronIndexToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonHadronIndex" )}, // Index of hadron the lepton is associated to
166 leptonViaTauToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonViaTau" )}, // Whether lepton comes directly from hadron or via tau decay
167 fromTopWeakDecayToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadFromTopWeakDecay" )}, // Tells whether the hadron appears in the chain after top decay
168 bHadronIdToken_{produces< std::vector<int> > ( "gen"+flavourStr_+"HadBHadronId" )} // Index of a b-hadron which the current hadron comes from (for c-hadrons)
169 {
170  // Hadron matching products
171 }
T getParameter(std::string const &) const
const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
const edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
const edm::EDPutTokenT< std::vector< int > > leptonIndexToken_
const edm::EDPutTokenT< std::vector< reco::GenParticle > > plusMothersToken_
const edm::EDPutTokenT< std::vector< int > > leptonViaTauToken_
const std::string flavourStr_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const edm::EDPutTokenT< std::vector< int > > indexToken_
const bool onlyJetClusteredHadrons_
const edm::EDPutTokenT< std::vector< std::vector< int > > > plusMothersIndicesToken_
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
const edm::EDPutTokenT< std::vector< int > > jetIndexToken_
const edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
const edm::EDPutTokenT< std::vector< int > > flavourToken_
GenHFHadronMatcher::~GenHFHadronMatcher ( )
override

Definition at line 173 of file GenHFHadronMatcher.cc.

174 {
175 }

Member Function Documentation

int GenHFHadronMatcher::analyzeMothers ( const reco::Candidate thisParticle,
int &  topDaughterQId,
int &  topBarDaughterQId,
std::vector< const reco::Candidate * > &  hadMothers,
std::vector< std::vector< int > > &  hadMothersIndices,
std::set< const reco::Candidate * > *  analyzedParticles,
const int  prevPartIndex 
) const
private

do a recursive search for the mother particles until the b-quark is found or the absolute mother is found

the treatment of b-bar resonances depends on the global parameter noBBbarResonances_

Parameters
[in]thisParticlecurrent particle from which starts the search of the hadron and all its mothers up to proton
[out]hadronthe last hadron in the decay chain [that decays weekly]
[out]leptonlepton found in the current decay chain
[out]topDaughterQIdId of the top quark daughter b(c) quark
[out]topBarDaughterQIdId of the antitop quark daughter b(c) quark
[out]hadMotherslist of all processed particles ending with proton
[out]hadMothersIndiceslist of i-vectors containing j-indices representing particles that are mothers of each i-particle from hadMothers
[out]analyzedParticleslist of particles analysed in the chain [used for infinite loop detection]
[out]prevPartIndexindex of the previous particle in the current chain [used for infinite loop detection]
Returns
index of hadron in the hadMothers list [-1 if no hadron found]

Definition at line 614 of file GenHFHadronMatcher.cc.

References funct::abs(), mps_fire::i, idInList(), reco::Candidate::mother(), reco::Candidate::numberOfMothers(), reco::Candidate::pdgId(), reco::Candidate::pt(), and putMotherIndex().

Referenced by findHadronJets().

615 {
616  // Getting the index of the particle which is a hadron in the first call
617  int hadronIndex=-1; // Index of the hadron that is returned by this function
618  int index = idInList( hadMothers, thisParticle );
619  if ( index<0 ) { // If hadron is not in the list of mothers yet
620  hadMothers.push_back ( thisParticle );
621  hadronIndex=hadMothers.size()-1;
622  } else { // If hadron is in the list of mothers already
623  hadronIndex=index;
624  }
625 
626  int partIndex = -1; // Index of particle being checked in the list of mothers
627  partIndex = idInList( hadMothers, thisParticle );
628 
629  // Checking whether this particle is already in the chain of analyzed particles in order to identify a loop
630  bool isLoop = false;
631  if ( !analyzedParticles ) {
632  analyzedParticles = new std::set<const reco::Candidate*>;
633  }
634  for ( unsigned int i=0; i<analyzedParticles->size(); i++ ) {
635  if ( analyzedParticles->count ( thisParticle ) <=0 ) {
636  continue;
637  }
638  isLoop = true;
639  break;
640  }
641 
642  // If a loop has been detected
643  if ( isLoop ) {
644  if ( prevPartIndex>=0 ) {
645  putMotherIndex ( hadMothersIndices, prevPartIndex, -1 ); // Setting mother index of previous particle to -1
646  }
647  return hadronIndex; // Stopping further processing of the current chain
648  }
649  analyzedParticles->insert ( thisParticle );
650 
651  // Putting the mothers to the list of mothers
652  for ( size_t iMother = 0; iMother < thisParticle->numberOfMothers(); ++iMother ) {
653  const reco::Candidate* mother = thisParticle->mother ( iMother );
654  int mothIndex = idInList( hadMothers, mother );
655  if ( mothIndex == partIndex && partIndex>=0 ) {
656  continue; // Skipping the mother that is its own daughter
657  }
658 
659  // If this mother isn't yet in the list and hadron or lepton is in the list
660  if ( mothIndex<0 ) {
661  hadMothers.push_back ( mother );
662  mothIndex=hadMothers.size()-1;
663  }
664  // If hadron has already been found in current chain and the mother isn't a duplicate of the particle being checked
665  if ( mothIndex!=partIndex && partIndex>=0 ) {
666  putMotherIndex ( hadMothersIndices, partIndex, mothIndex ); // Putting the index of mother for current particle
667  }
668  analyzeMothers ( mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex );
669  // Setting the id of the particle which is a quark from the top decay
670  if(std::abs(mother->pdgId())==6) {
671  int& bId = mother->pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
672  int thisFlav = std::abs(thisParticle->pdgId());
673  if( bId<0){
674  if(thisFlav <= 5) bId = partIndex;
675  } else {
676  int bIdFlav = std::abs(hadMothers.at(bId)->pdgId());
677  if( bIdFlav != 5 && thisFlav == 5) bId = partIndex;
678  else if( thisFlav == 5 && thisParticle->pt() > hadMothers.at(bId)->pt() ) bId = partIndex;
679  } // If daughter quark of the top not found yet
680  } // If the mother is a top quark and hadron has been found
681  } // End of loop over mothers
682 
683  analyzedParticles->erase ( thisParticle ); // Removing current particle from the current chain that is being analyzed
684 
685  if ( partIndex<0 ) {
686  return hadronIndex; // Safety check
687  }
688 
689  // Adding -1 to the list of mother indices for current particle if it has no mothers (for consistency between numbering of indices and mothers)
690  if ( (int)thisParticle->numberOfMothers() <=0) {
691  putMotherIndex ( hadMothersIndices, partIndex, -1 );
692  }
693 
694  return hadronIndex;
695 
696 }
int analyzeMothers(const reco::Candidate *thisParticle, int &topDaughterQId, int &topBarDaughterQId, std::vector< const reco::Candidate * > &hadMothers, std::vector< std::vector< int > > &hadMothersIndices, std::set< const reco::Candidate * > *analyzedParticles, const int prevPartIndex) const
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
int idInList(std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle) const
Check if the cpecified particle is already in the list of particles.
virtual int pdgId() const =0
PDG identifier.
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual double pt() const =0
transverse momentum
bool putMotherIndex(std::vector< std::vector< int > > &hadMothersIndices, int partIndex, int mothIndex) const
puts mother index to the list of mothers of particle, if it isn&#39;t there already
bool GenHFHadronMatcher::checkForLoop ( std::vector< const reco::Candidate * > &  particleChain,
const reco::Candidate particle 
) const
private
void GenHFHadronMatcher::fillDescriptions ( edm::ConfigurationDescriptions descriptions)
static

description of the run-time parameters

Definition at line 183 of file GenHFHadronMatcher.cc.

References edm::ConfigurationDescriptions::add(), edm::ParameterSetDescription::add(), funct::false, and funct::true.

184 {
186  desc.add<edm::InputTag>("genParticles")->setComment( "Collection of GenParticle objects which contains all particles produced in the event" );
187  desc.add<edm::InputTag>("jetFlavourInfos")->setComment( "Output from the JetFlavour tool. Contains information about partons/hadrons/leptons associated to jets" );
188  desc.add<bool> ( "noBBbarResonances",true )->setComment ( "Whether resonances should not be treated as hadrons" );
189  desc.add<bool> ( "onlyJetClusteredHadrons",false )->setComment ( "Whether only hadrons that are matched to jets should be analysed. Runs x1000 faster in Sherpa" );
190  desc.add<int> ( "flavour",5 )->setComment ( "Flavour of weakly decaying hadron that should be analysed (4-c, 5-b)" );
191  descriptions.add ( "matchGenHFHadron",desc );
192 }
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::vector< int > GenHFHadronMatcher::findHadronJets ( const reco::GenParticleCollection genParticles,
const reco::JetFlavourInfoMatchingCollection jetFlavourInfos,
std::vector< int > &  hadIndex,
std::vector< reco::GenParticle > &  hadMothers,
std::vector< std::vector< int > > &  hadMothersIndices,
std::vector< int > &  hadLeptonIndex,
std::vector< int > &  hadLeptonHadIndex,
std::vector< int > &  hadLeptonViaTau,
std::vector< int > &  hadFlavour,
std::vector< int > &  hadFromTopWeakDecay,
std::vector< int > &  hadBHadronId 
) const
private

identify the jets that contain b-hadrons

For each hadron all mothers from all levels and chains are analysed to find the quark or gluon from which the hadron has originated. This is done by searching through the generator particle decay tree starting from the hadron, performing checks for flavour and kinematic consistency. The hadrons that are not last in the decay chain (don't decay weakly) are skipped. Additionally for each hadron it is checked whether it comes from the top weak decay branch and whether it comes from some other b-hadron decay

b-bbar (c-cbar) resonances can either be considered as hadrons or not, depending on the configuration.

Parameters
[out]hadIndexvector of indices of found hadrons in hadMothers
[out]hadMothersvector of all mothers at all levels of each found hadron
[out]hadMothersIndicesconnection between each particle from hadMothers and its mothers
[out]hadLeptonIndexindex of lepton among the hadMothers
[out]hadLeptonHadIndexindex of hadron associated to each lepton
[out]hadLeptonViaTauwhether lepton is from direct hadron->lepton or hadron->tau->lepton
[out]hadFlavourflavour of each found hadron
[out]hadFromTopWeakDecaywhether each hadron contains the top quark in its decay chain [works only for B-Hadrons]
[out]hadBHadronIdfor each hadron - index of the ancestor b-hadron [-1 if hadron doesn't come from another b-hdaron]
Returns
vector of jet indices that were matched to each hadron [by the jet clustering algorithm]

Definition at line 261 of file GenHFHadronMatcher.cc.

References funct::abs(), analyzeMothers(), edm::AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper >::begin(), edm::RefVector< C, T, F >::begin(), boostedElectronIsolation_cff::deltaR, PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi::dR, edm::AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper >::end(), edm::RefVector< C, T, F >::end(), funct::false, spr::find(), findInMothers(), fixExtraSameFlavours(), flavour_, flavourSign(), reco::JetFlavourInfo::getbHadrons(), reco::JetFlavourInfo::getcHadrons(), jets_cff::hadronFlavour, hasHadronDaughter(), mps_fire::i, createfilelist::int, isHadron(), reco::CompositeRefCandidateT< D >::mother(), reco::Candidate::mother(), onlyJetClusteredHadrons_, or, common_cff::pdgId, reco::Candidate::pdgId(), and reco::LeafCandidate::pdgId().

Referenced by produce().

268 {
269  std::vector<int> hadJetIndex;
270  std::vector<const reco::Candidate*> hadMothersCand;
271 
272  int topDaughterQId = -1;
273  int topBarDaughterQId = -1;
274 
275  // Looping over all jets to get hadrons associated to them
276  for(reco::JetFlavourInfoMatchingCollection::const_iterator i_info = jetFlavourInfos->begin(); i_info != jetFlavourInfos->end(); ++i_info){
277  reco::JetFlavourInfo jetInfo = i_info->second;
278  const int jetIndex = i_info - jetFlavourInfos->begin();
279  // Looping over each hadron associated with the jet and finding its origin
280  const reco::GenParticleRefVector& hadronsInJet = flavour_==5 ? jetInfo.getbHadrons() : flavour_==4 ? jetInfo.getcHadrons() : reco::GenParticleRefVector();
281  for(reco::GenParticleRefVector::const_iterator hadron = hadronsInJet.begin(); hadron != hadronsInJet.end(); ++hadron) {
282  // Check that the hadron satisfies criteria configured in the module
283  if(!isHadron ( flavour_, (&**hadron) )) continue;
284  if(hasHadronDaughter ( flavour_, (reco::Candidate*)(&**hadron) )) continue;
285  // Scanning the chain starting from the hadron
286  int hadronIndex = analyzeMothers ( (reco::Candidate*)(&**hadron), topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, nullptr, -1 );
287  // Storing the index of the hadron to the list
288  hadIndex.push_back ( hadronIndex );
289  hadJetIndex.push_back ( jetIndex ); // Putting jet index to the result list
290  }
291  } // End of loop over jets
292 
293  // Access all hadrons which are not associated with jets, if requested
295  for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
296  const reco::GenParticle* thisParticle = &*i_particle;
297  if(!isHadron(flavour_, thisParticle)) continue;
298  // Skipping the hadron if it was already found directly from jets
299  if(std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end()) continue;
300 
301  // Scanning the chain starting from the hadron
302  int hadronIndex = analyzeMothers ( thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, nullptr, -1 );
303  // Storing the index of the hadron to the list
304  hadIndex.push_back ( hadronIndex );
305  hadJetIndex.push_back ( -1 ); // Jet index undefined
306  }
307  }
308 
309  // Transfering Candidates to the list of processed particles for further analysis
310  for ( int i=0; i< (int)hadMothersCand.size(); i++ ) {
311  const reco::GenParticle* particle = dynamic_cast<const reco::GenParticle*>( hadMothersCand.at(i) );
312  hadMothers.push_back(*particle);
313  }
314 
315  // Adding leptons from hadron decays
316  for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
317  const reco::GenParticle lepton = *i_particle;
318  const int pdg_abs = lepton.pdgId();
319  // Skipping if not a lepton: e/mu
320  if(pdg_abs != 11 && pdg_abs != 13) continue;
321  bool leptonViaTau = false;
322  const reco::Candidate* leptonMother = lepton.mother();
323  if(!leptonMother) continue;
324  // Taking next mother if direct mother is a tau
325  if(std::abs(leptonMother->pdgId()) == 15) {
326  leptonViaTau = true;
327  leptonMother = leptonMother->mother();
328  }
329  // Skipping this lepton if its mother is not a proper hadron
330  if(leptonMother == nullptr or !isHadron(flavour_, leptonMother)) continue;
331  // Finding the index of this hadron in the list of analysed particles
332  size_t leptonHadronParticleIndex = std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
333  if(leptonHadronParticleIndex >= hadMothersCand.size()) continue;
334  // Finding the actual hadron index among those that were found
335  size_t leptonHadronIndex = std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
336  if(leptonHadronIndex >= hadIndex.size()) continue;
337  // Putting the lepton, its index and hadron index to the corresponding lists
338  hadMothers.push_back(lepton);
339  const int leptonIndex = hadMothersCand.size()-1;
340  hadLeptonIndex.push_back(leptonIndex);
341  hadLeptonViaTau.push_back(leptonViaTau);
342  hadLeptonHadIndex.push_back(leptonHadronIndex);
343  }
344 
345  // Checking mothers of hadrons in order to assign flags (where the hadron comes from)
346  unsigned int nHad = hadIndex.size();
347 
348  std::vector<std::vector<int> > LastQuarkMotherIds;
349  std::vector<std::vector<int> > LastQuarkIds;
350  std::vector<int> lastQuarkIndices(nHad, -1);
351 
352  // Looping over all hadrons
353  for ( unsigned int hadNum=0; hadNum<nHad; hadNum++ ) {
354  unsigned int hadIdx = hadIndex.at(hadNum); // Index of hadron in the hadMothers
355 
356  std::vector <int> FirstQuarkId;
357  std::vector <int> LastQuarkId;
358  std::vector <int> LastQuarkMotherId;
359 
360  const int hadronFlavourSign = flavourSign( hadMothers.at(hadIdx).pdgId() );
361 
362  // Searching only first quark in the chain with the same flavour as hadron
363  if(hadronFlavourSign != 0) {
364  findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadronFlavourSign*flavour_, false, -1, 1, false );
365  }
366  // Searching for quarks with both flavours since it is a bb/cc resonance
367  else {
368  findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, flavour_, false, -1, 1, false );
369  findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, -1*flavour_, false, -1, 1, false );
370  }
371 
372  // Finding last quark for each first quark
373  for ( unsigned int qId=0; qId<FirstQuarkId.size(); qId++ ) {
374  // Identifying the flavour of the first quark to find the last quark of the same flavour
375  const int quarkFlavourSign = flavourSign( hadMothers.at(FirstQuarkId.at(qId)).pdgId() );
376  // Finding last quark of the hadron starting from the first quark
377  findInMothers( FirstQuarkId.at(qId), LastQuarkId, hadMothersIndices, hadMothers, 0, quarkFlavourSign*flavour_, false, -1, 2, false );
378  } // End of loop over all first quarks of the hadron
379 
380 
381  // Setting initial flavour of the hadron
382  int hadronFlavour = 0;
383 
384  // Initialising pairs of last quark index and its distance from the hadron (to sort by distance)
385  std::vector<std::pair<double, int> > lastQuark_dR_id_pairs;
386 
387  // Finding the closest quark in dR
388  for ( unsigned int qId = 0; qId < LastQuarkId.size(); qId++ ) {
389  int qIdx = LastQuarkId.at(qId);
390  // Calculating the dR between hadron and quark
391  float dR = deltaR ( hadMothers.at(hadIdx).eta(),hadMothers.at(hadIdx).phi(),hadMothers.at(qIdx).eta(),hadMothers.at(qIdx).phi() );
392 
393  std::pair<double, int> dR_hadId_pair(dR,qIdx);
394  lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
395  } // End of loop over all last quarks of the hadron
396 
397  std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
398 
399  if(lastQuark_dR_id_pairs.size() > 1) {
400  double dRratio = (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first)/lastQuark_dR_id_pairs.at(1).first;
401  int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
402  LastQuarkId.clear();
403  if(dRratio>0.5) LastQuarkId.push_back(qIdx_closest);
404  else for(std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs) LastQuarkId.push_back(qIdDrPair.second);
405  }
406  for(int qIdx : LastQuarkId) {
407  int qmIdx = hadMothersIndices.at(qIdx).at(0);
408  LastQuarkMotherId.push_back(qmIdx);
409  }
410 
411  if((int)LastQuarkId.size()>0) lastQuarkIndices.at(hadNum) = 0; // Setting the first quark in array as a candidate if it exists
412 
413  LastQuarkIds.push_back( LastQuarkId );
414 
415  LastQuarkMotherIds.push_back ( LastQuarkMotherId );
416 
417  if(LastQuarkMotherId.empty()) {
418  hadronFlavour = 0;
419  } else {
420  int qIdx = LastQuarkId.at( lastQuarkIndices.at(hadNum) );
421  int qFlav = flavourSign( hadMothers.at(qIdx).pdgId() );
422  hadronFlavour = qFlav*std::abs( hadMothers.at( LastQuarkMotherId.at( lastQuarkIndices.at(hadNum) ) ).pdgId() );
423  }
424  hadFlavour.push_back(hadronFlavour); // Adding hadron flavour to the list of flavours
425 
426  // Checking whether hadron comes from the Top weak decay
427  int isFromTopWeakDecay = 1;
428  std::vector <int> checkedParticles;
429  if(hadFlavour.at(hadNum) != 0) {
430  int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
431  bool fromTB = topDaughterQId >= 0 ? findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0, false, topDaughterQId, 2, false ) >= 0 : false;
432  checkedParticles.clear();
433  bool fromTbarB = topBarDaughterQId >= 0 ? findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0, false, topBarDaughterQId, 2, false) >= 0 : false;
434  checkedParticles.clear();
435  if(!fromTB && !fromTbarB) {
436  isFromTopWeakDecay = 0;
437  }
438  } else isFromTopWeakDecay = 2;
439  hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
440  int bHadronMotherId = findInMothers( hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555, true, -1, 1, false );
441  hadBHadronId.push_back(bHadronMotherId);
442 
443 
444  if(!LastQuarkMotherId.empty()) {
445  std::set<int> checkedHadronIds;
446  fixExtraSameFlavours(hadNum, hadIndex, hadMothers, hadMothersIndices, hadFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadFlavour, checkedHadronIds, 0);
447  }
448 
449  } // End of loop over all hadrons
450 
451  return hadJetIndex;
452 }
int pdgId() const final
PDG identifier.
transient_vector_type::const_iterator const_iterator
const GenParticleRefVector & getbHadrons() const
Return a vector of GenParticleRef&#39;s to b hadrons clustered inside the jet.
const GenParticleRefVector & getcHadrons() const
Return a vector of GenParticleRef&#39;s to c hadrons clustered inside the jet.
int analyzeMothers(const reco::Candidate *thisParticle, int &topDaughterQId, int &topBarDaughterQId, std::vector< const reco::Candidate * > &hadMothers, std::vector< std::vector< int > > &hadMothersIndices, std::set< const reco::Candidate * > *analyzedParticles, const int prevPartIndex) const
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
const_iterator end() const
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:253
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:248
int flavourSign(const int pdgId) const
Sign of the flavour (matter/antimatter)
virtual int pdgId() const =0
PDG identifier.
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Class storing the jet flavour information.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool hasHadronDaughter(const int flavour, const reco::Candidate *thisParticle) const
Check if the particle has bHadron among daughters.
const bool onlyJetClusteredHadrons_
bool isHadron(const int flavour, const reco::Candidate *thisParticle) const
Check the pdgId of a given particle if it is a hadron.
edm::RefVector< GenParticleCollection > GenParticleRefVector
vector of reference to GenParticle in the same collection
bool fixExtraSameFlavours(const unsigned int hadId, const std::vector< int > &hadIndices, const std::vector< reco::GenParticle > &hadMothers, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< int > &isFromTopWeakDecay, const std::vector< std::vector< int > > &LastQuarkIds, const std::vector< std::vector< int > > &LastQuarkMotherIds, std::vector< int > &lastQuarkIndices, std::vector< int > &hadronFlavour, std::set< int > &checkedHadronIds, const int lastQuarkIndex) const
hadronFlavour
Definition: jets_cff.py:474
int findInMothers(int idx, std::vector< int > &mothChains, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose) const
helper function to find indices of particles with particular pdgId and status from the list of mother...
const_iterator begin() const
const Candidate * mother(size_type=0) const override
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
int GenHFHadronMatcher::findInMothers ( int  idx,
std::vector< int > &  mothChains,
const std::vector< std::vector< int > > &  hadMothersIndices,
const std::vector< reco::GenParticle > &  hadMothers,
int  status,
int  pdgId,
bool  pdgAbs = false,
int  stopId = -1,
int  firstLast = 0,
bool  verbose = false 
) const
private

helper function to find indices of particles with particular pdgId and status from the list of mothers of a given particle

Parameters
[in]idxindex of particle, mothers of which should be searched
[in]mothChainsvector of indices where the found mothers are stored
[in]hadMothersIndiceslist of indices pointing to mothers of each particle from list of mothers
[in]hadMothersvector of all hadron mother particles of all levels
[in]statusstatus of mother that is being looked for
[in]pdgIdpdgId of mother that is being looked for [flavour*111111 used to identify hadrons of particular flavour]
[in]pdgAbswhether the sign of pdgId should be taken into account
[in]stopIdid of the particle in the hadMothers array after which the checking should stop
[in]firstLastshould all(0), first(1) or last(2) occurances of the searched particle be stored
[in]verboseoption to print every particle that is processed during the search
Returns
index of the found particle in the hadMothers array [-1 if the specified particle not found]

Definition at line 761 of file GenHFHadronMatcher.cc.

References funct::abs(), funct::false, spr::find(), mps_fire::i, training_settings::idx, isHadronPdgId(), and funct::true.

Referenced by findHadronJets().

764 {
765  int foundStopId = -1;
766  int pdg_1 = hadMothers.at(idx).pdgId();
767 
768  if ( (int)hadMothersIndices.size() <= idx ) {
769  if ( verbose ) {
770  printf ( " Stopping checking particle %d. No mothers are stored.\n",idx );
771  }
772  return -1; // Skipping if no mothers are stored for this particle
773  }
774 
775  if(std::abs(hadMothers.at( idx ).pdgId()) > 10 && std::abs(hadMothers.at( idx ).pdgId()) < 19) printf("Lepton: %d\n", hadMothers.at( idx ).pdgId());
776 
777  std::vector<int> mothers = hadMothersIndices.at(idx);
778  unsigned int nMothers = mothers.size();
779  bool isCorrect=false; // Whether current particle is what is being searched
780  if ( verbose ) {
781  if ( std::abs( hadMothers.at(idx).pdgId() ) ==2212 ) {
782  printf ( "Chk: %d\tpdg: %d\tstatus: %d",idx, hadMothers.at(idx).pdgId(), hadMothers.at(idx).status() );
783  } else {
784  printf ( " Chk: %d(%d mothers)\tpdg: %d\tstatus: %d\tPt: %.3f\tEta: %.3f",idx, nMothers, hadMothers.at(idx).pdgId(), hadMothers.at(idx).status(), hadMothers.at(idx).pt(),hadMothers.at(idx).eta() );
785  }
786  }
787  bool hasCorrectMothers = true;
788  if(nMothers<1) hasCorrectMothers=false; else if(mothers.at(0)<0) hasCorrectMothers=false;
789  if(!hasCorrectMothers) {
790  if(verbose) printf(" NO CORRECT MOTHER\n");
791  return -1;
792  }
793  // Stopping if the particular particle has been found
794  if(stopId>=0 && idx == stopId) return idx;
795 
796  // Stopping if the hadron of particular flavour has been found
797  if(pdgId%111111==0 && pdgId!=0) {
798  if(isHadronPdgId(pdgId/111111, hadMothers.at(idx).pdgId())) {
799  return idx;
800  }
801  }
802 
803  // Checking whether current mother satisfies selection criteria
804  if ( ( ( hadMothers.at(idx).pdgId() == pdgId && pdgAbs==false )
805  || ( std::abs( hadMothers.at(idx).pdgId() ) == std::abs( pdgId ) && pdgAbs==true ) )
806  && ( hadMothers.at(idx).status() == status || status==0 )
807  && hasCorrectMothers ) {
808  isCorrect=true;
809  // Adding to the list of candidates if not there and if mother of this quark has correct flavour sign
810  const bool inList = std::find(mothChains.begin(), mothChains.end(), idx) != mothChains.end();
811  if ( !inList && mothers.at(0) >= 0 && ( hadMothers.at(idx).pdgId()*pdgId > 0 || !pdgAbs ) ) {
812  if ( firstLast==0 || firstLast==1 ) {
813  mothChains.push_back(idx);
814  }
815  if ( verbose ) {
816  printf ( " *" );
817  }
818  }
819  if ( verbose ) {
820  printf ( " +++" );
821  }
822  }
823  if ( verbose ) {
824  printf ( "\n" );
825  }
826 
827  if ( isCorrect && firstLast==1 ) {
828  return -1; // Stopping if only the first particle in the chain is looked for
829  }
830 
831  // Checking next level mothers
832  unsigned int nDifferingMothers = 0;
833  for ( unsigned int i = 0; i < nMothers; i++ ) {
834  int idx2 = mothers.at(i);
835  if ( idx2 < 0 ) {
836  if(verbose) printf("^^^ Has no mother\n");
837  continue; // Skipping if mother's id is -1 (no mother), that means current particle is a proton
838  }
839  if ( idx2 == idx ) {
840  if(verbose) printf("^^^ Stored as its own mother\n");
841  continue; // Skipping if particle is stored as its own mother
842  }
843  int pdg_2 = hadMothers[idx2].pdgId();
844  // Inverting the flavour if bb oscillation detected
845  if ( isHadronPdgId(pdgId, pdg_1) && isHadronPdgId(pdgId, pdg_2) && pdg_1*pdg_2 < 0 ) {
846  pdgId *= -1;
847  if(verbose) printf("######### Inverting flavour of the hadron\n");
848  }
849  // Counting how many mothers are different from this particle
850  if ( ( std::abs( pdg_2 ) != std::abs( pdgId ) && pdgAbs==true ) ||
851  ( pdg_2 != pdgId && pdgAbs == false ) ) {
852  nDifferingMothers++;
853  }
854 
855  // Checking next level mother
856  if ( verbose ) {
857  printf ( "Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",i,nMothers,idx, idx2, pdgId );
858  }
859  if(firstLast==2 && pdg_1 != pdg_2) continue; // Requiring the same flavour when finding the last quark
860  foundStopId = findInMothers ( idx2, mothChains, hadMothersIndices, hadMothers, status, pdgId, pdgAbs, stopId, firstLast, verbose );
861  }
862  // Storing this particle if all its mothers are of another type and the last of its kind should be stored
863  if(firstLast==2 && isCorrect && nDifferingMothers >= nMothers) {
864  if ( verbose ) {
865  printf ( "Checking particle %d once more to store it as the last quark\n",idx);
866  }
867  foundStopId = findInMothers ( idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1, verbose );
868  }
869 
870  return foundStopId;
871 }
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isHadronPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a hadron of particular flavour.
int findInMothers(int idx, std::vector< int > &mothChains, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose) const
helper function to find indices of particles with particular pdgId and status from the list of mother...
bool GenHFHadronMatcher::fixExtraSameFlavours ( const unsigned int  hadId,
const std::vector< int > &  hadIndices,
const std::vector< reco::GenParticle > &  hadMothers,
const std::vector< std::vector< int > > &  hadMothersIndices,
const std::vector< int > &  isFromTopWeakDecay,
const std::vector< std::vector< int > > &  LastQuarkIds,
const std::vector< std::vector< int > > &  LastQuarkMotherIds,
std::vector< int > &  lastQuarkIndices,
std::vector< int > &  hadronFlavour,
std::set< int > &  checkedHadronIds,
const int  lastQuarkIndex 
) const
private

Finds hadrons that have the same flavour and origin and resolve this ambiguity fixExtraSameFlavours

Parameters
hadIdIndex of the hadron being checked
hadIndexVector of indices of each hadron pointing to the hadMothers
hadMothersVector of gen particles (contain hadrons and all its ancestors)
hadMothersIndicesVector of indices for each particle from hadMothers
isFromTopWeakDecayVector of values showing whether particle comes from the top weak decay
LastQuarkIdsVector of indices of last quarks for each hadron
LastQuarkMotherIdsVector of indices of mothers for each last quark from LastQuarkIds
lastQuakIndicesVector of indices pointing to particular index from the LastQuarkIds and LastQuarkMotherIds to be used for each hadron
lastQuarkIndexIndex from the LastQuarkIds and LastQuarkMotherIds for this particular hadron with index hadId
Returns
Whether other mother with unique association has been found for the hadrons

Definition at line 906 of file GenHFHadronMatcher.cc.

References funct::abs(), DEFINE_FWK_MODULE, and isNeutralPdg().

Referenced by findHadronJets().

912 {
913  if(checkedHadronIds.count(hadId) != 0) return false; // Hadron already checked previously and should be skipped
914  checkedHadronIds.insert(hadId); // Putting hadron to the list of checked ones in this run
915 
916  if(lastQuarkIndex<0) return false;
917  if((int)LastQuarkIds.at(hadId).size()<lastQuarkIndex+1) return false;
918  int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
919  int LastQuarkMotherId = LastQuarkMotherIds.at( hadId ).at( lastQuarkIndex );
920  int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
921  int hadFlavour = qmFlav*std::abs( hadMothers.at( LastQuarkMotherId ).pdgId() );
922  bool ambiguityResolved = true;
923  // If last quark has inconsistent flavour with its mother, setting the hadron flavour to gluon
924  if( (hadMothers.at(LastQuarkId).pdgId()*hadMothers.at(LastQuarkMotherId).pdgId() < 0 && !isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
925  // If particle not coming from the Top weak decay has Top flavour
926  (std::abs(hadronFlavour.at(hadId))==6 && isFromTopWeakDecay.at(hadId)==0) ) {
927  if((int)LastQuarkIds.at(hadId).size()>lastQuarkIndex+1) fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1);
928  else hadronFlavour.at(hadId) = qmFlav*21;
929  return true;
930  }
931 
932  int nSameFlavourHadrons = 0;
933  // Looping over all previous hadrons
934  for(unsigned int iHad = 0; iHad<hadronFlavour.size(); iHad++) {
935  if(iHad==hadId) continue;
936  int theLastQuarkIndex = lastQuarkIndices.at(iHad);
937  if(theLastQuarkIndex<0) continue;
938  if((int)LastQuarkMotherIds.at( iHad ).size() <= theLastQuarkIndex) continue;
939  int theLastQuarkMotherId = LastQuarkMotherIds.at( iHad ).at( theLastQuarkIndex );
940  int theHadFlavour = hadronFlavour.at(iHad);
941  // Skipping hadrons with different flavour
942  if(theHadFlavour==0 || std::abs(theHadFlavour)==21) continue;
943  if(theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId) continue;
944  ambiguityResolved = false;
945  nSameFlavourHadrons++;
946 
947  // Checking other b-quark mother candidates of this hadron
948  if((int)LastQuarkIds.at(hadId).size() > lastQuarkIndex+1) {
949  if(fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1) ) {
950  ambiguityResolved = true;
951  break;
952  }
953  } else
954  // Checking other b-quark mother candidates of the particular previous hadron
955  if((int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex+1) {
956  if(fixExtraSameFlavours(iHad, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, theLastQuarkIndex+1) ) {
957  ambiguityResolved = true;
958  break;
959  };
960  }
961 
962  } // End of loop over all previous hadrons
963 
964  checkedHadronIds.erase(hadId); // Removing the hadron from the list of checked hadrons
965  if(nSameFlavourHadrons>0 && !ambiguityResolved) {
966  hadronFlavour.at(hadId) = qmFlav*21;
967  return true;
968  }
969  lastQuarkIndices.at(hadId) = lastQuarkIndex;
970  hadronFlavour.at(hadId) = hadFlavour;
971  return true;
972 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool fixExtraSameFlavours(const unsigned int hadId, const std::vector< int > &hadIndices, const std::vector< reco::GenParticle > &hadMothers, const std::vector< std::vector< int > > &hadMothersIndices, const std::vector< int > &isFromTopWeakDecay, const std::vector< std::vector< int > > &LastQuarkIds, const std::vector< std::vector< int > > &LastQuarkMotherIds, std::vector< int > &lastQuarkIndices, std::vector< int > &hadronFlavour, std::set< int > &checkedHadronIds, const int lastQuarkIndex) const
bool isNeutralPdg(int pdgId) const
Check whether a given pdgId represents neutral particle.
hadronFlavour
Definition: jets_cff.py:474
int GenHFHadronMatcher::flavourSign ( const int  pdgId) const
private

Sign of the flavour (matter/antimatter)

Parameters
[in]pdgIdpdgId to be checked
Returns
+1/-1/0 matter/antimatter/undefined

Definition at line 561 of file GenHFHadronMatcher.cc.

References funct::abs(), and isMesonPdgId().

Referenced by findHadronJets().

562 {
563  int flavourSign = pdgId / std::abs(pdgId);
564  // B mesons have opposite sign
565  if( isMesonPdgId(5, pdgId) ) flavourSign *= -1;
566  // Returning 0 for bb/cc resonances
567  if(pdgId % 1000 / 10 / 11 > 0) flavourSign = 0;
568 
569  return flavourSign;
570 }
bool isMesonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a meson of particular flavour.
int flavourSign(const int pdgId) const
Sign of the flavour (matter/antimatter)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::string GenHFHadronMatcher::getParticleName ( int  id) const
private
bool GenHFHadronMatcher::hasHadronDaughter ( const int  flavour,
const reco::Candidate thisParticle 
) const
private

Check if the particle has bHadron among daughters.

Parameters
[in]flavourflavour of a hadron that is being searched (5-B, 4-C)
[in]thisParticlea particle that is to be analysed
Returns
whether the particle has a hadron among its daughters

Definition at line 581 of file GenHFHadronMatcher.cc.

References reco::Candidate::daughter(), createfilelist::int, isHadron(), gen::k, and reco::Candidate::numberOfDaughters().

Referenced by findHadronJets().

582 {
583  // Looping through daughters of the particle
584  bool hasDaughter = false;
585  for ( int k=0; k< (int)thisParticle->numberOfDaughters(); k++ ) {
586  if ( !isHadron( flavour, thisParticle->daughter(k) ) ) {
587  continue;
588  }
589  hasDaughter = true;
590  break;
591  }
592 
593  return hasDaughter;
594 }
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
bool isHadron(const int flavour, const reco::Candidate *thisParticle) const
Check the pdgId of a given particle if it is a hadron.
int k[5][pyjets_maxn]
virtual size_type numberOfDaughters() const =0
number of daughters
int GenHFHadronMatcher::idInList ( std::vector< const reco::Candidate * >  particleList,
const reco::Candidate particle 
) const
private

Check if the cpecified particle is already in the list of particles.

Parameters
[in]particleListlist of particles to be checked
[in]particleparticle that should be checked
Returns
the index of the particle in the list [-1 if particle not found]

Definition at line 463 of file GenHFHadronMatcher.cc.

References spr::find(), and position.

Referenced by analyzeMothers().

464 {
465  const unsigned int position = std::find(particleList.begin(), particleList.end(), particle) - particleList.begin();
466  if( position >= particleList.size() ) return -1;
467 
468  return position;
469 }
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
static int position[264][3]
Definition: ReadPGInfo.cc:509
int GenHFHadronMatcher::idInList ( std::vector< int >  list,
const int  value 
) const
private

Definition at line 471 of file GenHFHadronMatcher.cc.

References spr::find(), position, and relativeConstraints::value.

472 {
473  const unsigned int position = std::find(list.begin(), list.end(), value) - list.begin();
474  if( position >= list.size() ) return -1;
475 
476  return position;
477 }
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
static int position[264][3]
Definition: ReadPGInfo.cc:509
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
bool GenHFHadronMatcher::isBaryonPdgId ( const int  flavour,
const int  pdgId 
) const
private

Check the pdgId if it represents a baryon of particular flavour.

Parameters
[in]flavourflavour of a hadron that is being searched (5-B, 4-C)
[in]pdgIdpdgId to be checked
Returns
true if the pdgId represents a baryon of specified flavour

Definition at line 542 of file GenHFHadronMatcher.cc.

References funct::abs().

Referenced by isHadronPdgId().

543 {
544  const int flavour_abs = std::abs(flavour);
545  if(flavour_abs != 5 && flavour_abs != 4) return false;
546  const int pdgId_abs = std::abs(pdgId);
547 
548  if ( pdgId_abs/1000 != flavour_abs) return false;
549 
550  return true;
551 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool GenHFHadronMatcher::isHadron ( const int  flavour,
const reco::Candidate thisParticle 
) const
private

Check the pdgId of a given particle if it is a hadron.

Parameters
[in]flavourflavour of a hadron that is being searched (5-B, 4-C)
[in]thisParticlea particle that is to be analysed
Returns
whether the particle is a hadron of specified flavour

Definition at line 488 of file GenHFHadronMatcher.cc.

References isHadronPdgId(), and reco::Candidate::pdgId().

Referenced by findHadronJets(), and hasHadronDaughter().

489 {
490  return isHadronPdgId(flavour, thisParticle->pdgId());
491 }
virtual int pdgId() const =0
PDG identifier.
bool isHadronPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a hadron of particular flavour.
bool GenHFHadronMatcher::isHadronPdgId ( const int  flavour,
const int  pdgId 
) const
private

Check the pdgId if it represents a hadron of particular flavour.

Parameters
[in]flavourflavour of a hadron that is being searched (5-B, 4-C)
[in]pdgIdpdgId to be checked
Returns
true if the pdgId represents a hadron of specified flavour

Definition at line 502 of file GenHFHadronMatcher.cc.

References isBaryonPdgId(), and isMesonPdgId().

Referenced by findInMothers(), and isHadron().

503 {
504  if( isBaryonPdgId(flavour, pdgId) || isMesonPdgId(flavour, pdgId) ) return true;
505 
506  return false;
507 }
bool isMesonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a meson of particular flavour.
bool isBaryonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a baryon of particular flavour.
bool GenHFHadronMatcher::isMesonPdgId ( const int  flavour,
const int  pdgId 
) const
private

Check the pdgId if it represents a meson of particular flavour.

Parameters
[in]flavourflavour of a hadron that is being searched (5-B, 4-C)
[in]pdgIdpdgId to be checked
Returns
true if the pdgId represents a meson of specified flavour

Definition at line 518 of file GenHFHadronMatcher.cc.

References funct::abs(), and noBBbarResonances_.

Referenced by flavourSign(), and isHadronPdgId().

519 {
520  const int flavour_abs = std::abs(flavour);
521  if(flavour_abs != 5 && flavour_abs != 4) return false;
522  const int pdgId_abs = std::abs(pdgId);
523 
524  if( pdgId_abs/100%10 != flavour_abs) return false;
525  // Excluding baryons
526  if ( pdgId_abs/1000 == flavour_abs) return false;
527  // Excluding bb/cc resonances if required
528  if ( noBBbarResonances_ && pdgId_abs/10%100 == 11*flavour_abs ) return false;
529 
530  return true;
531 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool GenHFHadronMatcher::isNeutralPdg ( int  pdgId) const
private

Check whether a given pdgId represents neutral particle.

Parameters
[in]pdgId
[in]thisParticle- a particle that is to be analysed
Returns
if the particle has a hadron among its daughters

Definition at line 882 of file GenHFHadronMatcher.cc.

References funct::abs(), and spr::find().

Referenced by fixExtraSameFlavours().

883 {
884  const int neutralPdgs_array[] = {9, 21, 22, 23, 25};
885  const std::vector<int> neutralPdgs( neutralPdgs_array, neutralPdgs_array + sizeof(neutralPdgs_array) / sizeof(int) );
886  if( std::find( neutralPdgs.begin(), neutralPdgs.end(), std::abs(pdgId) ) == neutralPdgs.end() ) return false;
887 
888  return true;
889 }
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void GenHFHadronMatcher::produce ( edm::StreamID  ,
edm::Event evt,
const edm::EventSetup setup 
) const
overrideprivate

Definition at line 201 of file GenHFHadronMatcher.cc.

References bHadronIdToken_, edm::Event::emplace(), findHadronJets(), flavourToken_, fromTopWeakDecayToken_, GenHFHadronMatcher_cfi::genParticles, genParticlesToken_, edm::Event::getByToken(), indexToken_, GenHFHadronMatcher_cfi::jetFlavourInfos, jetFlavourInfosToken_, jetIndexToken_, leptonHadronIndexToken_, leptonIndexToken_, leptonViaTauToken_, eostools::move(), plusMothersIndicesToken_, plusMothersToken_, and edm::Handle< T >::product().

202 {
203  using namespace edm;
204 
206  evt.getByToken(genParticlesToken_, genParticles);
207 
209  evt.getByToken(jetFlavourInfosToken_, jetFlavourInfos);
210 
211  // Defining adron matching variables
212  std::vector<reco::GenParticle> hadMothers;
213  std::vector<std::vector<int>> hadMothersIndices;
214  std::vector<int> hadIndex;
215  std::vector<int> hadFlavour;
216  std::vector<int> hadJetIndex;
217  std::vector<int> hadLeptonIndex;
218  std::vector<int> hadLeptonHadIndex;
219  std::vector<int> hadLeptonViaTau;
220  std::vector<int> hadFromTopWeakDecay;
221  std::vector<int> hadBHadronId;
222 
223  hadJetIndex = findHadronJets (genParticles.product(), jetFlavourInfos.product(), hadIndex, hadMothers, hadMothersIndices, hadLeptonIndex, hadLeptonHadIndex, hadLeptonViaTau, hadFlavour, hadFromTopWeakDecay, hadBHadronId );
224 
225  // Putting products to the event
226  evt.emplace(plusMothersToken_, std::move(hadMothers));
227  evt.emplace(plusMothersIndicesToken_, std::move(hadMothersIndices));
228  evt.emplace(indexToken_, std::move(hadIndex));
229  evt.emplace(flavourToken_, std::move(hadFlavour));
230  evt.emplace(jetIndexToken_, std::move(hadJetIndex));
231  evt.emplace(leptonIndexToken_, std::move(hadLeptonIndex));
232  evt.emplace(leptonHadronIndexToken_, std::move(hadLeptonHadIndex));
233  evt.emplace(leptonViaTauToken_, std::move(hadLeptonViaTau));
234  evt.emplace(fromTopWeakDecayToken_, std::move(hadFromTopWeakDecay));
235  evt.emplace(bHadronIdToken_, std::move(hadBHadronId));
236 }
const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
const edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
const edm::EDPutTokenT< std::vector< int > > leptonIndexToken_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
const edm::EDPutTokenT< std::vector< reco::GenParticle > > plusMothersToken_
const edm::EDPutTokenT< std::vector< int > > leptonViaTauToken_
const edm::EDPutTokenT< std::vector< int > > indexToken_
std::vector< int > findHadronJets(const reco::GenParticleCollection *genParticles, const reco::JetFlavourInfoMatchingCollection *jetFlavourInfos, std::vector< int > &hadIndex, std::vector< reco::GenParticle > &hadMothersGenPart, std::vector< std::vector< int > > &hadMothersIndices, std::vector< int > &hadLeptonIndex, std::vector< int > &hadLeptonHadIndex, std::vector< int > &hadLeptonViaTau, std::vector< int > &hadFlavour, std::vector< int > &hadFromTopWeakDecay, std::vector< int > &hadBHadronId) const
identify the jets that contain b-hadrons
const edm::EDPutTokenT< std::vector< std::vector< int > > > plusMothersIndicesToken_
T const * product() const
Definition: Handle.h:74
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
Definition: Event.h:413
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
HLT enums.
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
const edm::EDPutTokenT< std::vector< int > > jetIndexToken_
const edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
def move(src, dest)
Definition: eostools.py:511
const edm::EDPutTokenT< std::vector< int > > flavourToken_
bool GenHFHadronMatcher::putMotherIndex ( std::vector< std::vector< int > > &  hadMothersIndices,
int  partIndex,
int  mothIndex 
) const
private

puts mother index to the list of mothers of particle, if it isn't there already

Parameters
[in]hadMothersIndicesvector of indices of mothers for each particle
[in]partIndexindex of the particle for which the mother index should be stored
[in]mothIndexindex of mother that should be stored for current particle
Returns
whether the particle index was alreade in the list

Definition at line 708 of file GenHFHadronMatcher.cc.

References createfilelist::int, and gen::k.

Referenced by analyzeMothers().

709 {
710  // Putting vector of mothers indices for the given particle
711  bool inList=false;
712  if ( partIndex<0 ) {
713  return false;
714  }
715 
716  while ( (int)hadMothersIndices.size() <= partIndex ) { // If there is no list of mothers for current particle yet
717  std::vector<int> mothersIndices;
718  hadMothersIndices.push_back ( mothersIndices );
719  }
720 
721  std::vector<int> *hadMotherIndices = &hadMothersIndices.at(partIndex);
722  // Removing other mothers if particle must have no mothers
723  if ( mothIndex == -1 ) {
724  hadMotherIndices->clear();
725  } else {
726  // Checking if current mother is already in the list of theParticle's mothers
727  for ( int k = 0; k < (int)hadMotherIndices->size(); k++ ) {
728  if ( hadMotherIndices->at(k) != mothIndex && hadMotherIndices->at(k) != -1 ) {
729  continue;
730  }
731  inList=true;
732  break;
733  }
734  }
735  // Adding current mother to the list of mothers of this particle
736  if ( !inList ) {
737  hadMotherIndices->push_back(mothIndex);
738  }
739 
740  return inList;
741 }
int k[5][pyjets_maxn]

Member Data Documentation

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::bHadronIdToken_
private

Definition at line 115 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const int GenHFHadronMatcher::flavour_
private

Definition at line 101 of file GenHFHadronMatcher.cc.

Referenced by findHadronJets(), and GenHFHadronMatcher().

const std::string GenHFHadronMatcher::flavourStr_
private

Definition at line 105 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::flavourToken_
private

Definition at line 109 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::fromTopWeakDecayToken_
private

Definition at line 114 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDGetTokenT<reco::GenParticleCollection> GenHFHadronMatcher::genParticlesToken_
private

Definition at line 99 of file GenHFHadronMatcher.cc.

Referenced by produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::indexToken_
private

Definition at line 108 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDGetTokenT<reco::JetFlavourInfoMatchingCollection> GenHFHadronMatcher::jetFlavourInfosToken_
private

Definition at line 100 of file GenHFHadronMatcher.cc.

Referenced by produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::jetIndexToken_
private

Definition at line 110 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::leptonHadronIndexToken_
private

Definition at line 112 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::leptonIndexToken_
private

Definition at line 111 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDPutTokenT< std::vector<int> > GenHFHadronMatcher::leptonViaTauToken_
private

Definition at line 113 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const bool GenHFHadronMatcher::noBBbarResonances_
private

Definition at line 102 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and isMesonPdgId().

const bool GenHFHadronMatcher::onlyJetClusteredHadrons_
private

Definition at line 103 of file GenHFHadronMatcher.cc.

Referenced by findHadronJets(), and GenHFHadronMatcher().

const edm::EDPutTokenT< std::vector< std::vector<int> > > GenHFHadronMatcher::plusMothersIndicesToken_
private

Definition at line 107 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

const edm::EDPutTokenT< std::vector<reco::GenParticle> > GenHFHadronMatcher::plusMothersToken_
private

Definition at line 106 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().