00001
00002
00003
00004
00005
00014
00015
00016
00017
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
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
00052
00053
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
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
00079 std::vector<std::string> forced_names = p.getParameter< std::vector<std::string> >("list_forced_decays");
00080
00081 produces<edm::HepMCProduct>();
00082
00083 m_EvtGen = new EvtGen (decay_table_s.c_str(),pdt_s.c_str(),the_engine);
00084
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
00093
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);
00108 forced_Hep.push_back(EvtPDL::getStdHep(found));
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
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
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
00155
00156 nlist = 0;
00157
00158
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) {
00164
00165
00166 idHep = (*p)->pdg_id();
00167 int do_force=0;
00168 for(int i=0;i<nforced;i++)
00169 {
00170 if(idHep == forced_Hep[i])
00171 {
00172 update_candlist(i,*p);
00173 do_force=1;
00174 }
00175 }
00176 if(do_force==0)
00177 {
00178 idEvt = EvtPDL::evtIdFromStdHep(idHep);
00179 ipart = idEvt.getId();
00180 if (ipart==-1) continue;
00181 if (EvtDecayTable::getNMode(ipart)==0) continue;
00182 decay(*p,idEvt,newEvt,true);
00183 }
00184 }
00185 }
00186
00187 if(nlist!=0)
00188 {
00189
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);
00197 }
00198 else
00199 {
00200 int id_non_alias = forced_Evt[index[k]].getId();
00201 EvtId non_alias(id_non_alias,id_non_alias);
00202 decay(listp[k],non_alias,newEvt,false);
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
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
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
00257
00258 if (del_daug) go_through_daughters(partEvt);
00259
00260
00261 static EvtStdHep evtstdhep;
00262
00263 evtstdhep.init();
00264 partEvt->makeStdHep(evtstdhep);
00265
00266 if (ntotal < 1000 && ntotal%10 == 0) {
00267
00268
00269 partEvt->printParticle();
00270 partEvt->printTree();
00271 std::cout << evtstdhep << "\n" <<
00272 "--------------------------------------------" << std::endl;
00273 }
00274
00275 ntotal++;
00276 partEvt->deleteTree();
00277
00278
00279
00280
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
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
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)
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