00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00124 }
00125
00126
00127 tcPVector all;
00128 ev.select(back_inserter(all), SelectAll());
00129 vertices.reserve(all.size()*2);
00130 sortTopologically(all);
00131
00132
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
00140
00141
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
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
00163
00164
00165 vertices.push_back(Vertex());
00166 prov[p] = &vertices.back();
00167 vertices.back().out.insert(p);
00168 }
00169 }
00170
00171
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
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
00201 for ( typename GenVertexMap::iterator it = vmap.begin();
00202 it != vmap.end(); ++it )
00203 Traits::addVertex(*geneve, it->second);
00204
00205
00206
00207
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
00217 geneve->set_beam_particles(pmap[ev.incoming().first],
00218 pmap[ev.incoming().second]);
00219
00220
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
00275
00276
00277
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
00299 tSubProPtr sub = e.primarySubProcess();
00300 int id1 = sub->incoming().first ->id();
00301 int id2 = sub->incoming().second->id();
00302
00303 tcEHPtr eh = dynamic_ptr_cast<tcEHPtr>(e.handler());
00304
00305 double x1 = eh->lastX1();
00306 double x2 = eh->lastX2();
00307
00308 pair<PDF,PDF> pdfs;
00309 pdfs.first = eh->pdf<PDF>(sub->incoming().first );
00310 pdfs.second = eh->pdf<PDF>(sub->incoming().second);
00311
00312 Energy2 scale = eh->lastScale();
00313
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
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