13 addRadiation_(cfg.getParameter<bool>(
"addRadiation")),
21 else if (mode ==
"kStable")
24 throw cms::Exception(
"Configuration") << mode <<
" is not a supported FillMode!\n";
29 else if (mode ==
"Run2")
32 throw cms::Exception(
"Configuration") << mode <<
" is not a supported RunMode!\n";
37 produces<reco::GenParticleCollection>();
58 std::vector<const reco::GenParticle*> tops;
86 std::vector<const reco::GenParticle*> decaying_tops =
findDecayingTops(*src);
100 std::vector<const reco::GenParticle*> tops;
101 for (reco::GenParticleCollection::const_iterator
t = parts.begin();
t != parts.end(); ++
t) {
103 tops.push_back(&(*
t));
111 std::vector<const reco::GenParticle*> tops;
112 for (reco::GenParticleCollection::const_iterator
t = parts.begin();
t != parts.end(); ++
t) {
116 bool hasTopMother =
false;
117 for (
unsigned idx = 0; idx <
t->numberOfMothers(); ++idx) {
124 tops.push_back(&(*
t));
133 std::vector<const reco::GenParticle*> tops;
134 for (reco::GenParticleCollection::const_iterator
t = parts.begin();
t != parts.end(); ++
t) {
138 bool hasTopDaughter =
false;
139 for (
unsigned idx = 0; idx <
t->numberOfDaughters(); ++idx) {
141 hasTopDaughter =
true;
146 tops.push_back(&(*
t));
155 unsigned int w_index = 0;
179 bool containsItself =
false;
180 unsigned int d_idx = 0;
183 containsItself =
true;
203 for (std::vector<const reco::GenParticle*>::const_iterator it = tops.begin(); it != tops.end(); ++it) {
217 bool containsWBoson =
false, containsQuarkDaughter =
false;
220 containsQuarkDaughter =
true;
222 containsWBoson =
true;
224 if (containsQuarkDaughter && containsWBoson)
230 edm::LogInfo(
"decayChain") <<
" Failed to find top quarks in decay chain. Will assume that this a \n"
231 <<
" non-top sample and produce an empty decaySubset.\n";
234 " Can not find back any of the supported hadronization models. Models \n"
235 " which are supported are: \n"
236 " Pythia LO(+PS): Top(status 3) --> WBoson(status 3), Quark(status 3)\n"
237 " Herwig NLO(+PS): Top(status 2) --> Top(status 3) --> Top(status 2) \n");
247 if (genEvtInfoProduct.
isValid()) {
250 if (moduleName ==
"ExternalGeneratorFilter") {
252 edm::LogInfo(
"SpecialModule") <<
"GEN events are produced by ExternalGeneratorFilter, "
253 <<
"which is a wrapper of the original module: " <<
moduleName;
258 if (moduleName.find(
"Pythia6") != std::string::npos)
260 else if (moduleName.find(
"Pythia8") != std::string::npos)
262 else if (moduleName.find(
"Herwig6") != std::string::npos)
264 else if (moduleName.find(
"ThePEG") != std::string::npos)
267 else if (moduleName.find(
"Sherpa") != std::string::npos)
275 unsigned nTops = tops.size();
276 for (std::vector<const reco::GenParticle*>::iterator it = tops.begin(); it != tops.end();) {
278 bool isContained =
false;
279 bool expectedStatus =
false;
288 expectedStatus =
true;
293 if (!expectedStatus) {
296 edm::LogInfo(
"decayChain") <<
" W boson does not have the expected status. This happens, e.g., \n"
297 <<
" with MC@NLO in the case of additional ttbar pairs from radiated \n"
298 <<
" gluons. We hope everything is fine, remove the correspdonding top \n"
299 <<
" quark from our list since it is not part of the primary ttbar pair \n"
300 <<
" and try to continue. \n";
304 if (tops.empty() && nTops != 0)
306 " Did not find a W boson with appropriate status for any of the top \n"
307 " quarks in this event. This means that the hadronization of the W \n"
308 " boson might be screwed up or there is another problem with the \n"
309 " particle listing in this MC sample. Please contact an expert. \n");
315 unsigned int statusFlag;
320 for (std::vector<const reco::GenParticle*>::const_iterator it = tops.begin(); it != tops.end(); ++it) {
323 std::unique_ptr<reco::GenParticle> topPtr(
325 target.push_back(*topPtr);
329 std::vector<int> topDaughters;
333 std::vector<int> wDaughters;
343 std::unique_ptr<reco::GenParticle> bPtr(
344 new reco::GenParticle(td->threeCharge(),
p4(td, statusFlag), td->vertex(), td->pdgId(), statusFlag,
false));
345 target.push_back(*bPtr);
360 target.push_back(*wPtr);
378 wd->threeCharge(),
p4(wd, statusFlag), wd->vertex(), wd->pdgId(), statusFlag,
false));
379 target.push_back(*qPtr);
399 target.push_back(*radPtr);
414 new reco::GenParticle(ts->threeCharge(), ts->p4(), ts->vertex(), ts->pdgId(), ts->status(),
false);
415 std::unique_ptr<reco::GenParticle> sPtr(cand);
416 target.push_back(*sPtr);
417 if (ts->begin() != ts->end()) {
427 refs_[iTop] = topDaughters;
428 refs_[iW] = wDaughters;
433 const std::vector<const reco::GenParticle*>& decayingTops,
435 std::vector<const reco::GenParticle*>::const_iterator top_start;
436 std::vector<const reco::GenParticle*>::const_iterator top_end;
438 top_start = primalTops.begin();
439 top_end = primalTops.end();
441 top_start = decayingTops.begin();
442 top_end = decayingTops.end();
444 for (std::vector<const reco::GenParticle*>::const_iterator it = top_start; it != top_end; ++it) {
447 std::unique_ptr<reco::GenParticle> topPtr(
449 target.push_back(*topPtr);
454 std::vector<int> topDaughters;
458 std::vector<int> wDaughters;
465 std::unique_ptr<reco::GenParticle> qPtr(
466 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
467 target.push_back(*qPtr);
478 std::unique_ptr<reco::GenParticle> WPtr(
479 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
480 target.push_back(*WPtr);
491 std::unique_ptr<reco::GenParticle> qPtr(
492 new reco::GenParticle(wd->threeCharge(), wd->p4(), wd->vertex(), wd->pdgId(), wd->status(),
false));
493 target.push_back(*qPtr);
510 std::unique_ptr<reco::GenParticle> radPtr(
511 new reco::GenParticle(td->threeCharge(), td->p4(), td->vertex(), td->pdgId(), td->status(),
false));
512 target.push_back(*radPtr);
523 refs_[iTop] = topDaughters;
524 refs_[iW] = wDaughters;
543 vec +=
p4(
p, statusFlag);
554 if (vec.mass() - (*top)->mass() > 0) {
587 vec +=
p4(
p, statusFlag);
599 std::vector<int> daughters;
607 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
608 target.push_back(*ptr);
609 daughters.push_back(++idx);
612 if (!daughters.empty()) {
613 refs_[idxBuffer] = daughters;
618 std::vector<int> daughters;
623 if (daughter->pdgId() != part->
pdgId()) {
625 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
626 target.push_back(*ptr);
627 daughters.push_back(++idx);
630 if (!daughters.empty()) {
631 refs_[idxBuffer] = daughters;
640 std::vector<int> daughters;
644 daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(),
false));
645 target.push_back(*ptr);
647 daughters.push_back(++idx);
653 if (!daughters.empty()) {
654 refs_[idxBuffer] = daughters;
670 for (reco::GenParticleCollection::iterator
p = sel.begin();
p != sel.end(); ++
p, ++idx) {
672 std::map<int, std::vector<int> >::const_iterator daughters =
refs_.find(idx);
673 if (daughters !=
refs_.end()) {
674 for (std::vector<int>::const_iterator daughter = daughters->second.begin(); daughter != daughters->second.end();
677 if (part ==
nullptr) {
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
const Candidate * mother(size_type=0) const override
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
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 checkShowerModel(const std::vector< const reco::GenParticle * > &tops) const
check the decay chain for the used shower model
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
virtual int threeCharge() const =0
electric charge
virtual int status() const =0
status word
size_t numberOfDaughters() const override
number of daughters
int status() const final
status word
const Point & vertex() const override
vertex position (overwritten by PF...)
size_t numberOfMothers() const override
number of mothers
std::vector< const reco::GenParticle * > findTops(const reco::GenParticleCollection &parts)
find top quarks in list of input particles
const LorentzVector & p4() const final
four-momentum Lorentz vector
void addDaughter(const typename daughters::value_type &)
add a daughter via a reference
void clearReferences()
clear references
int pdgId() const final
PDG identifier.
edm::EDGetTokenT< GenEventInfoProduct > genEventInfo_srcToken_
input tag for the genEventInfo source
virtual size_type numberOfDaughters() const =0
number of daughters
int threeCharge() const final
electric charge
~TopDecaySubset() override
default destructor
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
const_iterator end() const
last daughter const_iterator
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
Abs< T >::type abs(const T &t)
bool addRadiation_
add radiation or not?
ShowerModel
classification of potential shower types
virtual const Point & vertex() const =0
vertex position
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)
ProcessHistory const & processHistory() const override
T getParameter(std::string const &) const
TopDecaySubset(const edm::ParameterSet &cfg)
default constructor
RunMode runMode_
run mode (Run1 || Run2)
void fillListing(const std::vector< const reco::GenParticle * > &tops, reco::GenParticleCollection &target)
fill output vector for full decay chain
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
const_iterator begin() const
first daughter const_iterator
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)
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
const reco::GenParticle * findLastParticleInChain(const reco::GenParticle *p)