77 std::vector<int> &hadIndex, std::vector<reco::GenParticle> &hadMothersGenPart,
78 std::vector<std::vector<int> > &hadMothersIndices, std::vector<int> &hadLeptonIndex,
79 std::vector<int> &hadLeptonHadIndex, std::vector<int> &hadLeptonViaTau,
80 std::vector<int> &hadFlavour, std::vector<int> &hadFromTopWeakDecay, std::vector<int> &hadBHadronId );
82 std::vector<const reco::Candidate*> &hadMothers, std::vector<std::vector<int> > &hadMothersIndices,
83 std::set<const reco::Candidate*> *analyzedParticles,
const int prevPartIndex );
84 bool putMotherIndex( std::vector<std::vector<int> > &hadMothersIndices,
int partIndex,
int mothIndex );
93 int findInMothers(
int idx, std::vector<int> &mothChains,
const std::vector<std::vector<int> > &hadMothersIndices,
94 const std::vector<reco::GenParticle> &hadMothers,
int status,
int pdgId,
bool pdgAbs,
95 int stopId,
int firstLast,
bool verbose );
102 const std::vector<reco::GenParticle> &hadMothers,
const std::vector<std::vector<int> > &hadMothersIndices,
103 const std::vector<int> &isFromTopWeakDecay,
const std::vector<std::vector<int> > &LastQuarkIds,
104 const std::vector<std::vector<int> > &LastQuarkMotherIds, std::vector<int> &lastQuarkIndices,
105 std::vector<int> &hadronFlavour, std::set<int> &checkedHadronIds,
const int lastQuarkIndex );
141 jetFlavourInfosToken_(consumes<
reco::JetFlavourInfoMatchingCollection>(cfg.getParameter<edm::
InputTag>(
"jetFlavourInfos")))
150 }
else if ( flavour_==4 ) {
153 edm::LogError (
"GenHFHadronMatcher" ) <<
"Flavour option must be 4 (c-jet) or 5 (b-jet), but is: " << flavour_ <<
". Correct this!";
157 produces< std::vector<reco::GenParticle> > (
"gen"+
flavourStr_+
"HadPlusMothers" );
158 produces< std::vector< std::vector<int> > > (
"gen"+
flavourStr_+
"HadPlusMothersIndices" );
159 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadIndex" );
160 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadFlavour" );
161 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadJetIndex" );
162 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonIndex" );
163 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonHadronIndex" );
164 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadLeptonViaTau" );
165 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadFromTopWeakDecay" );
166 produces< std::vector<int> > (
"gen"+
flavourStr_+
"HadBHadronId" );
182 desc.
add<
edm::InputTag>(
"genParticles")->setComment(
"Collection of GenParticle objects which contains all particles produced in the event" );
183 desc.
add<
edm::InputTag>(
"jetFlavourInfos")->setComment(
"Output from the JetFlavour tool. Contains information about partons/hadrons/leptons associated to jets" );
184 desc.
add<
bool> (
"noBBbarResonances",
true )->setComment (
"Whether resonances should not be treated as hadrons" );
185 desc.
add<
bool> (
"onlyJetClusteredHadrons",
false )->setComment (
"Whether only hadrons that are matched to jets should be analysed. Runs x1000 faster in Sherpa" );
186 desc.
add<
int> (
"flavour",5 )->setComment (
"Flavour of weakly decaying hadron that should be analysed (4-c, 5-b)" );
187 descriptions.
add (
"matchGenHFHadron",desc );
210 auto hadMothers = std::make_unique<std::vector<reco::GenParticle> >();
211 auto hadMothersIndices = std::make_unique<std::vector<std::vector<int> > >();
212 auto hadIndex = std::make_unique<std::vector<int> >();
213 auto hadFlavour = std::make_unique<std::vector<int> >();
214 auto hadJetIndex = std::make_unique<std::vector<int> >();
215 auto hadLeptonIndex = std::make_unique<std::vector<int> >();
216 auto hadLeptonHadIndex = std::make_unique<std::vector<int> >();
217 auto hadLeptonViaTau = std::make_unique<std::vector<int> >();
218 auto hadFromTopWeakDecay = std::make_unique<std::vector<int> >();
219 auto hadBHadronId = std::make_unique<std::vector<int> >();
221 *hadJetIndex =
findHadronJets (
genParticles.product(), jetFlavourInfos.product(), *hadIndex, *hadMothers, *hadMothersIndices, *hadLeptonIndex, *hadLeptonHadIndex, *hadLeptonViaTau, *hadFlavour, *hadFromTopWeakDecay, *hadBHadronId );
293 std::vector<int> &hadIndex,
294 std::vector<reco::GenParticle> &hadMothers, std::vector<std::vector<int> > &hadMothersIndices,
295 std::vector<int> &hadLeptonIndex, std::vector<int> &hadLeptonHadIndex,
296 std::vector<int> &hadLeptonViaTau, std::vector<int> &hadFlavour,
297 std::vector<int> &hadFromTopWeakDecay, std::vector<int> &hadBHadronId )
299 std::vector<int> hadJetIndex;
300 std::vector<const reco::Candidate*> hadMothersCand;
302 int topDaughterQId = -1;
303 int topBarDaughterQId = -1;
308 const int jetIndex = i_info - jetFlavourInfos->
begin();
316 int hadronIndex =
analyzeMothers ( (
reco::Candidate*)(&**hadron), topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
318 hadIndex.push_back ( hadronIndex );
319 hadJetIndex.push_back ( jetIndex );
325 for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
329 if(
std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end())
continue;
332 int hadronIndex =
analyzeMothers ( thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices, 0, -1 );
334 hadIndex.push_back ( hadronIndex );
335 hadJetIndex.push_back ( -1 );
340 for (
int i=0;
i< (int)hadMothersCand.size();
i++ ) {
342 hadMothers.push_back(*particle);
346 for(reco::GenParticleCollection::const_iterator i_particle = genParticles->begin(); i_particle != genParticles->end(); ++i_particle){
348 const int pdg_abs = lepton.
pdgId();
350 if(pdg_abs != 11 && pdg_abs != 13)
continue;
351 bool leptonViaTau =
false;
353 if(!leptonMother)
continue;
357 leptonMother = leptonMother->
mother();
362 size_t leptonHadronParticleIndex =
std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
363 if(leptonHadronParticleIndex >= hadMothersCand.size())
continue;
365 size_t leptonHadronIndex =
std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
366 if(leptonHadronIndex >= hadIndex.size())
continue;
368 hadMothers.push_back(lepton);
369 const int leptonIndex = hadMothersCand.size()-1;
370 hadLeptonIndex.push_back(leptonIndex);
371 hadLeptonViaTau.push_back(leptonViaTau);
372 hadLeptonHadIndex.push_back(leptonHadronIndex);
376 unsigned int nHad = hadIndex.size();
378 std::vector<std::vector<int> > LastQuarkMotherIds;
379 std::vector<std::vector<int> > LastQuarkIds;
380 std::vector<int> lastQuarkIndices(nHad, -1);
383 for (
unsigned int hadNum=0; hadNum<nHad; hadNum++ ) {
384 unsigned int hadIdx = hadIndex.at(hadNum);
386 std::vector <int> FirstQuarkId;
387 std::vector <int> LastQuarkId;
388 std::vector <int> LastQuarkMotherId;
390 const int hadronFlavourSign =
flavourSign( hadMothers.at(hadIdx).pdgId() );
393 if(hadronFlavourSign != 0) {
394 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadronFlavourSign*
flavour_,
false, -1, 1,
false );
398 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0,
flavour_,
false, -1, 1,
false );
399 findInMothers( hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, -1*
flavour_,
false, -1, 1,
false );
403 for (
unsigned int qId=0; qId<FirstQuarkId.size(); qId++ ) {
405 const int quarkFlavourSign =
flavourSign( hadMothers.at(FirstQuarkId.at(qId)).
pdgId() );
407 findInMothers( FirstQuarkId.at(qId), LastQuarkId, hadMothersIndices, hadMothers, 0, quarkFlavourSign*
flavour_,
false, -1, 2,
false );
412 int hadronFlavour = 0;
415 std::vector<std::pair<double, int> > lastQuark_dR_id_pairs;
418 for (
unsigned int qId = 0; qId < LastQuarkId.size(); qId++ ) {
419 int qIdx = LastQuarkId.at(qId);
421 float dR =
deltaR ( hadMothers.at(hadIdx).eta(),hadMothers.at(hadIdx).phi(),hadMothers.at(qIdx).eta(),hadMothers.at(qIdx).phi() );
423 std::pair<double, int> dR_hadId_pair(dR,qIdx);
424 lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
427 std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
429 if(lastQuark_dR_id_pairs.size() > 1) {
430 double dRratio = (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first)/lastQuark_dR_id_pairs.at(1).first;
431 int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
433 if(dRratio>0.5) LastQuarkId.push_back(qIdx_closest);
434 else for(std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs) LastQuarkId.push_back(qIdDrPair.second);
436 for(
int qIdx : LastQuarkId) {
437 int qmIdx = hadMothersIndices.at(qIdx).at(0);
438 LastQuarkMotherId.push_back(qmIdx);
441 if((
int)LastQuarkId.size()>0) lastQuarkIndices.at(hadNum) = 0;
443 LastQuarkIds.push_back( LastQuarkId );
445 LastQuarkMotherIds.push_back ( LastQuarkMotherId );
447 if(LastQuarkMotherId.size()<1) {
450 int qIdx = LastQuarkId.at( lastQuarkIndices.at(hadNum) );
451 int qFlav =
flavourSign( hadMothers.at(qIdx).pdgId() );
452 hadronFlavour = qFlav*
std::abs( hadMothers.at( LastQuarkMotherId.at( lastQuarkIndices.at(hadNum) ) ).pdgId() );
454 hadFlavour.push_back(hadronFlavour);
457 int isFromTopWeakDecay = 1;
458 std::vector <int> checkedParticles;
459 if(hadFlavour.at(hadNum) != 0) {
460 int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
461 bool fromTB = topDaughterQId >= 0 ?
findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0,
false, topDaughterQId, 2,
false ) >= 0 :
false;
462 checkedParticles.clear();
463 bool fromTbarB = topBarDaughterQId >= 0 ?
findInMothers( lastQIndex, checkedParticles, hadMothersIndices, hadMothers, -1, 0,
false, topBarDaughterQId, 2,
false) >= 0 :
false;
464 checkedParticles.clear();
465 if(!fromTB && !fromTbarB) {
466 isFromTopWeakDecay = 0;
468 }
else isFromTopWeakDecay = 2;
469 hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
470 int bHadronMotherId =
findInMothers( hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555,
true, -1, 1,
false );
471 hadBHadronId.push_back(bHadronMotherId);
474 if(LastQuarkMotherId.size()>0) {
475 std::set<int> checkedHadronIds;
476 fixExtraSameFlavours(hadNum, hadIndex, hadMothers, hadMothersIndices, hadFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadFlavour, checkedHadronIds, 0);
495 const unsigned int position =
std::find(particleList.begin(), particleList.end(), particle) - particleList.begin();
496 if( position >= particleList.size() )
return -1;
504 if( position >= list.size() )
return -1;
550 const int flavour_abs =
std::abs(flavour);
551 if(flavour_abs != 5 && flavour_abs != 4)
return false;
552 const int pdgId_abs =
std::abs(pdgId);
554 if( pdgId_abs/100%10 != flavour_abs)
return false;
556 if ( pdgId_abs/1000 == flavour_abs)
return false;
574 const int flavour_abs =
std::abs(flavour);
575 if(flavour_abs != 5 && flavour_abs != 4)
return false;
576 const int pdgId_abs =
std::abs(pdgId);
578 if ( pdgId_abs/1000 != flavour_abs)
return false;
597 if(pdgId % 1000 / 10 / 11 > 0) flavourSign = 0;
614 bool hasDaughter =
false;
644 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 )
650 hadMothers.push_back ( thisParticle );
651 hadronIndex=hadMothers.size()-1;
657 partIndex =
idInList( hadMothers, thisParticle );
661 if ( !analyzedParticles ) {
662 analyzedParticles =
new std::set<const reco::Candidate*>;
664 for (
unsigned int i=0;
i<analyzedParticles->size();
i++ ) {
665 if ( analyzedParticles->count ( thisParticle ) <=0 ) {
674 if ( prevPartIndex>=0 ) {
679 analyzedParticles->insert ( thisParticle );
682 for (
size_t iMother = 0; iMother < thisParticle->
numberOfMothers(); ++iMother ) {
684 int mothIndex =
idInList( hadMothers, mother );
685 if ( mothIndex == partIndex && partIndex>=0 ) {
691 hadMothers.push_back ( mother );
692 mothIndex=hadMothers.size()-1;
695 if ( mothIndex!=partIndex && partIndex>=0 ) {
698 analyzeMothers ( mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex );
701 int& bId = mother->
pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
704 if(thisFlav <= 5) bId = partIndex;
706 int bIdFlav =
std::abs(hadMothers.at(bId)->pdgId());
707 if( bIdFlav != 5 && thisFlav == 5) bId = partIndex;
708 else if( thisFlav == 5 && thisParticle->
pt() > hadMothers.at(bId)->pt() ) bId = partIndex;
713 analyzedParticles->erase ( thisParticle );
746 while ( (
int)hadMothersIndices.size() <= partIndex ) {
747 std::vector<int> mothersIndices;
748 hadMothersIndices.push_back ( mothersIndices );
751 std::vector<int> *hadMotherIndices = &hadMothersIndices.at(partIndex);
753 if ( mothIndex == -1 ) {
754 hadMotherIndices->clear();
757 for (
int k = 0;
k < (int)hadMotherIndices->size();
k++ ) {
758 if ( hadMotherIndices->at(
k) != mothIndex && hadMotherIndices->at(
k) != -1 ) {
767 hadMotherIndices->push_back(mothIndex);
792 const std::vector<reco::GenParticle> &hadMothers,
int status,
int pdgId,
bool pdgAbs=
false,
793 int stopId=-1,
int firstLast=0,
bool verbose=
false)
795 int foundStopId = -1;
796 int pdg_1 = hadMothers.at(idx).pdgId();
798 if ( (
int)hadMothersIndices.size() <= idx ) {
800 printf (
" Stopping checking particle %d. No mothers are stored.\n",idx );
805 if(
std::abs(hadMothers.at( idx ).pdgId()) > 10 &&
std::abs(hadMothers.at( idx ).pdgId()) < 19) printf(
"Lepton: %d\n", hadMothers.at( idx ).pdgId());
807 std::vector<int> mothers = hadMothersIndices.at(idx);
808 unsigned int nMothers = mothers.size();
809 bool isCorrect=
false;
811 if (
std::abs( hadMothers.at(idx).pdgId() ) ==2212 ) {
812 printf (
"Chk: %d\tpdg: %d\tstatus: %d",idx, hadMothers.at(idx).pdgId(), hadMothers.at(idx).status() );
814 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() );
817 bool hasCorrectMothers =
true;
818 if(nMothers<1) hasCorrectMothers=
false;
else if(mothers.at(0)<0) hasCorrectMothers=
false;
819 if(!hasCorrectMothers) {
820 if(
verbose) printf(
" NO CORRECT MOTHER\n");
824 if(stopId>=0 && idx == stopId)
return idx;
827 if(pdgId%111111==0 && pdgId!=0) {
828 if(
isHadronPdgId(pdgId/111111, hadMothers.at(idx).pdgId())) {
834 if ( ( ( hadMothers.at(idx).pdgId() == pdgId && pdgAbs==
false )
836 && ( hadMothers.at(idx).status() == status || status==0 )
837 && hasCorrectMothers ) {
840 const bool inList =
std::find(mothChains.begin(), mothChains.end(), idx) != mothChains.end();
841 if ( !inList && mothers.at(0) >= 0 && ( hadMothers.at(idx).pdgId()*pdgId > 0 || !pdgAbs ) ) {
842 if ( firstLast==0 || firstLast==1 ) {
843 mothChains.push_back(idx);
857 if ( isCorrect && firstLast==1 ) {
862 unsigned int nDifferingMothers = 0;
863 for (
unsigned int i = 0;
i < nMothers;
i++ ) {
864 int idx2 = mothers.at(
i);
866 if(
verbose) printf(
"^^^ Has no mother\n");
870 if(
verbose) printf(
"^^^ Stored as its own mother\n");
873 int pdg_2 = hadMothers[idx2].pdgId();
877 if(
verbose) printf(
"######### Inverting flavour of the hadron\n");
881 ( pdg_2 != pdgId && pdgAbs ==
false ) ) {
887 printf (
"Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",
i,nMothers,idx, idx2, pdgId );
889 if(firstLast==2 && pdg_1 != pdg_2)
continue;
890 foundStopId =
findInMothers ( idx2, mothChains, hadMothersIndices, hadMothers, status, pdgId, pdgAbs, stopId, firstLast,
verbose );
893 if(firstLast==2 && isCorrect && nDifferingMothers >= nMothers) {
895 printf (
"Checking particle %d once more to store it as the last quark\n",idx);
897 foundStopId =
findInMothers ( idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1,
verbose );
914 const int neutralPdgs_array[] = {9, 21, 22, 23, 25};
915 const std::vector<int> neutralPdgs( neutralPdgs_array, neutralPdgs_array +
sizeof(neutralPdgs_array) /
sizeof(
int) );
916 if(
std::find( neutralPdgs.begin(), neutralPdgs.end(),
std::abs(pdgId) ) == neutralPdgs.end() )
return false;
937 const unsigned int hadId,
const std::vector<int> &hadIndices,
const std::vector<reco::GenParticle> &hadMothers,
938 const std::vector<std::vector<int> > &hadMothersIndices,
const std::vector<int> &isFromTopWeakDecay,
939 const std::vector<std::vector<int> > &LastQuarkIds,
const std::vector<std::vector<int> > &LastQuarkMotherIds,
940 std::vector<int> &lastQuarkIndices, std::vector<int> &hadronFlavour,
941 std::set<int> &checkedHadronIds,
const int lastQuarkIndex)
943 if(checkedHadronIds.count(hadId) != 0)
return false;
944 checkedHadronIds.insert(hadId);
946 if(lastQuarkIndex<0)
return false;
947 if((
int)LastQuarkIds.at(hadId).size()<lastQuarkIndex+1)
return false;
948 int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
949 int LastQuarkMotherId = LastQuarkMotherIds.at( hadId ).at( lastQuarkIndex );
950 int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
951 int hadFlavour = qmFlav*
std::abs( hadMothers.at( LastQuarkMotherId ).pdgId() );
952 bool ambiguityResolved =
true;
954 if( (hadMothers.at(LastQuarkId).pdgId()*hadMothers.at(LastQuarkMotherId).pdgId() < 0 && !
isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
956 (
std::abs(hadronFlavour.at(hadId))==6 && isFromTopWeakDecay.at(hadId)==0) ) {
957 if((
int)LastQuarkIds.at(hadId).size()>lastQuarkIndex+1)
fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1);
958 else hadronFlavour.at(hadId) = qmFlav*21;
962 int nSameFlavourHadrons = 0;
964 for(
unsigned int iHad = 0; iHad<hadronFlavour.size(); iHad++) {
965 if(iHad==hadId)
continue;
966 int theLastQuarkIndex = lastQuarkIndices.at(iHad);
967 if(theLastQuarkIndex<0)
continue;
968 if((
int)LastQuarkMotherIds.at( iHad ).size() <= theLastQuarkIndex)
continue;
969 int theLastQuarkMotherId = LastQuarkMotherIds.at( iHad ).at( theLastQuarkIndex );
970 int theHadFlavour = hadronFlavour.at(iHad);
972 if(theHadFlavour==0 ||
std::abs(theHadFlavour)==21)
continue;
973 if(theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId)
continue;
974 ambiguityResolved =
false;
975 nSameFlavourHadrons++;
978 if((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex+1) {
979 if(
fixExtraSameFlavours(hadId, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, lastQuarkIndex+1) ) {
980 ambiguityResolved =
true;
985 if((
int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex+1) {
986 if(
fixExtraSameFlavours(iHad, hadIndices, hadMothers, hadMothersIndices, isFromTopWeakDecay, LastQuarkIds, LastQuarkMotherIds, lastQuarkIndices, hadronFlavour, checkedHadronIds, theLastQuarkIndex+1) ) {
987 ambiguityResolved =
true;
994 checkedHadronIds.erase(hadId);
995 if(nSameFlavourHadrons>0 && !ambiguityResolved) {
996 hadronFlavour.at(hadId) = qmFlav*21;
999 lastQuarkIndices.at(hadId) = lastQuarkIndex;
1000 hadronFlavour.at(hadId) = hadFlavour;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
edm::ESHandle< ParticleDataTable > pdt_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
int idInList(std::vector< const reco::Candidate * > particleList, const reco::Candidate *particle)
Check if the cpecified particle is already in the list of particles.
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'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
virtual double pt() const =0
transverse momentum
#define DEFINE_FWK_MODULE(type)
const GenParticleRefVector & getcHadrons() const
Return a vector of GenParticleRef's to c hadrons clustered inside the jet.
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
virtual void endRun(edm::Run &, edm::EventSetup const &)
const_iterator end() const
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 &)
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 size_type numberOfDaughters() const =0
number of daughters
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.
virtual void beginRun(edm::Run &, edm::EventSetup const &)
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)
virtual int pdgId() const =0
PDG identifier.
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
virtual void beginLuminosityBlock(edm::LuminosityBlock &, edm::EventSetup const &)
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
virtual void endLuminosityBlock(edm::LuminosityBlock &, edm::EventSetup const &)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
virtual int pdgId() const final
PDG identifier.
static int position[264][3]
GenHFHadronMatcher(const edm::ParameterSet &)
constructor initialising producer products and config parameters
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.
bool onlyJetClusteredHadrons_
int flavour(const Candidate &part)
const_iterator begin() const
virtual const Candidate * mother(size_type=0) const
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
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.
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