CMS 3D CMS Logo

HadronAndPartonSelector.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: HadronAndPartonSelector
4 // Class: HadronAndPartonSelector
5 //
37 //
38 // Original Author: Dinko Ferencek
39 // Created: Tue Nov 5 22:43:43 CET 2013
40 //
41 //
42 
43 // system include files
44 #include <memory>
45 
46 // user include files
49 
52 
54 
67 
68 //
69 // constants, enums and typedefs
70 //
71 typedef std::shared_ptr<BasePartonSelector> PartonSelectorPtr;
72 
73 //
74 // class declaration
75 //
76 
78 public:
80  ~HadronAndPartonSelector() override;
81 
82  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
83 
84 private:
85  void produce(edm::Event&, const edm::EventSetup&) override;
86 
87  // ----------member data ---------------------------
88  const edm::EDGetTokenT<GenEventInfoProduct> srcToken_; // To get handronizer module type
89  const edm::EDGetTokenT<reco::GenParticleCollection> particlesToken_; // Input GenParticle collection
90 
91  std::string partonMode_; // Parton selection mode
95 };
96 
97 //
98 // static data member definitions
99 //
100 
101 //
102 // constructors and destructor
103 //
105  :
106 
107  srcToken_(mayConsume<GenEventInfoProduct>(iConfig.getParameter<edm::InputTag>("src"))),
108  particlesToken_(consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("particles"))),
109  partonMode_(iConfig.getParameter<std::string>("partonMode")),
110  fullChainPhysPartons_(iConfig.getParameter<bool>("fullChainPhysPartons"))
111 
112 {
113  //register your products
114  produces<reco::GenParticleRefVector>("bHadrons");
115  produces<reco::GenParticleRefVector>("cHadrons");
116  produces<reco::GenParticleRefVector>("algorithmicPartons");
117  produces<reco::GenParticleRefVector>("physicsPartons");
118  produces<reco::GenParticleRefVector>("leptons");
119 
120  partonSelectorSet_ = false;
121  partonSelector_ = nullptr;
122 }
123 
125  // do anything here that needs to be done at desctruction time
126  // (e.g. close files, deallocate resources etc.)
127 }
128 
129 //
130 // member functions
131 //
132 
133 // ------------ method called to produce the data ------------
135  // determine hadronizer type (done only once per job)
136  if (partonMode_ == "Auto") {
137  edm::Handle<GenEventInfoProduct> genEvtInfoProduct;
138  iEvent.getByToken(srcToken_, genEvtInfoProduct);
139 
140  std::string moduleName = "";
141  if (genEvtInfoProduct.isValid()) {
142  const edm::StableProvenance& prov = iEvent.getStableProvenance(genEvtInfoProduct.id());
143  moduleName = edm::moduleName(prov, iEvent.processHistory());
144  if (moduleName == "ExternalGeneratorFilter") {
145  moduleName = edm::parameterSet(prov, iEvent.processHistory()).getParameter<std::string>("@external_type");
146  edm::LogInfo("SpecialModule") << "GEN events are produced by ExternalGeneratorFilter, "
147  << "which is a wrapper of the original module: " << moduleName;
148  }
149  }
150 
151  if (moduleName.find("Pythia6") != std::string::npos)
152  partonMode_ = "Pythia6";
153  else if (moduleName.find("Pythia8") != std::string::npos)
154  partonMode_ = "Pythia8";
155  else if (moduleName.find("ThePEG") != std::string::npos)
156  partonMode_ = "Herwig++";
157  else if (moduleName.find("Herwig7") != std::string::npos)
158  partonMode_ = "Herwig++";
159  else if (moduleName.find("Sherpa") != std::string::npos)
160  partonMode_ = "Sherpa";
161  else
162  partonMode_ = "Undefined";
163  }
164 
165  // set the parton selection mode (done only once per job)
166  if (!partonSelectorSet_) {
167  if (partonMode_ == "Undefined")
168  edm::LogWarning("UndefinedPartonMode")
169  << "Could not automatically determine the hadronizer type and set the correct parton selection mode. "
170  "Parton-based jet flavour will not be defined.";
171  else if (partonMode_ == "Pythia6") {
173  edm::LogInfo("PartonModeDefined") << "Using Pythia6 parton selection mode.";
174  } else if (partonMode_ == "Pythia8") {
176  edm::LogInfo("PartonModeDefined") << "Using Pythia8 parton selection mode.";
177  } else if (partonMode_ == "Herwig++") {
179  edm::LogInfo("PartonModeDefined") << "Using Herwig++ parton selection mode.";
180  } else if (partonMode_ == "Sherpa") {
182  edm::LogInfo("PartonModeDefined") << "Using Sherpa parton selection mode.";
183  } else
184  throw cms::Exception("InvalidPartonMode") << "Parton selection mode is invalid: " << partonMode_
185  << ", use Auto | Pythia6 | Pythia8 | Herwig++ | Sherpa" << std::endl;
186 
187  partonSelectorSet_ = true;
188  }
189 
191  iEvent.getByToken(particlesToken_, particles);
192 
193  auto bHadrons = std::make_unique<reco::GenParticleRefVector>();
194  auto cHadrons = std::make_unique<reco::GenParticleRefVector>();
195  auto partons = std::make_unique<reco::GenParticleRefVector>();
196  auto physicsPartons = std::make_unique<reco::GenParticleRefVector>();
197  auto leptons = std::make_unique<reco::GenParticleRefVector>();
198 
199  // loop over particles and select b and c hadrons and leptons
200  for (reco::GenParticleCollection::const_iterator it = particles->begin(); it != particles->end(); ++it) {
201  // if b hadron
202  if (CandMCTagUtils::hasBottom(*it)) {
203  // check if any of the daughters is also a b hadron
204  bool hasbHadronDaughter = false;
205  for (size_t i = 0; i < it->numberOfDaughters(); ++i) {
206  if (CandMCTagUtils::hasBottom(*(it->daughter(i)))) {
207  hasbHadronDaughter = true;
208  break;
209  }
210  }
211  if (hasbHadronDaughter)
212  continue; // skip excited b hadrons that have other b hadrons as daughters
213 
214  bHadrons->push_back(reco::GenParticleRef(particles, it - particles->begin()));
215  }
216 
217  // if c hadron
218  if (CandMCTagUtils::hasCharm(*it)) {
219  // check if any of the daughters is also a c hadron
220  bool hascHadronDaughter = false;
221  for (size_t i = 0; i < it->numberOfDaughters(); ++i) {
222  if (CandMCTagUtils::hasCharm(*(it->daughter(i)))) {
223  hascHadronDaughter = true;
224  break;
225  }
226  }
227  if (hascHadronDaughter)
228  continue; // skip excited c hadrons that have other c hadrons as daughters
229 
230  cHadrons->push_back(reco::GenParticleRef(particles, it - particles->begin()));
231  }
232 
233  // status==1 electrons and muons
234  if ((reco::isElectron(*it) || reco::isMuon(*it)) && it->status() == 1)
235  leptons->push_back(reco::GenParticleRef(particles, it - particles->begin()));
236 
237  // status==2 taus
238  if (reco::isTau(*it) && it->status() == 2)
239  leptons->push_back(reco::GenParticleRef(particles, it - particles->begin()));
240  }
241 
242  // select algorithmic partons
243  if (partonMode_ != "Undefined") {
245  }
246 
247  // select physics partons
248  for (reco::GenParticleCollection::const_iterator it = particles->begin(); it != particles->end(); ++it) {
249  if (!fullChainPhysPartons_) {
250  if (!(it->status() == 3 || ((partonMode_ == "Pythia8") && (it->status() == 23))))
251  continue;
252  }
253  if (!CandMCTagUtils::isParton(*it))
254  continue; // skip particle if not a parton
255  physicsPartons->push_back(reco::GenParticleRef(particles, it - particles->begin()));
256  }
257 
258  iEvent.put(std::move(bHadrons), "bHadrons");
259  iEvent.put(std::move(cHadrons), "cHadrons");
260  iEvent.put(std::move(partons), "algorithmicPartons");
261  iEvent.put(std::move(physicsPartons), "physicsPartons");
262  iEvent.put(std::move(leptons), "leptons");
263 }
264 
265 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
267  //The following says we do not know what parameters are allowed so do no validation
268  // Please change this to state exactly what you do use, even if it is no parameters
270  desc.setUnknown();
271  descriptions.addDefault(desc);
272 }
273 
274 //define this as a plug-in
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
Selects hadrons and partons from a collection of GenParticles.
ProductID id() const
Definition: HandleBase.cc:29
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:9
std::shared_ptr< BasePartonSelector > PartonSelectorPtr
bool hasCharm(const reco::Candidate &c)
Definition: CandMCTag.cc:35
Herwig++ parton selector derived from the base parton selector.
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
const edm::EDGetTokenT< reco::GenParticleCollection > particlesToken_
void produce(edm::Event &, const edm::EventSetup &) override
int iEvent
Definition: GenABIO.cc:224
Sherpa parton selector derived from the base parton selector.
void addDefault(ParameterSetDescription const &psetDescription)
bool isElectron(const Candidate &part)
Definition: pdgIdUtils.h:7
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Pythia6 parton selector derived from the base parton selector.
Pythia8 parton selector derived from the base parton selector.
Log< level::Info, false > LogInfo
bool isParton(const reco::Candidate &c)
Definition: CandMCTag.cc:46
bool isValid() const
Definition: HandleBase.h:70
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:27
fixed size matrix
HLT enums.
HadronAndPartonSelector(const edm::ParameterSet &)
Log< level::Warning, false > LogWarning
bool hasBottom(const reco::Candidate &c)
Definition: CandMCTag.cc:24
def move(src, dest)
Definition: eostools.py:511
const edm::EDGetTokenT< GenEventInfoProduct > srcToken_
bool isTau(const Candidate &part)
Definition: pdgIdUtils.h:11