CMS 3D CMS Logo

EvtGenProducer.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    EvtGenInterface
00004 // Class:      EvtGenProducer
00005 // 
00014 //
00015 // Original Author:  Nello Nappi
00016 //         Created:  Fri May 11 15:19:32 CEST 2007
00017 // $Id: EvtGenProducer.cc,v 1.6 2008/07/10 08:45:44 covarell Exp $
00018 //
00019 //
00020 #include "FWCore/PluginManager/interface/PluginManager.h"
00021 
00022 #include "FWCore/Framework/interface/MakerMacros.h"
00023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00024 
00025 #include "SimDataFormats/HepMCProduct/interface/HepMCProduct.h"
00026 
00027 // #include "HepMC/IO_HEPEVT.h"
00028 
00029 #include "FWCore/Utilities/interface/Exception.h"
00030 #include "FWCore/Framework/interface/Event.h"
00031 #include "FWCore/Framework/interface/Run.h"
00032 #include "Utilities/General/interface/FileInPath.h"
00033 #include "FWCore/ServiceRegistry/interface/Service.h"
00034 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00035 #include "CLHEP/Random/Random.h"
00036 
00037 #include "GeneratorInterface/EvtGenInterface/interface/EvtGenProducer.h"
00038 #include "GeneratorInterface/EvtGenInterface/interface/myEvtRandomEngine.h"
00039 
00040 #include <iostream>
00041 #include "HepMC/PythiaWrapper6_2.h"
00042 
00043 #define PYGIVE pygive_
00044 extern "C" {
00045   void PYGIVE(const char*,int length);
00046 }
00047 
00048 EvtGenProducer::EvtGenProducer(edm::ParameterSet const & p)
00049 {   
00050 
00051   // create random engine and initialize seed using Random Number 
00052   // Generator Service 
00053   // as configured in the configuration file
00054 
00055   edm::Service<edm::RandomNumberGenerator> rngen;
00056   
00057   if ( ! rngen.isAvailable()) {             
00058     throw cms::Exception("Configuration")
00059       << "The EvtGenProducer module requires the RandomNumberGeneratorService\n"
00060       "which is not present in the configuration file.  You must add the service\n"
00061       "in the configuration file if you  want to run EvtGenProducer";
00062     }
00063 
00064   CLHEP::HepRandomEngine& m_engine = rngen->getEngine();
00065   m_flat = new CLHEP::RandFlat(m_engine, 0., 1.);
00066   myEvtRandomEngine* the_engine = new myEvtRandomEngine(&m_engine); 
00067 
00068   // Get data from parameter set
00069   edm::FileInPath decay_table = p.getParameter<edm::FileInPath>("decay_table");
00070   edm::FileInPath pdt = p.getParameter<edm::FileInPath>("particle_property_file");
00071   bool useDefault = p.getUntrackedParameter<bool>("use_default_decay",true);
00072   edm::FileInPath user_decay = p.getParameter<edm::FileInPath>("user_decay_file");
00073   std::string decay_table_s = decay_table.fullPath();
00074   std::string pdt_s = pdt.fullPath();
00075   std::string user_decay_s = user_decay.fullPath();
00076 
00077   pythia_params = p.getParameter< std::vector<std::string> >("processParameters");
00078   // any number of alias names for forced decays can be specified using dynamic std vector of strings 
00079   std::vector<std::string> forced_names = p.getParameter< std::vector<std::string> >("list_forced_decays");
00080     
00081   produces<edm::HepMCProduct>();   // declare 
00082     
00083   m_EvtGen = new EvtGen (decay_table_s.c_str(),pdt_s.c_str(),the_engine);  
00084   // 4th parameter should be rad cor - set to PHOTOS (default)
00085  
00086   if (!useDefault) m_EvtGen->readUDecay( user_decay_s.c_str() );
00087 
00088   std::vector<std::string>::const_iterator i;
00089   nforced=0;
00090 
00091   for (i=forced_names.begin(); i!=forced_names.end(); ++i)   
00092     // i will point to strings containing
00093     // names of particles with forced decay
00094     {
00095       nforced++;
00096       EvtId found = EvtPDL::getId(*i);      
00097       if (found.getId()==-1)
00098         {
00099           throw cms::Exception("Configuration")
00100             << "name in part list for forced decays not found: " << *i; 
00101         }
00102       if (found.getId()==found.getAlias())
00103         {
00104           throw cms::Exception("Configuration")
00105             << "name in part list for forced decays is not an alias: " << *i; 
00106         }
00107       forced_Evt.push_back(found);                      // forced_Evt is the list of EvtId's
00108       forced_Hep.push_back(EvtPDL::getStdHep(found));   // forced_Hep is the list of stdhep codes
00109     }
00110 
00111 }
00112 
00113 EvtGenProducer::~EvtGenProducer() 
00114 {  
00115 }
00116 
00117 void EvtGenProducer::beginJob(const edm::EventSetup & es)
00118 {
00119   ntotal = 0;
00120   nevent = 0;
00121   std::cout << " EvtGenProducer starting ... " << std::endl;
00122 }
00123  
00124 void EvtGenProducer::endJob()
00125 { 
00126   std::cout << " EvtGenProducer terminating ... " << std::endl; 
00127 }
00128  
00129 void EvtGenProducer::produce(edm::Event & e, const edm::EventSetup & es)
00130 {
00131   nevent++;
00132   npartial = 0;
00133   // std::cout << "nevent = " << nevent << std::endl ;
00134   
00135   int idHep,ipart,status;
00136   EvtId idEvt;
00137   std::auto_ptr<edm::HepMCProduct> new_product( new edm::HepMCProduct() ); 
00138 
00139   edm::Handle< edm::HepMCProduct > EvtHandle ;
00140   e.getByLabel( "source", EvtHandle ) ;
00141 
00142   const HepMC::GenEvent* Evt = EvtHandle->GetEvent() ;
00143   nPythia = Evt->particles_size();
00144   HepMC::GenEvent* newEvt = new HepMC::GenEvent( *Evt );
00145 
00146   // Do here initialization of EvtPythia then restore original settings
00147   if (nevent == 1) {
00148     EvtPythia::pythiaInit(0);
00149     for( std::vector<std::string>::const_iterator itPar = pythia_params.begin(); itPar != pythia_params.end(); ++itPar ) {
00150       call_pygive(*itPar);
00151     }
00152   } 
00153 
00154   // First pass through undecayed Pythia particles to decay particles known to EvtGen left stable by Pythia
00155   // except candidates to be forced which will be searched later to include EvtGen decay products 
00156   nlist = 0;
00157 
00158   // Notice dynamical use of newEvt
00159   for (HepMC::GenEvent::particle_const_iterator p= newEvt->particles_begin(); p != newEvt->particles_end(); ++p)
00160     {
00161       status = (*p)->status();
00162  
00163       if(status==1) {           // only not decayed (status = 1) particles
00164           
00165 
00166           idHep = (*p)->pdg_id();
00167           int do_force=0;
00168           for(int i=0;i<nforced;i++)           // First check if part with forced decay
00169             {                                  // In that case do not decay immediately 
00170               if(idHep == forced_Hep[i])       // (only 1 per event will be forced)      
00171                 {                              // Fill list
00172                   update_candlist(i,*p);
00173                   do_force=1;
00174                 }
00175             }
00176           if(do_force==0)         // particles with decays not forced are decayed immediately 
00177             {
00178               idEvt = EvtPDL::evtIdFromStdHep(idHep);
00179               ipart = idEvt.getId();
00180               if (ipart==-1) continue;                          // particle not known to EvtGen       
00181               if (EvtDecayTable::getNMode(ipart)==0) continue;  // particles stable for EvtGen
00182               decay(*p,idEvt,newEvt,true);                      // generate decay
00183             }
00184         }
00185     }
00186 
00187   if(nlist!=0)   
00188      {
00189       // decide randomly which one to decay as alias
00190       int which = (int)(nlist*m_flat->fire()); 
00191       if (which == nlist) which = nlist-1;
00192   
00193           for(int k=0;k < nlist; k++)
00194             {
00195               if(k == which) {          
00196                 decay(listp[k],forced_Evt[index[k]],newEvt,false);  // decay as alias
00197               } 
00198               else
00199                 {
00200                   int id_non_alias = forced_Evt[index[k]].getId();
00201                   EvtId non_alias(id_non_alias,id_non_alias); // create new EvtId with id = alias
00202                   decay(listp[k],non_alias,newEvt,false);     // decay as standard (non alias)
00203                 }
00204             }
00205      }
00206 
00207   new_product->addHepMCData( newEvt );
00208   e.put( new_product );
00209   
00210 }
00211 
00212 void EvtGenProducer::decay(HepMC::GenParticle* partHep, EvtId idEvt, HepMC::GenEvent* theEvent, bool del_daug )
00213 {
00214   // Set spin type
00215   EvtSpinType::spintype stype = EvtPDL::getSpinType(idEvt);
00216   EvtParticle* partEvt;
00217     switch (stype){
00218     case EvtSpinType::SCALAR: 
00219       partEvt = new EvtScalarParticle();
00220       break;
00221     case EvtSpinType::STRING:
00222       partEvt = new EvtStringParticle();    
00223       break;
00224     case EvtSpinType::DIRAC: 
00225       partEvt = new EvtDiracParticle();
00226       break;
00227     case EvtSpinType::VECTOR:
00228       partEvt = new EvtVectorParticle();
00229       break;
00230     case EvtSpinType::RARITASCHWINGER:
00231       partEvt = new EvtRaritaSchwingerParticle();
00232       break;
00233     case EvtSpinType::TENSOR:
00234       partEvt = new EvtTensorParticle();
00235       break;
00236     case EvtSpinType::SPIN5HALF: case EvtSpinType::SPIN3: case EvtSpinType::SPIN7HALF: case EvtSpinType::SPIN4:
00237       partEvt = new EvtHighSpinParticle();
00238       break;
00239     default:
00240       std::cout << "Unknown spintype in EvtSpinType!" << std::endl;   
00241       return;
00242     }
00243 
00244     // Generate decay
00245     EvtVector4R momEvt;
00246     HepMC::FourVector momHep = partHep->momentum();
00247     momEvt.set(momHep.t(),momHep.x(),momHep.y(),momHep.z());
00248     EvtVector4R posEvt;
00249     HepMC::GenVertex* initVert = partHep->production_vertex();
00250     HepMC::FourVector posHep = initVert->position();
00251     posEvt.set(posHep.t(),posHep.x(),posHep.y(),posHep.z());
00252     partEvt->init(idEvt,momEvt);
00253     partEvt->setDiagonalSpinDensity();     
00254     partEvt->decay();
00255                        
00256     // extend the search of candidates to be forced to EvtGen decay products and delete their daughters  ** 
00257     // otherwise they wouldn't get their chance to take part in the forced decay lottery                 **
00258     if (del_daug) go_through_daughters(partEvt);    // recursive function go_through_daughters will do   **
00259 
00260     // Change particle in stdHEP format
00261     static EvtStdHep evtstdhep;
00262     
00263     evtstdhep.init();
00264     partEvt->makeStdHep(evtstdhep);
00265 
00266     if (ntotal < 1000 && ntotal%10 == 0) {     // DEBUG
00267     // if (evtstdhep.getStdHepID(0) == 521 || evtstdhep.getStdHepID(0) == 523) {     // DEBUG
00268    
00269       partEvt->printParticle();                
00270       partEvt->printTree();
00271       std::cout << evtstdhep << "\n"  <<
00272       "--------------------------------------------" << std::endl;
00273     } 
00274 
00275     ntotal++;
00276     partEvt->deleteTree();
00277 
00278     // ********* Now add to the HepMC Event **********
00279 
00280     // Then loop on evtstdhep to add vertexes... 
00281     HepMC::GenVertex* theVerts[100];
00282     for (int ivert = 0; ivert < 100; ivert++) { 
00283       theVerts[ivert] = 0;
00284     }
00285 
00286     for (int ipart = 0; ipart < evtstdhep.getNPart(); ipart++) {
00287       int theMum = evtstdhep.getFirstMother(ipart);
00288       if (theMum != -1 && !theVerts[theMum]) {
00289         EvtVector4R theVpos = evtstdhep.getX4(ipart) + posEvt;
00290         theVerts[theMum] = 
00291           new HepMC::GenVertex(HepMC::FourVector(theVpos.get(1),
00292                                                  theVpos.get(2),
00293                                                  theVpos.get(3),
00294                                                  theVpos.get(0)),0);
00295       }
00296     }
00297 
00298     // ...then particles
00299     partHep->set_status(2);
00300     theVerts[0]->add_particle_in( partHep );
00301 
00302     for (int ipart2 = 1; ipart2 < evtstdhep.getNPart(); ipart2++) {
00303       int idHep = evtstdhep.getStdHepID(ipart2);
00304       HepMC::GenParticle* thePart = 
00305         new HepMC::GenParticle( HepMC::FourVector(evtstdhep.getP4(ipart2).get(1),
00306                                                   evtstdhep.getP4(ipart2).get(2),
00307                                                   evtstdhep.getP4(ipart2).get(3),
00308                                                   evtstdhep.getP4(ipart2).get(0)),
00309                                 idHep,
00310                                 evtstdhep.getIStat(ipart2));
00311       npartial++;
00312       thePart->suggest_barcode(npartial + nPythia);
00313       int theMum2 = evtstdhep.getFirstMother(ipart2);
00314       if (theMum2 != -1 && theVerts[theMum2]) theVerts[theMum2]->add_particle_out( thePart );
00315       if (theVerts[ipart2]) theVerts[ipart2]->add_particle_in( thePart );
00316        
00317     }
00318     
00319     for (int ipart3 = 0; ipart3 < evtstdhep.getNPart(); ipart3++) {
00320       if (theVerts[ipart3]) theEvent->add_vertex( theVerts[ipart3] );
00321     }
00322     
00323 }        
00324 
00325 void
00326 EvtGenProducer::call_pygive(const std::string& iParm ) {
00327   
00328   //call the fortran routine pygive with a fortran string
00329   PYGIVE( iParm.c_str(), iParm.length() );  
00330  
00331 }
00332 
00333 void 
00334 EvtGenProducer::go_through_daughters(EvtParticle* part) {
00335 
00336   int NDaug=part->getNDaug();
00337   if(NDaug)
00338     {
00339       EvtParticle* Daughter;
00340       for (int i=0;i<NDaug;i++)
00341         {
00342           Daughter=part->getDaug(i);
00343           int idHep = EvtPDL::getStdHep(Daughter->getId());
00344           int found=0;
00345           for(int k=0;k<nforced;k++)         
00346             {
00347               if(idHep == forced_Hep[k])
00348                 { 
00349                   found = 1;
00350                   Daughter->deleteDaughters();
00351                 }
00352             }
00353           if (!found) go_through_daughters(Daughter);
00354         }
00355     }
00356 }
00357 
00358 void 
00359 EvtGenProducer::update_candlist( int theIndex, HepMC::GenParticle *thePart )
00360 {
00361   if(nlist<10)                 // not nice ... but is 10 a reasonable maximum?
00362      {
00363        bool isThere = false;
00364        if (nlist) {
00365          for (int check=0; check < nlist; check++) {
00366            if (listp[check]->barcode() == thePart->barcode()) isThere = true;
00367          }
00368        }
00369        if (!isThere) { 
00370          listp[nlist] = thePart;
00371          index[nlist++] = theIndex;
00372        }
00373      }
00374   else
00375     {
00376       throw cms::Exception("runtime")
00377         << "more than 10 candidates to be forced ";
00378       return; 
00379     }  
00380   return;
00381 }
00382 

Generated on Tue Jun 9 17:36:53 2009 for CMSSW by  doxygen 1.5.4