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