CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/GeneratorInterface/ThePEGInterface/src/HepMCConverter.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // HepMCConverter.tcc is a part of ThePEG - Toolkit for HEP Event Generation
00004 // Copyright (C) 1999-2007 Leif Lonnblad
00005 //
00006 // ThePEG is licenced under version 2 of the GPL, see COPYING for details.
00007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
00008 //
00009 //
00010 // This is the implementation of the non-inlined, non-templated member
00011 // functions of the HepMCConverter class.
00012 //
00013 
00014 // C. Saout: Copied from ThePEG and slightly modified
00015 
00016 #include <set>
00017 
00018 #include <HepMC/GenEvent.h>
00019 #include <HepMC/GenVertex.h>
00020 #include <HepMC/GenParticle.h>
00021 #include <HepMC/Polarization.h>
00022 
00023 #include <ThePEG/StandardModel/StandardModelBase.h>
00024 #include <ThePEG/Repository/EventGenerator.h>
00025 #include <ThePEG/EventRecord/Particle.h>
00026 #include <ThePEG/EventRecord/StandardSelectors.h>
00027 #include <ThePEG/EventRecord/Collision.h>
00028 #include <ThePEG/EventRecord/Step.h>
00029 #include <ThePEG/EventRecord/SubProcess.h>
00030 #include <ThePEG/Handlers/XComb.h>
00031 #include <ThePEG/Handlers/EventHandler.h>
00032 #include <ThePEG/PDF/PartonExtractor.h>
00033 #include <ThePEG/PDF/PDF.h>
00034 
00035 #include "GeneratorInterface/ThePEGInterface/interface/HepMCConverter.h"
00036 
00037 namespace ThePEG {
00038 
00039 
00040 template <typename HepMCEventT, typename Traits>
00041 typename HepMCConverter<HepMCEventT,Traits>::GenEvent *
00042 HepMCConverter<HepMCEventT,Traits>::
00043 convert(const Event & ev, bool nocopies, Energy eunit, Length lunit) {
00044   HepMCConverter<HepMCEventT,Traits> converter(ev, nocopies, eunit, lunit);
00045   return converter.geneve;
00046 }
00047 
00048 template <typename HepMCEventT, typename Traits>
00049 void HepMCConverter<HepMCEventT,Traits>::
00050 convert(const Event & ev, GenEvent & gev, bool nocopies) {
00051   HepMCConverter<HepMCEventT,Traits>
00052     converter(ev, gev, nocopies,
00053               Traits::momentumUnit(gev), Traits::lengthUnit(gev));
00054 }
00055 
00056 template <typename HepMCEventT, typename Traits>
00057 void HepMCConverter<HepMCEventT,Traits>::
00058 convert(const Event & ev, GenEvent & gev, bool nocopies,
00059         Energy eunit, Length lunit) {
00060   HepMCConverter<HepMCEventT,Traits> converter(ev, gev, nocopies, eunit, lunit);
00061 }
00062 
00063 template <typename HepMCEventT, typename Traits>
00064 HepMCConverter<HepMCEventT,Traits>::
00065 HepMCConverter(const Event & ev, bool nocopies, Energy eunit, Length lunit)
00066   : energyUnit(eunit), lengthUnit(lunit) {
00067 
00068   geneve = Traits::newEvent(ev.number(), ev.weight());
00069 
00070   init(ev, nocopies);
00071 
00072 }
00073 
00074 template <typename HepMCEventT, typename Traits>
00075 HepMCConverter<HepMCEventT,Traits>::
00076 HepMCConverter(const Event & ev, GenEvent & gev, bool nocopies,
00077                Energy eunit, Length lunit)
00078   : energyUnit(eunit), lengthUnit(lunit) {
00079 
00080   geneve = &gev;
00081 
00082   init(ev, nocopies);
00083 
00084 }
00085 
00086 struct ParticleOrderNumberCmp {
00087   bool operator()(tcPPtr a, tcPPtr b) const {
00088     return a->number() < b->number();
00089   }
00090 };
00091 
00092 template <typename HepMCEventT, typename Traits>
00093 void HepMCConverter<HepMCEventT,Traits>::init(const Event & ev, bool nocopies) {
00094 
00095   if ( Traits::hasUnits() ) {
00096     if ( lengthUnit != millimeter && lengthUnit != centimeter )
00097       throw HepMCConverterException()
00098         << "Length unit used for HepMC::GenEvent was not MM nor CM."
00099         << Exception::runerror;
00100     if ( energyUnit != GeV && energyUnit != MeV )
00101       throw HepMCConverterException()
00102         << "Momentum unit used for HepMC::GenEvent was not GEV nor MEV."
00103         << Exception::runerror;
00104   } else {
00105     if ( lengthUnit != millimeter )
00106       throw HepMCConverterException()
00107         << "Length unit used for HepMC::GenEvent was not MM and the "
00108         << "HepMCTraits class claims that the used version of HepMC "
00109         << "cannot handle user-defined units."
00110         << Exception::runerror;
00111     if ( energyUnit != GeV )
00112       throw HepMCConverterException()
00113         << "Momentum unit used for HepMC::GenEvent was not GEV and the "
00114         << "HepMCTraits class claims that the used version of HepMC "
00115         << "cannot handle user-defined units."
00116         << Exception::runerror;
00117   }
00118   Traits::setUnits(*geneve, energyUnit, lengthUnit);
00119 
00120   if ( ev.primaryCollision() && ( eh =
00121        dynamic_ptr_cast<tcEHPtr>(ev.primaryCollision()->handler()) ) ) {
00122 
00123     // Get general event info if present.
00124   }
00125 
00126   // Extract all particles and order them.
00127   tcPVector all;
00128   ev.select(back_inserter(all), SelectAll());
00129   vertices.reserve(all.size()*2);
00130   sortTopologically(all);
00131 
00132   // Create GenParticle's and map them to the ThePEG particles.
00133   for ( int i = 0, N = all.size(); i < N; ++i ) {
00134     tcPPtr p = all[i];
00135     if ( nocopies && p->next() ) continue;
00136     if ( pmap.find(p) != pmap.end() ) continue;
00137     GenParticle * gp = pmap[p] = createParticle(p);
00138     if ( p->hasColourInfo() ) {
00139       // Check if the particle is connected to colour lines, in which
00140       // case the lines are mapped to an integer and set in the
00141       // GenParticle's Flow info.
00142       tcColinePtr l;
00143       if ( l = p->colourLine() ) {
00144         if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
00145         Traits::setColourLine(*gp, 1, flowmap[l]);
00146       }
00147       if ( l = p->antiColourLine() ) {
00148         if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
00149         Traits::setColourLine(*gp, 2, flowmap[l]);
00150       }
00151     }
00152 
00153     if ( !p->children().empty() || p->next() ) {
00154       // If the particle has children it should have a decay vertex:
00155       vertices.push_back(Vertex());
00156       decv[p] = &vertices.back();
00157       vertices.back().in.insert(p);
00158     }
00159 
00160     if ( !p->parents().empty() || p->previous() ||
00161          (p->children().empty() && !p->next()) ) {
00162       // If the particle has parents it should have a production
00163       // vertex. If neither parents or children it should still have a
00164       // dummy production vertex.
00165       vertices.push_back(Vertex());
00166       prov[p] = &vertices.back();
00167       vertices.back().out.insert(p);
00168     }
00169   }
00170 
00171   // Now go through the the particles again, and join the vertices.
00172   for ( int i = 0, N = all.size(); i < N; ++i ) {
00173     tcPPtr p = all[i];
00174     if ( nocopies ) {
00175       if ( p->next() ) continue;
00176       for ( int i = 0, N = p->children().size(); i < N; ++i )
00177         join(p, p->children()[i]->final());
00178       tcPPtr pp = p;
00179       while ( pp->parents().empty() && pp->previous() ) pp = pp->previous();
00180       for ( int i = 0, N = pp->parents().size(); i < N; ++i )
00181         join(pp->parents()[i]->final(), p);
00182     } else {
00183       for ( int i = 0, N = p->children().size(); i < N; ++i )
00184         join(p, p->children()[i]);
00185       if ( p->next() ) join(p, p->next());
00186       for ( int i = 0, N = p->parents().size(); i < N; ++i )
00187         join(p->parents()[i], p);
00188       if ( p->previous() ) join(p->previous(), p);
00189     }
00190   }
00191 
00192   // Time to create the GenVertex's
00193   for ( typename VertexMap::iterator it = prov.begin(); it != prov.end(); ++it )
00194     if ( !member(vmap, it->second) )
00195       vmap[it->second] = createVertex(it->second);
00196   for ( typename VertexMap::iterator it = decv.begin(); it != decv.end(); ++it )
00197     if ( !member(vmap, it->second) )
00198       vmap[it->second] = createVertex(it->second);
00199 
00200   // Add the vertices.
00201   for ( typename GenVertexMap::iterator it = vmap.begin();
00202         it != vmap.end(); ++it )
00203     Traits::addVertex(*geneve, it->second);
00204 
00205   // Now find the primary signal process vertex defined to be the
00206   // decay vertex of the first parton coming into the primary hard
00207   // sub-collision.
00208   tSubProPtr sub = ev.primarySubProcess();
00209   if ( sub && sub->incoming().first ) {
00210     const Vertex * prim = decv[sub->incoming().first];
00211     Traits::setSignalProcessVertex(*geneve, vmap[prim]);
00212     vmap.erase(prim);
00213   }
00214   
00215 
00216   // and the incoming beam particles
00217   geneve->set_beam_particles(pmap[ev.incoming().first],
00218                            pmap[ev.incoming().second]);
00219 
00220   // and the PDF info
00221 }
00222 
00223 template <typename HepMCEventT, typename Traits>
00224 typename HepMCConverter<HepMCEventT,Traits>::GenParticle *
00225 HepMCConverter<HepMCEventT,Traits>::createParticle(tcPPtr p) const {
00226   int status = 1;
00227   if ( !p->children().empty() || p->next() ) {
00228     tStepPtr step = p->birthStep();
00229     if ((!step || (step && (!step->handler() || step->handler() == eh))) && p->id() != 82)
00230       status = 3;
00231     else
00232       status = 2;
00233   }
00234   GenParticle * gp =
00235     Traits::newParticle(p->momentum(), p->id(), status, energyUnit);
00236 
00237   if ( p->spinInfo() && p->spinInfo()->hasPolarization() ) {
00238     DPair pol = p->spinInfo()->polarization();
00239     Traits::setPolarization(*gp, pol.first, pol.second);
00240   }
00241 
00242   return gp;
00243 
00244 }
00245 
00246 template <typename HepMCEventT, typename Traits>
00247 void HepMCConverter<HepMCEventT,Traits>::join(tcPPtr parent, tcPPtr child) {
00248   Vertex * dec = decv[parent];
00249   Vertex * pro = prov[child];
00250   if ( !pro || !dec ) throw HepMCConverterException()
00251     << "Found a reference to a ThePEG::Particle which was not in the Event."
00252     << Exception::eventerror;
00253   if ( pro == dec ) return;
00254   while ( !pro->in.empty() ) {
00255     dec->in.insert(*(pro->in.begin()));
00256     decv[*(pro->in.begin())] = dec;
00257     pro->in.erase(pro->in.begin());
00258   }
00259   while ( !pro->out.empty() ) {
00260     dec->out.insert(*(pro->out.begin()));
00261     prov[*(pro->out.begin())] = dec;
00262     pro->out.erase(pro->out.begin());
00263   }
00264 }
00265 
00266 template <typename HepMCEventT, typename Traits>
00267 typename HepMCConverter<HepMCEventT,Traits>::GenVertex *
00268 HepMCConverter<HepMCEventT,Traits>::createVertex(Vertex * v) {
00269   if ( !v ) throw HepMCConverterException()
00270     << "Found internal null Vertex." << Exception::abortnow;
00271 
00272   GenVertex * gv = new GenVertex();
00273 
00274   // We assume that the vertex position is the average of the decay
00275   // vertices of all incoming and the creation vertices of all
00276   // outgoing particles in the lab. Note that this will probably not
00277   // be useful information for very small distances.
00278   LorentzPoint p;
00279   for ( tcParticleSet::iterator it = v->in.begin();
00280         it != v->in.end(); ++it ) {
00281     p += (**it).labDecayVertex();
00282     Traits::addIncoming(*gv, pmap[*it]);
00283   }
00284   for ( tcParticleSet::iterator it = v->out.begin();
00285         it != v->out.end(); ++it ) {
00286     p += (**it).labVertex();
00287     Traits::addOutgoing(*gv, pmap[*it]);
00288   }
00289 
00290   p /= double(v->in.size() + v->out.size());
00291   Traits::setPosition(*gv, p, lengthUnit);
00292 
00293   return gv;
00294 }
00295 
00296 template <typename HepMCEventT, typename Traits>
00297 void HepMCConverter<HepMCEventT,Traits>::setPdfInfo(const Event & e) {
00298   // ids of the partons going into the primary sub process
00299   tSubProPtr sub = e.primarySubProcess();
00300   int id1 = sub->incoming().first ->id();
00301   int id2 = sub->incoming().second->id();
00302   // get the event handler
00303   tcEHPtr eh = dynamic_ptr_cast<tcEHPtr>(e.handler());
00304   // get the values of x
00305   double x1 = eh->lastX1();
00306   double x2 = eh->lastX2();
00307   // get the pdfs
00308   pair<PDF,PDF> pdfs;
00309   pdfs.first  =  eh->pdf<PDF>(sub->incoming().first );
00310   pdfs.second =  eh->pdf<PDF>(sub->incoming().second);
00311   // get the scale
00312   Energy2 scale = eh->lastScale();
00313   // get the values of the pdfs
00314   double xf1 = pdfs.first.xfx(sub->incoming().first->dataPtr(), scale, x1);
00315   double xf2 = pdfs.second.xfx(sub->incoming().second->dataPtr(), scale, x2);
00316 
00317   Traits::setPdfInfo(*geneve, id1, id2, x1, x2, sqrt(scale/GeV2), xf1, xf2);
00318 
00319 }
00320 
00321 template<typename HepMCEventT, typename Traits>
00322 void HepMCConverter<HepMCEventT, Traits>::sortTopologically(tcPVector &all)
00323 {
00324   // order the particles topologically
00325   std::set<tcPPtr> visited;
00326   for(unsigned int head = 0; head < all.size(); head++) {
00327     bool vetoed = true;
00328     for(unsigned int cur = head; cur < all.size(); cur++) {
00329       vetoed = false;
00330       for(tParticleVector::const_iterator iter =
00331         all[cur]->parents().begin();
00332         iter != all[cur]->parents().end(); ++iter) {
00333           if (visited.find(*iter) == visited.end()) {
00334             vetoed = true;
00335             break;
00336           }
00337         }
00338       if (!vetoed) {
00339         if (cur != head)
00340           std::swap(all[head], all[cur]);
00341         break;
00342       }
00343     }
00344     visited.insert(all[head]);
00345   }
00346   visited.clear();
00347 }
00348 
00349 template class ThePEG::HepMCConverter<HepMC::GenEvent>;
00350 
00351 
00352 }
00353 
00354