65 std::vector<int> &hadIndex,
66 std::vector<reco::GenParticle> &hadMothersGenPart,
67 std::vector<std::vector<int>> &hadMothersIndices,
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,
78 std::vector<std::vector<int>> &hadMothersIndices,
79 std::set<const reco::Candidate *> *analyzedParticles,
80 const int prevPartIndex)
const;
81 bool putMotherIndex(std::vector<std::vector<int>> &hadMothersIndices,
int partIndex,
int mothIndex)
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,
110 const std::vector<std::vector<int>> &LastQuarkIds,
111 const std::vector<std::vector<int>> &LastQuarkMotherIds,
112 std::vector<int> &lastQuarkIndices,
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!";
183 produces<std::vector<int>>(
"gen" +
flavourStr_ +
"HadIndex")},
198 "HadFromTopWeakDecay")},
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,
303 std::vector<std::vector<int>> &hadMothersIndices,
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();
341 hadIndex.push_back(hadronIndex);
342 hadJetIndex.push_back(jetIndex);
348 for (reco::GenParticleCollection::const_iterator i_particle = genParticles->begin();
349 i_particle != genParticles->end();
355 if (
std::find(hadMothersCand.begin(), hadMothersCand.end(), thisParticle) != hadMothersCand.end())
360 thisParticle, topDaughterQId, topBarDaughterQId, hadMothersCand, hadMothersIndices,
nullptr, -1);
362 hadIndex.push_back(hadronIndex);
363 hadJetIndex.push_back(-1);
368 for (
int i = 0;
i < (
int)hadMothersCand.size();
i++) {
370 hadMothers.push_back(*particle);
374 for (reco::GenParticleCollection::const_iterator i_particle = genParticles->begin();
375 i_particle != genParticles->end();
378 const int pdg_abs = lepton.
pdgId();
380 if (pdg_abs != 11 && pdg_abs != 13)
382 bool leptonViaTau =
false;
389 leptonMother = leptonMother->
mother();
395 size_t leptonHadronParticleIndex =
396 std::find(hadMothersCand.begin(), hadMothersCand.end(), leptonMother) - hadMothersCand.begin();
397 if (leptonHadronParticleIndex >= hadMothersCand.size())
400 size_t leptonHadronIndex =
401 std::find(hadIndex.begin(), hadIndex.end(), leptonHadronParticleIndex) - hadIndex.begin();
402 if (leptonHadronIndex >= hadIndex.size())
405 hadMothers.push_back(lepton);
406 const int leptonIndex = hadMothersCand.size() - 1;
407 hadLeptonIndex.push_back(leptonIndex);
408 hadLeptonViaTau.push_back(leptonViaTau);
409 hadLeptonHadIndex.push_back(leptonHadronIndex);
413 unsigned int nHad = hadIndex.size();
415 std::vector<std::vector<int>> LastQuarkMotherIds;
416 std::vector<std::vector<int>> LastQuarkIds;
417 std::vector<int> lastQuarkIndices(nHad, -1);
420 for (
unsigned int hadNum = 0; hadNum < nHad; hadNum++) {
421 unsigned int hadIdx = hadIndex.at(hadNum);
423 std::vector<int> FirstQuarkId;
424 std::vector<int> LastQuarkId;
425 std::vector<int> LastQuarkMotherId;
427 const int hadronFlavourSign =
flavourSign(hadMothers.at(hadIdx).pdgId());
430 if (hadronFlavourSign != 0) {
432 hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, hadronFlavourSign *
flavour_,
false, -1, 1,
false);
436 findInMothers(hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0,
flavour_,
false, -1, 1,
false);
437 findInMothers(hadIdx, FirstQuarkId, hadMothersIndices, hadMothers, 0, -1 *
flavour_,
false, -1, 1,
false);
441 for (
unsigned int qId = 0; qId < FirstQuarkId.size(); qId++) {
443 const int quarkFlavourSign =
flavourSign(hadMothers.at(FirstQuarkId.at(qId)).
pdgId());
461 std::vector<std::pair<double, int>> lastQuark_dR_id_pairs;
464 for (
unsigned int qId = 0; qId < LastQuarkId.size(); qId++) {
465 int qIdx = LastQuarkId.at(qId);
467 float dR =
deltaR(hadMothers.at(hadIdx).eta(),
468 hadMothers.at(hadIdx).phi(),
469 hadMothers.at(qIdx).eta(),
470 hadMothers.at(qIdx).phi());
472 std::pair<double, int> dR_hadId_pair(dR, qIdx);
473 lastQuark_dR_id_pairs.push_back(dR_hadId_pair);
476 std::sort(lastQuark_dR_id_pairs.begin(), lastQuark_dR_id_pairs.end());
478 if (lastQuark_dR_id_pairs.size() > 1) {
480 (lastQuark_dR_id_pairs.at(1).first - lastQuark_dR_id_pairs.at(0).first) / lastQuark_dR_id_pairs.at(1).first;
481 int qIdx_closest = lastQuark_dR_id_pairs.at(0).second;
484 LastQuarkId.push_back(qIdx_closest);
486 for (std::pair<double, int> qIdDrPair : lastQuark_dR_id_pairs)
487 LastQuarkId.push_back(qIdDrPair.second);
489 for (
int qIdx : LastQuarkId) {
490 int qmIdx = hadMothersIndices.at(qIdx).at(0);
491 LastQuarkMotherId.push_back(qmIdx);
494 if ((
int)LastQuarkId.size() > 0)
495 lastQuarkIndices.at(hadNum) = 0;
497 LastQuarkIds.push_back(LastQuarkId);
499 LastQuarkMotherIds.push_back(LastQuarkMotherId);
501 if (LastQuarkMotherId.empty()) {
504 int qIdx = LastQuarkId.at(lastQuarkIndices.at(hadNum));
505 int qFlav =
flavourSign(hadMothers.at(qIdx).pdgId());
506 hadronFlavour = qFlav *
std::abs(hadMothers.at(LastQuarkMotherId.at(lastQuarkIndices.at(hadNum))).pdgId());
508 hadFlavour.push_back(hadronFlavour);
511 int isFromTopWeakDecay = 1;
512 std::vector<int> checkedParticles;
513 if (hadFlavour.at(hadNum) != 0) {
514 int lastQIndex = LastQuarkId.at(lastQuarkIndices.at(hadNum));
515 bool fromTB = topDaughterQId >= 0 ?
findInMothers(lastQIndex,
526 checkedParticles.clear();
527 bool fromTbarB = topBarDaughterQId >= 0 ?
findInMothers(lastQIndex,
538 checkedParticles.clear();
539 if (!fromTB && !fromTbarB) {
540 isFromTopWeakDecay = 0;
543 isFromTopWeakDecay = 2;
544 hadFromTopWeakDecay.push_back(isFromTopWeakDecay);
545 int bHadronMotherId =
546 findInMothers(hadIdx, checkedParticles, hadMothersIndices, hadMothers, 0, 555555,
true, -1, 1,
false);
547 hadBHadronId.push_back(bHadronMotherId);
549 if (!LastQuarkMotherId.empty()) {
550 std::set<int> checkedHadronIds;
579 const unsigned int position =
std::find(particleList.begin(), particleList.end(), particle) - particleList.begin();
580 if (position >= particleList.size())
588 if (position >= list.size())
630 const int flavour_abs =
std::abs(flavour);
631 if (flavour_abs != 5 && flavour_abs != 4)
633 const int pdgId_abs =
std::abs(pdgId);
635 if (pdgId_abs / 100 % 10 != flavour_abs)
638 if (pdgId_abs / 1000 == flavour_abs)
656 const int flavour_abs =
std::abs(flavour);
657 if (flavour_abs != 5 && flavour_abs != 4)
659 const int pdgId_abs =
std::abs(pdgId);
661 if (pdgId_abs / 1000 != flavour_abs)
680 if (pdgId % 1000 / 10 / 11 > 0)
696 bool hasDaughter =
false;
727 int &topBarDaughterQId,
728 std::vector<const reco::Candidate *> &hadMothers,
729 std::vector<std::vector<int>> &hadMothersIndices,
730 std::set<const reco::Candidate *> *analyzedParticles,
731 const int prevPartIndex)
const {
733 int hadronIndex = -1;
736 hadMothers.push_back(thisParticle);
737 hadronIndex = hadMothers.size() - 1;
743 partIndex =
idInList(hadMothers, thisParticle);
747 if (!analyzedParticles) {
748 analyzedParticles =
new std::set<const reco::Candidate *>;
750 for (
unsigned int i = 0;
i < analyzedParticles->size();
i++) {
751 if (analyzedParticles->count(thisParticle) <= 0) {
760 if (prevPartIndex >= 0) {
765 analyzedParticles->insert(thisParticle);
768 for (
size_t iMother = 0; iMother < thisParticle->
numberOfMothers(); ++iMother) {
770 int mothIndex =
idInList(hadMothers, mother);
771 if (mothIndex == partIndex && partIndex >= 0) {
777 hadMothers.push_back(mother);
778 mothIndex = hadMothers.size() - 1;
781 if (mothIndex != partIndex && partIndex >= 0) {
785 mother, topDaughterQId, topBarDaughterQId, hadMothers, hadMothersIndices, analyzedParticles, partIndex);
788 int &bId = mother->
pdgId() < 0 ? topBarDaughterQId : topDaughterQId;
794 int bIdFlav =
std::abs(hadMothers.at(bId)->pdgId());
795 if (bIdFlav != 5 && thisFlav == 5)
797 else if (thisFlav == 5 && thisParticle->
pt() > hadMothers.at(bId)->pt())
803 analyzedParticles->erase(thisParticle);
828 int mothIndex)
const {
835 while ((
int)hadMothersIndices.size() <= partIndex) {
836 std::vector<int> mothersIndices;
837 hadMothersIndices.push_back(mothersIndices);
840 std::vector<int> *hadMotherIndices = &hadMothersIndices.at(partIndex);
842 if (mothIndex == -1) {
843 hadMotherIndices->clear();
846 for (
int k = 0;
k < (
int)hadMotherIndices->size();
k++) {
847 if (hadMotherIndices->at(
k) != mothIndex && hadMotherIndices->at(
k) != -1) {
856 hadMotherIndices->push_back(mothIndex);
880 std::vector<int> &mothChains,
881 const std::vector<std::vector<int>> &hadMothersIndices,
882 const std::vector<reco::GenParticle> &hadMothers,
889 int foundStopId = -1;
890 int pdg_1 = hadMothers.at(idx).pdgId();
892 if ((
int)hadMothersIndices.size() <=
idx) {
894 printf(
" Stopping checking particle %d. No mothers are stored.\n", idx);
899 if (
std::abs(hadMothers.at(idx).pdgId()) > 10 &&
std::abs(hadMothers.at(idx).pdgId()) < 19)
900 printf(
"Lepton: %d\n", hadMothers.at(idx).pdgId());
902 std::vector<int>
mothers = hadMothersIndices.at(idx);
903 unsigned int nMothers = mothers.size();
904 bool isCorrect =
false;
906 if (
std::abs(hadMothers.at(idx).pdgId()) == 2212) {
907 printf(
"Chk: %d\tpdg: %d\tstatus: %d", idx, hadMothers.at(idx).pdgId(), hadMothers.at(idx).status());
909 printf(
" Chk: %d(%d mothers)\tpdg: %d\tstatus: %d\tPt: %.3f\tEta: %.3f",
912 hadMothers.at(idx).pdgId(),
913 hadMothers.at(idx).status(),
914 hadMothers.at(idx).pt(),
915 hadMothers.at(idx).eta());
918 bool hasCorrectMothers =
true;
920 hasCorrectMothers =
false;
921 else if (mothers.at(0) < 0)
922 hasCorrectMothers =
false;
923 if (!hasCorrectMothers) {
925 printf(
" NO CORRECT MOTHER\n");
929 if (stopId >= 0 && idx == stopId)
933 if (pdgId % 111111 == 0 && pdgId != 0) {
934 if (
isHadronPdgId(pdgId / 111111, hadMothers.at(idx).pdgId())) {
940 if (((hadMothers.at(idx).pdgId() == pdgId && pdgAbs ==
false) ||
941 (
std::abs(hadMothers.at(idx).pdgId()) ==
std::abs(pdgId) && pdgAbs ==
true)) &&
942 (hadMothers.at(idx).status() == status || status == 0) && hasCorrectMothers) {
945 const bool inList =
std::find(mothChains.begin(), mothChains.end(),
idx) != mothChains.end();
946 if (!inList && mothers.at(0) >= 0 && (hadMothers.at(idx).pdgId() * pdgId > 0 || !pdgAbs)) {
947 if (firstLast == 0 || firstLast == 1) {
948 mothChains.push_back(idx);
962 if (isCorrect && firstLast == 1) {
967 unsigned int nDifferingMothers = 0;
968 for (
unsigned int i = 0;
i < nMothers;
i++) {
969 int idx2 = mothers.at(
i);
972 printf(
"^^^ Has no mother\n");
977 printf(
"^^^ Stored as its own mother\n");
980 int pdg_2 = hadMothers[idx2].pdgId();
985 printf(
"######### Inverting flavour of the hadron\n");
988 if ((
std::abs(pdg_2) !=
std::abs(pdgId) && pdgAbs ==
true) || (pdg_2 != pdgId && pdgAbs ==
false)) {
994 printf(
"Checking mother %d out of %d mothers (%d -> %d), looking for pdgId: %d\n",
i, nMothers, idx, idx2, pdgId);
996 if (firstLast == 2 && pdg_1 != pdg_2)
999 idx2, mothChains, hadMothersIndices, hadMothers, status, pdgId, pdgAbs, stopId, firstLast,
verbose);
1002 if (firstLast == 2 && isCorrect && nDifferingMothers >= nMothers) {
1004 printf(
"Checking particle %d once more to store it as the last quark\n", idx);
1006 foundStopId =
findInMothers(idx, mothChains, hadMothersIndices, hadMothers, 0, pdgId, pdgAbs, stopId, 1,
verbose);
1021 const int neutralPdgs_array[] = {9, 21, 22, 23, 25};
1022 const std::vector<int> neutralPdgs(neutralPdgs_array, neutralPdgs_array +
sizeof(neutralPdgs_array) /
sizeof(
int));
1023 if (
std::find(neutralPdgs.begin(), neutralPdgs.end(),
std::abs(pdgId)) == neutralPdgs.end())
1044 const std::vector<int> &hadIndices,
1045 const std::vector<reco::GenParticle> &hadMothers,
1046 const std::vector<std::vector<int>> &hadMothersIndices,
1047 const std::vector<int> &isFromTopWeakDecay,
1048 const std::vector<std::vector<int>> &LastQuarkIds,
1049 const std::vector<std::vector<int>> &LastQuarkMotherIds,
1050 std::vector<int> &lastQuarkIndices,
1052 std::set<int> &checkedHadronIds,
1053 const int lastQuarkIndex)
const {
1054 if (checkedHadronIds.count(hadId) != 0)
1056 checkedHadronIds.insert(hadId);
1058 if (lastQuarkIndex < 0)
1060 if ((
int)LastQuarkIds.at(hadId).size() < lastQuarkIndex + 1)
1062 int LastQuarkId = LastQuarkIds.at(hadId).at(lastQuarkIndex);
1063 int LastQuarkMotherId = LastQuarkMotherIds.at(hadId).at(lastQuarkIndex);
1064 int qmFlav = hadMothers.at(LastQuarkId).pdgId() < 0 ? -1 : 1;
1065 int hadFlavour = qmFlav *
std::abs(hadMothers.at(LastQuarkMotherId).pdgId());
1066 bool ambiguityResolved =
true;
1068 if ((hadMothers.at(LastQuarkId).pdgId() * hadMothers.at(LastQuarkMotherId).pdgId() < 0 &&
1069 !
isNeutralPdg(hadMothers.at(LastQuarkMotherId).pdgId())) ||
1071 (
std::abs(hadronFlavour.at(hadId)) == 6 && isFromTopWeakDecay.at(hadId) == 0)) {
1072 if ((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex + 1)
1083 lastQuarkIndex + 1);
1085 hadronFlavour.at(hadId) = qmFlav * 21;
1089 int nSameFlavourHadrons = 0;
1091 for (
unsigned int iHad = 0; iHad < hadronFlavour.size(); iHad++) {
1094 int theLastQuarkIndex = lastQuarkIndices.at(iHad);
1095 if (theLastQuarkIndex < 0)
1097 if ((
int)LastQuarkMotherIds.at(iHad).size() <= theLastQuarkIndex)
1099 int theLastQuarkMotherId = LastQuarkMotherIds.at(iHad).at(theLastQuarkIndex);
1100 int theHadFlavour = hadronFlavour.at(iHad);
1102 if (theHadFlavour == 0 ||
std::abs(theHadFlavour) == 21)
1104 if (theHadFlavour != hadFlavour || theLastQuarkMotherId != LastQuarkMotherId)
1106 ambiguityResolved =
false;
1107 nSameFlavourHadrons++;
1110 if ((
int)LastQuarkIds.at(hadId).size() > lastQuarkIndex + 1) {
1121 lastQuarkIndex + 1)) {
1122 ambiguityResolved =
true;
1127 if ((
int)LastQuarkIds.at(iHad).size() > theLastQuarkIndex + 1) {
1138 theLastQuarkIndex + 1)) {
1139 ambiguityResolved =
true;
1146 checkedHadronIds.erase(hadId);
1147 if (nSameFlavourHadrons > 0 && !ambiguityResolved) {
1148 hadronFlavour.at(hadId) = qmFlav * 21;
1151 lastQuarkIndices.at(hadId) = lastQuarkIndex;
1152 hadronFlavour.at(hadId) = hadFlavour;
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
int pdgId() const final
PDG identifier.
const edm::EDPutTokenT< std::vector< reco::GenParticle > > plusMothersToken_
bool isMesonPdgId(const int flavour, const int pdgId) const
Check the pdgId if it represents a meson of particular flavour.
const edm::EDPutTokenT< std::vector< std::vector< int > > > plusMothersIndicesToken_
const edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
transient_vector_type::const_iterator const_iterator
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
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
const edm::EDPutTokenT< std::vector< int > > bHadronIdToken_
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
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
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
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
#define DEFINE_FWK_MODULE(type)
int flavourSign(const int pdgId) const
Sign of the flavour (matter/antimatter)
~GenHFHadronMatcher() override
const edm::EDPutTokenT< std::vector< int > > leptonHadronIndexToken_
virtual int pdgId() const =0
PDG identifier.
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
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 > > 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.
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
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&...args)
puts a new product
virtual double pt() const =0
transverse momentum
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.
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...
virtual size_type numberOfDaughters() const =0
number of daughters
const edm::EDPutTokenT< std::vector< int > > fromTopWeakDecayToken_
const_iterator begin() const
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) ...
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
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_