70 std::vector<int> &hadIndex, std::vector<reco::GenParticle> &hadMothersGenPart,
71 std::vector<std::vector<int> > &hadMothersIndices, std::vector<int> &hadLeptonIndex,
72 std::vector<int> &hadLeptonHadIndex, std::vector<int> &hadLeptonViaTau,
73 std::vector<int> &hadFlavour, std::vector<int> &hadFromTopWeakDecay, std::vector<int> &hadBHadronId );
75 std::vector<const reco::Candidate*> &hadMothers, std::vector<std::vector<int> > &hadMothersIndices,
76 std::set<const reco::Candidate*> *analyzedParticles,
const int prevPartIndex );
77 bool putMotherIndex( std::vector<std::vector<int> > &hadMothersIndices,
int partIndex,
int mothIndex );
86 int findInMothers(
int idx, std::vector<int> &mothChains,
const std::vector<std::vector<int> > &hadMothersIndices,
87 const std::vector<reco::GenParticle> &hadMothers,
int status,
int pdgId,
bool pdgAbs,
88 int stopId,
int firstLast,
bool verbose );
95 const std::vector<reco::GenParticle> &hadMothers,
const std::vector<std::vector<int> > &hadMothersIndices,
96 const std::vector<int> &isFromTopWeakDecay,
const std::vector<std::vector<int> > &LastQuarkIds,
97 const std::vector<std::vector<int> > &LastQuarkMotherIds, std::vector<int> &lastQuarkIndices,
98 std::vector<int> &
hadronFlavour, std::set<int> &checkedHadronIds,
const int lastQuarkIndex );
143 }
else if ( flavour_==4 ) {
146 edm::LogError (
"GenHFHadronMatcher" ) <<
"Flavour option must be 4 (c-jet) or 5 (b-jet), but is: " << flavour_ <<
". Correct this!";
150 produces< std::vector<reco::GenParticle> > (
"gen"+
flavourStr_+
"HadPlusMothers" );
151 produces< std::vector< std::vector<int> > > (
"gen"+
flavourStr_+
"HadPlusMothersIndices" );
152 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadIndex" );
153 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadFlavour" );
154 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadJetIndex" );
155 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonIndex" );
156 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonHadronIndex" );
157 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonViaTau" );
158 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadFromTopWeakDecay" );
159 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadBHadronId" );
175 desc.
add<
edm::InputTag>(
"genParticles")->setComment(
"Collection of GenParticle objects which contains all particles produced in the event" );
176 desc.
add<
edm::InputTag>(
"jetFlavourInfos")->setComment(
"Output from the JetFlavour tool. Contains information about partons/hadrons/leptons associated to jets" );
177 desc.
add<
bool> (
"noBBbarResonances",
true )->setComment (
"Whether resonances should not be treated as hadrons" );
178 desc.
add<
bool> (
"onlyJetClusteredHadrons",
false )->setComment (
"Whether only hadrons that are matched to jets should be analysed. Runs x1000 faster in Sherpa" );
179 desc.
add<
int> (
"flavour",5 )->setComment (
"Flavour of weakly decaying hadron that should be analysed (4-c, 5-b)" );
180 descriptions.
add (
"matchGenHFHadron",desc );
203 auto hadMothers = std::make_unique<std::vector<reco::GenParticle> >();
204 auto hadMothersIndices = std::make_unique<std::vector<std::vector<int> > >();
205 auto hadIndex = std::make_unique<std::vector<int> >();
206 auto hadFlavour = std::make_unique<std::vector<int> >();
207 auto hadJetIndex = std::make_unique<std::vector<int> >();
208 auto hadLeptonIndex = std::make_unique<std::vector<int> >();
209 auto hadLeptonHadIndex = std::make_unique<std::vector<int> >();
210 auto hadLeptonViaTau = std::make_unique<std::vector<int> >();
211 auto hadFromTopWeakDecay = std::make_unique<std::vector<int> >();
212 auto hadBHadronId = std::make_unique<std::vector<int> >();
214 *hadJetIndex =
findHadronJets (genParticles.
product(), jetFlavourInfos.
product(), *hadIndex, *hadMothers, *hadMothersIndices, *hadLeptonIndex, *hadLeptonHadIndex, *hadLeptonViaTau, *hadFlavour, *hadFromTopWeakDecay, *hadBHadronId );
254 std::vector<int> &hadIndex,
255 std::vector<reco::GenParticle> &hadMothers, std::vector<std::vector<int> > &hadMothersIndices,
256 std::vector<int> &hadLeptonIndex, std::vector<int> &hadLeptonHadIndex,
257 std::vector<int> &hadLeptonViaTau, std::vector<int> &hadFlavour,
258 std::vector<int> &hadFromTopWeakDecay, std::vector<int> &hadBHadronId )
260 std::vector<int> hadJetIndex;
261 std::vector<const reco::Candidate*> hadMothersCand;
263 int topDaughterQId = -1;
264 int topBarDaughterQId = -1;
269 const int jetIndex = i_info - jetFlavourInfos->
begin();
277 int hadronIndex =
analyzeMothers ( (
reco::Candidate*)(&**hadron), topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
279 hadIndex.push_back ( hadronIndex );
280 hadJetIndex.push_back ( jetIndex );
286 for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
290 if(
std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end())
continue;
293 int hadronIndex =
analyzeMothers ( thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
295 hadIndex.push_back ( hadronIndex );
296 hadJetIndex.push_back ( -1 );
301 for (
int i=0;
i< (
int)hadMothersCand.size();
i++ ) {
303 hadMothers.push_back(*particle);
307 for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
309 const int pdg_abs = lepton.
pdgId();
311 if(pdg_abs != 11 && pdg_abs != 13)
continue;
312 bool leptonViaTau =
false;
314 if(!leptonMother)
continue;
318 leptonMother = leptonMother->
mother();
323 size_t leptonHadronParticleIndex =
std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
324 if(leptonHadronParticleIndex >= hadMothersCand.size())
continue;
326 size_t leptonHadronIndex =
std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
327 if(leptonHadronIndex >= hadIndex.size())
continue;
329 hadMothers.push_back(lepton);
330 const int leptonIndex = hadMothersCand.size()-1;
331 hadLeptonIndex.push_back(leptonIndex);
332 hadLeptonViaTau.push_back(leptonViaTau);
333 hadLeptonHadIndex.push_back(leptonHadronIndex);
337 unsigned int nHad = hadIndex.size();
339 std::vector<std::vector<int> > LastQuarkMotherIds;
340 std::vector<std::vector<int> > LastQuarkIds;
341 std::vector<int> lastQuarkIndices(nHad, -1);
344 for (
unsigned int hadNum=0; hadNum<nHad; hadNum++ ) {
345 unsigned int hadIdx = hadIndex.at(hadNum);
347 std::vector <int> FirstQuarkId;
348 std::vector <int> LastQuarkId;
349 std::vector <int> LastQuarkMotherId;
351 const int hadronFlavourSign =
flavourSign( hadMothers.at(hadIdx).pdgId() );
354 if(hadronFlavourSign != 0) {
355 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadronFlavourSign*
flavour_,
false, -1, 1,
false );
359 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0,
flavour_,
false, -1, 1,
false );
360 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, -1*
flavour_,
false, -1, 1,
false );
364 for (
unsigned int qId=0; qId<FirstQuarkId.size(); qId++ ) {
366 const int quarkFlavourSign =
flavourSign( hadMothers.at(FirstQuarkId.at(qId)).
pdgId() );
368 findInMothers( FirstQuarkId.at(qId), LastQuarkId, hadMothersIndices, hadMothers, 0, quarkFlavourSign*
flavour_,
false, -1, 2,
false );
376 std::vector<std::pair<double, int> > lastQuark_dR_id_pairs;
379 for (
unsigned int qId = 0; qId < LastQuarkId.size(); qId++ ) {
380 int qIdx = LastQuarkId.at(qId);
382 float dR =
deltaR ( hadMothers.at(hadIdx).eta(),hadMothers.at(hadIdx).phi(),hadMothers.at(qIdx).eta(),hadMothers.at(qIdx).phi() );
384 std::pair<double, int> dR_hadId_pair(dR,qIdx);
385 lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
388 std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
390 if(lastQuark_dR_id_pairs.size() > 1) {
391 double dRratio = (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first)/lastQuark_dR_id_pairs.at(1).first;
392 int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
394 if(dRratio>0.5) LastQuarkId.push_back(qIdx_closest);
395 else for(std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs) LastQuarkId.push_back(qIdDrPair.second);
397 for(
int qIdx : LastQuarkId) {
398 int qmIdx = hadMothersIndices.at(qIdx).at(0);
399 LastQuarkMotherId.push_back(qmIdx);
402 if((
int)LastQuarkId.size()>0) lastQuarkIndices.at(hadNum) = 0;
404 LastQuarkIds.push_back( LastQuarkId );
406 LastQuarkMotherIds.push_back ( LastQuarkMotherId );
408 if(LastQuarkMotherId.size()<1) {
411 int qIdx = LastQuarkId.at( lastQuarkIndices.at(hadNum) );
412 int qFlav =
flavourSign( hadMothers.at(qIdx).pdgId() );
413 hadronFlavour = qFlav*
std::abs( hadMothers.at( LastQuarkMotherId.at( lastQuarkIndices.at(hadNum) ) ).pdgId() );
415 hadFlavour.push_back(hadronFlavour);
418 int isFromTopWeakDecay = 1;
419 std::vector <int> checkedParticles;
420 if(hadFlavour.at(hadNum) != 0) {
421 int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
422 bool fromTB = topDaughterQId >= 0 ?
findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0,
false, topDaughterQId, 2,
false ) >= 0 :
false;
423 checkedParticles.clear();
424 bool fromTbarB = topBarDaughterQId >= 0 ?
findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0,
false, topBarDaughterQId, 2,
false) >= 0 :
false;
425 checkedParticles.clear();
426 if(!fromTB && !fromTbarB) {
427 isFromTopWeakDecay = 0;
429 }
else isFromTopWeakDecay = 2;
430 hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
431 int bHadronMotherId =
findInMothers( hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555,
true, -1, 1,
false );
432 hadBHadronId.push_back(bHadronMotherId);
435 if(LastQuarkMotherId.size()>0) {
436 std::set<int> checkedHadronIds;
437 fixExtraSameFlavours(hadNum, hadIndex, hadMothers, hadMothersIndices, hadFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadFlavour, checkedHadronIds, 0);
456 const unsigned int position =
std::find(particleList.begin(), particleList.end(), particle) - particleList.begin();
457 if( position >= particleList.size() )
return -1;
465 if( position >= list.size() )
return -1;
511 const int flavour_abs =
std::abs(flavour);
512 if(flavour_abs != 5 && flavour_abs != 4)
return false;
513 const int pdgId_abs =
std::abs(pdgId);
515 if( pdgId_abs/100%10 != flavour_abs)
return false;
517 if ( pdgId_abs/1000 == flavour_abs)
return false;
535 const int flavour_abs =
std::abs(flavour);
536 if(flavour_abs != 5 && flavour_abs != 4)
return false;
537 const int pdgId_abs =
std::abs(pdgId);
539 if ( pdgId_abs/1000 != flavour_abs)
return false;
558 if(pdgId % 1000 / 10 / 11 > 0) flavourSign = 0;
575 bool hasDaughter =
false;
605 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 )
611 hadMothers.push_back ( thisParticle );
612 hadronIndex=hadMothers.size()-1;
618 partIndex =
idInList( hadMothers, thisParticle );
622 if ( !analyzedParticles ) {
623 analyzedParticles =
new std::set<const reco::Candidate*>;
625 for (
unsigned int i=0;
i<analyzedParticles->size();
i++ ) {
626 if ( analyzedParticles->count ( thisParticle ) <=0 ) {
635 if ( prevPartIndex>=0 ) {
640 analyzedParticles->insert ( thisParticle );
643 for (
size_t iMother = 0; iMother < thisParticle->
numberOfMothers(); ++iMother ) {
645 int mothIndex =
idInList( hadMothers, mother );
646 if ( mothIndex == partIndex && partIndex>=0 ) {
652 hadMothers.push_back ( mother );
653 mothIndex=hadMothers.size()-1;
656 if ( mothIndex!=partIndex && partIndex>=0 ) {
659 analyzeMothers ( mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex );
662 int& bId = mother->
pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
665 if(thisFlav <= 5) bId = partIndex;
667 int bIdFlav =
std::abs(hadMothers.at(bId)->pdgId());
668 if( bIdFlav != 5 && thisFlav == 5) bId = partIndex;
669 else if( thisFlav == 5 && thisParticle->
pt() > hadMothers.at(bId)->pt() ) bId = partIndex;
674 analyzedParticles->erase ( thisParticle );
707 while ( (
int)hadMothersIndices.size() <= partIndex ) {
708 std::vector<int> mothersIndices;
709 hadMothersIndices.push_back ( mothersIndices );
712 std::vector<int> *hadMotherIndices = &hadMothersIndices.at(partIndex);
714 if ( mothIndex == -1 ) {
715 hadMotherIndices->clear();
718 for (
int k = 0;
k < (
int)hadMotherIndices->size();
k++ ) {
719 if ( hadMotherIndices->at(
k) != mothIndex && hadMotherIndices->at(
k) != -1 ) {
728 hadMotherIndices->push_back(mothIndex);
753 const std::vector<reco::GenParticle> &hadMothers,
int status,
int pdgId,
bool pdgAbs=
false,
754 int stopId=-1,
int firstLast=0,
bool verbose=
false)
756 int foundStopId = -1;
757 int pdg_1 = hadMothers.at(idx).pdgId();
759 if ( (
int)hadMothersIndices.size() <=
idx ) {
761 printf (
" Stopping checking particle %d. No mothers are stored.\n",idx );
766 if(
std::abs(hadMothers.at( idx ).pdgId()) > 10 &&
std::abs(hadMothers.at( idx ).pdgId()) < 19) printf(
"Lepton: %d\n", hadMothers.at( idx ).pdgId());
768 std::vector<int> mothers = hadMothersIndices.at(idx);
769 unsigned int nMothers = mothers.size();
770 bool isCorrect=
false;
772 if (
std::abs( hadMothers.at(idx).pdgId() ) ==2212 ) {
773 printf (
"Chk: %d\tpdg: %d\tstatus: %d",idx, hadMothers.at(idx).pdgId(), hadMothers.at(idx).status() );
775 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() );
778 bool hasCorrectMothers =
true;
779 if(nMothers<1) hasCorrectMothers=
false;
else if(mothers.at(0)<0) hasCorrectMothers=
false;
780 if(!hasCorrectMothers) {
781 if(
verbose) printf(
" NO CORRECT MOTHER\n");
785 if(stopId>=0 && idx == stopId)
return idx;
788 if(pdgId%111111==0 && pdgId!=0) {
789 if(
isHadronPdgId(pdgId/111111, hadMothers.at(idx).pdgId())) {
795 if ( ( ( hadMothers.at(idx).pdgId() == pdgId && pdgAbs==
false )
797 && ( hadMothers.at(idx).status() == status || status==0 )
798 && hasCorrectMothers ) {
801 const bool inList =
std::find(mothChains.begin(), mothChains.end(),
idx) != mothChains.end();
802 if ( !inList && mothers.at(0) >= 0 && ( hadMothers.at(idx).pdgId()*pdgId > 0 || !pdgAbs ) ) {
803 if ( firstLast==0 || firstLast==1 ) {
804 mothChains.push_back(idx);
818 if ( isCorrect && firstLast==1 ) {
823 unsigned int nDifferingMothers = 0;
824 for (
unsigned int i = 0;
i < nMothers;
i++ ) {
825 int idx2 = mothers.at(
i);
827 if(
verbose) printf(
"^^^ Has no mother\n");
831 if(
verbose) printf(
"^^^ Stored as its own mother\n");
834 int pdg_2 = hadMothers[idx2].pdgId();
838 if(
verbose) printf(
"######### Inverting flavour of the hadron\n");
842 ( pdg_2 != pdgId && pdgAbs ==
false ) ) {
848 printf (
"Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",
i,nMothers,idx, idx2, pdgId );
850 if(firstLast==2 && pdg_1 != pdg_2)
continue;
851 foundStopId =
findInMothers ( idx2, mothChains, hadMothersIndices, hadMothers, status, pdgId, pdgAbs, stopId, firstLast,
verbose );
854 if(firstLast==2 && isCorrect && nDifferingMothers >= nMothers) {
856 printf (
"Checking particle %d once more to store it as the last quark\n",idx);
858 foundStopId =
findInMothers ( idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1,
verbose );
875 const int neutralPdgs_array[] = {9, 21, 22, 23, 25};
876 const std::vector<int> neutralPdgs( neutralPdgs_array, neutralPdgs_array +
sizeof(neutralPdgs_array) /
sizeof(
int) );
877 if(
std::find( neutralPdgs.begin(), neutralPdgs.end(),
std::abs(pdgId) ) == neutralPdgs.end() )
return false;
898 const unsigned int hadId,
const std::vector<int> &hadIndices,
const std::vector<reco::GenParticle> &hadMothers,
899 const std::vector<std::vector<int> > &hadMothersIndices,
const std::vector<int> &isFromTopWeakDecay,
900 const std::vector<std::vector<int> > &LastQuarkIds,
const std::vector<std::vector<int> > &LastQuarkMotherIds,
901 std::vector<int> &lastQuarkIndices, std::vector<int> &
hadronFlavour,
902 std::set<int> &checkedHadronIds,
const int lastQuarkIndex)
904 if(checkedHadronIds.count(hadId) != 0)
return false;
905 checkedHadronIds.insert(hadId);
907 if(lastQuarkIndex<0)
return false;
908 if((
int)LastQuarkIds.at(hadId).size()<lastQuarkIndex+1)
return false;
909 int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
910 int LastQuarkMotherId = LastQuarkMotherIds.at( hadId ).at( lastQuarkIndex );
911 int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
912 int hadFlavour = qmFlav*
std::abs( hadMothers.at( LastQuarkMotherId ).pdgId() );
913 bool ambiguityResolved =
true;
915 if( (hadMothers.at(LastQuarkId).pdgId()*hadMothers.at(LastQuarkMotherId).pdgId() < 0 && !
isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
917 (
std::abs(hadronFlavour.at(hadId))==6 && isFromTopWeakDecay.at(hadId)==0) ) {
918 if((
int)LastQuarkIds.at(hadId).size()>lastQuarkIndex+1)
fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1);
919 else hadronFlavour.at(hadId) = qmFlav*21;
923 int nSameFlavourHadrons = 0;
925 for(
unsigned int iHad = 0; iHad<hadronFlavour.size(); iHad++) {
926 if(iHad==hadId)
continue;
927 int theLastQuarkIndex = lastQuarkIndices.at(iHad);
928 if(theLastQuarkIndex<0)
continue;
929 if((
int)LastQuarkMotherIds.at( iHad ).size() <= theLastQuarkIndex)
continue;
930 int theLastQuarkMotherId = LastQuarkMotherIds.at( iHad ).at( theLastQuarkIndex );
931 int theHadFlavour = hadronFlavour.at(iHad);
933 if(theHadFlavour==0 ||
std::abs(theHadFlavour)==21)
continue;
934 if(theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId)
continue;
935 ambiguityResolved =
false;
936 nSameFlavourHadrons++;
939 if((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex+1) {
940 if(
fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1) ) {
941 ambiguityResolved =
true;
946 if((
int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex+1) {
947 if(
fixExtraSameFlavours(iHad, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, theLastQuarkIndex+1) ) {
948 ambiguityResolved =
true;
955 checkedHadronIds.erase(hadId);
956 if(nSameFlavourHadrons>0 && !ambiguityResolved) {
957 hadronFlavour.at(hadId) = qmFlav*21;
960 lastQuarkIndices.at(hadId) = lastQuarkIndex;
961 hadronFlavour.at(hadId) = hadFlavour;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
int pdgId() const final
PDG identifier.
edm::ESHandle< ParticleDataTable > pdt_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
int idInList(std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle)
Check if the cpecified particle is already in the list of particles.
transient_vector_type::const_iterator const_iterator
const GenParticleRefVector & getbHadrons() const
Return a vector of GenParticleRef's to b hadrons clustered inside the jet.
int flavourSign(const int pdgId)
Sign of the flavour (matter/antimatter)
bool isHadronPdgId(const int flavour, const int pdgId)
Check the pdgId if it represents a hadron of particular flavour.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
#define DEFINE_FWK_MODULE(type)
const GenParticleRefVector & getcHadrons() const
Return a vector of GenParticleRef's to c hadrons clustered inside the jet.
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
const_iterator end() const
def setup(process, global_tag, zero_tesla=False)
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
bool checkForLoop(std::vector< const reco::Candidate * > &particleChain, const reco::Candidate *particle)
const_iterator end() const
Termination of iteration.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
bool isNeutralPdg(int pdgId)
Check whether a given pdgId represents neutral particle.
const_iterator begin() const
Initialize an iterator over the RefVector.
void getData(T &iHolder) const
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)
helper function to find indices of particles with particular pdgId and status from the list of mother...
virtual void produce(edm::Event &, const edm::EventSetup &)
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
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...
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)
Class storing the jet flavour information.
Abs< T >::type abs(const T &t)
edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
bool isMesonPdgId(const int flavour, const int pdgId)
Check the pdgId if it represents a meson of particular flavour.
ParameterDescriptionBase * add(U const &iLabel, T const &value)
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
bool isBaryonPdgId(const int flavour, const int pdgId)
Check the pdgId if it represents a baryon of particular flavour.
double deltaR(double eta1, double eta2, double phi1, double phi2)
edm::RefVector< GenParticleCollection > GenParticleRefVector
vector of reference to GenParticle in the same collection
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
description of the run-time parameters
T const * product() const
virtual double pt() const =0
transverse momentum
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static int position[264][3]
GenHFHadronMatcher(const edm::ParameterSet &)
constructor initialising producer products and config parameters
bool isHadron(const int flavour, const reco::Candidate *thisParticle)
Check the pdgId of a given particle if it is a hadron.
bool onlyJetClusteredHadrons_
virtual size_type numberOfDaughters() const =0
number of daughters
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)
Finds the origin of each heavy flavour hadron and associated jets to it.
const Candidate * mother(size_type=0) const override
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
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
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
std::string getParticleName(int id) const