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;
84 bool isMesonPdgId(
const int flavour,
const int pdgId)
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,
113 std::vector<int> &hadronFlavour,
114 std::set<int> &checkedHadronIds,
115 const int lastQuarkIndex)
const;
160 }
else if (flavour == 4) {
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"))),
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;
253 jetFlavourInfos.product(),
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;
318 i_info != jetFlavourInfos->
end();
321 const int jetIndex = i_info - jetFlavourInfos->
begin();
342 hadIndex.push_back(hadronIndex);
343 hadJetIndex.push_back(jetIndex);
349 for (reco::GenParticleCollection::const_iterator i_particle = genParticles->begin();
350 i_particle != genParticles->end();
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();
376 i_particle != genParticles->end();
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());
459 int hadronFlavour = 0;
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());
509 hadFlavour.push_back(hadronFlavour);
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())
589 if (position >= list.size())
631 const int flavour_abs =
std::abs(flavour);
632 if (flavour_abs != 5 && flavour_abs != 4)
634 const int pdgId_abs =
std::abs(pdgId);
636 if (pdgId_abs / 100 % 10 != flavour_abs)
639 if (pdgId_abs / 1000 == flavour_abs)
657 const int flavour_abs =
std::abs(flavour);
658 if (flavour_abs != 5 && flavour_abs != 4)
660 const int pdgId_abs =
std::abs(pdgId);
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);
900 if (
std::abs(hadMothers.at(idx).pdgId()) > 10 &&
std::abs(hadMothers.at(idx).pdgId()) < 19)
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)
934 if (pdgId % 111111 == 0 && pdgId != 0) {
935 if (
isHadronPdgId(pdgId / 111111, hadMothers.at(idx).pdgId())) {
941 if (((hadMothers.at(idx).pdgId() == pdgId && pdgAbs ==
false) ||
942 (
std::abs(hadMothers.at(idx).pdgId()) ==
std::abs(pdgId) && pdgAbs ==
true)) &&
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");
989 if ((
std::abs(pdg_2) !=
std::abs(pdgId) && pdgAbs ==
true) || (pdg_2 != pdgId && pdgAbs ==
false)) {
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);
1007 foundStopId =
findInMothers(idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1,
verbose);
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));
1024 if (
std::find(neutralPdgs.begin(), neutralPdgs.end(),
std::abs(pdgId)) == neutralPdgs.end())
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,
1052 std::vector<int> &hadronFlavour,
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())) ||
1072 (
std::abs(hadronFlavour.at(hadId)) == 6 && isFromTopWeakDecay.at(hadId) == 0)) {
1073 if ((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex + 1)
1084 lastQuarkIndex + 1);
1086 hadronFlavour.at(hadId) = qmFlav * 21;
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);
1101 int theHadFlavour = hadronFlavour.at(iHad);
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) {
1149 hadronFlavour.at(hadId) = qmFlav * 21;
1152 lastQuarkIndices.at(hadId) = lastQuarkIndex;
1153 hadronFlavour.at(hadId) = hadFlavour;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
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) ...
bool isMesonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a meson of particular flavour.
const Candidate * mother(size_type=0) const override
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
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
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
const GenParticleRefVector & getbHadrons() const
Return a vector of GenParticleRef's to b hadrons clustered inside the jet.
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)
const_iterator end() const
const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
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 checkForLoop(std::vector< const reco::Candidate * > &particleChain, const reco::Candidate *particle) const
Log< level::Error, false > LogError
const_iterator end() const
Termination of iteration.
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 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 bool noBBbarResonances_
const_iterator begin() const
Initialize an iterator over the RefVector.
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
int pdgId() const final
PDG identifier.
virtual size_type numberOfDaughters() const =0
number of daughters
int flavourSign(const int pdgId) const
Sign of the flavour (matter/antimatter)
static constexpr int verbose
~GenHFHadronMatcher() override
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
printf("params %d %f %f %f\n", minT, eps, errmax, chi2max)
const edm::EDPutTokenT< std::vector< int > > jetIndexToken_
Class storing the jet flavour information.
const std::string flavourStr_
Abs< T >::type abs(const T &t)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool hasHadronDaughter(const int flavour, const reco::Candidate *thisParticle) const
Check if the particle has bHadron among daughters.
const bool onlyJetClusteredHadrons_
const edm::EDPutTokenT< std::vector< int > > leptonViaTauToken_
bool isHadronPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a hadron of particular flavour.
bool isHadron(const int flavour, const reco::Candidate *thisParticle) const
Check the pdgId of a given particle if it is a hadron.
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
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
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
bool isNeutralPdg(int pdgId) const
Check whether a given pdgId represents neutral particle.
T getParameter(std::string const &) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static int position[264][3]
GenHFHadronMatcher(const edm::ParameterSet &)
bool isBaryonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a baryon of particular flavour.
const edm::EDGetTokenT< reco::JetFlavourInfoMatchingCollection > jetFlavourInfosToken_
int findInMothers(int idx, std::vector< int > &mothChains, const std::vector< std::vector< int >> &hadMothersIndices, const std::vector< reco::GenParticle > &hadMothers, int status, int pdgId, bool pdgAbs, int stopId, int firstLast, bool verbose) const
helper function to find indices of particles with particular pdgId and status from the list of mother...
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
const_iterator begin() const
Finds the origin of each heavy flavour hadron and associated jets to it.
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
const edm::EDPutTokenT< std::vector< int > > indexToken_
std::string getParticleName(int id) const
int analyzeMothers(const reco::Candidate *thisParticle, int &topDaughterQId, int &topBarDaughterQId, std::vector< const reco::Candidate * > &hadMothers, std::vector< std::vector< int >> &hadMothersIndices, std::set< const reco::Candidate * > *analyzedParticles, const int prevPartIndex) const
do a recursive search for the mother particles until the b-quark is found or the absolute mother is f...
const edm::EDPutTokenT< std::vector< int > > flavourToken_