CMS 3D CMS Logo

GeneratorFilter.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 //
4 
5 // class template GeneratorFilter<HAD> provides an EDFilter which uses
6 // the hadronizer type HAD to generate partons, hadronize them, and
7 // decay the resulting particles, in the CMS framework.
8 
9 #ifndef gen_GeneratorFilter_h
10 #define gen_GeneratorFilter_h
11 
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
27 #include "CLHEP/Random/RandomEngine.h"
28 
29 // #include "GeneratorInterface/ExternalDecays/interface/ExternalDecayDriver.h"
30 
31 //#include "GeneratorInterface/LHEInterface/interface/LHEEvent.h"
37 
38 namespace edm
39 {
40  template <class HAD, class DEC> class GeneratorFilter : public one::EDFilter<EndRunProducer,
41  BeginLuminosityBlockProducer,
42  EndLuminosityBlockProducer,
43  one::WatchLuminosityBlocks,
44  one::SharedResources>
45  {
46  public:
47  typedef HAD Hadronizer;
48  typedef DEC Decayer;
49 
50  // The given ParameterSet will be passed to the contained
51  // Hadronizer object.
52  explicit GeneratorFilter(ParameterSet const& ps);
53 
54  ~GeneratorFilter() override;
55 
56  bool filter(Event& e, EventSetup const& es) override;
57  void endRunProduce(Run &, EventSetup const&) override;
58  void beginLuminosityBlock(LuminosityBlock const&, EventSetup const&) override;
60  void endLuminosityBlock(LuminosityBlock const&, EventSetup const&) override;
61  void endLuminosityBlockProduce(LuminosityBlock &, EventSetup const&) override;
62  void preallocThreads(unsigned int iThreads) override;
63 
64  private:
65  Hadronizer hadronizer_;
66  //gen::ExternalDecayDriver* decayer_;
67  Decayer* decayer_;
68  unsigned int nEventsInLumiBlock_;
69  unsigned int nThreads_{1};
70  bool initialized_ = false;
71  };
72 
73  //------------------------------------------------------------------------
74  //
75  // Implementation
76 
77  template <class HAD, class DEC>
79  EDFilter(),
80  hadronizer_(ps),
83  {
84  // TODO:
85  // Put the list of types produced by the filters here.
86  // The current design calls for:
87  // * GenRunInfoProduct
88  // * HepMCProduct
89  //
90  // other maybe added as needs be
91  //
92 
93  std::vector<std::string> const& sharedResources = hadronizer_.sharedResources();
94  for(auto const& resource : sharedResources) {
95  usesResource(resource);
96  }
97 
98  if ( ps.exists("ExternalDecays") )
99  {
100  //decayer_ = new gen::ExternalDecayDriver(ps.getParameter<ParameterSet>("ExternalDecays"));
101  ParameterSet ps1 = ps.getParameter<ParameterSet>("ExternalDecays");
102  decayer_ = new Decayer(ps1);
103 
104  std::vector<std::string> const& sharedResourcesDec = decayer_->sharedResources();
105  for(auto const& resource : sharedResourcesDec) {
106  usesResource(resource);
107  }
108  }
109 
110  // This handles the case where there are no shared resources, because you
111  // have to declare something when the SharedResources template parameter was used.
112  if(sharedResources.empty() && (!decayer_ || decayer_->sharedResources().empty())) {
113  usesResource(edm::uniqueSharedResourceName());
114  }
115 
116  produces<edm::HepMCProduct>("unsmeared");
117  produces<GenEventInfoProduct>();
118  produces<GenLumiInfoHeader, edm::Transition::BeginLuminosityBlock>();
119  produces<GenLumiInfoProduct, edm::Transition::EndLuminosityBlock>();
120  produces<GenRunInfoProduct, edm::Transition::EndRun>();
121 
122  }
123 
124  template <class HAD, class DEC>
126  { if ( decayer_ ) delete decayer_;}
127 
128  template <class HAD, class DEC>
129  void
131  nThreads_ = iThreads;
132  }
133 
134  template <class HAD, class DEC>
135  bool
137  {
138  RandomEngineSentry<HAD> randomEngineSentry(&hadronizer_, ev.streamID());
139  RandomEngineSentry<DEC> randomEngineSentryDecay(decayer_, ev.streamID());
140 
141  //added for selecting/filtering gen events, in the case of hadronizer+externalDecayer
142 
143  bool passEvtGenSelector = false;
144  std::unique_ptr<HepMC::GenEvent> event(nullptr);
145 
146  while(!passEvtGenSelector)
147  {
148  event.reset();
149  hadronizer_.setEDMEvent(ev);
150 
151  if ( !hadronizer_.generatePartonsAndHadronize() ) return false;
152 
153  // this is "fake" stuff
154  // in principle, decays are done as part of full event generation,
155  // except for particles that are marked as to be kept stable
156  // but we currently keep in it the design, because we might want
157  // to use such feature for other applications
158  //
159  if ( !hadronizer_.decay() ) return false;
160 
161  event = hadronizer_.getGenEvent();
162  if ( !event.get() ) return false;
163 
164  // The external decay driver is being added to the system,
165  // it should be called here
166  //
167  if ( decayer_ )
168  {
169  auto t = decayer_->decay( event.get() );
170  if(t != event.get()) {
171  event.reset(t);
172  }
173  }
174  if ( !event.get() ) return false;
175 
176  passEvtGenSelector = hadronizer_.select( event.get() );
177 
178  }
179  // check and perform if there're any unstable particles after
180  // running external decay packages
181  //
182  // fisrt of all, put back modified event tree (after external decay)
183  //
184  hadronizer_.resetEvent( std::move(event) );
185 
186  //
187  // now run residual decays
188  //
189  if ( !hadronizer_.residualDecay() ) return false;
190 
191  hadronizer_.finalizeEvent();
192 
193  event = hadronizer_.getGenEvent();
194  if ( !event.get() ) return false;
195 
196  event->set_event_number( ev.id().event() );
197 
198  //
199  // tutto bene - finally, form up EDM products !
200  //
201  auto genEventInfo = hadronizer_.getGenEventInfo();
202  if (!genEventInfo.get())
203  {
204  // create GenEventInfoProduct from HepMC event in case hadronizer didn't provide one
205  genEventInfo.reset(new GenEventInfoProduct(event.get()));
206  }
207 
209 
210  std::unique_ptr<HepMCProduct> bare_product(new HepMCProduct());
211  bare_product->addHepMCData( event.release() );
212  ev.put(std::move(bare_product), "unsmeared");
214  return true;
215  }
216 
217  template <class HAD, class DEC>
218  void
220  {
221  // If relevant, record the integrated luminosity for this run
222  // here. To do so, we would need a standard function to invoke on
223  // the contained hadronizer that would report the integrated
224  // luminosity.
225 
226  if(initialized_) {
227  hadronizer_.statistics();
228 
229  if ( decayer_ ) decayer_->statistics();
230  }
231 
232  std::unique_ptr<GenRunInfoProduct> griproduct(new GenRunInfoProduct(hadronizer_.getGenRunInfo()));
233  r.put(std::move(griproduct));
234  }
235 
236  template <class HAD, class DEC>
237  void
239  {}
240 
241  template <class HAD, class DEC>
242  void
244  {
246  RandomEngineSentry<HAD> randomEngineSentry(&hadronizer_, lumi.index());
247  RandomEngineSentry<DEC> randomEngineSentryDecay(decayer_, lumi.index());
248 
249  hadronizer_.randomizeIndex(lumi,randomEngineSentry.randomEngine());
250  hadronizer_.generateLHE(lumi,randomEngineSentry.randomEngine(), nThreads_);
251 
252  if ( !hadronizer_.readSettings(0) )
254  << "Failed to read settings for the hadronizer "
255  << hadronizer_.classname() << " \n";
256 
257  if ( decayer_ )
258  {
259  decayer_->init(es);
260  if ( !hadronizer_.declareStableParticles( decayer_->operatesOnParticles() ) )
262  << "Failed to declare stable particles in hadronizer "
263  << hadronizer_.classname()
264  << "\n";
265  if ( !hadronizer_.declareSpecialSettings( decayer_->specialSettings() ) )
267  << "Failed to declare special settings in hadronizer "
268  << hadronizer_.classname()
269  << "\n";
270  }
271 
272  if ( !hadronizer_.initializeForInternalPartons() )
274  << "Failed to initialize hadronizer "
275  << hadronizer_.classname()
276  << " for internal parton generation\n";
277 
278  std::unique_ptr<GenLumiInfoHeader> genLumiInfoHeader(hadronizer_.getGenLumiInfoHeader());
280  initialized_ = true;
281  }
282 
283  template <class HAD, class DEC>
284  void
286  {
287  hadronizer_.cleanLHE();
288  }
289 
290  template <class HAD, class DEC>
291  void
293  {
294  hadronizer_.statistics();
295  if ( decayer_ ) decayer_->statistics();
296 
297  GenRunInfoProduct genRunInfo = GenRunInfoProduct(hadronizer_.getGenRunInfo());
298  std::vector<GenLumiInfoProduct::ProcessInfo> GenLumiProcess;
299  const GenRunInfoProduct::XSec& xsec = genRunInfo.internalXSec();
301  temp.setProcess(0);
302  temp.setLheXSec(xsec.value(), xsec.error()); // Pythia gives error of -1
304  temp.setNPassNeg(0);
306  temp.setNTotalNeg(0);
310  temp.setAccepted(0,-1,-1);
311  temp.setAcceptedBr(0,-1,-1);
312  GenLumiProcess.push_back(temp);
313 
314  std::unique_ptr<GenLumiInfoProduct> genLumiInfo(new GenLumiInfoProduct());
315  genLumiInfo->setHEPIDWTUP(-1);
316  genLumiInfo->setProcessInfo( GenLumiProcess );
317 
318  lumi.put(std::move(genLumiInfo));
319 
321 
322  }
323 }
324 
325 #endif // gen_GeneratorFilter_h
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
void setTried(unsigned int n, double sum, double sum2)
void endLuminosityBlock(LuminosityBlock const &, EventSetup const &) override
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
void setSelected(unsigned int n, double sum, double sum2)
bool filter(Event &e, EventSetup const &es) override
LuminosityBlockIndex index() const
void setKilled(unsigned int n, double sum, double sum2)
#define nullptr
bool exists(std::string const &parameterName) const
checks if a parameter exists
bool ev
GeneratorFilter(ParameterSet const &ps)
void setAccepted(unsigned int n, double sum, double sum2)
void setAcceptedBr(unsigned int n, double sum, double sum2)
void put(std::unique_ptr< PROD > product)
Put a new product.
unsigned int nThreads_
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 but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
unsigned int nEventsInLumiBlock_
void beginLuminosityBlock(LuminosityBlock const &, EventSetup const &) override
void put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Run.h:108
void endRunProduce(Run &, EventSetup const &) override
void setLheXSec(double value, double err)
const XSec & internalXSec() const
edm::EventID id() const
Definition: EventBase.h:59
HLT enums.
void preallocThreads(unsigned int iThreads) override
StreamID streamID() const
Definition: Event.h:95
void endLuminosityBlockProduce(LuminosityBlock &, EventSetup const &) override
std::string uniqueSharedResourceName()
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
void beginLuminosityBlockProduce(LuminosityBlock &, EventSetup const &) override