CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/GeneratorInterface/Pythia6Interface/plugins/Pythia6Gun.cc

Go to the documentation of this file.
00001 /*
00002  *  $Date: 2010/07/20 04:42:50 $
00003  *  $Revision: 1.19 $
00004  *  \author Julia Yarba
00005  */
00006 
00007 #include <iostream>
00008 
00009 #include "Pythia6Gun.h"
00010 
00011 //#include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
00012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00013 #include "FWCore/Utilities/interface/Exception.h"
00014 
00015 #include "FWCore/Framework/interface/EDProducer.h"
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 
00019 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
00020 
00021 using namespace edm;
00022 using namespace gen;
00023 
00024 
00025 Pythia6Gun::Pythia6Gun( const ParameterSet& pset ) :
00026    fPy6Service( new Pythia6Service(pset) ),
00027    fEvt(0)
00028    // fPDGTable( new DefaultConfig::ParticleDataTable("PDG Table") )
00029 {
00030 
00031    ParameterSet pgun_params = 
00032       pset.getParameter<ParameterSet>("PGunParameters");
00033       
00034    // although there's the method ParameterSet::empty(),  
00035    // it looks like it's NOT even necessary to check if it is,
00036    // before trying to extract parameters - if it is empty,
00037    // the default values seem to be taken
00038    //
00039    fMinPhi     = pgun_params.getParameter<double>("MinPhi"); // ,-3.14159265358979323846);
00040    fMaxPhi     = pgun_params.getParameter<double>("MaxPhi"); // , 3.14159265358979323846);
00041    
00042    fHepMCVerbosity   = pset.getUntrackedParameter<bool>("pythiaHepMCVerbosity", false ) ;
00043    fPylistVerbosity  = pset.getUntrackedParameter<int>( "pythiaPylistVerbosity", 0 ) ;
00044    fMaxEventsToPrint = pset.getUntrackedParameter<int>( "maxEventsToPrint", 0 );
00045 
00046 // Turn off banner printout
00047    if (!call_pygive("MSTU(12)=12345")) 
00048    {
00049       throw edm::Exception(edm::errors::Configuration,"PythiaError") 
00050             <<" pythia did not accept MSTU(12)=12345";
00051    }
00052 
00053    produces<HepMCProduct>();
00054 
00055 }
00056 
00057 Pythia6Gun::~Pythia6Gun()
00058 { 
00059    if ( fPy6Service ) delete fPy6Service; 
00060    //
00061    // note that GenEvent or any undelaying (GenVertex, GenParticle) do NOT
00062    // need to be cleaned, as it'll be done automatically by HepMCProduct
00063    //
00064 }
00065 
00066 
00067 void Pythia6Gun::beginJob()
00068 {
00069    // es.getData( fPDGTable ) ;
00070    return ;
00071 
00072 }
00073 
00074 void Pythia6Gun::endJob()
00075 {
00076 }
00077 
00078 void Pythia6Gun::beginRun( Run & r, EventSetup const& es )
00079 {
00080    assert ( fPy6Service ) ;
00081 
00082    Pythia6Service::InstanceWrapper guard(fPy6Service);  // grab Py6 instance
00083 
00084    fPy6Service->setGeneralParams();
00085    fPy6Service->setCSAParams();
00086    fPy6Service->setSLHAParams();
00087    
00088    call_pygive("MSTU(10)=1");
00089       
00090    call_pyinit("NONE", "", "", 0.0);
00091    
00092    std::cout << " FYI: MSTU(10)=1 is ENFORCED in Py6-PGuns, for technical reasons"
00093              << std::endl;
00094    return;
00095 }
00096 
00097 void Pythia6Gun::endRun( Run & r, EventSetup const& es )
00098 {
00099    
00100    // here put in GenRunInfoProduct
00101    
00102    call_pystat(1);
00103    
00104    return;
00105 }
00106 
00107 void Pythia6Gun::attachPy6DecaysToGenEvent()
00108 {
00109 
00110    for ( int iprt=fPartIDs.size(); iprt<pyjets.n; iprt++ ) // the pointer is shifted by -1, c++ style
00111    {
00112       int parent = pyjets.k[2][iprt];
00113       if ( parent != 0 )
00114       {
00115          // pull up parent particle
00116          //
00117          HepMC::GenParticle* parentPart = fEvt->barcode_to_particle( parent );
00118          parentPart->set_status( 2 ); // reset status, to mark that it's decayed
00119          
00120          HepMC::GenVertex* DecVtx = new HepMC::GenVertex(HepMC::FourVector(pyjets.v[0][iprt],
00121                                                                            pyjets.v[1][iprt],
00122                                                                            pyjets.v[2][iprt],
00123                                                                            pyjets.v[3][iprt]));
00124          DecVtx->add_particle_in( parentPart ); // this will cleanup end_vertex if exists,
00125                                                 // and replace with the new one
00126                                                 // I presume barcode will be given automatically
00127          
00128          HepMC::FourVector  pmom(pyjets.p[0][iprt],pyjets.p[1][iprt],
00129                                  pyjets.p[2][iprt],pyjets.p[3][iprt] );
00130          
00131          int dstatus = 0;
00132          if ( pyjets.k[0][iprt] >= 1 && pyjets.k[0][iprt] <= 10 )  
00133          {
00134             dstatus = 1;
00135          }
00136          else if ( pyjets.k[0][iprt] >= 11 && pyjets.k[0][iprt] <= 20 ) 
00137          {
00138             dstatus = 2;
00139          }
00140          else if ( pyjets.k[0][iprt] >= 21 && pyjets.k[0][iprt] <= 30 ) 
00141          {
00142             dstatus = 3;
00143          }
00144          else if ( pyjets.k[0][iprt] >= 31 && pyjets.k[0][iprt] <= 100 )
00145          {
00146             dstatus = pyjets.k[0][iprt];
00147          }
00148          HepMC::GenParticle* daughter = 
00149             new HepMC::GenParticle(pmom,
00150                                    HepPID::translatePythiatoPDT( pyjets.k[1][iprt] ),
00151                                    dstatus);
00152          daughter->suggest_barcode( iprt+1 );
00153          DecVtx->add_particle_out( daughter );
00154          // give particle barcode as well !
00155 
00156          int iprt1;
00157          for ( iprt1=iprt+1; iprt1<pyjets.n; iprt1++ ) // the pointer is shifted by -1, c++ style
00158          {
00159             if ( pyjets.k[2][iprt1] != parent ) break; // another parent particle, break the loop
00160 
00161             HepMC::FourVector  pmomN(pyjets.p[0][iprt1],pyjets.p[1][iprt1],
00162                                      pyjets.p[2][iprt1],pyjets.p[3][iprt1] );
00163 
00164             dstatus = 0;
00165             if ( pyjets.k[0][iprt1] >= 1 && pyjets.k[0][iprt1] <= 10 )  
00166             {
00167                dstatus = 1;
00168             }
00169             else if ( pyjets.k[0][iprt1] >= 11 && pyjets.k[0][iprt1] <= 20 ) 
00170             {
00171                dstatus = 2;
00172             }
00173             else if ( pyjets.k[0][iprt1] >= 21 && pyjets.k[0][iprt1] <= 30 ) 
00174             {
00175                dstatus = 3;
00176             }
00177             else if ( pyjets.k[0][iprt1] >= 31 && pyjets.k[0][iprt1] <= 100 )
00178             {
00179                dstatus = pyjets.k[0][iprt1];
00180             }
00181             HepMC::GenParticle* daughterN = 
00182                new HepMC::GenParticle(pmomN,
00183                                       HepPID::translatePythiatoPDT( pyjets.k[1][iprt1] ),
00184                                       dstatus);
00185             daughterN->suggest_barcode( iprt1+1 );
00186             DecVtx->add_particle_out( daughterN );           
00187          }
00188          
00189          iprt = iprt1-1; // reset counter such that it doesn't go over the same child more than once
00190                          // don't forget to offset back into c++ counting, as it's already +1 forward
00191 
00192          fEvt->add_vertex( DecVtx );
00193 
00194       }
00195    }
00196 
00197    return;
00198 
00199 }
00200 
00201 void Pythia6Gun::produce( edm::Event& evt, const edm::EventSetup& )
00202 {
00203 
00204    generateEvent() ;
00205    
00206    fEvt->set_beam_particles(0,0);
00207    fEvt->set_event_number(evt.id().event()) ;
00208    fEvt->set_signal_process_id(pypars.msti[0]) ;  
00209 
00210    attachPy6DecaysToGenEvent();
00211 
00212    int evtN = evt.id().event();
00213    if ( evtN <= fMaxEventsToPrint )
00214    {
00215       if ( fPylistVerbosity )
00216       {
00217          call_pylist(fPylistVerbosity);
00218       }
00219       if ( fHepMCVerbosity )
00220       {
00221          if ( fEvt ) fEvt->print();
00222       }
00223    }
00224     
00225    loadEvent( evt );
00226 }
00227 
00228 void Pythia6Gun::loadEvent( edm::Event& evt )
00229 {
00230 
00231    std::auto_ptr<HepMCProduct> bare_product(new HepMCProduct());  
00232    
00233    if(fEvt)  bare_product->addHepMCData( fEvt );
00234 
00235    evt.put(bare_product);
00236 
00237    
00238    return;
00239 
00240 }
00241 
00242 HepMC::GenParticle* Pythia6Gun::addAntiParticle( int& ip, int& particleID,
00243                                                  double& ee, double& eta, double& phi )
00244 {
00245 
00246    if ( ip < 2 ) return 0;
00247 
00248 // translate PDG to Py6
00249    int py6PID = HepPID::translatePDTtoPythia( particleID );
00250 // Check if particle is its own anti-particle.
00251    int pythiaCode = pycomp_(py6PID); // this is py6 internal validity check, it takes Pythia6 pid
00252                                      // so actually I'll need to convert
00253    int has_antipart = pydat2.kchg[3-1][pythiaCode-1];
00254    int particleID2 = has_antipart ? -1 * particleID : particleID; // this is PDG, for HepMC::GenEvent
00255    int py6PID2 = has_antipart ? -1 * py6PID : py6PID;    // this py6 id, for py1ent   
00256    double the = 2.*atan(exp(eta));
00257    phi  = phi + M_PI;
00258    if (phi > 2.* M_PI) {phi = phi - 2.* M_PI;}         
00259 
00260    // copy over mass of the previous one, because then py6 will pick it up
00261    pyjets.p[4][ip-1] = pyjets.p[4][ip-2];
00262 
00263    py1ent_(ip, py6PID2, ee, the, phi);
00264 
00265    double px     = pyjets.p[0][ip-1]; // pt*cos(phi) ;
00266    double py     = pyjets.p[1][ip-1]; // pt*sin(phi) ;
00267    double pz     = pyjets.p[2][ip-1]; // mom*cos(the) ;
00268    HepMC::FourVector ap(px,py,pz,ee) ;
00269    HepMC::GenParticle* APart =
00270                new HepMC::GenParticle(ap,particleID2,1);
00271    APart->suggest_barcode( ip ) ;
00272 
00273    return APart;
00274 
00275 }