65 std::vector<int> &hadIndex,
66 std::vector<reco::GenParticle> &hadMothersGenPart,
68 std::vector<int> &hadLeptonIndex,
69 std::vector<int> &hadLeptonHadIndex,
70 std::vector<int> &hadLeptonViaTau,
71 std::vector<int> &hadFlavour,
72 std::vector<int> &hadFromTopWeakDecay,
73 std::vector<int> &hadBHadronId)
const;
76 int &topBarDaughterQId,
77 std::vector<const reco::Candidate *> &hadMothers,
79 std::set<const reco::Candidate *> *analyzedParticles,
80 const int prevPartIndex)
const;
91 std::vector<int> &mothChains,
92 const std::vector<std::vector<int>> &hadMothersIndices,
93 const std::vector<reco::GenParticle> &hadMothers,
106 const std::vector<int> &hadIndices,
107 const std::vector<reco::GenParticle> &hadMothers,
108 const std::vector<std::vector<int>> &hadMothersIndices,
109 const std::vector<int> &isFromTopWeakDecay,
111 const std::vector<std::vector<int>> &LastQuarkMotherIds,
112 std::vector<int> &lastQuarkIndices,
114 std::set<int> &checkedHadronIds,
115 const int lastQuarkIndex)
const;
163 edm::LogError(
"GenHFHadronMatcher") <<
"Flavour option must be 4 (c-jet) or 5 (b-jet), but is: " <<
flavour 164 <<
". Correct this!";
171 jetFlavourInfosToken_(
172 consumes<
reco::JetFlavourInfoMatchingCollection>(
cfg.getParameter<
edm::
InputTag>(
"jetFlavourInfos"))),
173 flavour_{
std::abs(
cfg.getParameter<
int>(
"flavour"))},
174 noBBbarResonances_{
cfg.getParameter<
bool>(
"noBBbarResonances")},
175 onlyJetClusteredHadrons_{
cfg.getParameter<
bool>(
"onlyJetClusteredHadrons")},
176 flavourStr_{flavourName(flavour_)},
177 plusMothersToken_{produces<std::vector<reco::GenParticle>>(
178 "gen" + flavourStr_ +
180 plusMothersIndicesToken_{produces<std::vector<std::vector<int>>>(
181 "gen" + flavourStr_ +
"HadPlusMothersIndices")},
183 produces<std::vector<int>>(
"gen" + flavourStr_ +
"HadIndex")},
184 flavourToken_{produces<std::vector<int>>(
185 "gen" + flavourStr_ +
187 jetIndexToken_{produces<std::vector<int>>(
188 "gen" + flavourStr_ +
"HadJetIndex")},
189 leptonIndexToken_{produces<std::vector<int>>(
190 "gen" + flavourStr_ +
192 leptonHadronIndexToken_{produces<std::vector<int>>(
193 "gen" + flavourStr_ +
"HadLeptonHadronIndex")},
194 leptonViaTauToken_{produces<std::vector<int>>(
195 "gen" + flavourStr_ +
"HadLeptonViaTau")},
196 fromTopWeakDecayToken_{produces<std::vector<int>>(
197 "gen" + flavourStr_ +
198 "HadFromTopWeakDecay")},
199 bHadronIdToken_{produces<std::vector<int>>(
"gen" + flavourStr_ +
"HadBHadronId")}
215 ->setComment(
"Collection of GenParticle objects which contains all particles produced in the event");
218 "Output from the JetFlavour tool. Contains information about partons/hadrons/leptons associated to jets");
219 desc.add<
bool>(
"noBBbarResonances",
true)->setComment(
"Whether resonances should not be treated as hadrons");
220 desc.add<
bool>(
"onlyJetClusteredHadrons",
false)
221 ->setComment(
"Whether only hadrons that are matched to jets should be analysed. Runs x1000 faster in Sherpa");
222 desc.add<
int>(
"flavour", 5)->setComment(
"Flavour of weakly decaying hadron that should be analysed (4-c, 5-b)");
223 descriptions.
add(
"matchGenHFHadron",
desc);
241 std::vector<reco::GenParticle> hadMothers;
242 std::vector<std::vector<int>> hadMothersIndices;
243 std::vector<int> hadIndex;
244 std::vector<int> hadFlavour;
245 std::vector<int> hadJetIndex;
246 std::vector<int> hadLeptonIndex;
247 std::vector<int> hadLeptonHadIndex;
248 std::vector<int> hadLeptonViaTau;
249 std::vector<int> hadFromTopWeakDecay;
250 std::vector<int> hadBHadronId;
301 std::vector<int> &hadIndex,
302 std::vector<reco::GenParticle> &hadMothers,
304 std::vector<int> &hadLeptonIndex,
305 std::vector<int> &hadLeptonHadIndex,
306 std::vector<int> &hadLeptonViaTau,
307 std::vector<int> &hadFlavour,
308 std::vector<int> &hadFromTopWeakDecay,
309 std::vector<int> &hadBHadronId)
const {
310 std::vector<int> hadJetIndex;
311 std::vector<const reco::Candidate *> hadMothersCand;
313 int topDaughterQId = -1;
314 int topBarDaughterQId = -1;
342 hadIndex.push_back(hadronIndex);
343 hadJetIndex.push_back(jetIndex);
349 for (reco::GenParticleCollection::const_iterator i_particle =
genParticles->begin();
356 if (
std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end())
361 thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices,
nullptr, -1);
363 hadIndex.push_back(hadronIndex);
364 hadJetIndex.push_back(-1);
369 for (
int i = 0;
i < (
int)hadMothersCand.size();
i++) {
371 hadMothers.push_back(*particle);
375 for (reco::GenParticleCollection::const_iterator i_particle =
genParticles->begin();
379 const int pdg_abs = lepton.
pdgId();
381 if (pdg_abs != 11 && pdg_abs != 13)
383 bool leptonViaTau =
false;
390 leptonMother = leptonMother->
mother();
396 size_t leptonHadronParticleIndex =
397 std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
398 if (leptonHadronParticleIndex >= hadMothersCand.size())
401 size_t leptonHadronIndex =
402 std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
403 if (leptonHadronIndex >= hadIndex.size())
406 hadMothers.push_back(lepton);
407 const int leptonIndex = hadMothersCand.size() - 1;
408 hadLeptonIndex.push_back(leptonIndex);
409 hadLeptonViaTau.push_back(leptonViaTau);
410 hadLeptonHadIndex.push_back(leptonHadronIndex);
414 unsigned int nHad = hadIndex.size();
416 std::vector<std::vector<int>> LastQuarkMotherIds;
417 std::vector<std::vector<int>> LastQuarkIds;
418 std::vector<int> lastQuarkIndices(nHad, -1);
421 for (
unsigned int hadNum = 0; hadNum < nHad; hadNum++) {
422 unsigned int hadIdx = hadIndex.at(hadNum);
424 std::vector<int> FirstQuarkId;
425 std::vector<int> LastQuarkId;
426 std::vector<int> LastQuarkMotherId;
428 const int hadronFlavourSign =
flavourSign(hadMothers.at(hadIdx).pdgId());
431 if (hadronFlavourSign != 0) {
433 hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadronFlavourSign *
flavour_,
false, -1, 1,
false);
437 findInMothers(hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0,
flavour_,
false, -1, 1,
false);
438 findInMothers(hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, -1 *
flavour_,
false, -1, 1,
false);
442 for (
unsigned int qId = 0; qId < FirstQuarkId.size(); qId++) {
444 const int quarkFlavourSign =
flavourSign(hadMothers.at(FirstQuarkId.at(qId)).
pdgId());
462 std::vector<std::pair<double, int>> lastQuark_dR_id_pairs;
465 for (
unsigned int qId = 0; qId < LastQuarkId.size(); qId++) {
466 int qIdx = LastQuarkId.at(qId);
468 float dR =
deltaR(hadMothers.at(hadIdx).eta(),
469 hadMothers.at(hadIdx).phi(),
470 hadMothers.at(qIdx).eta(),
471 hadMothers.at(qIdx).phi());
473 std::pair<double, int> dR_hadId_pair(
dR, qIdx);
474 lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
477 std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
479 if (lastQuark_dR_id_pairs.size() > 1) {
481 (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first) / lastQuark_dR_id_pairs.at(1).first;
482 int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
485 LastQuarkId.push_back(qIdx_closest);
487 for (std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs)
488 LastQuarkId.push_back(qIdDrPair.second);
490 for (
int qIdx : LastQuarkId) {
491 int qmIdx = hadMothersIndices.at(qIdx).at(0);
492 LastQuarkMotherId.push_back(qmIdx);
495 if ((
int)LastQuarkId.size() > 0)
496 lastQuarkIndices.at(hadNum) = 0;
498 LastQuarkIds.push_back(LastQuarkId);
500 LastQuarkMotherIds.push_back(LastQuarkMotherId);
502 if (LastQuarkMotherId.empty()) {
505 int qIdx = LastQuarkId.at(lastQuarkIndices.at(hadNum));
506 int qFlav =
flavourSign(hadMothers.at(qIdx).pdgId());
507 hadronFlavour = qFlav *
std::abs(hadMothers.at(LastQuarkMotherId.at(lastQuarkIndices.at(hadNum))).pdgId());
512 int isFromTopWeakDecay = 1;
513 std::vector<int> checkedParticles;
514 if (hadFlavour.at(hadNum) != 0) {
515 int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
516 bool fromTB = topDaughterQId >= 0 ?
findInMothers(lastQIndex,
527 checkedParticles.clear();
528 bool fromTbarB = topBarDaughterQId >= 0 ?
findInMothers(lastQIndex,
539 checkedParticles.clear();
540 if (!fromTB && !fromTbarB) {
541 isFromTopWeakDecay = 0;
544 isFromTopWeakDecay = 2;
545 hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
546 int bHadronMotherId =
547 findInMothers(hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555,
true, -1, 1,
false);
548 hadBHadronId.push_back(bHadronMotherId);
550 if (!LastQuarkMotherId.empty()) {
551 std::set<int> checkedHadronIds;
580 const unsigned int position =
std::find(particleList.begin(), particleList.end(), particle) - particleList.begin();
581 if (
position >= particleList.size())
632 if (flavour_abs != 5 && flavour_abs != 4)
636 if (pdgId_abs / 100 % 10 != flavour_abs)
639 if (pdgId_abs / 1000 == flavour_abs)
658 if (flavour_abs != 5 && flavour_abs != 4)
662 if (pdgId_abs / 1000 != flavour_abs)
681 if (
pdgId % 1000 / 10 / 11 > 0)
697 bool hasDaughter =
false;
728 int &topBarDaughterQId,
729 std::vector<const reco::Candidate *> &hadMothers,
731 std::set<const reco::Candidate *> *analyzedParticles,
732 const int prevPartIndex)
const {
734 int hadronIndex = -1;
737 hadMothers.push_back(thisParticle);
738 hadronIndex = hadMothers.size() - 1;
744 partIndex =
idInList(hadMothers, thisParticle);
748 if (!analyzedParticles) {
749 analyzedParticles =
new std::set<const reco::Candidate *>;
751 for (
unsigned int i = 0;
i < analyzedParticles->size();
i++) {
752 if (analyzedParticles->count(thisParticle) <= 0) {
761 if (prevPartIndex >= 0) {
766 analyzedParticles->insert(thisParticle);
769 for (
size_t iMother = 0; iMother < thisParticle->
numberOfMothers(); ++iMother) {
771 int mothIndex =
idInList(hadMothers, mother);
772 if (mothIndex == partIndex && partIndex >= 0) {
778 hadMothers.push_back(mother);
779 mothIndex = hadMothers.size() - 1;
782 if (mothIndex != partIndex && partIndex >= 0) {
786 mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex);
789 int &bId = mother->
pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
795 int bIdFlav =
std::abs(hadMothers.at(bId)->pdgId());
796 if (bIdFlav != 5 && thisFlav == 5)
798 else if (thisFlav == 5 && thisParticle->
pt() > hadMothers.at(bId)->pt())
804 analyzedParticles->erase(thisParticle);
829 int mothIndex)
const {
836 while ((
int)hadMothersIndices.size() <= partIndex) {
837 std::vector<int> mothersIndices;
838 hadMothersIndices.push_back(mothersIndices);
841 std::vector<int> *hadMotherIndices = &hadMothersIndices.at(partIndex);
843 if (mothIndex == -1) {
844 hadMotherIndices->clear();
847 for (
int k = 0;
k < (
int)hadMotherIndices->size();
k++) {
848 if (hadMotherIndices->at(
k) != mothIndex && hadMotherIndices->at(
k) != -1) {
857 hadMotherIndices->push_back(mothIndex);
881 std::vector<int> &mothChains,
882 const std::vector<std::vector<int>> &hadMothersIndices,
883 const std::vector<reco::GenParticle> &hadMothers,
890 int foundStopId = -1;
891 int pdg_1 = hadMothers.at(
idx).pdgId();
893 if ((
int)hadMothersIndices.size() <=
idx) {
895 printf(
" Stopping checking particle %d. No mothers are stored.\n",
idx);
901 printf(
"Lepton: %d\n", hadMothers.at(
idx).pdgId());
903 std::vector<int> mothers = hadMothersIndices.at(
idx);
904 unsigned int nMothers = mothers.size();
905 bool isCorrect =
false;
907 if (
std::abs(hadMothers.at(
idx).pdgId()) == 2212) {
908 printf(
"Chk: %d\tpdg: %d\tstatus: %d",
idx, hadMothers.at(
idx).pdgId(), hadMothers.at(
idx).status());
910 printf(
" Chk: %d(%d mothers)\tpdg: %d\tstatus: %d\tPt: %.3f\tEta: %.3f",
913 hadMothers.at(
idx).pdgId(),
914 hadMothers.at(
idx).status(),
915 hadMothers.at(
idx).pt(),
916 hadMothers.at(
idx).eta());
919 bool hasCorrectMothers =
true;
921 hasCorrectMothers =
false;
922 else if (mothers.at(0) < 0)
923 hasCorrectMothers =
false;
924 if (!hasCorrectMothers) {
926 printf(
" NO CORRECT MOTHER\n");
930 if (stopId >= 0 &&
idx == stopId)
941 if (((hadMothers.at(
idx).pdgId() ==
pdgId && pdgAbs ==
false) ||
943 (hadMothers.at(
idx).status() ==
status ||
status == 0) && hasCorrectMothers) {
946 const bool inList =
std::find(mothChains.begin(), mothChains.end(),
idx) != mothChains.end();
947 if (!inList && mothers.at(0) >= 0 && (hadMothers.at(
idx).pdgId() *
pdgId > 0 || !pdgAbs)) {
948 if (firstLast == 0 || firstLast == 1) {
949 mothChains.push_back(
idx);
963 if (isCorrect && firstLast == 1) {
968 unsigned int nDifferingMothers = 0;
969 for (
unsigned int i = 0;
i < nMothers;
i++) {
970 int idx2 = mothers.at(
i);
973 printf(
"^^^ Has no mother\n");
978 printf(
"^^^ Stored as its own mother\n");
981 int pdg_2 = hadMothers[idx2].pdgId();
986 printf(
"######### Inverting flavour of the hadron\n");
995 printf(
"Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",
i, nMothers,
idx, idx2,
pdgId);
997 if (firstLast == 2 && pdg_1 != pdg_2)
1000 idx2, mothChains, hadMothersIndices, hadMothers,
status,
pdgId, pdgAbs, stopId, firstLast,
verbose);
1003 if (firstLast == 2 && isCorrect && nDifferingMothers >= nMothers) {
1005 printf(
"Checking particle %d once more to store it as the last quark\n",
idx);
1022 const int neutralPdgs_array[] = {9, 21, 22, 23, 25};
1023 const std::vector<int> neutralPdgs(neutralPdgs_array, neutralPdgs_array +
sizeof(neutralPdgs_array) /
sizeof(
int));
1045 const std::vector<int> &hadIndices,
1046 const std::vector<reco::GenParticle> &hadMothers,
1047 const std::vector<std::vector<int>> &hadMothersIndices,
1048 const std::vector<int> &isFromTopWeakDecay,
1049 const std::vector<std::vector<int>> &LastQuarkIds,
1050 const std::vector<std::vector<int>> &LastQuarkMotherIds,
1051 std::vector<int> &lastQuarkIndices,
1053 std::set<int> &checkedHadronIds,
1054 const int lastQuarkIndex)
const {
1055 if (checkedHadronIds.count(hadId) != 0)
1057 checkedHadronIds.insert(hadId);
1059 if (lastQuarkIndex < 0)
1061 if ((
int)LastQuarkIds.at(hadId).size() < lastQuarkIndex + 1)
1063 int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
1064 int LastQuarkMotherId = LastQuarkMotherIds.at(hadId).at(lastQuarkIndex);
1065 int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
1066 int hadFlavour = qmFlav *
std::abs(hadMothers.at(LastQuarkMotherId).pdgId());
1067 bool ambiguityResolved =
true;
1069 if ((hadMothers.at(LastQuarkId).pdgId() * hadMothers.at(LastQuarkMotherId).pdgId() < 0 &&
1070 !
isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
1073 if ((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex + 1)
1084 lastQuarkIndex + 1);
1090 int nSameFlavourHadrons = 0;
1092 for (
unsigned int iHad = 0; iHad <
hadronFlavour.size(); iHad++) {
1095 int theLastQuarkIndex = lastQuarkIndices.at(iHad);
1096 if (theLastQuarkIndex < 0)
1098 if ((
int)LastQuarkMotherIds.at(iHad).size() <= theLastQuarkIndex)
1100 int theLastQuarkMotherId = LastQuarkMotherIds.at(iHad).at(theLastQuarkIndex);
1103 if (theHadFlavour == 0 ||
std::abs(theHadFlavour) == 21)
1105 if (theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId)
1107 ambiguityResolved =
false;
1108 nSameFlavourHadrons++;
1111 if ((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex + 1) {
1122 lastQuarkIndex + 1)) {
1123 ambiguityResolved =
true;
1128 if ((
int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex + 1) {
1139 theLastQuarkIndex + 1)) {
1140 ambiguityResolved =
true;
1147 checkedHadronIds.erase(hadId);
1148 if (nSameFlavourHadrons > 0 && !ambiguityResolved) {
1152 lastQuarkIndices.at(hadId) = lastQuarkIndex;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
bool fixExtraSameFlavours(const unsigned int hadId, const std::vector< int > &hadIndices, const std::vector< reco::GenParticle > &hadMothers, const std::vector< std::vector< int >> &hadMothersIndices, const std::vector< int > &isFromTopWeakDecay, const std::vector< std::vector< int >> &LastQuarkIds, const std::vector< std::vector< int >> &LastQuarkMotherIds, std::vector< int > &lastQuarkIndices, std::vector< int > &hadronFlavour, std::set< int > &checkedHadronIds, const int lastQuarkIndex) const
const edm::EDPutTokenT< std::vector< reco::GenParticle > > plusMothersToken_
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
const Candidate * mother(size_type=0) const override
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
bool isHadronPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a hadron of particular flavour.
const edm::EDPutTokenT< std::vector< std::vector< int > > > plusMothersIndicesToken_
const edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
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.
std::string getParticleName(int id) const
virtual double pt() const =0
transverse momentum
bool isMesonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a meson of particular flavour.
#define DEFINE_FWK_MODULE(type)
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
const edm::EDPutTokenT< std::vector< int > > leptonIndexToken_
bool checkForLoop(std::vector< const reco::Candidate *> &particleChain, const reco::Candidate *particle) const
const bool noBBbarResonances_
int pdgId() const final
PDG identifier.
virtual size_type numberOfDaughters() const =0
number of daughters
~GenHFHadronMatcher() override
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
int idInList(std::vector< const reco::Candidate *> particleList, const reco::Candidate *particle) const
Check if the cpecified particle is already in the list of particles.
bool isNeutralPdg(int pdgId) const
Check whether a given pdgId represents neutral particle.
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
const edm::EDPutTokenT< std::vector< int > > jetIndexToken_
Class storing the jet flavour information.
const std::string flavourStr_
Abs< T >::type abs(const T &t)
const bool onlyJetClusteredHadrons_
const edm::EDPutTokenT< std::vector< int > > leptonViaTauToken_
virtual int pdgId() const =0
PDG identifier.
edm::RefVector< GenParticleCollection > GenParticleRefVector
vector of reference to GenParticle in the same collection
int analyzeMothers(const reco::Candidate *thisParticle, int &topDaughterQId, int &topBarDaughterQId, std::vector< const reco::Candidate *> &hadMothers, std::vector< std::vector< int >> &hadMothersIndices, std::set< const reco::Candidate *> *analyzedParticles, const int prevPartIndex) const
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
description of the run-time parameters
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&... args)
puts a new product
const_iterator end() const
Termination of iteration.
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static int position[264][3]
bool hasHadronDaughter(const int flavour, const reco::Candidate *thisParticle) const
Check if the particle has bHadron among daughters.
GenHFHadronMatcher(const edm::ParameterSet &)
bool putMotherIndex(std::vector< std::vector< int >> &hadMothersIndices, int partIndex, int mothIndex) const
puts mother index to the list of mothers of particle, if it isn't there already
const GenParticleRefVector & getcHadrons() const
Return a vector of GenParticleRef's to c hadrons clustered inside the jet.
const edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
const_iterator begin() const
Initialize an iterator over the RefVector.
int findInMothers(int idx, std::vector< int > &mothChains, const std::vector< std::vector< int >> &hadMothersIndices, const std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose) const
helper function to find indices of particles with particular pdgId and status from the list of mother...
std::vector< int > findHadronJets(const reco::GenParticleCollection *genParticles, const reco::JetFlavourInfoMatchingCollection *jetFlavourInfos, std::vector< int > &hadIndex, std::vector< reco::GenParticle > &hadMothersGenPart, std::vector< std::vector< int >> &hadMothersIndices, std::vector< int > &hadLeptonIndex, std::vector< int > &hadLeptonHadIndex, std::vector< int > &hadLeptonViaTau, std::vector< int > &hadFlavour, std::vector< int > &hadFromTopWeakDecay, std::vector< int > &hadBHadronId) const
identify the jets that contain b-hadrons
int flavourSign(const int pdgId) const
Sign of the flavour (matter/antimatter)
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
bool isBaryonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a baryon of particular flavour.
Finds the origin of each heavy flavour hadron and associated jets to it.
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
bool isHadron(const int flavour, const reco::Candidate *thisParticle) const
Check the pdgId of a given particle if it is a hadron.
const edm::EDPutTokenT< std::vector< int > > indexToken_
const edm::EDPutTokenT< std::vector< int > > flavourToken_