00001
00002
00003
00004 #include "Pythia6Hadronizer.h"
00005
00006 #include "HepMC/GenEvent.h"
00007 #include "HepMC/PdfInfo.h"
00008 #include "HepMC/PythiaWrapper6_4.h"
00009 #include "HepMC/HEPEVT_Wrapper.h"
00010 #include "HepMC/IO_HEPEVT.h"
00011
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013
00014 #include "GeneratorInterface/Core/interface/FortranCallback.h"
00015
00016 #include "GeneratorInterface/LHEInterface/interface/LHERunInfo.h"
00017
00018 #include "SimDataFormats/GeneratorProducts/interface/LHEEventProduct.h"
00019
00020 #include "GeneratorInterface/PartonShowerVeto/interface/JetMatching.h"
00021
00022
00023 HepMC::IO_HEPEVT conv;
00024
00025 #include "HepPID/ParticleIDTranslations.hh"
00026
00027
00028
00029
00030 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Service.h"
00031 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Declarations.h"
00032
00033 namespace gen
00034 {
00035
00036 extern "C" {
00037
00038
00039
00040
00041
00042
00043
00044
00045 void pystrhad_();
00046 void pystfr_(int&);
00047
00048
00049 void pyglrhad_();
00050 void pyglfr_();
00051
00052
00053
00054
00055 }
00056
00057 class Pythia6ServiceWithCallback : public Pythia6Service {
00058 public:
00059 Pythia6ServiceWithCallback( const edm::ParameterSet& ps ) : Pythia6Service(ps) {}
00060
00061 private:
00062 void upInit()
00063 { FortranCallback::getInstance()->fillHeader(); }
00064
00065 void upEvnt()
00066 {
00067 FortranCallback::getInstance()->fillEvent();
00068 if ( Pythia6Hadronizer::getJetMatching() )
00069 Pythia6Hadronizer::getJetMatching()->beforeHadronisationExec();
00070 }
00071
00072 bool upVeto()
00073 {
00074 if ( !Pythia6Hadronizer::getJetMatching() )
00075 return false;
00076
00077 if ( !hepeup_.nup || Pythia6Hadronizer::getJetMatching()->isMatchingDone() )
00078 return true;
00079
00080
00081 return Pythia6Hadronizer::getJetMatching()->match(0, 0, true);
00082 }
00083 };
00084
00085 static struct {
00086 int n, npad, k[5][pyjets_maxn];
00087 double p[5][pyjets_maxn], v[5][pyjets_maxn];
00088 } pyjets_local;
00089
00090 JetMatching* Pythia6Hadronizer::fJetMatching = 0;
00091
00092 Pythia6Hadronizer::Pythia6Hadronizer(edm::ParameterSet const& ps)
00093 : BaseHadronizer(ps),
00094 fPy6Service( new Pythia6ServiceWithCallback(ps) ),
00095 fInitialState(PP),
00096 fCOMEnergy(ps.getParameter<double>("comEnergy")),
00097 fHepMCVerbosity(ps.getUntrackedParameter<bool>("pythiaHepMCVerbosity",false)),
00098 fMaxEventsToPrint(ps.getUntrackedParameter<int>("maxEventsToPrint", 0)),
00099 fPythiaListVerbosity(ps.getUntrackedParameter<int>("pythiaPylistVerbosity", 0)),
00100 fDisplayPythiaBanner(ps.getUntrackedParameter<bool>("displayPythiaBanner",false)),
00101 fDisplayPythiaCards(ps.getUntrackedParameter<bool>("displayPythiaCards",false))
00102 {
00103
00104
00105
00106
00107 if ( ps.exists( "PPbarInitialState" ) )
00108 {
00109 if ( fInitialState == PP )
00110 {
00111 fInitialState = PPbar;
00112 edm::LogInfo("GeneratorInterface|Pythia6Interface")
00113 << "Pythia6 will be initialized for PROTON-ANTIPROTON INITIAL STATE. "
00114 << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00115 std::cout << "Pythia6 will be initialized for PROTON-ANTIPROTON INITIAL STATE." << std::endl;
00116 std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00117 }
00118 else
00119 {
00120
00121 }
00122 }
00123 else if ( ps.exists( "ElectronPositronInitialState" ) )
00124 {
00125 if ( fInitialState == PP )
00126 {
00127 fInitialState = ElectronPositron;
00128 edm::LogInfo("GeneratorInterface|Pythia6Interface")
00129 << "Pythia6 will be initialized for ELECTRON-POSITRON INITIAL STATE. "
00130 << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00131 std::cout << "Pythia6 will be initialized for ELECTRON-POSITRON INITIAL STATE." << std::endl;
00132 std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00133 }
00134 else
00135 {
00136
00137 }
00138 }
00139 else if ( ps.exists( "ElectronProtonInitialState" ) )
00140 {
00141 if ( fInitialState == PP )
00142 {
00143 fInitialState = ElectronProton;
00144 fBeam1PZ = (ps.getParameter<edm::ParameterSet>("ElectronProtonInitialState")).getParameter<double>("electronMomentum");
00145 fBeam2PZ = (ps.getParameter<edm::ParameterSet>("ElectronProtonInitialState")).getParameter<double>("protonMomentum");
00146 edm::LogInfo("GeneratorInterface|Pythia6Interface")
00147 << "Pythia6 will be initialized for ELECTRON-PROTON INITIAL STATE. "
00148 << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00149 std::cout << "Pythia6 will be initialized for ELECTRON-PROTON INITIAL STATE." << std::endl;
00150 std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00151 }
00152 else
00153 {
00154
00155 }
00156 }
00157 else if ( ps.exists( "PositronProtonInitialState" ) )
00158 {
00159 if ( fInitialState == PP )
00160 {
00161 fInitialState = PositronProton;
00162 fBeam1PZ = (ps.getParameter<edm::ParameterSet>("ElectronProtonInitialState")).getParameter<double>("positronMomentum");
00163 fBeam2PZ = (ps.getParameter<edm::ParameterSet>("ElectronProtonInitialState")).getParameter<double>("protonMomentum");
00164 edm::LogInfo("GeneratorInterface|Pythia6Interface")
00165 << "Pythia6 will be initialized for POSITRON-PROTON INITIAL STATE. "
00166 << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00167 std::cout << "Pythia6 will be initialized for POSITRON-PROTON INITIAL STATE." << std::endl;
00168 std::cout << "This is a user-request change from the DEFAULT PROTON-PROTON initial state." << std::endl;
00169 }
00170 else
00171 {
00172
00173 throw edm::Exception(edm::errors::Configuration,"Pythia6Interface")
00174 <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron, ElectronProton, and PositronProton \n";
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 fStopHadronsEnabled = false;
00185 if ( ps.exists( "stopHadrons" ) )
00186 fStopHadronsEnabled = ps.getParameter<bool>("stopHadrons") ;
00187
00188 fGluinoHadronsEnabled = false;
00189 if ( ps.exists( "gluinoHadrons" ) )
00190 fGluinoHadronsEnabled = ps.getParameter<bool>("gluinoHadrons");
00191
00192 fImposeProperTime = false;
00193 if ( ps.exists( "imposeProperTime" ) )
00194 {
00195 fImposeProperTime = ps.getParameter<bool>("imposeProperTime");
00196 }
00197
00198 fConvertToPDG = false;
00199 if ( ps.exists( "doPDGConvert" ) )
00200 fConvertToPDG = ps.getParameter<bool>("doPDGConvert");
00201
00202 if ( ps.exists("jetMatching") )
00203 {
00204 edm::ParameterSet jmParams =
00205 ps.getUntrackedParameter<edm::ParameterSet>(
00206 "jetMatching");
00207
00208 fJetMatching = JetMatching::create(jmParams).release();
00209 }
00210
00211
00212
00213 if ( !fDisplayPythiaBanner )
00214 {
00215 if (!call_pygive("MSTU(12)=12345"))
00216 {
00217 throw edm::Exception(edm::errors::Configuration,"PythiaError")
00218 <<" Pythia did not accept MSTU(12)=12345";
00219 }
00220 }
00221
00222
00223
00224 if ( ! fDisplayPythiaCards )
00225 {
00226 if (!call_pygive("MSTU(13)=0"))
00227 {
00228 throw edm::Exception(edm::errors::Configuration,"PythiaError")
00229 <<" Pythia did not accept MSTU(13)=0";
00230 }
00231 }
00232
00233
00234
00235 flushTmpStorage();
00236
00237 }
00238
00239 Pythia6Hadronizer::~Pythia6Hadronizer()
00240 {
00241 if ( fPy6Service != 0 ) delete fPy6Service;
00242 if ( fJetMatching != 0 ) delete fJetMatching;
00243 }
00244
00245 void Pythia6Hadronizer::flushTmpStorage()
00246 {
00247
00248 pyjets_local.n = 0 ;
00249 pyjets_local.npad = 0 ;
00250 for ( int ip=0; ip<pyjets_maxn; ip++ )
00251 {
00252 for ( int i=0; i<5; i++ )
00253 {
00254 pyjets_local.k[i][ip] = 0;
00255 pyjets_local.p[i][ip] = 0.;
00256 pyjets_local.v[i][ip] = 0.;
00257 }
00258 }
00259 return;
00260
00261 }
00262
00263 void Pythia6Hadronizer::fillTmpStorage()
00264 {
00265
00266 pyjets_local.n = pyjets.n;
00267 pyjets_local.npad = pyjets.npad;
00268 for ( int ip=0; ip<pyjets_maxn; ip++ )
00269 {
00270 for ( int i=0; i<5; i++ )
00271 {
00272 pyjets_local.k[i][ip] = pyjets.k[i][ip];
00273 pyjets_local.p[i][ip] = pyjets.p[i][ip];
00274 pyjets_local.v[i][ip] = pyjets.v[i][ip];
00275 }
00276 }
00277
00278 return ;
00279
00280 }
00281
00282 void Pythia6Hadronizer::finalizeEvent()
00283 {
00284
00285 bool lhe = lheEvent() != 0;
00286
00287 HepMC::PdfInfo pdf;
00288
00289
00290
00291 if (lhe)
00292 {
00293 lheEvent()->fillEventInfo( event().get() );
00294 lheEvent()->fillPdfInfo( &pdf );
00295 }
00296 else
00297 {
00298
00299
00300
00301 if ( event()->signal_process_id() <= 0) event()->set_signal_process_id( pypars.msti[0] );
00302 if ( event()->event_scale() <=0 ) event()->set_event_scale( pypars.pari[22] );
00303 if ( event()->alphaQED() <= 0) event()->set_alphaQED( pyint1.vint[56] );
00304 if ( event()->alphaQCD() <= 0) event()->set_alphaQCD( pyint1.vint[57] );
00305
00306
00307
00308
00309 if ( pdf.id1() <= 0) pdf.set_id1( pyint1.mint[14] == 21 ? 0 : pyint1.mint[14] );
00310 if ( pdf.id2() <= 0) pdf.set_id2( pyint1.mint[15] == 21 ? 0 : pyint1.mint[15] );
00311 if ( pdf.x1() <= 0) pdf.set_x1( pyint1.vint[40] );
00312 if ( pdf.x2() <= 0) pdf.set_x2( pyint1.vint[41] );
00313 if ( pdf.pdf1() <= 0) pdf.set_pdf1( pyint1.vint[38] / pyint1.vint[40] );
00314 if ( pdf.pdf2() <= 0) pdf.set_pdf2( pyint1.vint[39] / pyint1.vint[41] );
00315 if ( pdf.scalePDF() <= 0) pdf.set_scalePDF( pyint1.vint[50] );
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 event()->set_pdf_info( pdf ) ;
00345
00346
00347
00348 if (lhe && std::abs(lheRunInfo()->getHEPRUP()->IDWTUP) == 4)
00349
00350 event()->weights().push_back( pyint1.vint[96] * 1.0e9 );
00351 else
00352 event()->weights().push_back( pyint1.vint[96] );
00353
00354
00355
00356 event()->weights().push_back( 1./(pyint1.vint[98]) );
00357
00358
00359
00360
00361 eventInfo().reset( new GenEventInfoProduct( event().get() ) );
00362
00363
00364
00365
00366 if (!lhe)
00367 {
00368 eventInfo()->setBinningValues( std::vector<double>(1, pypars.pari[16]) );
00369 }
00370
00371
00372
00373 if ( fImposeProperTime || pydat1.mstj[21]==3 || pydat1.mstj[21]==4 ) imposeProperTime();
00374
00375
00376 if ( fConvertToPDG ) {
00377 for ( HepMC::GenEvent::particle_iterator part = event()->particles_begin();
00378 part != event()->particles_end(); ++part) {
00379 (*part)->set_pdg_id(HepPID::translatePythiatoPDT((*part)->pdg_id()));
00380 }
00381 }
00382
00383
00384
00385 if (fMaxEventsToPrint > 0)
00386 {
00387 fMaxEventsToPrint--;
00388 if (fPythiaListVerbosity) call_pylist(fPythiaListVerbosity);
00389 if (fHepMCVerbosity)
00390 {
00391 std::cout << "Event process = " << pypars.msti[0] << std::endl
00392 << "----------------------" << std::endl;
00393 event()->print();
00394 }
00395 }
00396
00397
00398 if ( fDisplayPythiaCards ) {
00399 fDisplayPythiaCards = false;
00400 call_pylist(12);
00401 call_pylist(13);
00402 std::cout << "\n PYPARS \n" << std::endl;
00403 std::cout << std::setw(5) << std::fixed << "I"
00404 << std::setw(10) << std::fixed << "MSTP(I)"
00405 << std::setw(16) << std::fixed << "PARP(I)"
00406 << std::setw(10) << std::fixed << "MSTI(I)"
00407 << std::setw(16) << std::fixed << "PARI(I)" << std::endl;
00408 for ( unsigned int ind=0; ind < 200; ind++ ) {
00409 std::cout << std::setw(5) << std::fixed << ind+1
00410 << std::setw(10) << std::fixed << pypars.mstp[ind]
00411 << std::setw(16) << std::fixed << pypars.parp[ind]
00412 << std::setw(10) << std::fixed << pypars.msti[ind]
00413 << std::setw(16) << std::fixed << pypars.pari[ind] << std::endl;
00414 }
00415 }
00416
00417 return;
00418 }
00419
00420 bool Pythia6Hadronizer::generatePartonsAndHadronize()
00421 {
00422 Pythia6Service::InstanceWrapper guard(fPy6Service);
00423
00424 FortranCallback::getInstance()->resetIterationsPerEvent();
00425
00426
00427
00428
00429 if ( fStopHadronsEnabled || fGluinoHadronsEnabled )
00430 {
00431
00432 call_pygive("MSTJ(14)=-1");
00433 }
00434
00435 call_pyevnt();
00436
00437 if ( fStopHadronsEnabled || fGluinoHadronsEnabled )
00438 {
00439
00440 call_pygive("MSTJ(14)=1");
00441 int ierr=0;
00442 if ( fStopHadronsEnabled )
00443 {
00444 pystfr_(ierr);
00445 if ( ierr != 0 )
00446 {
00447 event().reset();
00448 return false;
00449 }
00450 }
00451 if ( fGluinoHadronsEnabled ) pyglfr_();
00452 }
00453
00454 if ( pyint1.mint[50] != 0 )
00455 {
00456 event().reset();
00457 return false;
00458 }
00459
00460 call_pyhepc(1);
00461 event().reset( conv.read_next_event() );
00462
00463
00464
00465 flushTmpStorage();
00466 fillTmpStorage();
00467
00468 return true;
00469 }
00470
00471 bool Pythia6Hadronizer::hadronize()
00472 {
00473 Pythia6Service::InstanceWrapper guard(fPy6Service);
00474
00475 FortranCallback::getInstance()->setLHEEvent( lheEvent() );
00476 FortranCallback::getInstance()->resetIterationsPerEvent();
00477 if ( fJetMatching )
00478 {
00479 fJetMatching->resetMatchingStatus() ;
00480 fJetMatching->beforeHadronisation( lheEvent() );
00481 }
00482
00483
00484
00485 if ( fStopHadronsEnabled || fGluinoHadronsEnabled )
00486 {
00487 call_pygive("MSTJ(1)=-1");
00488 call_pygive("MSTJ(14)=-1");
00489 }
00490
00491 call_pyevnt();
00492
00493 if ( FortranCallback::getInstance()->getIterationsPerEvent() > 1 ||
00494 hepeup_.nup <= 0 || pypars.msti[0] == 1 )
00495 {
00496
00497 lheEvent()->count( lhef::LHERunInfo::kSelected );
00498
00499 event().reset();
00500 return false;
00501 }
00502
00503
00504
00505 lheEvent()->count( lhef::LHERunInfo::kAccepted );
00506
00507 if ( fStopHadronsEnabled || fGluinoHadronsEnabled )
00508 {
00509 call_pygive("MSTJ(1)=1");
00510 call_pygive("MSTJ(14)=1");
00511 int ierr = 0;
00512 if ( fStopHadronsEnabled )
00513 {
00514 pystfr_(ierr);
00515 if ( ierr != 0 )
00516 {
00517 event().reset();
00518 return false;
00519 }
00520 }
00521
00522 if ( fGluinoHadronsEnabled ) pyglfr_();
00523 }
00524
00525 if ( pyint1.mint[50] != 0 )
00526 {
00527 event().reset();
00528 return false;
00529 }
00530
00531 call_pyhepc(1);
00532 event().reset( conv.read_next_event() );
00533
00534
00535
00536 flushTmpStorage();
00537 fillTmpStorage();
00538
00539 return true;
00540 }
00541
00542 bool Pythia6Hadronizer::decay()
00543 {
00544 return true;
00545 }
00546
00547 bool Pythia6Hadronizer::residualDecay()
00548 {
00549
00550
00551
00552 Pythia6Service::InstanceWrapper guard(fPy6Service);
00553
00554
00555
00556 int NPartsBeforeDecays = pyjets_local.n ;
00557 int NPartsAfterDecays = event().get()->particles_size();
00558 int barcode = NPartsAfterDecays;
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 for ( int ipart=NPartsAfterDecays; ipart>NPartsBeforeDecays; ipart-- )
00569 {
00570 HepMC::GenParticle* part = event().get()->barcode_to_particle( ipart );
00571 int status = part->status();
00572 if ( status != 1 ) continue;
00573
00574 int pdgid = part->pdg_id();
00575 int py6ptr = pycomp_( pdgid );
00576 if ( pydat3.mdcy[0][py6ptr-1] != 1 ) continue;
00577 int py6id = HepPID::translatePDTtoPythia( pdgid );
00578
00579
00580
00581
00582
00583 if ( part->momentum().t() <= part->generated_mass() )
00584 {
00585 continue ;
00586 }
00587 else
00588 {
00589 pyjets.n = 0;
00590 for ( int i=0; i<5; i++ )
00591 {
00592 pyjets.k[i][0] = 0;
00593 pyjets.p[i][0] = 0.;
00594 pyjets.v[i][0] = 0.;
00595 }
00596 pyjets.k[0][0] = 1;
00597 pyjets.k[1][0] = py6id;
00598 pyjets.p[4][0] = part->generated_mass();
00599 pyjets.p[3][0] = part->momentum().t();
00600 pyjets.p[0][0] = part->momentum().x();
00601 pyjets.p[1][0] = part->momentum().y();
00602 pyjets.p[2][0] = part->momentum().z();
00603 HepMC::GenVertex* prod_vtx = part->production_vertex();
00604 if ( !prod_vtx ) continue;
00605 pyjets.v[0][0] = prod_vtx->position().x();
00606 pyjets.v[1][0] = prod_vtx->position().y();
00607 pyjets.v[2][0] = prod_vtx->position().z();
00608 pyjets.v[3][0] = prod_vtx->position().t();
00609 pyjets.v[4][0] = 0.;
00610 pyjets.n = 1;
00611 pyjets.npad = pyjets_local.npad;
00612 }
00613
00614
00615
00616 int parent = 1;
00617 pydecy_( parent );
00618
00619
00620
00621 for ( int iprt1=1; iprt1<pyjets.n; iprt1++ )
00622 {
00623 part->set_status( 2 );
00624
00625 HepMC::GenVertex* DecVtx = new HepMC::GenVertex( HepMC::FourVector(pyjets.v[0][iprt1],
00626 pyjets.v[1][iprt1],
00627 pyjets.v[2][iprt1],
00628 pyjets.v[3][iprt1]) );
00629 DecVtx->add_particle_in( part );
00630
00631
00632 HepMC::FourVector pmom(pyjets.p[0][iprt1],pyjets.p[1][iprt1],
00633 pyjets.p[2][iprt1],pyjets.p[3][iprt1] );
00634
00635 int dstatus = 0;
00636 if ( pyjets.k[0][iprt1] >= 1 && pyjets.k[0][iprt1] <= 10 )
00637 {
00638 dstatus = 1;
00639 }
00640 else if ( pyjets.k[0][iprt1] >= 11 && pyjets.k[0][iprt1] <= 20 )
00641 {
00642 dstatus = 2;
00643 }
00644 else if ( pyjets.k[0][iprt1] >= 21 && pyjets.k[0][iprt1] <= 30 )
00645 {
00646 dstatus = 3;
00647 }
00648 else if ( pyjets.k[0][iprt1] >= 31 && pyjets.k[0][iprt1] <= 100 )
00649 {
00650 dstatus = pyjets.k[0][iprt1];
00651 }
00652 HepMC::GenParticle* daughter = new HepMC::GenParticle(pmom,
00653 HepPID::translatePythiatoPDT( pyjets.k[1][iprt1] ),
00654 dstatus);
00655 barcode++;
00656 daughter->suggest_barcode( barcode );
00657 DecVtx->add_particle_out( daughter );
00658
00659 int iprt2;
00660 for ( iprt2=iprt1+1; iprt2<pyjets.n; iprt2++ )
00661 {
00662 if ( pyjets.k[2][iprt2] != parent )
00663 {
00664 parent = pyjets.k[2][iprt2];
00665 break;
00666 }
00667
00668 HepMC::FourVector pmomN(pyjets.p[0][iprt2],pyjets.p[1][iprt2],
00669 pyjets.p[2][iprt2],pyjets.p[3][iprt2] );
00670
00671 dstatus = 0;
00672 if ( pyjets.k[0][iprt2] >= 1 && pyjets.k[0][iprt2] <= 10 )
00673 {
00674 dstatus = 1;
00675 }
00676 else if ( pyjets.k[0][iprt2] >= 11 && pyjets.k[0][iprt2] <= 20 )
00677 {
00678 dstatus = 2;
00679 }
00680 else if ( pyjets.k[0][iprt2] >= 21 && pyjets.k[0][iprt2] <= 30 )
00681 {
00682 dstatus = 3;
00683 }
00684 else if ( pyjets.k[0][iprt2] >= 31 && pyjets.k[0][iprt2] <= 100 )
00685 {
00686 dstatus = pyjets.k[0][iprt2];
00687 }
00688 HepMC::GenParticle* daughterN = new HepMC::GenParticle(pmomN,
00689 HepPID::translatePythiatoPDT( pyjets.k[1][iprt2] ),
00690 dstatus);
00691 barcode++;
00692 daughterN->suggest_barcode( barcode );
00693 DecVtx->add_particle_out( daughterN );
00694 }
00695
00696 iprt1 = iprt2-1;
00697
00698
00699 event().get()->add_vertex( DecVtx );
00700
00701 }
00702
00703 }
00704
00705
00706
00707 if ( pyjets_local.n != pyjets.n )
00708 {
00709
00710
00711 pyjets.n = pyjets_local.n;
00712 pyjets.npad = pyjets_local.npad;
00713 for ( int ip=0; ip<pyjets_local.n; ip++ )
00714 {
00715 for ( int i=0; i<5; i++ )
00716 {
00717 pyjets.k[i][ip] = pyjets_local.k[i][ip];
00718 pyjets.p[i][ip] = pyjets_local.p[i][ip];
00719 pyjets.v[i][ip] = pyjets_local.v[i][ip];
00720 }
00721 }
00722 }
00723
00724 return true;
00725 }
00726
00727 bool Pythia6Hadronizer::readSettings( int key )
00728 {
00729
00730 Pythia6Service::InstanceWrapper guard(fPy6Service);
00731
00732 fPy6Service->setGeneralParams();
00733 if ( key == 0 ) fPy6Service->setCSAParams();
00734 fPy6Service->setSLHAParams();
00735
00736 return true;
00737
00738 }
00739
00740 bool Pythia6Hadronizer::initializeForExternalPartons()
00741 {
00742 Pythia6Service::InstanceWrapper guard(fPy6Service);
00743
00744
00745
00746
00747
00748 fPy6Service->setPYUPDAParams(false);
00749
00750 FortranCallback::getInstance()->setLHERunInfo( lheRunInfo() );
00751
00752 if ( fStopHadronsEnabled )
00753 {
00754
00755 call_pygive("MSTP(111)=0");
00756 pystrhad_();
00757 call_pygive("MWID(302)=0");
00758 call_pygive("MDCY(302,1)=0");
00759
00760 }
00761
00762 if ( fGluinoHadronsEnabled )
00763 {
00764
00765 call_pygive("MSTP(111)=0");
00766 pyglrhad_();
00767
00768
00769 }
00770
00771 call_pyinit("USER", "", "", 0.0);
00772
00773 fPy6Service->setPYUPDAParams(true);
00774
00775 std::vector<std::string> slha = lheRunInfo()->findHeader("slha");
00776 if (!slha.empty()) {
00777 edm::LogInfo("Generator|LHEInterface")
00778 << "Pythia6 hadronisation found an SLHA header, "
00779 << "will be passed on to Pythia." << std::endl;
00780 fPy6Service->setSLHAFromHeader(slha);
00781 fPy6Service->closeSLHA();
00782 }
00783
00784 if ( fJetMatching )
00785 {
00786 fJetMatching->init( lheRunInfo() );
00787
00788 call_pygive("MSTP(143)=1");
00789 }
00790
00791 return true;
00792 }
00793
00794 bool Pythia6Hadronizer::initializeForInternalPartons()
00795 {
00796
00797 Pythia6Service::InstanceWrapper guard(fPy6Service);
00798
00799 fPy6Service->setPYUPDAParams(false);
00800
00801 if ( fStopHadronsEnabled )
00802 {
00803
00804 call_pygive("MSTP(111)=0");
00805 pystrhad_();
00806 }
00807
00808 if ( fGluinoHadronsEnabled )
00809 {
00810
00811 call_pygive("MSTP(111)=0");
00812 pyglrhad_();
00813 }
00814
00815 if ( fInitialState == PP )
00816 {
00817 call_pyinit("CMS", "p", "p", fCOMEnergy);
00818 }
00819 else if ( fInitialState == PPbar )
00820 {
00821 call_pyinit( "CMS", "p", "pbar", fCOMEnergy);
00822 }
00823 else if ( fInitialState == ElectronPositron )
00824 {
00825 call_pyinit( "CMS", "e+", "e-", fCOMEnergy );
00826 }
00827 else if ( fInitialState == ElectronProton)
00828 {
00829
00830 pyjets.p[0][0] = 0.;
00831 pyjets.p[1][0] = 0.;
00832 pyjets.p[2][0] = fBeam1PZ;
00833 pyjets.p[0][1] = 0.;
00834 pyjets.p[1][1] = 0.;
00835 pyjets.p[2][1] = fBeam2PZ;
00836
00837 call_pyinit( "3mom", "e-", "p", 0.0 );
00838 }
00839 else if ( fInitialState == PositronProton)
00840 {
00841
00842 pyjets.p[0][0] = 0.;
00843 pyjets.p[1][0] = 0.;
00844 pyjets.p[2][0] = fBeam1PZ;
00845 pyjets.p[0][1] = 0.;
00846 pyjets.p[1][1] = 0.;
00847 pyjets.p[2][1] = fBeam2PZ;
00848
00849 call_pyinit( "3mom", "e+", "p", 0.0 );
00850 }
00851 else
00852 {
00853
00854 throw edm::Exception(edm::errors::Configuration,"Pythia6Interface")
00855 <<" UNKNOWN INITIAL STATE. \n The allowed initial states are: PP, PPbar, ElectronPositron, ElectronProton, and PositronProton \n";
00856 }
00857
00858
00859 fPy6Service->setPYUPDAParams(true);
00860
00861 fPy6Service->closeSLHA();
00862
00863 return true;
00864 }
00865
00866 bool Pythia6Hadronizer::declareStableParticles( const std::vector<int> pdg )
00867 {
00868
00869 for ( unsigned int i=0; i<pdg.size(); i++ )
00870 {
00871 int PyID = HepPID::translatePDTtoPythia( pdg[i] );
00872
00873 int pyCode = pycomp_( PyID );
00874 if ( pyCode > 0 )
00875 {
00876 std::ostringstream pyCard ;
00877 pyCard << "MDCY(" << pyCode << ",1)=0";
00878
00879
00880
00881 call_pygive( pyCard.str() );
00882 }
00883 }
00884
00885 return true;
00886 }
00887
00888 bool Pythia6Hadronizer::declareSpecialSettings( const std::vector<std::string> settings )
00889 {
00890
00891 for ( unsigned int iss=0; iss<settings.size(); iss++ )
00892 {
00893 if ( settings[iss].find("QED-brem-off") == std::string::npos ) continue;
00894 size_t fnd1 = settings[iss].find(":");
00895 if ( fnd1 == std::string::npos ) continue;
00896
00897 std::string value = settings[iss].substr (fnd1+1);
00898
00899 if ( value == "all" )
00900 {
00901 call_pygive( "MSTJ(41)=3" );
00902 }
00903 else
00904 {
00905 int number = atoi(value.c_str());
00906 int PyID = HepPID::translatePDTtoPythia( number );
00907 int pyCode = pycomp_( PyID );
00908 if ( pyCode > 0 )
00909 {
00910
00911
00912
00913
00914 if ( pydat1_.mstj[38] > 0 && pydat1_.mstj[38] != pyCode )
00915 {
00916 throw edm::Exception(edm::errors::Configuration,"Pythia6Interface")
00917 << " Fatal conflict: \n mandatory internal directive to set MSTJ(39)=" << pyCode
00918 << " overrides user setting MSTJ(39)=" << pydat1_.mstj[38] << " - user will not get expected behaviour \n";
00919 }
00920 std::ostringstream pyCard ;
00921 pyCard << "MSTJ(39)=" << pyCode ;
00922 call_pygive( pyCard.str() );
00923 }
00924 }
00925 }
00926
00927 return true;
00928
00929 }
00930
00931 void Pythia6Hadronizer::imposeProperTime()
00932 {
00933
00934
00935
00936
00937 int dumm=0;
00938 HepMC::GenEvent::vertex_const_iterator vbegin = event()->vertices_begin();
00939 HepMC::GenEvent::vertex_const_iterator vend = event()->vertices_end();
00940 HepMC::GenEvent::vertex_const_iterator vitr = vbegin;
00941 for (; vitr != vend; ++vitr )
00942 {
00943 HepMC::GenVertex::particle_iterator pbegin = (*vitr)->particles_begin(HepMC::children);
00944 HepMC::GenVertex::particle_iterator pend = (*vitr)->particles_end(HepMC::children);
00945 HepMC::GenVertex::particle_iterator pitr = pbegin;
00946 for (; pitr != pend; ++pitr)
00947 {
00948 if ((*pitr)->end_vertex()) continue;
00949 if ((*pitr)->status()!=1) continue;
00950
00951 int pdgcode= abs((*pitr)->pdg_id());
00952
00953 if ( pydat3.mdcy[0][pycomp_(pdgcode)-1] !=1 ) continue;
00954
00955 double ctau = pydat2.pmas[3][pycomp_(pdgcode)-1];
00956 HepMC::FourVector mom = (*pitr)->momentum();
00957 HepMC::FourVector vin = (*vitr)->position();
00958 double x = 0.;
00959 double y = 0.;
00960 double z = 0.;
00961 double t = 0.;
00962 bool decayInRange = false;
00963 while (!decayInRange)
00964 {
00965 double unif_rand = fPy6Service->call(pyr_, &dumm);
00966
00967 double proper_length = - ctau * log(unif_rand);
00968 double factor = proper_length/mom.m();
00969 x = vin.x() + factor * mom.px();
00970 y = vin.y() + factor * mom.py();
00971 z = vin.z() + factor * mom.pz();
00972 t = vin.t() + factor * mom.e();
00973
00974 if (pydat1.mstj[21]==4) {
00975 if (std::sqrt(x*x+y*y)>pydat1.parj[72] || fabs(z)>pydat1.parj[73]) decayInRange = true;
00976
00977 }
00978 else if (pydat1.mstj[21]==3) {
00979 if (std::sqrt(x*x+y*y+z*z)>pydat1.parj[71]) decayInRange = true;
00980 }
00981
00982 else {
00983 decayInRange = true;
00984 }
00985 }
00986
00987 HepMC::GenVertex* vdec = new HepMC::GenVertex(HepMC::FourVector(x,y,z,t));
00988 event()->add_vertex(vdec);
00989 vdec->add_particle_in((*pitr));
00990 }
00991 }
00992
00993 return;
00994
00995 }
00996
00997 void Pythia6Hadronizer::statistics()
00998 {
00999
01000 if ( !runInfo().internalXSec() )
01001 {
01002
01003 double cs = pypars.pari[0];
01004 cs *= 1.0e9;
01005 runInfo().setInternalXSec( cs );
01006
01007 }
01008
01009 call_pystat(1);
01010
01011 return;
01012
01013 }
01014
01015 const char* Pythia6Hadronizer::classname() const
01016 {
01017 return "gen::Pythia6Hadronizer";
01018 }
01019
01020 }