71 void checkWBosons(std::vector<const reco::GenParticle*>& tops)
const;
75 void fillListing(
const std::vector<const reco::GenParticle*>& primalTops,
76 const std::vector<const reco::GenParticle*>& decayingTops,
91 bool recursive =
true);
116 std::map<int, std::vector<int> >
refs_;
123 addRadiation_(
cfg.getParameter<
bool>(
"addRadiation")),
124 showerModel_(kStart),
131 else if (
mode ==
"kStable")
139 else if (
mode ==
"Run2")
147 produces<reco::GenParticleCollection>();
165 std::vector<const reco::GenParticle*> tops;
207 std::vector<const reco::GenParticle*> tops;
208 for (reco::GenParticleCollection::const_iterator
t =
parts.begin();
t !=
parts.end(); ++
t) {
210 tops.push_back(&(*
t));
218 std::vector<const reco::GenParticle*> tops;
219 for (reco::GenParticleCollection::const_iterator
t =
parts.begin();
t !=
parts.end(); ++
t) {
223 bool hasTopMother =
false;
224 for (
unsigned idx = 0;
idx <
t->numberOfMothers(); ++
idx) {
231 tops.push_back(&(*
t));
240 std::vector<const reco::GenParticle*> tops;
241 for (reco::GenParticleCollection::const_iterator
t =
parts.begin();
t !=
parts.end(); ++
t) {
245 bool hasTopDaughter =
false;
246 for (
unsigned idx = 0;
idx <
t->numberOfDaughters(); ++
idx) {
248 hasTopDaughter =
true;
253 tops.push_back(&(*
t));
262 unsigned int w_index = 0;
286 bool containsItself =
false;
287 unsigned int d_idx = 0;
288 for (
unsigned idx = 0;
idx <
p->numberOfDaughters(); ++
idx) {
290 containsItself =
true;
301 if (
p->status() == 3)
310 for (std::vector<const reco::GenParticle*>::const_iterator
it = tops.begin();
it != tops.end(); ++
it) {
324 bool containsWBoson =
false, containsQuarkDaughter =
false;
327 containsQuarkDaughter =
true;
329 containsWBoson =
true;
331 if (containsQuarkDaughter && containsWBoson)
337 edm::LogInfo(
"decayChain") <<
" Failed to find top quarks in decay chain. Will assume that this a \n" 338 <<
" non-top sample and produce an empty decaySubset.\n";
341 " Can not find back any of the supported hadronization models. Models \n" 342 " which are supported are: \n" 343 " Pythia LO(+PS): Top(status 3) --> WBoson(status 3), Quark(status 3)\n" 344 " Herwig NLO(+PS): Top(status 2) --> Top(status 3) --> Top(status 2) \n");
354 if (genEvtInfoProduct.
isValid()) {
357 if (
moduleName ==
"ExternalGeneratorFilter") {
359 edm::LogInfo(
"SpecialModule") <<
"GEN events are produced by ExternalGeneratorFilter, " 360 <<
"which is a wrapper of the original module: " <<
moduleName;
365 if (
moduleName.find(
"Pythia6") != std::string::npos)
367 else if (
moduleName.find(
"Pythia8") != std::string::npos)
369 else if (
moduleName.find(
"Herwig6") != std::string::npos)
371 else if (
moduleName.find(
"ThePEG") != std::string::npos)
374 else if (
moduleName.find(
"Sherpa") != std::string::npos)
382 unsigned nTops = tops.size();
383 for (std::vector<const reco::GenParticle*>::iterator
it = tops.begin();
it != tops.end();) {
385 bool isContained =
false;
386 bool expectedStatus =
false;
395 expectedStatus =
true;
400 if (!expectedStatus) {
403 edm::LogInfo(
"decayChain") <<
" W boson does not have the expected status. This happens, e.g., \n" 404 <<
" with MC@NLO in the case of additional ttbar pairs from radiated \n" 405 <<
" gluons. We hope everything is fine, remove the correspdonding top \n" 406 <<
" quark from our list since it is not part of the primary ttbar pair \n" 407 <<
" and try to continue. \n";
411 if (tops.empty() && nTops != 0)
413 " Did not find a W boson with appropriate status for any of the top \n" 414 " quarks in this event. This means that the hadronization of the W \n" 415 " boson might be screwed up or there is another problem with the \n" 416 " particle listing in this MC sample. Please contact an expert. \n");
422 unsigned int statusFlag;
427 for (std::vector<const reco::GenParticle*>::const_iterator
it = tops.begin();
it != tops.end(); ++
it) {
430 std::unique_ptr<reco::GenParticle> topPtr(
432 target.push_back(*topPtr);
436 std::vector<int> topDaughters;
440 std::vector<int> wDaughters;
450 std::unique_ptr<reco::GenParticle> bPtr(
451 new reco::GenParticle(td->threeCharge(),
p4(td, statusFlag), td->vertex(), td->pdgId(), statusFlag,
false));
485 wd->threeCharge(),
p4(wd, statusFlag), wd->vertex(), wd->pdgId(), statusFlag,
false));
506 target.push_back(*radPtr);
517 if (
std::abs(ts->pdgId()) !=
t->pdgId() && ts->pdgId() !=
t->mother()->pdgId()) {
521 new reco::GenParticle(ts->threeCharge(), ts->p4(), ts->vertex(), ts->pdgId(), ts->status(),
false);
522 std::unique_ptr<reco::GenParticle> sPtr(
cand);
524 if (ts->begin() != ts->end()) {
534 refs_[iTop] = topDaughters;
535 refs_[iW] = wDaughters;
540 const std::vector<const reco::GenParticle*>& decayingTops,
542 std::vector<const reco::GenParticle*>::const_iterator top_start;
543 std::vector<const reco::GenParticle*>::const_iterator top_end;
545 top_start = primalTops.begin();
546 top_end = primalTops.end();
548 top_start = decayingTops.begin();
549 top_end = decayingTops.end();
551 for (std::vector<const reco::GenParticle*>::const_iterator
it = top_start;
it != top_end; ++
it) {
554 std::unique_ptr<reco::GenParticle> topPtr(
556 target.push_back(*topPtr);
561 std::vector<int> topDaughters;
565 std::vector<int> wDaughters;
572 std::unique_ptr<reco::GenParticle> qPtr(
573 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
585 std::unique_ptr<reco::GenParticle> WPtr(
586 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
598 std::unique_ptr<reco::GenParticle> qPtr(
599 new reco::GenParticle(wd->threeCharge(), wd->p4(), wd->vertex(), wd->pdgId(), wd->status(),
false));
617 std::unique_ptr<reco::GenParticle> radPtr(
618 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
619 target.push_back(*radPtr);
630 refs_[iTop] = topDaughters;
631 refs_[iW] = wDaughters;
650 vec +=
p4(
p, statusFlag);
661 if (vec.mass() - (*top)->mass() > 0) {
694 vec +=
p4(
p, statusFlag);
714 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
730 if (daughter->pdgId() !=
part->pdgId()) {
732 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
751 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
777 for (reco::GenParticleCollection::iterator
p =
sel.begin();
p !=
sel.end(); ++
p, ++
idx) {
781 for (std::vector<int>::const_iterator daughter =
daughters->second.begin(); daughter !=
daughters->second.end();
784 if (
part ==
nullptr) {
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
void addDaughters(int &idx, const reco::GenParticle::const_iterator part, reco::GenParticleCollection &target, bool recursive=true)
recursively fill vector for all further decay particles of a given particle
std::map< int, std::vector< int > > refs_
management of daughter indices for fillRefs
ShowerModel showerModel_
parton shower mode (filled in checkShowerModel)
void addRadiation(int &idx, const reco::GenParticle::const_iterator part, reco::GenParticleCollection &target)
fill vector including all radiations from quarks originating from W/top
RunMode
supported modes to run the code
virtual int status() const =0
status word
size_t numberOfDaughters() const override
number of daughters
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
std::vector< const reco::GenParticle * > findTops(const reco::GenParticleCollection &parts)
find top quarks in list of input particles
void clearReferences()
clear references
int pdgId() const final
PDG identifier.
edm::EDGetTokenT< GenEventInfoProduct > genEventInfo_srcToken_
input tag for the genEventInfo source
void fillListing(const std::vector< const reco::GenParticle *> &tops, reco::GenParticleCollection &target)
fill output vector for full decay chain
virtual size_type numberOfDaughters() const =0
number of daughters
ShowerModel checkShowerModel(const std::vector< const reco::GenParticle *> &tops) const
check the decay chain for the used shower model
reco::Particle::LorentzVector p4(const std::vector< const reco::GenParticle *>::const_iterator top, int statusFlag)
calculate lorentz vector from input (dedicated to top reconstruction)
void checkWBosons(std::vector< const reco::GenParticle *> &tops) const
check whether W bosons are contained in the original gen particle listing
const_iterator end() const
last daughter const_iterator
Abs< T >::type abs(const T &t)
bool addRadiation_
add radiation or not?
ShowerModel
classification of potential shower types
#define DEFINE_FWK_MODULE(type)
void produce(edm::Event &event, const edm::EventSetup &setup) override
write output into the event
std::vector< const reco::GenParticle * > findDecayingTops(const reco::GenParticleCollection &parts)
edm::EDGetTokenT< reco::GenParticleCollection > srcToken_
input tag for the genParticle source
void fillReferences(const reco::GenParticleRefProd &refProd, reco::GenParticleCollection &target)
fill references for output vector
virtual int pdgId() const =0
PDG identifier.
Log< level::Info, false > LogInfo
std::vector< const reco::GenParticle * > findPrimalTops(const reco::GenParticleCollection &parts)
TopDecaySubset(const edm::ParameterSet &cfg)
default constructor
RunMode runMode_
run mode (Run1 || Run2)
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
Module to produce the subset of generator particles directly contained in top decay chains...
math::XYZTLorentzVector LorentzVector
Lorentz vector.
const Candidate * daughter(size_type) const override
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
const reco::GenParticle * findPrimalW(const reco::GenParticle *top)
const_iterator begin() const
first daughter const_iterator
const reco::GenParticle * findLastParticleInChain(const reco::GenParticle *p)