Warning, /include/ThePEG/Vectors/HepMCConverter.tcc is written in an unsupported language. File is not indexed.
0001 // -*- C++ -*-
0002 //
0003 // HepMCConverter.tcc is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 //
0010 // This is the implementation of the non-inlined, non-templated member
0011 // functions of the HepMCConverter class.
0012 //
0013
0014 #include "ThePEG/StandardModel/StandardModelBase.h"
0015 #include "ThePEG/Repository/EventGenerator.h"
0016 #include "ThePEG/EventRecord/Particle.h"
0017 #include "ThePEG/EventRecord/StandardSelectors.h"
0018 #include "ThePEG/EventRecord/Collision.h"
0019 #include "ThePEG/EventRecord/Step.h"
0020 #include "ThePEG/EventRecord/SubProcess.h"
0021 #include "ThePEG/Handlers/XComb.h"
0022 #include "ThePEG/Handlers/EventHandler.h"
0023 #include "ThePEG/PDF/PartonExtractor.h"
0024 #include "ThePEG/PDF/PDF.h"
0025 #include "ThePEG/PDT/StandardMatchers.h"
0026 #include "ThePEG/Utilities/Throw.h"
0027 namespace ThePEG {
0028
0029
0030 template <typename HepMCEventT, typename Traits>
0031 typename HepMCConverter<HepMCEventT,Traits>::GenEvent *
0032 HepMCConverter<HepMCEventT,Traits>::
0033 convert(const Event & ev, bool nocopies, Energy eunit, Length lunit) {
0034 HepMCConverter<HepMCEventT,Traits> converter(ev, nocopies, eunit, lunit);
0035 return converter.geneve;
0036 }
0037
0038 template <typename HepMCEventT, typename Traits>
0039 void HepMCConverter<HepMCEventT,Traits>::
0040 convert(const Event & ev, GenEvent & gev, bool nocopies) {
0041 HepMCConverter<HepMCEventT,Traits>
0042 converter(ev, gev, nocopies,
0043 Traits::momentumUnit(gev), Traits::lengthUnit(gev));
0044 }
0045
0046 template <typename HepMCEventT, typename Traits>
0047 void HepMCConverter<HepMCEventT,Traits>::
0048 convert(const Event & ev, GenEvent & gev, bool nocopies,
0049 Energy eunit, Length lunit) {
0050 HepMCConverter<HepMCEventT,Traits> converter(ev, gev, nocopies, eunit, lunit);
0051 }
0052
0053 template <typename HepMCEventT, typename Traits>
0054 HepMCConverter<HepMCEventT,Traits>::
0055 HepMCConverter(const Event & ev, bool nocopies, Energy eunit, Length lunit)
0056 : energyUnit(eunit), lengthUnit(lunit) {
0057
0058 geneve = Traits::newEvent(ev.number(), ev.weight(), ev.optionalWeights());
0059
0060 init(ev, nocopies);
0061
0062 }
0063
0064 template <typename HepMCEventT, typename Traits>
0065 HepMCConverter<HepMCEventT,Traits>::
0066 HepMCConverter(const Event & ev, GenEvent & gev, bool nocopies,
0067 Energy eunit, Length lunit)
0068 : energyUnit(eunit), lengthUnit(lunit) {
0069
0070 geneve = &gev;
0071 Traits::resetEvent(geneve, ev.number(), ev.weight(), ev.optionalWeights());
0072
0073 init(ev, nocopies);
0074
0075 }
0076
0077 struct ParticleOrderNumberCmp {
0078 bool operator()(tcPPtr a, tcPPtr b) const {
0079 return a->number() < b->number();
0080 }
0081 };
0082
0083 template <typename HepMCEventT, typename Traits>
0084 void HepMCConverter<HepMCEventT,Traits>::init(const Event & ev, bool nocopies) {
0085
0086 if ( lengthUnit != millimeter && lengthUnit != centimeter )
0087 Throw<HepMCConverterException>()
0088 << "Length unit used for HepMC::GenEvent was not MM nor CM."
0089 << Exception::runerror;
0090 if ( energyUnit != GeV && energyUnit != MeV )
0091 Throw<HepMCConverterException>()
0092 << "Momentum unit used for HepMC::GenEvent was not GEV nor MEV."
0093 << Exception::runerror;
0094 Traits::setUnits(*geneve, energyUnit, lengthUnit);
0095
0096 tcEHPtr eh;
0097 if ( ev.primaryCollision() && ( eh =
0098 dynamic_ptr_cast<tcEHPtr>(ev.primaryCollision()->handler()) ) ) {
0099
0100 // Get general event info if present.
0101 Traits::setScaleAndAlphas(*geneve, eh->lastScale(),
0102 eh->lastAlphaS(),eh->lastAlphaEM(),
0103 energyUnit);
0104 }
0105
0106 // Extract all particles and order them.
0107 tcPVector all;
0108 ev.select(back_inserter(all), SelectAll());
0109 stable_sort(all.begin(), all.end(), ParticleOrderNumberCmp());
0110 vertices.reserve(all.size()*2);
0111
0112 // Create GenParticle's and map them to the ThePEG particles.
0113 for ( int i = 0, N = all.size(); i < N; ++i ) {
0114 tcPPtr p = all[i];
0115 if ( nocopies && p->next() ) continue;
0116 if ( pmap.find(p) != pmap.end() ) continue;
0117 pmap[p] = createParticle(p);
0118 if ( !p->children().empty() || p->next() ) {
0119 // If the particle has children it should have a decay vertex:
0120 vertices.push_back(Vertex());
0121 decv[p] = &vertices.back();
0122 vertices.back().in.insert(p);
0123 }
0124
0125 if ( !p->parents().empty() || p->previous() ||
0126 (p->children().empty() && !p->next()) ) {
0127 // If the particle has parents it should have a production
0128 // vertex. If neither parents or children it should still have a
0129 // dummy production vertex.
0130 vertices.push_back(Vertex());
0131 prov[p] = &vertices.back();
0132 vertices.back().out.insert(p);
0133 }
0134 }
0135
0136 // Now go through the the particles again, and join the vertices.
0137 for ( int i = 0, N = all.size(); i < N; ++i ) {
0138 tcPPtr p = all[i];
0139 if ( nocopies ) {
0140 if ( p->next() ) continue;
0141 for ( int i = 0, N = p->children().size(); i < N; ++i )
0142 join(p, p->children()[i]->final());
0143 tcPPtr pp = p;
0144 while ( pp->parents().empty() && pp->previous() ) pp = pp->previous();
0145 for ( int i = 0, N = pp->parents().size(); i < N; ++i )
0146 join(pp->parents()[i]->final(), p);
0147 } else {
0148 for ( int i = 0, N = p->children().size(); i < N; ++i )
0149 join(p, p->children()[i]);
0150 if ( p->next() ) join(p, p->next());
0151 for ( int i = 0, N = p->parents().size(); i < N; ++i )
0152 join(p->parents()[i], p);
0153 if ( p->previous() ) join(p->previous(), p);
0154 }
0155 }
0156
0157 // Time to create the GenVertex's
0158 for ( typename VertexMap::iterator it = prov.begin(); it != prov.end(); ++it )
0159 if ( !member(vmap, it->second) )
0160 vmap[it->second] = createVertex(it->second);
0161 for ( typename VertexMap::iterator it = decv.begin(); it != decv.end(); ++it )
0162 if ( !member(vmap, it->second) )
0163 vmap[it->second] = createVertex(it->second);
0164
0165 // First add the decay vertices for the first beam particle to avoid issue in HepMC3
0166 const Vertex * prim = decv[ev.incoming().first];
0167 if(prim) {
0168 Traits::addVertex(*geneve, vmap[prim]);
0169 vmap.erase(prim);
0170 }
0171
0172 // Now find the primary signal process vertex defined to be the
0173 // decay vertex of the first parton coming into the primary hard
0174 // sub-collision.
0175 tSubProPtr sub = ev.primarySubProcess();
0176 if ( sub && sub->incoming().first && sub->incoming().first!=ev.incoming().first) {
0177 const Vertex * prim = decv[sub->incoming().first];
0178 Traits::setSignalProcessVertex(*geneve, vmap[prim]);
0179 vmap.erase(prim);
0180 }
0181
0182 // Then add the rest of the vertices.
0183 for ( typename GenVertexMap::iterator it = vmap.begin();
0184 it != vmap.end(); ++it )
0185 Traits::addVertex(*geneve, it->second);
0186
0187 // and the incoming beam particles
0188 Traits::setBeamParticles(*geneve,pmap[ev.incoming().first],
0189 pmap[ev.incoming().second]);
0190
0191 // and the PDF info
0192 setPdfInfo(ev);
0193
0194 // and the cross section info
0195 Traits::setCrossSection(*geneve,
0196 eh->integratedXSec()/picobarn,
0197 eh->integratedXSecErr()/picobarn);
0198 for ( int i = 0, N = all.size(); i < N; ++i ) {
0199 tcPPtr p = all[i];
0200 if ( pmap.find(p) == pmap.end() ) continue;
0201 GenParticlePtrT gp = pmap[p];
0202 if ( p->hasColourInfo() ) {
0203 // Check if the particle is connected to colour lines, in which
0204 // case the lines are mapped to an integer and set in the
0205 // GenParticle's Flow info.
0206 tcColinePtr l;
0207 if ( (l = p->colourLine()) ) {
0208 if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
0209 Traits::setColourLine(*gp, 1, flowmap[l]);
0210 }
0211 if ( (l = p->antiColourLine()) ) {
0212 if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
0213 Traits::setColourLine(*gp, 2, flowmap[l]);
0214 }
0215 }
0216 if ( p->spinInfo() && p->spinInfo()->hasPolarization() ) {
0217 DPair pol = p->spinInfo()->polarization();
0218 Traits::setPolarization(*gp, pol.first, pol.second);
0219 }
0220 }
0221 }
0222
0223 template <typename HepMCEventT, typename Traits>
0224 typename HepMCConverter<HepMCEventT,Traits>::GenParticlePtrT
0225 HepMCConverter<HepMCEventT,Traits>::createParticle(tcPPtr p) const {
0226 int status = 1;
0227 size_t nChildren = p->children().size();
0228 if ( nChildren > 0 || p->next() ) status = 11;
0229 if ( nChildren > 1 ) {
0230 long id = p->data().id();
0231 if ( BaryonMatcher::Check(id) || MesonMatcher::Check(id) ||
0232 id == ParticleID::muminus || id == ParticleID::muplus ||
0233 id == ParticleID::tauminus || id == ParticleID::tauplus ) {
0234 bool child = false;
0235 for(unsigned int ix=0;ix<nChildren;++ix) {
0236 if(p->children()[ix]->id()==id) {
0237 child = true;
0238 break;
0239 }
0240 }
0241 if ( !child ) {
0242 if(p->data().widthCut()!=ZERO) {
0243 if(p->mass() <= p->data().massMax() &&
0244 p->mass() >= p->data().massMin() )
0245 status = 2;
0246 }
0247 else {
0248 status = 2;
0249 }
0250 }
0251 }
0252 }
0253 GenParticlePtrT gp =
0254 Traits::newParticle(p->momentum(), p->id(), p->status() ? p->status() : status, energyUnit);
0255
0256 if ( p->spinInfo() && p->spinInfo()->hasPolarization() ) {
0257 DPair pol = p->spinInfo()->polarization();
0258 Traits::setPolarization(*gp, pol.first, pol.second);
0259 }
0260
0261 return gp;
0262
0263 }
0264
0265 template <typename HepMCEventT, typename Traits>
0266 void HepMCConverter<HepMCEventT,Traits>::join(tcPPtr parent, tcPPtr child) {
0267 Vertex * dec = decv[parent];
0268 Vertex * pro = prov[child];
0269 if ( !pro || !dec ) Throw<HepMCConverterException>()
0270 << "Found a reference to a ThePEG::Particle which was not in the Event."
0271 << Exception::eventerror;
0272 if ( pro == dec ) return;
0273 while ( !pro->in.empty() ) {
0274 dec->in.insert(*(pro->in.begin()));
0275 decv[*(pro->in.begin())] = dec;
0276 pro->in.erase(pro->in.begin());
0277 }
0278 while ( !pro->out.empty() ) {
0279 dec->out.insert(*(pro->out.begin()));
0280 prov[*(pro->out.begin())] = dec;
0281 pro->out.erase(pro->out.begin());
0282 }
0283 }
0284
0285 template <typename HepMCEventT, typename Traits>
0286 typename HepMCConverter<HepMCEventT,Traits>::GenVertexPtrT
0287 HepMCConverter<HepMCEventT,Traits>::createVertex(Vertex * v) {
0288 if ( !v ) Throw<HepMCConverterException>()
0289 << "Found internal null Vertex." << Exception::abortnow;
0290
0291 GenVertexPtrT gv = Traits::newVertex();
0292
0293 // We assume that the vertex position is the average of the decay
0294 // vertices of all incoming and the creation vertices of all
0295 // outgoing particles in the lab. Note that this will probably not
0296 // be useful information for very small distances.
0297 LorentzPoint p;
0298 for ( tcParticleSet::iterator it = v->in.begin();
0299 it != v->in.end(); ++it ) {
0300 p += (**it).labDecayVertex();
0301 Traits::addIncoming(*gv, pmap[*it]);
0302 }
0303 for ( tcParticleSet::iterator it = v->out.begin();
0304 it != v->out.end(); ++it ) {
0305 p += (**it).labVertex();
0306 Traits::addOutgoing(*gv, pmap[*it]);
0307 }
0308
0309 p /= double(v->in.size() + v->out.size());
0310 Traits::setPosition(*gv, p, lengthUnit);
0311
0312 return gv;
0313 }
0314
0315 template <typename HepMCEventT, typename Traits>
0316 void HepMCConverter<HepMCEventT,Traits>::setPdfInfo(const Event & e) {
0317 // ids of the partons going into the primary sub process
0318 tSubProPtr sub = e.primarySubProcess();
0319 int id1 = sub->incoming().first ->id();
0320 int id2 = sub->incoming().second->id();
0321 // get the event handler
0322 tcEHPtr eh = dynamic_ptr_cast<tcEHPtr>(e.handler());
0323 // get the values of x
0324 double x1 = eh->lastX1();
0325 double x2 = eh->lastX2();
0326 // get the pdfs
0327 pair<PDF,PDF> pdfs;
0328 pdfs.first = eh->pdf<PDF>(sub->incoming().first );
0329 pdfs.second = eh->pdf<PDF>(sub->incoming().second);
0330 // get the scale
0331 Energy2 scale = eh->lastScale();
0332 // get the values of the pdfs
0333 double xf1 = pdfs.first.xfx(sub->incoming().first->dataPtr(), scale, x1);
0334 double xf2 = pdfs.second.xfx(sub->incoming().second->dataPtr(), scale, x2);
0335
0336 Traits::setPdfInfo(*geneve, id1, id2, x1, x2, sqrt(scale/GeV2), xf1, xf2);
0337
0338 }
0339
0340
0341
0342 }
0343
0344