CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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::EDProducer edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Public Member Functions

 GenHFHadronMatcher (const edm::ParameterSet &)
 constructor initialising producer products and config parameters More...
 
 ~GenHFHadronMatcher ()
 
- Public Member Functions inherited from edm::EDProducer
 EDProducer ()
 
ModuleDescription const & moduleDescription () const
 
virtual ~EDProducer ()
 
- Public Member Functions inherited from edm::ProducerBase
 ProducerBase ()
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
std::function< void(BranchDescription
const &)> 
registrationCallback () const
 used by the fwk to register list of products More...
 
virtual ~ProducerBase ()
 
- Public Member Functions inherited from edm::EDConsumerBase
std::vector< ConsumesInfoconsumesInfo () const
 
 EDConsumerBase ()
 
ProductHolderIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
 
std::vector
< ProductHolderIndexAndSkipBit >
const & 
itemsToGetFromEvent () const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
void modulesDependentUpon (const std::string &iProcessName, std::vector< const char * > &oModuleLabels) const
 
void modulesWhoseProductsAreConsumed (std::vector< ModuleDescription const * > &modules, ProductRegistry const &preg, std::map< std::string, ModuleDescription const * > const &labelsToDesc, std::string const &processName) const
 
bool registeredToConsume (ProductHolderIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
void updateLookup (BranchType iBranchType, ProductHolderIndexHelper const &)
 
virtual ~EDConsumerBase ()
 

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)
 description of the run-time parameters More...
 
- Static Public Member Functions inherited from edm::EDProducer
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)
 do a recursive search for the mother particles until the b-quark is found or the absolute mother is found More...
 
virtual void beginJob ()
 
virtual void beginLuminosityBlock (edm::LuminosityBlock &, edm::EventSetup const &)
 
virtual void beginRun (edm::Run &, edm::EventSetup const &)
 
bool checkForLoop (std::vector< const reco::Candidate * > &particleChain, const reco::Candidate *particle)
 
virtual void endJob ()
 
virtual void endLuminosityBlock (edm::LuminosityBlock &, edm::EventSetup const &)
 
virtual void endRun (edm::Run &, edm::EventSetup 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)
 identify the jets that contain b-hadrons More...
 
int findInMothers (int idx, std::vector< int > &mothChains, std::vector< std::vector< int > > &hadMothersIndices, std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose)
 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)
 
std::string getParticleName (int id) const
 
bool hasHadronDaughter (const int flavour, const reco::Candidate *thisParticle)
 Check if the particle has bHadron among daughters. More...
 
bool isHadron (const int flavour, const reco::Candidate *thisParticle)
 Check the pdgId of a given particle if it is a hadron. More...
 
bool isHadronPdgId (const int flavour, const int pdgId)
 Check the pdgId if it represents a hadron of particular flavour. More...
 
int isInList (std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle)
 Check if the cpecified particle is already in the list of particles. More...
 
int isInList (std::vector< int > list, const int value)
 
bool isNeutralPdg (int pdgId)
 Check whether a given pdgId represents neutral particle. More...
 
virtual void produce (edm::Event &, const edm::EventSetup &)
 
bool putMotherIndex (std::vector< std::vector< int > > &hadMothersIndices, int partIndex, int mothIndex)
 puts mother index to the list of mothers of particle, if it isn't there already More...
 

Private Attributes

int flavour_
 
std::string flavourStr_
 
edm::EDGetTokenT
< reco::GenParticleCollection
genParticlesToken_
 
edm::EDGetTokenT
< reco::JetFlavourInfoMatchingCollection
jetFlavourInfosToken_
 
bool noBBbarResonances_
 
bool onlyJetClusteredHadrons_
 
edm::ESHandle< ParticleDataTablepdt_
 

Additional Inherited Members

- Public Types inherited from edm::EDProducer
typedef EDProducer ModuleType
 
- Public Types inherited from edm::ProducerBase
typedef
ProductRegistryHelper::TypeLabelList 
TypeLabelList
 
- Protected Member Functions inherited from edm::ProducerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
- 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 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

constructor initialising producer products and config parameters

Warning
Definition of b-hadron and anti-b-hadron: The term b-hadron and anti-b-hadron is in reference to the quark content and not to distinguish particles from anti-particles. Here a b-hadron contains a b-quark and an anti-b-hadron contains an anti-b-quark. For mesons this means an inversion with respect to the PDG definition, as mesons actually contain anti-b-quarks and anti-mesons contain b-quarks.

Definition at line 132 of file GenHFHadronMatcher.cc.

References funct::abs(), flavour_, flavourStr_, edm::ParameterSet::getParameter(), noBBbarResonances_, and onlyJetClusteredHadrons_.

132  :
133 genParticlesToken_(consumes<reco::GenParticleCollection>(cfg.getParameter<edm::InputTag>("genParticles"))),
134 jetFlavourInfosToken_(consumes<reco::JetFlavourInfoMatchingCollection>(cfg.getParameter<edm::InputTag>("jetFlavourInfos")))
135 {
136  flavour_ = cfg.getParameter<int> ( "flavour" );
137  noBBbarResonances_ = cfg.getParameter<bool> ( "noBBbarResonances" );
138  onlyJetClusteredHadrons_ = cfg.getParameter<bool> ( "onlyJetClusteredHadrons" );
139 
140  flavour_ = abs ( flavour_ ); // Make flavour independent of sign given in configuration
141  if ( flavour_==5 ) {
142  flavourStr_="B";
143  } else if ( flavour_==4 ) {
144  flavourStr_="C";
145  } else {
146  edm::LogError ( "GenHFHadronMatcher" ) << "Flavour option must be 4 (c-jet) or 5 (b-jet), but is: " << flavour_ << ". Correct this!";
147  }
148 
149  // Hadron matching products
150  produces< std::vector<reco::GenParticle> > ( "gen"+flavourStr_+"HadPlusMothers" ); // All mothers in all decay chains above any hadron of specified flavour
151  produces< std::vector< std::vector<int> > > ( "gen"+flavourStr_+"HadPlusMothersIndices" ); // Indices of mothers of each hadMother
152  produces< std::vector<int> > ( "gen"+flavourStr_+"HadIndex" ); // Index of hadron in the vector of hadMothers
153  produces< std::vector<int> > ( "gen"+flavourStr_+"HadFlavour" ); // PdgId of the first non-b(c) quark mother with sign corresponding to hadron charge
154  produces< std::vector<int> > ( "gen"+flavourStr_+"HadJetIndex" ); // Index of genJet matched to each hadron by jet clustering algorithm
155  produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonIndex" ); // Index of lepton found among the hadron decay products in the list of mothers
156  produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonHadronIndex" ); // Index of hadron the lepton is associated to
157  produces< std::vector<int> > ( "gen"+flavourStr_+"HadLeptonViaTau" ); // Whether lepton comes directly from hadron or via tau decay
158  produces< std::vector<int> > ( "gen"+flavourStr_+"HadFromTopWeakDecay" ); // Tells whether the hadron appears in the chain after top decay
159  produces< std::vector<int> > ( "gen"+flavourStr_+"HadBHadronId" ); // Index of a b-hadron which the current hadron comes from (for c-hadrons)
160 
161 }
T getParameter(std::string const &) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
GenHFHadronMatcher::~GenHFHadronMatcher ( )

Definition at line 163 of file GenHFHadronMatcher.cc.

164 {
165 }

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 
)
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 587 of file GenHFHadronMatcher.cc.

References funct::abs(), i, cmsHarvester::index, isInList(), reco::Candidate::mother(), reco::Candidate::numberOfMothers(), reco::Candidate::pdgId(), reco::Candidate::pt(), and putMotherIndex().

Referenced by findHadronJets().

588 {
589 
590  // Getting the index of the particle which is a hadron in the first call
591  int hadronIndex=-1; // Index of the hadron that is returned by this function
592  int index = isInList ( hadMothers, thisParticle );
593  if ( index<0 ) { // If hadron is not in the list of mothers yet
594  hadMothers.push_back ( thisParticle );
595  hadronIndex=hadMothers.size()-1;
596  } else { // If hadron is in the list of mothers already
597  hadronIndex=index;
598  }
599 
600  int partIndex = -1; // Index of particle being checked in the list of mothers
601  partIndex = isInList ( hadMothers, thisParticle );
602 
603  // Checking whether this particle is already in the chain of analyzed particles in order to identify a loop
604  bool isLoop = false;
605  if ( !analyzedParticles ) {
606  analyzedParticles = new std::set<const reco::Candidate*>;
607  }
608  for ( unsigned int i=0; i<analyzedParticles->size(); i++ ) {
609  if ( analyzedParticles->count ( thisParticle ) <=0 ) {
610  continue;
611  }
612  isLoop = true;
613  break;
614  }
615 
616  // If a loop has been detected
617  if ( isLoop ) {
618  if ( prevPartIndex>=0 ) {
619  putMotherIndex ( hadMothersIndices, prevPartIndex, -1 ); // Setting mother index of previous particle to -1
620  }
621  return hadronIndex; // Stopping further processing of the current chain
622  }
623  analyzedParticles->insert ( thisParticle );
624 
625  // Putting the mothers to the list of mothers
626  for ( size_t iMother = 0; iMother < thisParticle->numberOfMothers(); ++iMother ) {
627  const reco::Candidate* mother = thisParticle->mother ( iMother );
628  int mothIndex = isInList ( hadMothers, mother );
629  if ( mothIndex == partIndex && partIndex>=0 ) {
630  continue; // Skipping the mother that is its own daughter
631  }
632 
633  // If this mother isn't yet in the list and hadron or lepton is in the list
634  if ( mothIndex<0 ) {
635  hadMothers.push_back ( mother );
636  mothIndex=hadMothers.size()-1;
637  }
638  // If hadron has already been found in current chain and the mother isn't a duplicate of the particle being checked
639  if ( mothIndex!=partIndex && partIndex>=0 ) {
640  putMotherIndex ( hadMothersIndices, partIndex, mothIndex ); // Putting the index of mother for current particle
641  }
642  analyzeMothers ( mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex );
643  // Setting the id of the particle which is a quark from the top decay
644  if(std::abs(mother->pdgId())==6) {
645  int& bId = mother->pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
646  int thisFlav = std::abs(thisParticle->pdgId());
647  if( bId<0){
648  if(thisFlav <= 5) bId = partIndex;
649  } else {
650  int bIdFlav = std::abs(hadMothers.at(bId)->pdgId());
651  if( bIdFlav != 5 && thisFlav == 5) bId = partIndex;
652  else if( thisFlav == 5 && thisParticle->pt() > hadMothers.at(bId)->pt() ) bId = partIndex;
653  } // If daughter quark of the top not found yet
654  } // If the mother is a top quark and hadron has been found
655  } // End of loop over mothers
656 
657  analyzedParticles->erase ( thisParticle ); // Removing current particle from the current chain that is being analyzed
658 
659  if ( partIndex<0 ) {
660  return hadronIndex; // Safety check
661  }
662 
663  // Adding -1 to the list of mother indices for current particle if it has no mothers (for consistency between numbering of indices and mothers)
664  if ( ( int ) thisParticle->numberOfMothers() <=0) {
665  putMotherIndex ( hadMothersIndices, partIndex, -1 );
666  }
667 
668 
669  return hadronIndex;
670 
671 }
int i
Definition: DBlmapReader.cc:9
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
virtual double pt() const =0
transverse momentum
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
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)
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool putMotherIndex(std::vector< std::vector< int > > &hadMothersIndices, int partIndex, int mothIndex)
puts mother index to the list of mothers of particle, if it isn&#39;t there already
virtual int pdgId() const =0
PDG identifier.
int isInList(std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle)
Check if the cpecified particle is already in the list of particles.
void GenHFHadronMatcher::beginJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 233 of file GenHFHadronMatcher.cc.

234 {
235 }
void GenHFHadronMatcher::beginLuminosityBlock ( edm::LuminosityBlock ,
edm::EventSetup const &   
)
privatevirtual

Definition at line 254 of file GenHFHadronMatcher.cc.

255 {
256 }
void GenHFHadronMatcher::beginRun ( edm::Run ,
edm::EventSetup const &   
)
privatevirtual

Definition at line 243 of file GenHFHadronMatcher.cc.

244 {
245 }
bool GenHFHadronMatcher::checkForLoop ( std::vector< const reco::Candidate * > &  particleChain,
const reco::Candidate particle 
)
private
void GenHFHadronMatcher::endJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 238 of file GenHFHadronMatcher.cc.

239 {
240 }
void GenHFHadronMatcher::endLuminosityBlock ( edm::LuminosityBlock ,
edm::EventSetup const &   
)
privatevirtual

Definition at line 259 of file GenHFHadronMatcher.cc.

260 {
261 }
void GenHFHadronMatcher::endRun ( edm::Run ,
edm::EventSetup const &   
)
privatevirtual

Definition at line 249 of file GenHFHadronMatcher.cc.

250 {
251 }
void GenHFHadronMatcher::fillDescriptions ( edm::ConfigurationDescriptions descriptions)
static

description of the run-time parameters

Definition at line 173 of file GenHFHadronMatcher.cc.

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

174 {
175 
177  desc.add<edm::InputTag>("genParticles")->setComment( "Collection of GenParticle objects which contains all particles produced in the event" );
178  desc.add<edm::InputTag>("jetFlavourInfos")->setComment( "Output from the JetFlavour tool. Contains information about partons/hadrons/leptons associated to jets" );
179  desc.add<bool> ( "noBBbarResonances",true )->setComment ( "Whether resonances should not be treated as hadrons" );
180  desc.add<bool> ( "onlyJetClusteredHadrons",false )->setComment ( "Whether only hadrons that are matched to jets should be analysed. Runs x1000 faster in Sherpa" );
181  desc.add<int> ( "flavour",5 )->setComment ( "Flavour of weakly decaying hadron that should be analysed (4-c, 5-b)" );
182  descriptions.add ( "matchGenHFHadron",desc );
183 }
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
volatile std::atomic< bool > shutdown_flag false
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 
)
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 287 of file GenHFHadronMatcher.cc.

References funct::abs(), analyzeMothers(), edm::RefVector< C, T, F >::begin(), edm::AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper >::begin(), deltaR(), PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi::dR, edm::AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper >::end(), edm::RefVector< C, T, F >::end(), edm::false, spr::find(), findInMothers(), fixExtraSameFlavours(), flavour_, reco::JetFlavourInfo::getbHadrons(), reco::JetFlavourInfo::getcHadrons(), reco::JetFlavourInfo::getLeptons(), hasHadronDaughter(), i, isHadron(), reco::Candidate::mother(), onlyJetClusteredHadrons_, benchmark_cfg::pdgId, reco::Candidate::pdgId(), and python.multivaluedict::sort().

Referenced by produce().

293 {
294  std::vector<int> hadJetIndex;
295  std::vector<const reco::Candidate*> hadMothersCand;
296 
297  int topDaughterQId = -1;
298  int topBarDaughterQId= -1;
299 
300  // Looping over all jets to get hadrons belonging to it
301  for(reco::JetFlavourInfoMatchingCollection::const_iterator i_info = jetFlavourInfos->begin(); i_info != jetFlavourInfos->end(); ++i_info){
302  reco::JetFlavourInfo jetInfo = i_info->second;
303  const int jetIndex = i_info - jetFlavourInfos->begin();
304  // Looping over each hadron associated with the jet and finding its origin
305  const reco::GenParticleRefVector& hadronsInJet = flavour_==5 ? jetInfo.getbHadrons() : flavour_==4 ? jetInfo.getcHadrons() : reco::GenParticleRefVector();
306  for(reco::GenParticleRefVector::const_iterator hadron = hadronsInJet.begin(); hadron != hadronsInJet.end(); ++hadron) {
307  // Check that the hadron satisfies criteria configured in the module
308  if(!isHadron ( flavour_, (&**hadron) )) continue;
309  if(hasHadronDaughter ( flavour_, (reco::Candidate*)(&**hadron) )) continue;
310  // Scanning the chain starting from the hadron
311  int hadronIndex = analyzeMothers ( (reco::Candidate*)(&**hadron), topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
312  // Storing the index of the hadron to the list
313  hadIndex.push_back ( hadronIndex );
314  hadJetIndex.push_back ( jetIndex ); // Putting jet index to the result list
315  }
316  // FIXME: Should be moved to a separate loop over jets after analysing all hadrons (in case leptons come from non-clustered hadrons)
317  // Looping over all leptons associated with the jet
318  const reco::GenParticleRefVector& leptonsInJet = jetInfo.getLeptons();
319  for(reco::GenParticleRefVector::const_iterator lepton = leptonsInJet.begin(); lepton != leptonsInJet.end(); ++lepton){
320  bool leptonViaTau = false;
321  // Skipping tau leptons
322  if(std::abs((*lepton)->pdgId()) == 15) continue;
323  const reco::Candidate* leptonMother = (*lepton)->mother();
324  if(!leptonMother) continue;
325  // Taking next mother if direct mother is a tau
326  if(std::abs(leptonMother->pdgId()) == 15) {
327  leptonViaTau = true;
328  leptonMother = leptonMother->mother();
329  }
330  // Skipping this lepton if its mother is not a proper hadron
331  if(!isHadron(flavour_, leptonMother)) continue;
332  // Finding the index of this hadron in the list of analysed particles
333  int leptonHadronParticleIndex = std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
334  if(leptonHadronParticleIndex >= (int)hadMothersCand.size()) continue;
335  if(leptonHadronParticleIndex < 0) continue;
336  // Finding the actual hadron index among those that were found
337  int leptonHadronIndex = std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
338  if(leptonHadronIndex >= (int)hadIndex.size()) continue;
339  // Putting the lepton, its index and hadron index to the corresponding lists
340  hadMothersCand.push_back(&**lepton);
341  const int leptonIndex = hadMothersCand.size()-1;
342  hadLeptonIndex.push_back(leptonIndex);
343  hadLeptonViaTau.push_back((int)leptonViaTau);
344  hadLeptonHadIndex.push_back(leptonHadronIndex);
345  }
346  } // End of loop over jets
347 
348 
349  // Access all hadrons which are not associated with jets if requested
351  for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
352  const reco::GenParticle* thisParticle = &*i_particle;
353  if(!isHadron(flavour_, thisParticle)) continue;
354  // Skipping the hadron if it was already found directly from jets
355  if(std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end()) continue;
356 
357  // Scanning the chain starting from the hadron
358  int hadronIndex = analyzeMothers ( thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
359  // Storing the index of the hadron to the list
360  hadIndex.push_back ( hadronIndex );
361  hadJetIndex.push_back ( -1 ); // Jet index undefined
362  }
363  }
364 
365 
366  for ( int i=0; i< ( int ) hadMothersCand.size(); i++ ) {
367  hadMothers.push_back ( ( *dynamic_cast<const reco::GenParticle*> ( hadMothersCand.at(i) ) ) );
368  }
369 
370  // Checking mothers of hadrons in order to assign flags (where the hadron comes from)
371  unsigned int nHad = hadIndex.size();
372 
373  std::vector<std::vector<int> > LastQuarkMotherIds;
374  std::vector<std::vector<int> > LastQuarkIds;
375  std::vector<int> lastQuarkIndices(nHad, -1);
376 
377  // Looping over all hadrons
378  for ( unsigned int hadNum=0; hadNum<nHad; hadNum++ ) {
379 
380  unsigned int hadIdx = hadIndex.at(hadNum); // Index of hadron in the hadMothers
381 
382  std::vector <int> FirstQuarkId;
383  std::vector <int> LastQuarkId;
384  std::vector <int> LastQuarkMotherId;
385 
386  int hadFlav = hadMothers.at(hadIdx).pdgId() <0?-1:1; // Charge of the hadron (-1,1)
387  if ( abs ( hadMothers.at(hadIdx).pdgId() ) /1000 < 1 ) {
388  hadFlav*=-1; // Inverting flavour of hadron if it is a meson
389  }
390 
391  // Searching only first quark in the chain with the same flavour as hadron
392  findInMothers ( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadFlav*flavour_, false, -1, 1, false );
393 
394  // Finding last quark for each first quark
395  for ( unsigned int qId=0; qId<FirstQuarkId.size(); qId++ ) {
396  // Identifying the flavour of the first quark to find the last quark of the same flavour
397  int bQFlav = hadMothers.at(FirstQuarkId.at(qId)).pdgId() < 0?-1:1;
398  // Finding last quark of the hadron starting from the first quark
399  findInMothers ( FirstQuarkId.at(qId), LastQuarkId, hadMothersIndices, hadMothers, 0, bQFlav*flavour_, false, -1, 2, false );
400  } // End of loop over all first quarks of the hadron
401 
402 
403  // Setting initial flavour of the hadron
404  int hadronFlavour = 0;
405 
406  // Initialising pairs of last quark index and its distance from the hadron (to sort by distance)
407  std::vector<std::pair<double, int> > lastQuark_dR_id_pairs;
408 
409  // Finding the closest quark in dR
410  for ( unsigned int qId=0; qId<LastQuarkId.size(); qId++ ) {
411  int qIdx = LastQuarkId.at(qId);
412  // Calculating the dR between hadron and quark
413  float dR = deltaR ( hadMothers.at(hadIdx).eta(),hadMothers.at(hadIdx).phi(),hadMothers.at(qIdx).eta(),hadMothers.at(qIdx).phi() );
414 
415  std::pair<double, int> dR_hadId_pair(dR,qIdx);
416  lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
417  } // End of loop over all last quarks of the hadron
418 
419  std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
420 
421  if(lastQuark_dR_id_pairs.size()>1) {
422  double dRratio = (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first)/lastQuark_dR_id_pairs.at(1).first;
423  int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
424  LastQuarkId.clear();
425  if(dRratio>0.5) LastQuarkId.push_back(qIdx_closest);
426  else for(std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs) LastQuarkId.push_back(qIdDrPair.second);
427  }
428  for(int qIdx : LastQuarkId) {
429  int qmIdx = hadMothersIndices.at ( qIdx ).at(0);
430  LastQuarkMotherId.push_back( qmIdx );
431  }
432 
433  if((int)LastQuarkId.size()>0) lastQuarkIndices.at(hadNum) = 0; // Setting the first quark in array as a candidate if it exists
434 
435  LastQuarkIds.push_back( LastQuarkId );
436 
437  LastQuarkMotherIds.push_back ( LastQuarkMotherId );
438 
439  if(LastQuarkMotherId.size()<1) {
440  hadronFlavour = 0;
441  } else {
442  int qIdx = LastQuarkId.at( lastQuarkIndices.at(hadNum) );
443  int qFlav = ( hadMothers.at(qIdx).pdgId() < 0 ) ? -1 : 1;
444  hadronFlavour = qFlav*std::abs( hadMothers.at( LastQuarkMotherId.at( lastQuarkIndices.at(hadNum) ) ).pdgId() );
445  }
446  hadFlavour.push_back(hadronFlavour); // Adding hadron flavour to the list of flavours
447 
448  // Checking whether hadron comes from the Top weak decay
449  int isFromTopWeakDecay = 1;
450  std::vector <int> checkedParticles;
451  if(hadFlavour.at(hadNum)!=0) {
452  int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
453  bool fromTB = topDaughterQId>=0?findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0, false, topDaughterQId, 2, false ) >= 0 : false;
454  checkedParticles.clear();
455  bool fromTbarB = topBarDaughterQId>=0?findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0, false, topBarDaughterQId, 2, false) >= 0:false;
456  checkedParticles.clear();
457  if(!fromTB && !fromTbarB) {
458  isFromTopWeakDecay = 0;
459  }
460  } else isFromTopWeakDecay = 2;
461  hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
462  int bHadronMotherId = findInMothers( hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555, true, -1, 1, false );
463  hadBHadronId.push_back(bHadronMotherId);
464 
465 
466  if(LastQuarkMotherId.size()>0) {
467  std::set<int> checkedHadronIds;
468  fixExtraSameFlavours(hadNum, hadIndex, hadMothers, hadMothersIndices, hadFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadFlavour, checkedHadronIds, 0);
469  }
470 
471  } // End of loop over all hadrons
472 
473 
474  return hadJetIndex;
475 }
int i
Definition: DBlmapReader.cc:9
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
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.
const_iterator end() const
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:249
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:244
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)
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
Class storing the jet flavour information.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int findInMothers(int idx, std::vector< int > &mothChains, std::vector< std::vector< int > > &hadMothersIndices, std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose)
helper function to find indices of particles with particular pdgId and status from the list of mother...
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
virtual int pdgId() const =0
PDG identifier.
edm::RefVector< GenParticleCollection > GenParticleRefVector
vector of reference to GenParticle in the same collection
const GenParticleRefVector & getLeptons() const
Return a vector of GenParticleRef&#39;s to leptons clustered inside the jet.
volatile std::atomic< bool > shutdown_flag false
bool isHadron(const int flavour, const reco::Candidate *thisParticle)
Check the pdgId of a given particle if it is a hadron.
const_iterator begin() const
bool hasHadronDaughter(const int flavour, const reco::Candidate *thisParticle)
Check if the particle has bHadron among daughters.
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)
int GenHFHadronMatcher::findInMothers ( int  idx,
std::vector< int > &  mothChains,
std::vector< std::vector< int > > &  hadMothersIndices,
std::vector< reco::GenParticle > &  hadMothers,
int  status,
int  pdgId,
bool  pdgAbs = false,
int  stopId = -1,
int  firstLast = 0,
bool  verbose = false 
)
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 736 of file GenHFHadronMatcher.cc.

References funct::abs(), edm::false, i, customizeTrackingMonitorSeedNumber::idx, isHadronPdgId(), relval_steps::k, and funct::true.

Referenced by findHadronJets().

737 {
738  int foundStopId = -1;
739  int pdg_1 = hadMothers.at ( idx ).pdgId();
740  int partCharge = ( hadMothers.at ( idx ).pdgId() >0 ) ?1:-1;
741 // Inverting charge if mother is a b(c) meson
742  if ( abs ( hadMothers.at ( idx ).pdgId() ) /1000 < 1 && ( abs ( hadMothers.at ( idx ).pdgId() ) /100%10 == 4 || abs ( hadMothers.at ( idx ).pdgId() ) /100%10 == 5 ) ) {
743  partCharge*=-1;
744  }
745 
746  if ( ( int ) hadMothersIndices.size() <=idx ) {
747  if ( verbose ) {
748  printf ( " Stopping checking particle %d. No mothers are stored.\n",idx );
749  }
750  return -1; // Skipping if no mothers are stored for this particle
751  }
752 
753  if(std::abs(hadMothers.at( idx ).pdgId()) > 10 && std::abs(hadMothers.at( idx ).pdgId()) < 19) printf("Lepton: %d\n", hadMothers.at( idx ).pdgId());
754 
755  std::vector<int> mothers = hadMothersIndices.at ( idx );
756  unsigned int nMothers = mothers.size();
757  bool isCorrect=false; // Whether current particle is what is being searched
758  if ( verbose ) {
759  if ( abs ( hadMothers.at ( idx ).pdgId() ) ==2212 ) {
760  printf ( "Chk: %d\tpdg: %d\tstatus: %d",idx, hadMothers.at ( idx ).pdgId(), hadMothers.at ( idx ).status() );
761  } else {
762  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() );
763  }
764  }
765  bool hasCorrectMothers = true;
766  if(nMothers<1) hasCorrectMothers=false; else if(mothers.at(0)<0) hasCorrectMothers=false;
767  if(!hasCorrectMothers) {
768  if(verbose) printf(" NO CORRECT MOTHER\n");
769  return -1;
770  }
771  // Stopping if the particular particle has been found
772  if(stopId>=0 && idx == stopId) return idx;
773 
774  // Stopping if the hadron of particular flavour has been found
775  if(pdgId%111111==0 && pdgId!=0) {
776  if(isHadronPdgId(pdgId/111111, hadMothers.at(idx).pdgId())) {
777  return idx;
778  }
779  }
780 
781  // Checking whether current mother satisfies selection criteria
782  if ( ( ( hadMothers.at ( idx ).pdgId() == pdgId && pdgAbs==false )
783  || ( abs ( hadMothers.at ( idx ).pdgId() ) == abs ( pdgId ) && pdgAbs==true ) )
784  && ( hadMothers.at ( idx ).status() == status || status==0 )
785  && hasCorrectMothers ) {
786  isCorrect=true;
787  bool inList=false;
788  for ( unsigned int k=0; k<mothChains.size(); k++ ) if ( mothChains[k]==idx ) {
789  inList=true; // Checking whether isn't already in the list
790  break;
791  }
792  if ( !inList && mothers.at ( 0 ) >=0 && ( hadMothers.at ( idx ).pdgId() *pdgId>0 || !pdgAbs ) ) { // If not in list and mother of this quark has correct charge
793  if ( firstLast==0 || firstLast==1 ) {
794  mothChains.push_back ( idx );
795  }
796  if ( verbose ) {
797  printf ( " *" );
798  }
799  }
800  if ( verbose ) {
801  printf ( " +++" );
802  }
803  }
804  if ( verbose ) {
805  printf ( "\n" );
806  }
807 
808  if ( isCorrect && firstLast==1 ) {
809  return -1; // Stopping if only the first particle in the chain is looked for
810  }
811 
812 // Checking next level mothers
813  unsigned int nDifferingMothers = 0;
814  for ( unsigned int i=0; i<nMothers; i++ ) {
815  int idx2 = mothers[i];
816  if ( idx2<0 ) {
817  if(verbose) printf("^^^ Has no mother\n");
818  continue; // Skipping if mother's id is -1 (no mother), that means current particle is a proton
819  }
820  if ( idx2==idx ) {
821  if(verbose) printf("^^^ Stored as its own mother\n");
822  continue; // Skipping if particle is stored as its own mother
823  }
824  int pdg_2 = hadMothers[idx2].pdgId();
825  // Inverting the flavour if bb oscillation detected
826  if ( isHadronPdgId(pdgId, pdg_1) && isHadronPdgId(pdgId, pdg_2) && pdg_1*pdg_2 < 0 ) {
827  pdgId*=-1;
828  if(verbose) printf("######### Inverting flavour of the hadron\n");
829  }
830  // Counting how many mothers are different from this particle
831  if ( ( std::abs ( pdg_2 ) != abs ( pdgId ) && pdgAbs==true ) ||
832  ( pdg_2 != pdgId && pdgAbs==false ) ) {
833  nDifferingMothers++;
834  }
835 
836 // Checking next level mother
837  if ( verbose ) {
838  printf ( "Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",i,nMothers,idx, idx2, pdgId );
839  }
840  if(firstLast==2 && pdg_1 != pdg_2) continue; // Requiring the same flavour when finding the last quark
841  foundStopId = findInMothers ( idx2, mothChains, hadMothersIndices, hadMothers, status, pdgId, pdgAbs, stopId, firstLast, verbose );
842  }
843  // Storing this particle if all its mothers are of another type and the last of its kind should be stored
844  if(firstLast==2 && isCorrect && nDifferingMothers >= nMothers) {
845  if ( verbose ) {
846  printf ( "Checking particle %d once more to store it as the last quark\n",idx);
847  }
848  foundStopId = findInMothers ( idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1, verbose );
849  }
850 
851  return foundStopId;
852 }
int i
Definition: DBlmapReader.cc:9
bool isHadronPdgId(const int flavour, const int pdgId)
Check the pdgId if it represents a hadron of particular flavour.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int findInMothers(int idx, std::vector< int > &mothChains, std::vector< std::vector< int > > &hadMothersIndices, std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose)
helper function to find indices of particles with particular pdgId and status from the list of mother...
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
volatile std::atomic< bool > shutdown_flag false
tuple status
Definition: ntuplemaker.py:245
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 
)
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 888 of file GenHFHadronMatcher.cc.

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

Referenced by findHadronJets().

894 {
895  if(checkedHadronIds.count(hadId) != 0) return false; // Hadron already checked previously and should be skipped
896  checkedHadronIds.insert(hadId); // Putting hadron to the list of checked ones in this run
897 
898  if(lastQuarkIndex<0) return false;
899  if((int)LastQuarkIds.at(hadId).size()<lastQuarkIndex+1) return false;
900  int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
901  int LastQuarkMotherId = LastQuarkMotherIds.at( hadId ).at( lastQuarkIndex );
902  int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
903  int hadFlavour = qmFlav*std::abs( hadMothers.at( LastQuarkMotherId ).pdgId() );
904  bool ambiguityResolved = true;
905  // If last quark has inconsistent flavour with its mother, setting the hadron flavour to gluon
906  if( (hadMothers.at(LastQuarkId).pdgId()*hadMothers.at(LastQuarkMotherId).pdgId() < 0 && !isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
907  // If particle not coming from the Top weak decay has Top flavour
908  (std::abs(hadronFlavour.at(hadId))==6 && isFromTopWeakDecay.at(hadId)==0) ) {
909  if((int)LastQuarkIds.at(hadId).size()>lastQuarkIndex+1) fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1);
910  else hadronFlavour.at(hadId) = qmFlav*21;
911  return true;
912  }
913 
914  int nSameFlavourHadrons = 0;
915  // Looping over all previous hadrons
916  for(unsigned int iHad = 0; iHad<hadronFlavour.size(); iHad++) {
917  if(iHad==hadId) continue;
918  int theLastQuarkIndex = lastQuarkIndices.at(iHad);
919  if(theLastQuarkIndex<0) continue;
920  if((int)LastQuarkMotherIds.at( iHad ).size() <= theLastQuarkIndex) continue;
921  int theLastQuarkMotherId = LastQuarkMotherIds.at( iHad ).at( theLastQuarkIndex );
922  int theHadFlavour = hadronFlavour.at(iHad);
923  // Skipping hadrons with different flavour
924  if(theHadFlavour==0 || std::abs(theHadFlavour)==21) continue;
925  if(theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId) continue;
926  ambiguityResolved = false;
927  nSameFlavourHadrons++;
928 
929  // Checking other b-quark mother candidates of this hadron
930  if((int)LastQuarkIds.at(hadId).size() > lastQuarkIndex+1) {
931  if(fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1) ) {
932  ambiguityResolved = true;
933  break;
934  }
935  } else
936  // Checking other b-quark mother candidates of the particular previous hadron
937  if((int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex+1) {
938  if(fixExtraSameFlavours(iHad, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, theLastQuarkIndex+1) ) {
939  ambiguityResolved = true;
940  break;
941  };
942  }
943 
944  } // End of loop over all previous hadrons
945 
946  checkedHadronIds.erase(hadId); // Removing the hadron from the list of checked hadrons
947  if(nSameFlavourHadrons>0 && !ambiguityResolved) {
948  hadronFlavour.at(hadId) = qmFlav*21;
949  return true;
950  }
951  lastQuarkIndices.at(hadId) = lastQuarkIndex;
952  hadronFlavour.at(hadId) = hadFlavour;
953  return true;
954 }
bool isNeutralPdg(int pdgId)
Check whether a given pdgId represents neutral particle.
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)
std::string GenHFHadronMatcher::getParticleName ( int  id) const
private
bool GenHFHadronMatcher::hasHadronDaughter ( const int  flavour,
const reco::Candidate thisParticle 
)
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 555 of file GenHFHadronMatcher.cc.

References reco::Candidate::daughter(), isHadron(), relval_steps::k, and reco::Candidate::numberOfDaughters().

Referenced by findHadronJets().

556 {
557 // Looping through daughters of the particle
558  bool hasDaughter = false;
559  for ( int k=0; k< ( int ) thisParticle->numberOfDaughters(); k++ ) {
560  if ( !isHadron ( flavour, thisParticle->daughter ( k ) ) ) {
561  continue;
562  }
563  hasDaughter = true;
564  break;
565  }
566  return hasDaughter;
567 }
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
virtual size_type numberOfDaughters() const =0
number of daughters
bool isHadron(const int flavour, const reco::Candidate *thisParticle)
Check the pdgId of a given particle if it is a hadron.
int flavour(const Candidate &part)
Definition: pdgIdUtils.h:31
bool GenHFHadronMatcher::isHadron ( const int  flavour,
const reco::Candidate thisParticle 
)
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 515 of file GenHFHadronMatcher.cc.

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

Referenced by findHadronJets(), and hasHadronDaughter().

516 {
517  return isHadronPdgId(flavour, thisParticle->pdgId());
518 }
bool isHadronPdgId(const int flavour, const int pdgId)
Check the pdgId if it represents a hadron of particular flavour.
virtual int pdgId() const =0
PDG identifier.
int flavour(const Candidate &part)
Definition: pdgIdUtils.h:31
bool GenHFHadronMatcher::isHadronPdgId ( const int  flavour,
const int  pdgId 
)
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
if the pdgId represents a hadron of specified flavour

Definition at line 529 of file GenHFHadronMatcher.cc.

References funct::abs(), and noBBbarResonances_.

Referenced by findInMothers(), and isHadron().

530 {
531  int flavour_abs = std::abs(flavour);
532  if(flavour_abs > 5 || flavour_abs < 1) return false;
533  int pdgId_abs = std::abs(pdgId);
534 
535  if ( pdgId_abs / 1000 == flavour_abs // baryons
536  || ( pdgId_abs / 100 % 10 == flavour_abs // mesons
537  && ! ( noBBbarResonances_ && pdgId_abs / 10 % 100 == 11*flavour_abs ) // but not a resonance
538  )
539  ) {
540  return true;
541  } else {
542  return false;
543  }
544 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int flavour(const Candidate &part)
Definition: pdgIdUtils.h:31
int GenHFHadronMatcher::isInList ( std::vector< const reco::Candidate * >  particleList,
const reco::Candidate particle 
)
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 486 of file GenHFHadronMatcher.cc.

References i.

Referenced by analyzeMothers().

487 {
488  for ( unsigned int i = 0; i<particleList.size(); i++ )
489  if ( particleList.at(i)==particle ) {
490  return i;
491  }
492 
493  return -1;
494 }
int i
Definition: DBlmapReader.cc:9
int GenHFHadronMatcher::isInList ( std::vector< int >  list,
const int  value 
)
private

Definition at line 496 of file GenHFHadronMatcher.cc.

References i, and relativeConstraints::value.

497 {
498  for ( unsigned int i = 0; i<list.size(); i++ )
499  if ( list.at(i)==value ) {
500  return i;
501  }
502 
503  return -1;
504 }
int i
Definition: DBlmapReader.cc:9
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::isNeutralPdg ( int  pdgId)
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 863 of file GenHFHadronMatcher.cc.

References funct::abs(), i, and bookConverter::max.

Referenced by fixExtraSameFlavours().

864 {
865  const int max = 5;
866  int neutralPdgs[max]= {9,21,22,23,25};
867  for ( int i=0; i<max; i++ ) if ( abs ( pdgId ) ==neutralPdgs[i] ) {
868  return true;
869  }
870  return false;
871 }
int i
Definition: DBlmapReader.cc:9
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void GenHFHadronMatcher::produce ( edm::Event evt,
const edm::EventSetup setup 
)
privatevirtual

Implements edm::EDProducer.

Definition at line 192 of file GenHFHadronMatcher.cc.

References findHadronJets(), flavourStr_, genParticleCandidates2GenParticles_cfi::genParticles, genParticlesToken_, edm::Event::getByToken(), edm::EventSetup::getData(), jetFlavourInfosToken_, pdt_, and edm::Event::put().

193 {
194 
195  setup.getData ( pdt_ );
196 
197  using namespace edm;
198 
201 
203  evt.getByToken(jetFlavourInfosToken_, jetFlavourInfos);
204 
205  // Defining adron matching variables
206  std::auto_ptr<std::vector<reco::GenParticle> > hadMothers ( new std::vector<reco::GenParticle> );
207  std::auto_ptr<std::vector<std::vector<int> > > hadMothersIndices ( new std::vector<std::vector<int> > );
208  std::auto_ptr<std::vector<int> > hadIndex ( new std::vector<int> );
209  std::auto_ptr<std::vector<int> > hadFlavour ( new std::vector<int> );
210  std::auto_ptr<std::vector<int> > hadJetIndex ( new std::vector<int> );
211  std::auto_ptr<std::vector<int> > hadLeptonIndex ( new std::vector<int> );
212  std::auto_ptr<std::vector<int> > hadLeptonHadIndex ( new std::vector<int> );
213  std::auto_ptr<std::vector<int> > hadLeptonViaTau( new std::vector<int> );
214  std::auto_ptr<std::vector<int> > hadFromTopWeakDecay ( new std::vector<int> );
215  std::auto_ptr<std::vector<int> > hadBHadronId ( new std::vector<int> );
216 
217  *hadJetIndex = findHadronJets (genParticles.product(), jetFlavourInfos.product(), *hadIndex, *hadMothers, *hadMothersIndices, *hadLeptonIndex, *hadLeptonHadIndex, *hadLeptonViaTau, *hadFlavour, *hadFromTopWeakDecay, *hadBHadronId );
218 
219  // Putting products to the event
220  evt.put ( hadMothers, "gen"+flavourStr_+"HadPlusMothers" );
221  evt.put ( hadMothersIndices, "gen"+flavourStr_+"HadPlusMothersIndices" );
222  evt.put ( hadIndex, "gen"+flavourStr_+"HadIndex" );
223  evt.put ( hadFlavour, "gen"+flavourStr_+"HadFlavour" );
224  evt.put ( hadJetIndex, "gen"+flavourStr_+"HadJetIndex" );
225  evt.put ( hadLeptonIndex, "gen"+flavourStr_+"HadLeptonIndex" );
226  evt.put ( hadLeptonHadIndex, "gen"+flavourStr_+"HadLeptonHadronIndex" );
227  evt.put ( hadLeptonViaTau, "gen"+flavourStr_+"HadLeptonViaTau" );
228  evt.put ( hadFromTopWeakDecay,"gen"+flavourStr_+"HadFromTopWeakDecay" );
229  evt.put ( hadBHadronId, "gen"+flavourStr_+"HadBHadronId" );
230 }
edm::ESHandle< ParticleDataTable > pdt_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:449
void getData(T &iHolder) const
Definition: EventSetup.h:78
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
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)
identify the jets that contain b-hadrons
bool GenHFHadronMatcher::putMotherIndex ( std::vector< std::vector< int > > &  hadMothersIndices,
int  partIndex,
int  mothIndex 
)
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 683 of file GenHFHadronMatcher.cc.

References relval_steps::k.

Referenced by analyzeMothers().

684 {
685  // Putting vector of mothers indices for the given particle
686  bool inList=false;
687  if ( partIndex<0 ) {
688  return false;
689  }
690 
691  while ( ( int ) hadMothersIndices.size() <=partIndex ) { // If there is no list of mothers for current particle yet
692  std::vector<int> mothersIndices;
693  hadMothersIndices.push_back ( mothersIndices );
694  }
695 
696  std::vector<int> *hadMotherIndices=&hadMothersIndices.at ( partIndex );
697  // Removing other mothers if particle must have no mothers
698  if ( mothIndex==-1 ) {
699  hadMotherIndices->clear();
700  } else {
701  // Checking if current mother is already in the list of theParticle's mothers
702  for ( int k=0; k< ( int ) hadMotherIndices->size(); k++ ) {
703  if ( hadMotherIndices->at ( k ) !=mothIndex && hadMotherIndices->at ( k ) !=-1 ) {
704  continue;
705  }
706  inList=true;
707  break;
708  }
709  }
710  // Adding current mother to the list of mothers of this particle
711  if ( !inList ) {
712  hadMotherIndices->push_back ( mothIndex );
713  }
714 
715  return inList;
716 }

Member Data Documentation

int GenHFHadronMatcher::flavour_
private

Definition at line 103 of file GenHFHadronMatcher.cc.

Referenced by findHadronJets(), and GenHFHadronMatcher().

std::string GenHFHadronMatcher::flavourStr_
private

Definition at line 107 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and produce().

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

Definition at line 101 of file GenHFHadronMatcher.cc.

Referenced by produce().

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

Definition at line 102 of file GenHFHadronMatcher.cc.

Referenced by produce().

bool GenHFHadronMatcher::noBBbarResonances_
private

Definition at line 104 of file GenHFHadronMatcher.cc.

Referenced by GenHFHadronMatcher(), and isHadronPdgId().

bool GenHFHadronMatcher::onlyJetClusteredHadrons_
private

Definition at line 105 of file GenHFHadronMatcher.cc.

Referenced by findHadronJets(), and GenHFHadronMatcher().

edm::ESHandle<ParticleDataTable> GenHFHadronMatcher::pdt_
private

Definition at line 109 of file GenHFHadronMatcher.cc.

Referenced by produce().