CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Pythia6Hadronizer.cc
Go to the documentation of this file.
1 
2 // -*- C++ -*-
3 
4 #include "Pythia6Hadronizer.h"
5 
6 #include "HepMC/GenEvent.h"
7 #include "HepMC/PdfInfo.h"
8 #include "HepMC/PythiaWrapper6_2.h"
9 #include "HepMC/HEPEVT_Wrapper.h"
10 #include "HepMC/IO_HEPEVT.h"
11 
13 
15 
17 
19 
21 
22 
23 HepMC::IO_HEPEVT conv;
24 
25 #include "HepPID/ParticleIDTranslations.hh"
26 
27 // NOTE: here a number of Pythia6 routines are declared,
28 // plus some functionalities to pass around Pythia6 params
29 //
32 
33 namespace gen
34 {
35 
36 extern "C" {
37 
38  //
39  // these two are NOT part of Pythi6 core code but are "custom" add-ons
40  // we keep them interfaced here, rather than in GenExtensions, because
41  // they tweak not at the ME level, but a step further, at the framgmentation
42  //
43  // stop-hadrons
44  //
45  void pystrhad_(); // init stop-hadrons (id's, names, charges...)
46  void pystfr_(int&); // tweaks fragmentation, fragments the string near to a stop,
47  // to form stop-hadron by producing a new q-qbar pair
48  // gluino/r-hadrons
49  void pyglrhad_();
50  void pyglfr_(); // tweaks fragmentation, fragment the string near to a gluino,
51  // to form gluino-hadron, either by producing a new g-g pair,
52  // or two new q-qbar ones
53 
54 
55 } // extern "C"
56 
58  public:
60 
61  private:
62  void upInit()
64 
65  void upEvnt()
66  {
70  }
71 
72  bool upVeto()
73  {
75  return false;
76 
78  return true;
79 
80  // NOTE: I'm passing NULL pointers, instead of HepMC::GenEvent, etc.
81  return Pythia6Hadronizer::getJetMatching()->match(0, 0, true);
82  }
83 };
84 
85 static struct {
86  int n, npad, k[5][pyjets_maxn];
87  double p[5][pyjets_maxn], v[5][pyjets_maxn];
88 } pyjets_local;
89 
90 JetMatching* Pythia6Hadronizer::fJetMatching = 0;
91 
93  : BaseHadronizer(ps),
94  fPy6Service( new Pythia6ServiceWithCallback(ps) ), // this will store py6 params for further settings
95  fCOMEnergy(ps.getParameter<double>("comEnergy")),
96  fHepMCVerbosity(ps.getUntrackedParameter<bool>("pythiaHepMCVerbosity",false)),
97  fMaxEventsToPrint(ps.getUntrackedParameter<int>("maxEventsToPrint", 0)),
98  fPythiaListVerbosity(ps.getUntrackedParameter<int>("pythiaPylistVerbosity", 0)),
99  fDisplayPythiaBanner(ps.getUntrackedParameter<bool>("displayPythiaBanner",false)),
100  fDisplayPythiaCards(ps.getUntrackedParameter<bool>("displayPythiaCards",false))
101 {
102 
103  // J.Y.: the following 4 params are "hacked", in the sense
104  // that they're tracked but get in optionally;
105  // this will be fixed once we update all applications
106  //
107 
108  fStopHadronsEnabled = false;
109  if ( ps.exists( "stopHadrons" ) )
110  fStopHadronsEnabled = ps.getParameter<bool>("stopHadrons") ;
111 
112  fGluinoHadronsEnabled = false;
113  if ( ps.exists( "gluinoHadrons" ) )
114  fGluinoHadronsEnabled = ps.getParameter<bool>("gluinoHadrons");
115 
116  fImposeProperTime = false;
117  if ( ps.exists( "imposeProperTime" ) )
118  {
119  fImposeProperTime = ps.getParameter<bool>("imposeProperTime");
120  }
121 
122  fConvertToPDG = false;
123  if ( ps.exists( "doPDGConvert" ) )
124  fConvertToPDG = ps.getParameter<bool>("doPDGConvert");
125 
126  if ( ps.exists("jetMatching") )
127  {
128  edm::ParameterSet jmParams =
130  "jetMatching");
131 
132  fJetMatching = JetMatching::create(jmParams).release();
133  }
134 
135  // first of all, silence Pythia6 banner printout, unless display requested
136  //
137  if ( !fDisplayPythiaBanner )
138  {
139  if (!call_pygive("MSTU(12)=12345"))
140  {
141  throw edm::Exception(edm::errors::Configuration,"PythiaError")
142  <<" Pythia did not accept MSTU(12)=12345";
143  }
144  }
145 
146 // silence printouts from PYGIVE, unless display requested
147 //
148  if ( ! fDisplayPythiaCards )
149  {
150  if (!call_pygive("MSTU(13)=0"))
151  {
152  throw edm::Exception(edm::errors::Configuration,"PythiaError")
153  <<" Pythia did not accept MSTU(13)=0";
154  }
155  }
156 
157  // tmp stuff to deal with EvtGen corrupting pyjets
158  // NPartsBeforeDecays = 0;
159  flushTmpStorage();
160 
161 }
162 
164 {
165  if ( fPy6Service != 0 ) delete fPy6Service;
166  if ( fJetMatching != 0 ) delete fJetMatching;
167 }
168 
170 {
171 
172  pyjets_local.n = 0 ;
173  pyjets_local.npad = 0 ;
174  for ( int ip=0; ip<pyjets_maxn; ip++ )
175  {
176  for ( int i=0; i<5; i++ )
177  {
178  pyjets_local.k[i][ip] = 0;
179  pyjets_local.p[i][ip] = 0.;
180  pyjets_local.v[i][ip] = 0.;
181  }
182  }
183  return;
184 
185 }
186 
188 {
189 
190  pyjets_local.n = pyjets.n;
191  pyjets_local.npad = pyjets.npad;
192  for ( int ip=0; ip<pyjets_maxn; ip++ )
193  {
194  for ( int i=0; i<5; i++ )
195  {
196  pyjets_local.k[i][ip] = pyjets.k[i][ip];
197  pyjets_local.p[i][ip] = pyjets.p[i][ip];
198  pyjets_local.v[i][ip] = pyjets.v[i][ip];
199  }
200  }
201 
202  return ;
203 
204 }
205 
207 {
208 
209  bool lhe = lheEvent() != 0;
210 
211  HepMC::PdfInfo pdf;
212 
213  // if we are in hadronizer mode, we can pass on information from
214  // the LHE input
215  if (lhe)
216  {
217  lheEvent()->fillEventInfo( event().get() );
218  lheEvent()->fillPdfInfo( &pdf );
219  }
220  else
221  {
222  // filling in factorization "Q scale" now! pthat moved to binningValues()
223  //
224 
225  if ( event()->signal_process_id() <= 0) event()->set_signal_process_id( pypars.msti[0] );
226  if ( event()->event_scale() <=0 ) event()->set_event_scale( pypars.pari[22] );
227  if ( event()->alphaQED() <= 0) event()->set_alphaQED( pyint1.vint[56] );
228  if ( event()->alphaQCD() <= 0) event()->set_alphaQCD( pyint1.vint[57] );
229 
230  // get pdf info directly from Pythia6 and set it up into HepMC::GenEvent
231  // S. Mrenna: Prefer vint block
232  //
233  if ( pdf.id1() <= 0) pdf.set_id1( pyint1.mint[14] == 21 ? 0 : pyint1.mint[14] );
234  if ( pdf.id2() <= 0) pdf.set_id2( pyint1.mint[15] == 21 ? 0 : pyint1.mint[15] );
235  if ( pdf.x1() <= 0) pdf.set_x1( pyint1.vint[40] );
236  if ( pdf.x2() <= 0) pdf.set_x2( pyint1.vint[41] );
237  if ( pdf.pdf1() <= 0) pdf.set_pdf1( pyint1.vint[38] / pyint1.vint[40] );
238  if ( pdf.pdf2() <= 0) pdf.set_pdf2( pyint1.vint[39] / pyint1.vint[41] );
239  if ( pdf.scalePDF() <= 0) pdf.set_scalePDF( pyint1.vint[50] );
240  }
241 
242 /* 9/9/2010 - JVY: This is the old piece of code - I can't remember why we implemented it this way.
243  However, it's causing problems with pdf1 & pdf2 when processing LHE samples,
244  specifically, because both are set to -1, it tries to fill with Py6 numbers that
245  are NOT valid/right at this point !
246  In general, for LHE/ME event processing we should implement the correct calculation
247  of the pdf's, rather than using py6 ones.
248 
249  // filling in factorization "Q scale" now! pthat moved to binningValues()
250 
251  if (!lhe || event()->signal_process_id() < 0) event()->set_signal_process_id( pypars.msti[0] );
252  if (!lhe || event()->event_scale() < 0) event()->set_event_scale( pypars.pari[22] );
253  if (!lhe || event()->alphaQED() < 0) event()->set_alphaQED( pyint1.vint[56] );
254  if (!lhe || event()->alphaQCD() < 0) event()->set_alphaQCD( pyint1.vint[57] );
255 
256  // get pdf info directly from Pythia6 and set it up into HepMC::GenEvent
257  // S. Mrenna: Prefer vint block
258  //
259  if (!lhe || pdf.id1() < 0) pdf.set_id1( pyint1.mint[14] == 21 ? 0 : pyint1.mint[14] );
260  if (!lhe || pdf.id2() < 0) pdf.set_id2( pyint1.mint[15] == 21 ? 0 : pyint1.mint[15] );
261  if (!lhe || pdf.x1() < 0) pdf.set_x1( pyint1.vint[40] );
262  if (!lhe || pdf.x2() < 0) pdf.set_x2( pyint1.vint[41] );
263  if (!lhe || pdf.pdf1() < 0) pdf.set_pdf1( pyint1.vint[38] / pyint1.vint[40] );
264  if (!lhe || pdf.pdf2() < 0) pdf.set_pdf2( pyint1.vint[39] / pyint1.vint[41] );
265  if (!lhe || pdf.scalePDF() < 0) pdf.set_scalePDF( pyint1.vint[50] );
266 */
267 
268  event()->set_pdf_info( pdf ) ;
269 
270  // this is "standard" Py6 event weight (corresponds to PYINT1/VINT(97)
271  //
272  if (lhe && std::abs(lheRunInfo()->getHEPRUP()->IDWTUP) == 4)
273  // translate mb to pb (CMS/Gen "convention" as of May 2009)
274  event()->weights().push_back( pyint1.vint[96] * 1.0e9 );
275  else
276  event()->weights().push_back( pyint1.vint[96] );
277  //
278  // this is event weight as 1./VINT(99) (PYINT1/VINT(99) is returned by the PYEVWT)
279  //
280  event()->weights().push_back( 1./(pyint1.vint[98]) );
281 
282  // now create the GenEventInfo product from the GenEvent and fill
283  // the missing pieces
284 
285  eventInfo().reset( new GenEventInfoProduct( event().get() ) );
286 
287  // in Pythia6 pthat is used to subdivide samples into different bins
288  // in LHE mode the binning is done by the external ME generator
289  // which is likely not pthat, so only filling it for Py6 internal mode
290  if (!lhe)
291  {
292  eventInfo()->setBinningValues( std::vector<double>(1, pypars.pari[16]) );
293  }
294 
295  // here we treat long-lived particles
296  //
297  if ( fImposeProperTime || pydat1.mstj[21]==3 || pydat1.mstj[21]==4 ) imposeProperTime();
298 
299  // convert particle IDs Py6->PDG, if requested
300  if ( fConvertToPDG ) {
301  for ( HepMC::GenEvent::particle_iterator part = event()->particles_begin();
302  part != event()->particles_end(); ++part) {
303  (*part)->set_pdg_id(HepPID::translatePythiatoPDT((*part)->pdg_id()));
304  }
305  }
306 
307  // service printouts, if requested
308  //
309  if (fMaxEventsToPrint > 0)
310  {
313  if (fHepMCVerbosity)
314  {
315  std::cout << "Event process = " << pypars.msti[0] << std::endl
316  << "----------------------" << std::endl;
317  event()->print();
318  }
319  }
320 
321  return;
322 }
323 
325 {
326  Pythia6Service::InstanceWrapper guard(fPy6Service); // grab Py6 instance
327 
329 
330  // generate event with Pythia6
331  //
332 
334  {
335  // call_pygive("MSTJ(1)=-1");
336  call_pygive("MSTJ(14)=-1");
337  }
338 
339  call_pyevnt();
340 
342  {
343  // call_pygive("MSTJ(1)=1");
344  call_pygive("MSTJ(14)=1");
345  int ierr=0;
346  if ( fStopHadronsEnabled )
347  {
348  pystfr_(ierr);
349  if ( ierr != 0 ) // skip failed events
350  {
351  event().reset();
352  return false;
353  }
354  }
356  }
357 
358  if ( pyint1.mint[50] != 0 ) // skip event if py6 considers it bad
359  {
360  event().reset();
361  return false;
362  }
363 
364  call_pyhepc(1);
365  event().reset( conv.read_next_event() );
366 
367  // this is to deal with post-gen tools & residualDecay() that may reuse PYJETS
368  //
369  flushTmpStorage();
370  fillTmpStorage();
371 
372  return true;
373 }
374 
376 {
377  Pythia6Service::InstanceWrapper guard(fPy6Service); // grab Py6 instance
378 
381  if ( fJetMatching )
382  {
385  }
386 
387  // generate event with Pythia6
388  //
390  {
391  call_pygive("MSTJ(1)=-1");
392  call_pygive("MSTJ(14)=-1");
393  }
394 
395  call_pyevnt();
396 
397  if ( FortranCallback::getInstance()->getIterationsPerEvent() > 1 ||
398  hepeup_.nup <= 0 || pypars.msti[0] == 1 )
399  {
400  // update LHE matching statistics
402 
403  event().reset();
404  return false;
405  }
406 
407  // update LHE matching statistics
408  //
410 
412  {
413  call_pygive("MSTJ(1)=1");
414  call_pygive("MSTJ(14)=1");
415  int ierr = 0;
416  if ( fStopHadronsEnabled )
417  {
418  pystfr_(ierr);
419  if ( ierr != 0 ) // skip failed events
420  {
421  event().reset();
422  return false;
423  }
424  }
425 
427  }
428 
429  if ( pyint1.mint[50] != 0 ) // skip event if py6 considers it bad
430  {
431  event().reset();
432  return false;
433  }
434 
435  call_pyhepc(1);
436  event().reset( conv.read_next_event() );
437 
438  // this is to deal with post-gen tools and/or residualDecay(), that may reuse PYJETS
439  //
440  flushTmpStorage();
441  fillTmpStorage();
442 
443  return true;
444 }
445 
447 {
448  return true;
449 }
450 
452 {
453 
454  // event().get()->print();
455 
456  Pythia6Service::InstanceWrapper guard(fPy6Service); // grab Py6 instance
457 
458  // int nDocLines = pypars.msti[3];
459 
460  int NPartsBeforeDecays = pyjets_local.n ;
461  int NPartsAfterDecays = event().get()->particles_size();
462  int barcode = NPartsAfterDecays;
463 
464  // JVY: well, in principle, it's not a 100% fair to go up to NPartsBeforeDecays,
465  // because Photos will attach gamma's to existing vertexes, i.e. in the middle
466  // of the event rather than at the end; but this will only shift poiters down,
467  // so we'll be going again over a few "original" particle...
468  // in the alternative, we may go all the way up to the beginning of the event
469  // and re-check if anything remains to decay, that's fine even if it'll take
470  // some extra CPU...
471 
472  for ( int ipart=NPartsAfterDecays; ipart>NPartsBeforeDecays; ipart-- )
473  {
474  HepMC::GenParticle* part = event().get()->barcode_to_particle( ipart );
475  int status = part->status();
476  if ( status != 1 ) continue; // check only "stable" particles,
477  // as some undecayed may still be marked as such
478  int pdgid = part->pdg_id();
479  int py6ptr = pycomp_( pdgid );
480  if ( pydat3.mdcy[0][py6ptr-1] != 1 ) continue; // particle is not expected to decay
481  int py6id = HepPID::translatePDTtoPythia( pdgid );
482  //
483  // first, will need to zero out, then fill up PYJETS
484  // I better do it directly (by hands) rather than via py1ent
485  // - to avoid (additional) mass smearing
486  //
487  if ( part->momentum().t() <= part->generated_mass() )
488  {
489  continue ; // e==m --> 0-momentum, nothing to decay...
490  }
491  else
492  {
493  pyjets.n = 0;
494  for ( int i=0; i<5; i++ )
495  {
496  pyjets.k[i][0] = 0;
497  pyjets.p[i][0] = 0.;
498  pyjets.v[i][0] = 0.;
499  }
500  pyjets.k[0][0] = 1;
501  pyjets.k[1][0] = py6id;
502  pyjets.p[4][0] = part->generated_mass();
503  pyjets.p[3][0] = part->momentum().t();
504  pyjets.p[0][0] = part->momentum().x();
505  pyjets.p[1][0] = part->momentum().y();
506  pyjets.p[2][0] = part->momentum().z();
507  HepMC::GenVertex* prod_vtx = part->production_vertex();
508  if ( !prod_vtx ) continue; // in principle, should never happen but...
509  pyjets.v[0][0] = prod_vtx->position().x();
510  pyjets.v[1][0] = prod_vtx->position().y();
511  pyjets.v[2][0] = prod_vtx->position().z();
512  pyjets.v[3][0] = prod_vtx->position().t();
513  pyjets.v[4][0] = 0.;
514  pyjets.n = 1;
515  pyjets.npad = pyjets_local.npad;
516  }
517 
518  // now call Py6 decay routine
519  //
520  int parent = 1; // since we always pass to Py6 a single particle
521  pydecy_( parent );
522 
523  // now attach decay products to mother
524  //
525  for ( int iprt1=1; iprt1<pyjets.n; iprt1++ )
526  {
527  part->set_status( 2 );
528 
529  HepMC::GenVertex* DecVtx = new HepMC::GenVertex( HepMC::FourVector(pyjets.v[0][iprt1],
530  pyjets.v[1][iprt1],
531  pyjets.v[2][iprt1],
532  pyjets.v[3][iprt1]) );
533  DecVtx->add_particle_in( part ); // this will cleanup end_vertex if exists, replace with the new one
534  // I presume (vtx) barcode will be given automatically
535 
536  HepMC::FourVector pmom(pyjets.p[0][iprt1],pyjets.p[1][iprt1],
537  pyjets.p[2][iprt1],pyjets.p[3][iprt1] );
538 
539  int dstatus = 0;
540  if ( pyjets.k[0][iprt1] >= 1 && pyjets.k[0][iprt1] <= 10 )
541  {
542  dstatus = 1;
543  }
544  else if ( pyjets.k[0][iprt1] >= 11 && pyjets.k[0][iprt1] <= 20 )
545  {
546  dstatus = 2;
547  }
548  else if ( pyjets.k[0][iprt1] >= 21 && pyjets.k[0][iprt1] <= 30 )
549  {
550  dstatus = 3;
551  }
552  else if ( pyjets.k[0][iprt1] >= 31 && pyjets.k[0][iprt1] <= 100 )
553  {
554  dstatus = pyjets.k[0][iprt1];
555  }
556  HepMC::GenParticle* daughter = new HepMC::GenParticle(pmom,
557  HepPID::translatePythiatoPDT( pyjets.k[1][iprt1] ),
558  dstatus);
559  barcode++;
560  daughter->suggest_barcode( barcode );
561  DecVtx->add_particle_out( daughter );
562 
563  int iprt2;
564  for ( iprt2=iprt1+1; iprt2<pyjets.n; iprt2++ ) // the pointer is shifted by -1, c++ style
565  {
566  if ( pyjets.k[2][iprt2] != parent )
567  {
568  parent = pyjets.k[2][iprt2];
569  break; // another parent particle; reset & break the loop
570  }
571 
572  HepMC::FourVector pmomN(pyjets.p[0][iprt2],pyjets.p[1][iprt2],
573  pyjets.p[2][iprt2],pyjets.p[3][iprt2] );
574 
575  dstatus = 0;
576  if ( pyjets.k[0][iprt2] >= 1 && pyjets.k[0][iprt2] <= 10 )
577  {
578  dstatus = 1;
579  }
580  else if ( pyjets.k[0][iprt2] >= 11 && pyjets.k[0][iprt2] <= 20 )
581  {
582  dstatus = 2;
583  }
584  else if ( pyjets.k[0][iprt2] >= 21 && pyjets.k[0][iprt2] <= 30 )
585  {
586  dstatus = 3;
587  }
588  else if ( pyjets.k[0][iprt2] >= 31 && pyjets.k[0][iprt2] <= 100 )
589  {
590  dstatus = pyjets.k[0][iprt2];
591  }
592  HepMC::GenParticle* daughterN = new HepMC::GenParticle(pmomN,
593  HepPID::translatePythiatoPDT( pyjets.k[1][iprt2] ),
594  dstatus);
595  barcode++;
596  daughterN->suggest_barcode( barcode );
597  DecVtx->add_particle_out( daughterN );
598  }
599 
600  iprt1 = iprt2-1; // reset counter such that it doesn't go over the same child more than once
601  // don't forget to offset back into c++ counting, as it's already +1 forward
602 
603  event().get()->add_vertex( DecVtx );
604 
605  }
606 
607  }
608 
609  // now restore the very original Py6 event record
610  //
611  if ( pyjets_local.n != pyjets.n )
612  {
613  // restore pyjets to its state as it was before external decays -
614  // might have been jammed by action above or by py1ent calls in EvtGen
615  pyjets.n = pyjets_local.n;
616  pyjets.npad = pyjets_local.npad;
617  for ( int ip=0; ip<pyjets_local.n; ip++ )
618  {
619  for ( int i=0; i<5; i++ )
620  {
621  pyjets.k[i][ip] = pyjets_local.k[i][ip];
622  pyjets.p[i][ip] = pyjets_local.p[i][ip];
623  pyjets.v[i][ip] = pyjets_local.v[i][ip];
624  }
625  }
626  }
627 
628  return true;
629 }
630 
632 {
633  Pythia6Service::InstanceWrapper guard(fPy6Service); // grab Py6 instance
634 
635  // note: CSA mode is NOT supposed to woirk with external partons !!!
636 
639 
641 
642  if ( fStopHadronsEnabled )
643  {
644  // overwrite mstp(111), no matter what
645  call_pygive("MSTP(111)=0");
646  pystrhad_();
647  call_pygive("MWID(302)=0"); // I don't know if this is specific to processing ME/LHE only,
648  call_pygive("MDCY(302,1)=0"); // or this should also be the case for full event...
649  // anyway, this comes from experience of processing MG events
650  }
651 
652  if ( fGluinoHadronsEnabled )
653  {
654  // overwrite mstp(111), no matter what
655  call_pygive("MSTP(111)=0");
656  pyglrhad_();
657  //call_pygive("MWID(309)=0");
658  //call_pygive("MDCY(309,1)=0");
659  }
660 
661  call_pyinit("USER", "", "", 0.0);
662 
664 
665  std::vector<std::string> slha = lheRunInfo()->findHeader("slha");
666  if (!slha.empty()) {
667  edm::LogInfo("Generator|LHEInterface")
668  << "Pythia6 hadronisation found an SLHA header, "
669  << "will be passed on to Pythia." << std::endl;
672  }
673 
674  if ( fJetMatching )
675  {
677 // FIXME: the jet matching routine might not be interested in PS callback
678  call_pygive("MSTP(143)=1");
679  }
680 
681  return true;
682 }
683 
685 {
686  Pythia6Service::InstanceWrapper guard(fPy6Service); // grab Py6 instance
687 
692 
693  if ( fStopHadronsEnabled )
694  {
695  // overwrite mstp(111), no matter what
696  call_pygive("MSTP(111)=0");
697  pystrhad_();
698  }
699 
700  if ( fGluinoHadronsEnabled )
701  {
702  // overwrite mstp(111), no matter what
703  call_pygive("MSTP(111)=0");
704  pyglrhad_();
705  }
706 
707  call_pyinit("CMS", "p", "p", fCOMEnergy);
708 
710 
712 
713  return true;
714 }
715 
716 bool Pythia6Hadronizer::declareStableParticles( const std::vector<int> pdg )
717 {
718 
719  for ( unsigned int i=0; i<pdg.size(); i++ )
720  {
721  int PyID = HepPID::translatePDTtoPythia( pdg[i] );
722  // int PyID = pdg[i];
723  int pyCode = pycomp_( PyID );
724  if ( pyCode > 0 )
725  {
726  std::ostringstream pyCard ;
727  pyCard << "MDCY(" << pyCode << ",1)=0";
728 /* this is a test printout...
729  std::cout << "pdg= " << pdg[i] << " " << pyCard.str() << std::endl;
730 */
731  call_pygive( pyCard.str() );
732  }
733  }
734 
735  return true;
736 }
737 
738 bool Pythia6Hadronizer::declareSpecialSettings( const std::vector<std::string> settings )
739 {
740 
741  for ( unsigned int iss=0; iss<settings.size(); iss++ )
742  {
743  if ( settings[iss].find("QED-brem-off") == std::string::npos ) continue;
744  size_t fnd1 = settings[iss].find(":");
745  if ( fnd1 == std::string::npos ) continue;
746 
747  std::string value = settings[iss].substr (fnd1+1);
748 
749  if ( value == "all" )
750  {
751  call_pygive( "MSTJ(41)=3" );
752  }
753  else
754  {
755  int number = atoi(value.c_str());
756  int PyID = HepPID::translatePDTtoPythia( number );
757  int pyCode = pycomp_( PyID );
758  if ( pyCode > 0 )
759  {
760 
761  // first of all, check if mstj(39) is 0 or if we're trying to override user's setting
762  // if so, throw an exception and stop, because otherwise the user will get behaviour
763  // that's different from what she/he expects !
764  if ( pydat1_.mstj[38] > 0 && pydat1_.mstj[38] != pyCode )
765  {
766  throw edm::Exception(edm::errors::Configuration,"Pythia6Interface")
767  << " Fatal conflict: \n mandatory internal directive to set MSTJ(39)=" << pyCode
768  << " overrides user setting MSTJ(39)=" << pydat1_.mstj[38] << " - user will not get expected behaviour \n";
769  }
770  std::ostringstream pyCard ;
771  pyCard << "MSTJ(39)=" << pyCode ;
772  call_pygive( pyCard.str() );
773  }
774  }
775  }
776 
777  return true;
778 
779 }
780 
782 {
783 
784  // this is practically a copy/paste of the original code by J.Alcaraz,
785  // taken directly from PythiaSource
786 
787  int dumm=0;
788  HepMC::GenEvent::vertex_const_iterator vbegin = event()->vertices_begin();
789  HepMC::GenEvent::vertex_const_iterator vend = event()->vertices_end();
790  HepMC::GenEvent::vertex_const_iterator vitr = vbegin;
791  for (; vitr != vend; ++vitr )
792  {
793  HepMC::GenVertex::particle_iterator pbegin = (*vitr)->particles_begin(HepMC::children);
794  HepMC::GenVertex::particle_iterator pend = (*vitr)->particles_end(HepMC::children);
795  HepMC::GenVertex::particle_iterator pitr = pbegin;
796  for (; pitr != pend; ++pitr)
797  {
798  if ((*pitr)->end_vertex()) continue;
799  if ((*pitr)->status()!=1) continue;
800 
801  int pdgcode= abs((*pitr)->pdg_id());
802  // Do nothing if the particle is not expected to decay
803  if ( pydat3.mdcy[0][pycomp_(pdgcode)-1] !=1 ) continue;
804 
805  double ctau = pydat2.pmas[3][pycomp_(pdgcode)-1];
806  HepMC::FourVector mom = (*pitr)->momentum();
807  HepMC::FourVector vin = (*vitr)->position();
808  double x = 0.;
809  double y = 0.;
810  double z = 0.;
811  double t = 0.;
812  bool decayInRange = false;
813  while (!decayInRange)
814  {
815  double unif_rand = fPy6Service->call(pyr_, &dumm);
816  // Value of 0 is excluded, so following line is OK
817  double proper_length = - ctau * log(unif_rand);
818  double factor = proper_length/mom.m();
819  x = vin.x() + factor * mom.px();
820  y = vin.y() + factor * mom.py();
821  z = vin.z() + factor * mom.pz();
822  t = vin.t() + factor * mom.e();
823  // Decay must be happen outside a cylindrical region
824  if (pydat1.mstj[21]==4) {
825  if (std::sqrt(x*x+y*y)>pydat1.parj[72] || fabs(z)>pydat1.parj[73]) decayInRange = true;
826  // Decay must be happen outside a given sphere
827  }
828  else if (pydat1.mstj[21]==3) {
829  if (std::sqrt(x*x+y*y+z*z)>pydat1.parj[71]) decayInRange = true;
830  }
831  // Decay is always OK otherwise
832  else {
833  decayInRange = true;
834  }
835  }
836 
837  HepMC::GenVertex* vdec = new HepMC::GenVertex(HepMC::FourVector(x,y,z,t));
838  event()->add_vertex(vdec);
839  vdec->add_particle_in((*pitr));
840  }
841  }
842 
843  return;
844 
845 }
846 
848 {
849 
850  if ( !runInfo().internalXSec() )
851  {
852  // set xsec if not already done (e.g. from LHE cross section collector)
853  double cs = pypars.pari[0]; // cross section in mb
854  cs *= 1.0e9; // translate to pb (CMS/Gen "convention" as of May 2009)
855  runInfo().setInternalXSec( cs );
856 // FIXME: can we get the xsec statistical error somewhere?
857  }
858 
859  call_pystat(1);
860 
861  return;
862 
863 }
864 
865 const char* Pythia6Hadronizer::classname() const
866 {
867  return "gen::Pythia6Hadronizer";
868 }
869 
870 } // namespace gen
#define pydat1
T getParameter(std::string const &) const
static std::auto_ptr< JetMatching > create(const edm::ParameterSet &params)
Definition: JetMatching.cc:47
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
void call(void(&fn)())
list parent
Definition: dbtoconf.py:74
unsigned int fPythiaListVerbosity
Pythia6ServiceWithCallback(const edm::ParameterSet &ps)
static struct gen::@303 pyjets_local
unsigned int fMaxEventsToPrint
static HepMC::IO_HEPEVT conv
void fillEventInfo(HepMC::GenEvent *hepmc) const
Definition: LHEEvent.cc:240
static JetMatching * getJetMatching()
struct HEPEUP_ hepeup_
bool call_pygive(const std::string &line)
bool exists(std::string const &parameterName) const
checks if a parameter exists
const char * classname() const
#define abs(x)
Definition: mlp_lapack.h:159
void setLHERunInfo(lhef::LHERunInfo *lheri)
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:198
virtual void beforeHadronisation(const lhef::LHEEvent *event)
Definition: JetMatching.cc:31
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
bool declareSpecialSettings(const std::vector< std::string >)
void setInternalXSec(const XSec &xsec)
#define vend()
Definition: vmac.h:42
void pyglrhad_()
double v[5][pyjets_maxn]
std::auto_ptr< HepMC::GenEvent > & event()
return((rh^lh)&mask)
#define pypars
GenRunInfoProduct & runInfo()
double p[5][pyjets_maxn]
void call_pylist(int mode)
void resetMatchingStatus()
Definition: JetMatching.h:66
lhef::LHEEvent * lheEvent()
Definition: DDAxes.h:10
T sqrt(T t)
Definition: SSEVec.h:28
void setSLHAFromHeader(const std::vector< std::string > &lines)
#define vbegin()
Definition: vmac.h:35
void fillPdfInfo(HepMC::PdfInfo *info) const
Definition: LHEEvent.cc:212
#define pyint1
void pydecy_(int &ip)
void setPYUPDAParams(bool afterPyinit)
void pystfr_(int &)
Pythia6Hadronizer(edm::ParameterSet const &ps)
std::auto_ptr< GenEventInfoProduct > & eventInfo()
lhef::LHERunInfo * lheRunInfo()
int k[5][pyjets_maxn]
struct gen::@242 pydat1_
static FortranCallback * getInstance()
int pycomp_(int &)
Pythia6Service * fPy6Service
void setLHEEvent(lhef::LHEEvent *lhee)
Log< T >::type log(const T &t)
Definition: Log.h:22
part
Definition: HCALResponse.h:21
virtual void beforeHadronisationExec()
Definition: JetMatching.cc:35
bool isMatchingDone()
Definition: JetMatching.h:67
void pyglfr_()
virtual int match(const HepMC::GenEvent *partonLevel, const HepMC::GenEvent *finalState, bool showeredFinalState=false)=0
tuple cout
Definition: gather_cfg.py:41
std::vector< std::string > findHeader(const std::string &tag) const
Definition: LHERunInfo.cc:390
tuple status
Definition: ntuplemaker.py:245
double pyr_(int *idummy)
virtual void init(const lhef::LHERunInfo *runInfo)
Definition: JetMatching.cc:27
bool declareStableParticles(const std::vector< int >)
void pystrhad_()
static JetMatching * fJetMatching