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