Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881709
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
59 KB
Subscribers
None
View Options
diff --git a/EventRecord/Particle.cc b/EventRecord/Particle.cc
--- a/EventRecord/Particle.cc
+++ b/EventRecord/Particle.cc
@@ -1,524 +1,525 @@
// -*- C++ -*-
//
// Particle.cc is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2017 Leif Lonnblad
//
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined member functions of
// the Particle class.
//
#include "Particle.h"
#include "ThePEG/EventRecord/Step.h"
#include "ThePEG/EventRecord/Event.h"
#include "ThePEG/EventRecord/ColourLine.h"
#include "ThePEG/Utilities/Rebinder.h"
#include "ThePEG/Config/algorithm.h"
#include "ThePEG/EventRecord/ParticleTraits.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include <iostream>
#include <iomanip>
#include <cctype>
#ifdef ThePEG_TEMPLATES_IN_CC_FILE
#include "Particle.tcc"
#endif
using namespace ThePEG;
Particle::ParticleRep::ParticleRep(const ParticleRep & p)
: theParents(p.theParents), theChildren(p.theChildren),
thePrevious(p.thePrevious), theNext(p.theNext),
theBirthStep(p.theBirthStep), theVertex(p.theVertex),
theLifeLength(p.theLifeLength), theScale(p.theScale),
theVetoScale(p.theVetoScale), theNumber(p.theNumber),
theExtraInfo(p.theExtraInfo.size()) {
if ( p.theColourInfo )
theColourInfo = dynamic_ptr_cast<CBPtr>(p.theColourInfo->clone());
if ( p.theSpinInfo )
theSpinInfo = dynamic_ptr_cast<SpinPtr>(p.theSpinInfo->clone());
for ( int i = 0, N = p.theExtraInfo.size(); i < N; ++i )
theExtraInfo[i] = p.theExtraInfo[i]->clone();
}
Particle::Particle(const Particle & p)
- : Base(p), theData(p.theData), theMomentum(p.theMomentum), theRep(p.theRep) {
+ : Base(p), theData(p.theData), theMomentum(p.theMomentum),
+ theRep(p.theRep), theStatus(p.theStatus) {
if ( p.theRep ) {
theRep = new ParticleRep(*p.theRep);
theRep->theParents.clear();
}
}
Particle::~Particle() {
if ( theRep ) {
if ( colourLine() ) colourLine()->removeColoured(this);
if ( antiColourLine() ) antiColourLine()->removeAntiColoured(this);
delete theRep;
}
theRep = 0;
theData = cEventPDPtr();
}
void Particle::initFull() {
if ( theRep ) return;
theRep = new ParticleRep;
Energy width = data().generateWidth(mass());
if ( width > ZERO ) {
Time lifetime = data().generateLifeTime(mass(), width);
theRep->theLifeLength.setTau(lifetime);
theRep->theLifeLength.
setVect((momentum().vect()*(lifetime /
max(mass(), Constants::epsilon*GeV))));
theRep->theLifeLength.rescaleEnergy();
}
}
PPtr Particle::clone() const {
return ptr_new<PPtr>(*this);
}
void Particle::rebind(const EventTranslationMap & trans) {
for ( ParticleVector::iterator pit = rep().theChildren.begin();
pit != rep().theChildren.end(); ++pit ) *pit = trans.translate(*pit);
for ( tParticleVector::iterator pit = rep().theParents.begin();
pit != rep().theParents.end(); ++pit ) *pit = trans.translate(*pit);
rep().thePrevious = trans.translate(rep().thePrevious);
rep().theNext = trans.translate(rep().theNext);
if ( hasColourInfo() ) colourInfo()->rebind(trans);
if ( spinInfo() ) spinInfo()->rebind(trans);
rep().theBirthStep = trans.translate(rep().theBirthStep);
for ( EIVector::const_iterator ie = rep().theExtraInfo.begin();
ie != rep().theExtraInfo.end(); ++ie ) (**ie).rebind(trans);
}
tParticleSet Particle::siblings() const {
tParticleSet theSiblings;
for ( tParticleVector::const_iterator pit = parents().begin();
pit != parents().end(); ++pit )
theSiblings.insert((*pit)->children().begin(), (*pit)->children().end());
theSiblings.erase(const_cast<Particle *>(this));
return theSiblings;
}
void Particle::colourNeighbour(tPPtr p, bool anti) {
tColinePtr line = colourLine(!anti);
if ( !line ) line = ColourLine::create(this, !anti);
line->addColoured(p, anti);
}
void Particle::outgoingColour(tPPtr p, bool anti) {
tColinePtr line = colourLine(anti);
if ( !line ) line = ColourLine::create(this, anti);
line->addColoured(p, anti);
}
tPPtr Particle::incomingColour(bool anti) const {
if ( !hasColourInfo() ) return tPPtr();
tColinePtr line = colourLine(anti);
if ( !line ) return tPPtr();
for ( int i = 0, N = parents().size(); i < N; ++i )
if ( parents()[i]->hasColourLine(line, anti) ) return parents()[i];
return tPPtr();
}
tPPtr Particle::outgoingColour(bool anti) const {
if ( !hasColourInfo() ) return tPPtr();
tColinePtr line = colourLine(anti);
if ( !line ) return tPPtr();
for ( int i = 0, N = children().size(); i < N; ++i )
if ( children()[i]->hasColourLine(line, anti) ) return children()[i];
return tPPtr();
}
LorentzPoint Particle::labVertex() const {
LorentzPoint r(rep().theBirthStep && rep().theBirthStep->collision()?
vertex() + rep().theBirthStep->collision()->vertex():
vertex());
return r;
}
void Particle::setLabVertex(const LorentzPoint & p) {
rep().theVertex = ( rep().theBirthStep && rep().theBirthStep->collision()?
p - rep().theBirthStep->collision()->vertex() : p );
}
void Particle::transform(const LorentzRotation & r) {
if ( hasRep() && spinInfo() ) spinInfo()->transform(momentum(), r);
theMomentum.transform(r);
if ( !hasRep() ) return;
rep().theVertex.transform(r);
rep().theLifeLength.transform(r);
}
void Particle::deepTransform(const LorentzRotation & r) {
transform(r);
if ( !theRep ) return;
for ( int i = 0, N = children().size(); i < N; ++i )
rep().theChildren[i]->deepTransform(r);
if ( rep().theNext ) rep().theNext->deepTransform(r);
}
void Particle::rotateX(double a) {
LorentzRotation r;
r.rotateX(a);
transform(r);
}
void Particle::deepRotateX(double a) {
LorentzRotation r;
r.rotateX(a);
deepTransform(r);
}
void Particle::rotateY(double a) {
LorentzRotation r;
r.rotateY(a);
transform(r);
}
void Particle::deepRotateY(double a) {
LorentzRotation r;
r.rotateY(a);
deepTransform(r);
}
void Particle::rotateZ(double a) {
LorentzRotation r;
r.rotateZ(a);
transform(r);
}
void Particle::deepRotateZ(double a) {
LorentzRotation r;
r.rotateZ(a);
deepTransform(r);
}
void Particle::rotate(double a, const Axis & axis) {
LorentzRotation r;
r.rotate(a, axis);
transform(r);
}
void Particle::deepRotate(double a, const Axis & axis) {
LorentzRotation r;
r.rotate(a, axis);
deepTransform(r);
}
string Particle::outputFormat =
"%n3%s10 %i7 %p[,]0 %c(,) %^^0%vv0 %>>0%<>0 %l{,}0\n"
" %x10.3%y10.3%z10.3%e10.3%m10.3\n";
int getNumber(string::const_iterator & pos, int def) {
if ( !isdigit(*pos) ) return def;
def = *pos++ - '0';
while ( isdigit(*pos) ) def = 10*def + *pos++ - '0';
return def;
}
void writePrecision(ostream & os, string::const_iterator & pos,
int defw, int defp, double x) {
defw = getNumber(pos, defw);
if ( *pos == '.' ) defp = getNumber(++pos, defp);
int oldp = os.precision();
os << setprecision(defp) << setw(defw) << x << setprecision(oldp);
}
void writeStringAdjusted(ostream & os, bool left, int w, string str) {
while ( !left && w-- > int(str.size()) ) os << ' ';
os << str;
while ( left && w-- > int(str.size()) ) os << ' ';
}
template <typename Container>
void writeParticleRanges(ostream & os, const Container & co, char sep, int w) {
set<int> cnum;
for ( typename Container::const_iterator it = co.begin();
it != co.end(); ++it) cnum.insert((**it).number());
bool elipsis = false;
int last = -10;
for ( set<int>::iterator it = cnum.begin(); it != cnum.end(); ++it) {
int n = *it;
int next = 0;
set<int>::iterator itn = it;
if ( ++itn != cnum.end() ) next = *itn;
bool writeit = true;
bool writesep = false;
if ( elipsis && ( n != last + 1 || n != next - 1 ) )
elipsis = false;
else if ( !elipsis && n == last + 1 && n == next -1 ) {
os << "..";
elipsis = true;
writeit = false;
}
else if ( elipsis && n == last + 1 && n == next -1 )
writeit = false;
else if ( it != cnum.begin() )
writesep = true;
if ( writeit ) {
if ( writesep ) os << sep;
os << setw(w) << n;
}
last = n;
}
}
ostream & ThePEG::operator<<(ostream & os, const Particle & p) {
return p.print(os, p.birthStep());
}
ostream & Particle::print(ostream & os, tcStepPtr step) const {
if ( !step ) step = birthStep();
tCollPtr coll = step? step->collision(): tCollPtr();
tEventPtr event = coll? coll->event(): tEventPtr();
string::const_iterator pos = Particle::outputFormat.begin();
ios::fmtflags saveflags = os.setf(ios::fixed, ios::floatfield);
while ( pos != Particle::outputFormat.end() ) {
if ( *pos == '%' && ++pos != Particle::outputFormat.end() ) {
bool left = false;
if ( *pos == '-' ) {
left = true;
os.setf(ios::left, ios::adjustfield);
++pos;
} else {
os.setf(ios::right, ios::adjustfield);
}
char mark;
char open;
char close;
char sep;
int w;
string str;
string fill;
if ( pos == Particle::outputFormat.end() ) break;
bool fullColour = false;
switch ( *pos ) {
case 'n':
os << setw(getNumber(++pos, 3)) << number();
break;
case 'i':
os << setw(getNumber(++pos, 8)) << id();
break;
case 's':
writeStringAdjusted(os, left, getNumber(++pos, 8), PDGName());
break;
case 'x':
writePrecision(os, ++pos, 10, 3, momentum().x()/GeV);
break;
case 'y':
writePrecision(os, ++pos, 10, 3, momentum().y()/GeV);
break;
case 'z':
writePrecision(os, ++pos, 10, 3, momentum().z()/GeV);
break;
case 'e':
writePrecision(os, ++pos, 10, 3, momentum().e()/GeV);
break;
case 'm':
writePrecision(os, ++pos, 10, 3, momentum().mass()/GeV);
break;
case 'P':
fullColour = true;
[[fallthrough]];
case 'p':
open = *++pos;
sep = *++pos;
close = *++pos;
w = getNumber(++pos, 0);
if ( parents().empty() ) break;
if ( open ) os << open;
writeParticleRanges(os, parents(), sep, w);
if ( fullColour && hasColourInfo() &&
( incomingColour() || incomingAntiColour() ) ) {
if ( close ) os << open;
if ( incomingColour() )
os << "+" << incomingColour()->number();
if ( incomingAntiColour() )
os << "-" << incomingAntiColour()->number();
if ( close ) os << close;
}
if ( close ) os << close;
break;
case 'l':
open = *++pos;
sep = *++pos;
close = *++pos;
w = getNumber(++pos, 0);
if ( hasColourInfo() &&
( colourLine() || antiColourLine() ) && event) {
if ( open ) os << open;
vector<tcColinePtr> clines = colourInfo()->colourLines();
for ( int i = 0, N = clines.size(); i < N; ++i ) {
if ( i > 0 && sep ) os << sep;
clines[i]->write(os, event, false);
}
vector<tcColinePtr> aclines = colourInfo()->antiColourLines();
for ( int i = 0, N = aclines.size(); i < N; ++i ) {
if ( ( i > 0 || clines.size() ) && sep ) os << sep;
aclines[i]->write(os, event, true);
}
if ( close ) os << close;
}
break;
case 'C':
fullColour = true;
[[fallthrough]];
case 'c':
open = *++pos;
sep = *++pos;
close = *++pos;
w = getNumber(++pos, 0);
if ( children().empty() ) break;
if ( open ) os << open;
writeParticleRanges(os, children(), sep, w);
if ( fullColour && hasColourInfo() &&
( outgoingColour() || outgoingAntiColour() ) ) {
if ( close ) os << open;
if ( outgoingColour() )
os << "+" << outgoingColour()->number();
if ( outgoingAntiColour() )
os << "-" << outgoingAntiColour()->number();
if ( close ) os << close;
}
if ( close ) os << close;
break;
case '>':
mark = *++pos;
w = getNumber(++pos, 0);
if ( hasColourInfo() && step && step->colourNeighbour(this) ) {
os << setw(w-1) << step->colourNeighbour(this)->number() << mark;
}
break;
case '<':
mark = *++pos;
w = getNumber(++pos, 0);
if ( hasColourInfo() && step && step->antiColourNeighbour(this) ) {
int n = step->antiColourNeighbour(this)->number();
ostringstream oss;
oss << mark << n;
writeStringAdjusted(os, left, w, oss.str());
}
break;
case 'v':
mark = *++pos;
w = getNumber(++pos, 0);
if ( next() ) {
if ( left && mark ) os << mark;
os << setw(w) << next()->number();
if ( !left && mark ) os << mark;
}
break;
case '^':
mark = *++pos;
w = getNumber(++pos, 0);
if ( previous() ) {
if ( left && mark ) os << mark;
os << setw(w) << previous()->number();
if ( !left && mark ) os << mark;
}
break;
case 'd':
switch ( *++pos ) {
case 'x':
writePrecision(os, ++pos, 10, 3, lifeLength().x()/mm);
break;
case 'y':
writePrecision(os, ++pos, 10, 3, lifeLength().y()/mm);
break;
case 'z':
writePrecision(os, ++pos, 10, 3, lifeLength().z()/mm);
break;
case 't':
writePrecision(os, ++pos, 10, 3, lifeLength().e()/mm);
break;
case 'T':
writePrecision(os, ++pos, 10, 3, lifeLength().tau()/mm);
break;
}
break;
case 'V':
switch ( *++pos ) {
case 'x':
writePrecision(os, ++pos, 10, 3, vertex().x()/mm);
break;
case 'y':
writePrecision(os, ++pos, 10, 3, vertex().y()/mm);
break;
case 'z':
writePrecision(os, ++pos, 10, 3, vertex().z()/mm);
break;
case 't':
writePrecision(os, ++pos, 10, 3, vertex().e()/mm);
break;
}
break;
case 'L':
switch ( *++pos ) {
case 'x':
writePrecision(os, ++pos, 10, 3, labVertex().x()/mm);
break;
case 'y':
writePrecision(os, ++pos, 10, 3, labVertex().y()/mm);
break;
case 'z':
writePrecision(os, ++pos, 10, 3, labVertex().z()/mm);
break;
case 't':
writePrecision(os, ++pos, 10, 3, labVertex().e()/mm);
break;
}
break;
default:
os << *pos++;
}
} else {
if ( pos != Particle::outputFormat.end() ) os << *pos++;
}
}
os.flags(saveflags);
return os;
}
void Particle::debugme() const {
cerr << *this;
EventRecordBase::debugme();
}
void Particle::persistentOutput(PersistentOStream & os) const {
EventConfig::putParticleData(os, theData);
- os << ounit(theMomentum, GeV) << bool( theRep != 0 );
+ os << ounit(theMomentum, GeV) << theStatus << bool( theRep != 0 );
if ( !theRep ) return;
os << rep().theParents << rep().theChildren
<< rep().thePrevious << rep().theNext << rep().theBirthStep
<< ounit(rep().theVertex, mm) << ounit(rep().theLifeLength, mm)
<< ounit(rep().theScale, GeV2) << ounit(rep().theVetoScale, GeV2)
<< rep().theNumber << rep().theDecayMode
<< rep().theColourInfo << rep().theSpinInfo << rep().theExtraInfo;
}
void Particle::persistentInput(PersistentIStream & is, int) {
bool readRep;
EventConfig::getParticleData(is, theData);
- is >> iunit(theMomentum, GeV) >> readRep;
+ is >> iunit(theMomentum, GeV) >> theStatus >> readRep;
if ( !readRep ) return;
if ( !hasRep() ) theRep = new ParticleRep;
is >> rep().theParents >> rep().theChildren
>> rep().thePrevious >> rep().theNext >> rep().theBirthStep
>> iunit(rep().theVertex, mm) >> iunit(rep().theLifeLength, mm)
>> iunit(rep().theScale, GeV2) >> iunit(rep().theVetoScale, GeV2)
>> rep().theNumber >> rep().theDecayMode
>> rep().theColourInfo >> rep().theSpinInfo >> rep().theExtraInfo;
}
ClassDescription<Particle> Particle::initParticle;
void Particle::Init() {}
diff --git a/EventRecord/Particle.h b/EventRecord/Particle.h
--- a/EventRecord/Particle.h
+++ b/EventRecord/Particle.h
@@ -1,1180 +1,1195 @@
// -*- C++ -*-
//
// Particle.h is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2017 Leif Lonnblad
//
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef ThePEG_Particle_H
#define ThePEG_Particle_H
// This is the decalaration of the Particle class.
#include "EventConfig.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "ThePEG/Vectors/LorentzRotation.h"
#include "ThePEG/Utilities/ClassDescription.h"
#include "ThePEG/EventRecord/MultiColour.h"
#include "ThePEG/EventRecord/SpinInfo.h"
#include "ThePEG/PDT/ParticleData.h"
namespace ThePEG {
/**
* The Particle class is used to describe an instance of a
* particle. Properties of the corresponding particle type can be
* accessed through a pointer to a ParticleData object.
*
* A Particle object contains pointers to other particles, such as a
* list of parents and a list of children. It may also contain a
* pointer to the previous or next instance of the same physical
* particle if the properties of a given particle has been changed
* during the generation. Coloured particles contains pointers to
* ColourLine defining the colour connections to other particles.
*
* The Particle also has a pointer to the Step object where it was
* first introduced in the Event.
*
* When printing a particle the format of the output is governed by
* the static <code>outputFormat</code> string. When a particle is sent
* to an <code>ostream</code>, the format string is written but with
* keys prefixed by the <code>\%</code> character replaced with
* infromation about the particle as follows:<BR> <code>\%\%</code> is
* replaced by a singel <code>\%</code><BR> <code>\%C</code> sets a flag so
* that subsequent output of children and parents etc. will contain
* colour information.<BR> <code>\%n</code> is replaced by the particles
* number in a fied ow width<BR> <code>\%s</code> is replaced by the name
* of the particle<BR> <code>\%i</code> is replaced by the id number of
* the particle type<BR><code>\%x, \%y, \%z, \%e, \%m</code> is replaced by
* the x-, y-, z-, energy- and mass-component of the particles
* momentum respectively<BR><code>\%dx, \%dy, \%dz, \%dt, \%dT</code> is
* replaced by the x-, y-, z-, time- and invariant time-component of
* the particles lifeLength respectively<BR><code>\%Vx, \%Vy, \%Vz,
* \%Vt</code> is replaced by the x-, y-, z- and time-component of the
* creation point relative to the vertex of the
* collision.<BR><code>\%Lx, \%Ly, \%Lz, \%Lt</code> is replaced by the x-,
* y-, z- and time-component of the creation point in the current
* lab-system.<BR> <code>\%p[,]</code> is replaced by a list (of numbers)
* of the particles parents enclosed by <code>[</code> and <code>]</code>
* and separated by <code>,</code>, The parent from which the particle
* inherits its (anti-) colour is marked by a (-)+<BR>
* <code>\%c(,)</code> is replaced by a list (of numbers) of the
* particles children enclosed by <code>(</code> and <code>)</code> and
* separated by <code>,</code>, The child which inherits the particles
* (anti-) colour is marked by a (-)+<BR> <code>\%></code> is replaced
* by the number of the colour neighbor<BR> <code>\%<</code> is
* replaced by the number of the anti-colour neighbor<BR>
* <code>\%^</code> is replaced by the number of the previous instance of
* the same physical particle<BR> <code>\%v</code> is replaced by the
* number of the next instance of the same physical particle.<BR>
* <code>\%l{,}</code> is replaced by the indices of the colour lines to
* which this particle is connected enclosed by <code>{</code> and
* <code>}</code> and separated by <code>,</code>, The line corresponding
* to the (anti-) colour of the particle is prefixed by a (-)+
*
* @see Event
* @see Collision
* @see Step
* @see SubProcess
* @see Lorentz5Vector
* @see ColourLine
* @see ColourBase
*/
class Particle: public EventRecordBase {
public:
/** Most of the Event classes are friends with each other. */
friend class Event;
/** Most of the Event classes are friends with each other. */
friend class Collision;
/** Most of the Event classes are friends with each other. */
friend class Step;
/** Most of the Event classes are friends with each other. */
friend class SubProcess;
/** ParticleData needs to be a friend. */
friend class ParticleData;
struct ParticleRep;
public:
/**
* Standard Constructor. Note that the default constructor is
* private - there is no particle without a pointer to a
* ParticleData object.
*/
- Particle(tcEventPDPtr newData) : theData(newData), theRep(0) {}
+ Particle(tcEventPDPtr newData) : theData(newData), theRep(0), theStatus(0) {}
/**
* Copy constructor.
*/
Particle(const Particle &);
/**
* Destructor.
*/
virtual ~Particle();
//@}
/** @name Functions relating to ancestry of particles. */
//@{
/**
* Returns true if and only if this particle has decayed.
*/
bool decayed() const {
return hasRep() && !rep().theChildren.empty();
}
/**
* The list of decay products.
*/
const ParticleVector & children() const {
static const ParticleVector null;
return hasRep() ? rep().theChildren : null;
}
/**
* Add a child (the childs parent pointer will be set accordingly).
*/
void addChild(tPPtr c) {
rep().theChildren.push_back(c);
(c->rep()).theParents.push_back(this);
}
/**
* Remove the given child from the list of children of this particle
* (the corresponding parent pointer of the child will also be
* removed).
*/
void abandonChild(tPPtr child) {
removeChild(child);
child->removeParent(this);
}
/**
* The list of parent particles.
*/
const tParticleVector & parents() const {
static const tParticleVector null;
return hasRep() ? rep().theParents : null;
}
/**
* Return a set of neighboring particles coming from the same decay
* as this one. The return value is a newly recalculated set
* every time. It must be stored to be used further, do not directly call
* e.g. siblings().begin() or siblings().end()!
*/
tParticleSet siblings() const;
/**
* Undo the decay of this particle, removing all children (and
* grand children ...) from the event record
*/
void undecay() {
if ( hasRep() ) {
rep().theChildren.clear();
rep().theNext = tPPtr();
}
}
/**
* If this particle has decayed set the corresponding decay mode.
*/
void decayMode(tDMPtr dm) { rep().theDecayMode = dm; }
/**
* If this particle has decayed get the corresponding decay mode.
*/
tDMPtr decayMode() const {
return hasRep() ? rep().theDecayMode : tDMPtr();
}
/**
* Next instance. Pointer to another instance of the same
* physical particle in later steps.
*/
tPPtr next() const {
return hasRep() ? rep().theNext : PPtr();
}
/**
* Previous instance. Pointer to another instance of the same
* physical particle in earlier steps.
*/
tPPtr previous() const {
return hasRep() ? rep().thePrevious : tPPtr();
}
/**
* Original instance. If there exists another previous instance of
* this particle return this instance (recursively).
*/
tcPPtr original() const {
return previous() ? tcPPtr(previous()->original()) : tcPPtr(this);
}
/**
* Original instance. If there exists another previous instance of
* this particle return this instance (recursively).
*/
tPPtr original() {
return previous() ? previous()->original() : tPPtr(this);
}
/**
* Final instance. If there exists another subsequent instance of
* this particle return this instance (recursively).
*/
tcPPtr final() const {
return next() ? tcPPtr(next()->final()) : tcPPtr(this);
}
/**
* Final instance. If there exists another subsequent instance of
* this particle return this instance (recursively).
*/
tPPtr final() {
return next() ? next()->final() : tPPtr(this);
}
//@}
/** @name Relations to the Event and Step. */
//@{
/**
* Get the first Step object where this particle occurred.
*/
tStepPtr birthStep() const {
return hasRep() ? rep().theBirthStep : tStepPtr();
}
/**
* Get the order-number for this particle in the current event.
*/
int number() const {
return hasRep() ? rep().theNumber : 0;
}
+
+ /**
+ * Get the status code of the particle
+ */
+ int status() const { return theStatus; }
+
+ /**
+ * Set the status code of the particle
+ */
+ void status(int n) { theStatus = n; }
//@}
/** @name Access the underlying ParticleData object. */
//@{
/**
* Access the ParticleData object of this particle type
*/
const ParticleDataClass & data() const { return *theData; }
/**
* Access the ParticleData object of this particle type
*/
tcEventPDPtr dataPtr() const { return theData; }
/**
* Return the PDG name of this particle.
*/
const string & PDGName() const { return data().PDGName(); }
/**
* Return the PDG id number of this particle.
*/
long id() const { return data().id(); }
//@}
/** @name Functions to access the momentum. */
//@{
/**
* Return the momentum of this particle.
*/
const Lorentz5Momentum & momentum() const { return theMomentum; }
/**
* Set the 3-momentum of this particle. The energy is set to be
* consistent with the mass.
*/
void set3Momentum(const Momentum3 & p) {
theMomentum.setVect(p);
theMomentum.rescaleEnergy();
}
/**
* Set the momentum of this particle. Afterwards, the underlying
* Lorentz5Momentum may have inconsistent mass.
*/
void setMomentum(const LorentzMomentum & p) {
theMomentum = p;
}
/**
* Set the momentum and mass.
*/
void set5Momentum(const Lorentz5Momentum & p) {
theMomentum = p;
}
/**
* Acces the mass of this particle.
*/
Energy mass() const { return momentum().mass(); }
/**
* Acces the mass of this particle type.
*/
Energy nominalMass() const { return data().mass(); }
/**
* Get the scale at which this particle is considered resolved.
*/
Energy2 scale() const {
return hasRep() ? rep().theScale : -1.0*GeV2;
}
/**
* Set the scale at which this particle is considered resolved.
*/
void scale(Energy2 q2) { rep().theScale = q2; }
/**
* Get the scale above which this particle should
* not radiate.
*/
Energy2 vetoScale() const {
return hasRep() ? rep().theVetoScale : -1.0*GeV2;
}
/**
* Set the scale above which this particle should
* not radiate.
*/
void vetoScale(Energy2 q2) { rep().theVetoScale = q2; }
/**
* Return the transverse mass (squared), calculated from the energy
* and the longitudinal momentum.
*/
Energy2 mt2() const { return sqr(momentum().t()) - sqr(momentum().z()); }
/**
* Return the transverse mass (squared), calculated from the energy
* and the longitudinal momentum.
*/
Energy mt() const { return sqrt(mt2()); }
/**
* Return the transverse mass (squared), calculated from the mass
* and the transverse momentum.
*/
Energy2 perpmass2() const { return momentum().perp2() + momentum().mass2(); }
/**
* Return the transverse mass (squared), calculated from the mass
* and the transverse momentum.
*/
Energy perpmass() const { return sqrt(perpmass2()); }
/**
* Return the (pseudo) rapidity.
*/
double rapidity() const {
return ( Pplus() > ZERO && Pminus() > ZERO )?
0.5*log(Pplus()/Pminus()) : Constants::MaxFloat;
}
/**
* Return the (pseudo) rapidity.
*/
double eta() const {
Energy rho = momentum().rho();
return rho > abs(momentum().z())?
0.5*log((rho+momentum().z())/(rho-momentum().z())) : Constants::MaxFloat;
}
/**
* Return the positive and negative light-cone momenta.
*/
Energy Pplus() const { return momentum().plus(); }
/**
* Return the positive and negative light-cone momenta.
*/
Energy Pminus() const { return momentum().minus(); }
//@}
/** @name Functions to access the position. */
//@{
/**
* The creation vertex of this particle. The point is given
* relative to the collision vertex.
*/
const LorentzPoint & vertex() const {
static const LorentzPoint null;
return hasRep() ? rep().theVertex : null;
}
/**
* The creation vertex of this particle. The absolute
* position in the lab is given.
*/
LorentzPoint labVertex() const;
/**
* The decay vertex of this particle. The point is given
* relative to the collision vertex.
*/
LorentzPoint decayVertex() const {
return vertex() + lifeLength();
}
/**
* The decay vertex of this particle. The absolute
* position in the lab is given.
*/
LorentzPoint labDecayVertex() const {
return labVertex() + lifeLength();
}
/**
* The life time/length. Return the Lorentz vector connecting the
* creation to the decay vertes.
*/
const Lorentz5Distance & lifeLength() const {
static const Lorentz5Distance null;
return hasRep() ? rep().theLifeLength : null;
}
/**
* Set the creation vertex relative to the collision vertex.
*/
void setVertex(const LorentzPoint & p) {
rep().theVertex = p;
}
/**
* Set the creation vertex in the lab frame of this particle.
*/
void setLabVertex(const LorentzPoint &);
/**
* Set the life length of this particle. The life time will be
* automatically rescaled to be consistent with the invariant
* distance.
*/
void setLifeLength(const Distance & d) {
rep().theLifeLength.setVect(d);
rep().theLifeLength.rescaleEnergy();
}
/**
* Set the life time/length of a particle. The invariant distance
* may become inconsistent.
*/
void setLifeLength(const LorentzDistance & d) {
rep().theLifeLength = d;
}
/**
* Set the life time/length of a particle.
*/
void setLifeLength(const Lorentz5Distance & d) {
rep().theLifeLength = d;
}
/**
* The invariant life time of this particle.
*/
Time lifeTime() const { return lifeLength().m(); }
//@}
/** @name Functions for (Lorentz) transformations. */
//@{
/**
* Do Lorentz transformations on this particle.
*/
void transform(const LorentzRotation & r);
/**
* Do Lorentz transformations on this particle. \a bx, \a by and \a
* bz are the boost vector components.
*/
void boost(double bx, double by, double bz) {
transform(LorentzRotation(Boost(bx, by, bz)));
}
/**
* Do Lorentz transformations on this particle. \a b is the boost
* vector.
*/
void boost(const Boost & b) { transform(LorentzRotation(b)); }
/**
* Rotate around the x-axis.
*/
void rotateX(double a);
/**
* Rotate around the y-axis.
*/
void rotateY(double a);
/**
* Rotate around the z-axis.
*/
void rotateZ(double a);
/**
* Rotate around the given \a axis.
*/
void rotate(double a, const Axis & axis);
/**
* Mirror in the xy-plane.
*/
void mirror() { theMomentum.setZ(-theMomentum.z()); }
/**
* Do Lorentz transformations on this particle and its decendants.
*/
void deepTransform(const LorentzRotation & r);
/**
* Do Lorentz transformations on this particle and its
* decendants. \a bx, \a by and \a bz are the boost vector
* components.
*/
void deepBoost(double bx, double by, double bz) {
deepTransform(LorentzRotation(Boost(bx, by, bz)));
}
/**
* Do Lorentz transformations on this particle and its
* decendants. \a b is the boost vector.
*/
void deepBoost(const Boost & b) { deepTransform(LorentzRotation(b)); }
/**
* Rotate this particle and its decendants around the x-axis.
*/
void deepRotateX(double a);
/**
* Rotate this particle and its decendants around the y-axis.
*/
void deepRotateY(double a);
/**
* Rotate this particle and its decendants around the z-axis.
*/
void deepRotateZ(double a);
/**
* Rotate this particle and its decendants around the given \a axis.
*/
void deepRotate(double a, const Axis & axis);
//@}
/** @name Functions controlling possible mass/momentum inconsistencies. */
//@{
/**
* Return the relative inconsistency in the mass component.
*/
double massError() const { return theMomentum.massError(); }
/**
* Return the relative inconsistency in the energy component.
*/
double energyError() const { return theMomentum.energyError(); }
/**
* Return the relative inconsistency in the spatial components.
*/
double rhoError() const { return theMomentum.rhoError(); }
/**
* Rescale energy, so that the invariant length/mass of the
* LorentzVector agrees with the current one.
*/
void rescaleEnergy() { theMomentum.rescaleEnergy(); }
/**
* Rescale spatial component, so that the invariant length/mass of
* the LorentzVector agrees with the current one.
*/
void rescaleRho() { theMomentum.rescaleRho(); }
/**
* Set the invariant length/mass member, so that it agrees with the
* invariant length/mass of the LorentzVector.
*/
void rescaleMass() { theMomentum.rescaleMass(); }
//@}
/** @name Acces incormation about colour connections */
//@{
/**
* True if this particle has colour information. To determine if
* this particle is actually coloured, the coloured(), hasColour() or
* hasAntiColour() methods should be used instead.
*/
bool hasColourInfo() const {
return hasRep() && rep().theColourInfo;
}
/**
* Return the colour lines to which this particles anti-colour is
* connected.
*/
tColinePtr antiColourLine() const {
return hasColourInfo() ? colourInfo()->antiColourLine() : tColinePtr();
}
/**
* Return the colour lines to which this particles (\a anti-)colour
* is connected.
*/
tColinePtr colourLine(bool anti = false) const {
if ( anti ) return antiColourLine();
return hasColourInfo() ? colourInfo()->colourLine() : tColinePtr();
}
/**
* Return true if the particle is connected to the given (\a anti-)
* colour \a line.
*/
bool hasColourLine(tcColinePtr line, bool anti = false) const {
return hasColourInfo() ? colourInfo()->hasColourLine(line, anti) : false;
}
/**
* Return true if the particle is connected to the given anti-colour
* \a line.
*/
bool hasAntiColourLine(tcColinePtr line) const {
return hasColourLine(line, true);
}
/**
* True if this particle type is not a colour singlet.
*/
bool coloured() const { return data().coloured(); }
/**
* True if this particle type carries (\a anti-)colour.
*/
bool hasColour(bool anti = false) const { return data().hasColour(anti); }
/**
* True if this particle type carries anti-colour.
*/
bool hasAntiColour() const { return data().hasAntiColour(); }
/**
* Get the ColourBase object.
*/
tcCBPtr colourInfo() const {
return hasRep() ? rep().theColourInfo : CBPtr();
}
/**
* Get the ColourBase object.
*/
tCBPtr colourInfo() {
if ( !rep().theColourInfo ) {
switch(theData->iColour()) {
case PDT::Colour6:
case PDT::Colour6bar:
rep().theColourInfo = new_ptr(MultiColour());
break;
default:
rep().theColourInfo = new_ptr(ColourBase());
}
}
return rep().theColourInfo;
}
/**
* Set the ColourBase object.
*/
void colourInfo(tCBPtr c) {
rep().theColourInfo = c;
}
/**
* Get a pointer to the colour neighbor. Returns a particle in the
* range \a first to \a last which colour is connected to the same
* line as this particles anti-colour. If \a anti is true return
* antiColourNeighbour().
*/
template <typename Iterator>
typename std::iterator_traits<Iterator>::value_type
colourNeighbour(Iterator first, Iterator last, bool anti = false) const;
/**
* Get a pointer to the anti-colour neighbor. Returns a particle in
* the range \a first to \a last which anti-colour is
* connected to the same line as this particles colour.
*/
template <typename Iterator>
typename std::iterator_traits<Iterator>::value_type
antiColourNeighbour(Iterator first, Iterator last) const {
return colourNeighbour(first, last, true);
}
/**
* Set the colour neighbor. Connects the given particles colour to
* the same colour line as this particles anti-colour. If \a anti is
* true call antiColourNeighbour(tPPtr).
*/
void colourNeighbour(tPPtr, bool anti = false);
/**
* Set the anti-colour neighbor. Connects the given particles
* anti-colour to the same colour line as this particles colour.
*/
void antiColourNeighbour(tPPtr p) { colourNeighbour(p, true); }
/**
* Connect colour. Create a colour line connecting to it this
* particles colour and the given particles anti-colour.
*/
void antiColourConnect(tPPtr neighbour) {
colourConnect(neighbour, true);
}
/**
* Connect colour. Create a colour line connecting to it this
* particles anti-colour and the given particles colour. If \a anti
* is true call antiColourConnect(tPPtr).
*/
void colourConnect(tPPtr neighbour, bool anti = false) {
colourNeighbour(neighbour, anti);
}
/**
* Incoming colour. Return the parent particle which colour is
* connected to the same colour line as this particle. If \a anti is
* true return incomingAntiColour().
*/
tPPtr incomingColour(bool anti = false) const;
/**
* Incoming anti-colour. Return the parent particle which
* anti-colour is connected to the same colour line as this
* particle.
*/
tPPtr incomingAntiColour() const { return incomingColour(true); }
/**
* Set incoming colour. Connect this particles colour to the same
* colour line as the given particle. If \a anti
* is true call incomingAntiColour(tPPtr).
*/
void incomingColour(tPPtr p, bool anti = false) { p->outgoingColour(this, anti); }
/**
* Set incoming anti-colour. Connect this particles anti colour to
* the same colour line as the given particle.
*/
void incomingAntiColour(tPPtr p) { p->outgoingColour(this, true); }
/**
* Outgoing colour. Return the daughter particle which colour is
* connected to the same colour line as this particle. If \a anti is
* true return outgoingAntiColour().
*/
tPPtr outgoingColour(bool anti = false) const;
/**
* Outgoing anti-colour. Return the daughter particle which
* anti-colour is connected to the same colour line as this
* particle.
*/
tPPtr outgoingAntiColour() const { return outgoingColour(true); }
/**
* Set outgoing colour. Connect this particles colour to the same
* colour line as the given particle. If \a anti
* is true call outgoingAntiColour(tPPtr).
*/
void outgoingColour(tPPtr, bool anti = false);
/**
* Set outgoing anti-colour. Connect this particles anti-colour to
* the same colour line as the given particle.
*/
void outgoingAntiColour(tPPtr p) { outgoingColour(p, true); }
/**
* Specify colour flow. Calls outgoingColour(tPPtr,bool).
*/
void colourFlow(tPPtr child, bool anti = false) {
outgoingColour(child, anti);
}
/**
* Specify anticolour flow. Calls outgoingAntiColour(tPPtr,bool).
*/
void antiColourFlow(tPPtr child) { colourFlow(child, true); }
/**
* Remove all colour information;
*/
void resetColour() {
if ( hasColourInfo() ) rep().theColourInfo = CBPtr();
}
//@}
/** @name Functions to access spin. */
//@{
/**
* Return the Spin object.
*/
tcSpinPtr spinInfo() const {
return hasRep() ? rep().theSpinInfo : SpinPtr();
}
/**
* Return the Spin object.
*/
tSpinPtr spinInfo() {
return hasRep() ? rep().theSpinInfo : SpinPtr();
}
/**
* Set the Spin object.
*/
void spinInfo(tSpinPtr s) { rep().theSpinInfo = s; }
//@}
/** @name Accessing user-defined information. */
//@{
/**
* Access user-defined information as a vector of EventInfoBase pointers.
*/
const EIVector & getInfo() const {
static const EIVector null;
return hasRep() ? rep().theExtraInfo : null;
}
/**
* Access user-defined information as a vector of EventInfoBase pointers.
*/
EIVector & getInfo() { return rep().theExtraInfo; }
//@}
public:
/** @name Accessing user-defined information. */
//@{
/**
* True if this particle has instantiated the object with
* information other than type and momentum.
*/
bool hasRep() const { return theRep; }
/**
* If this particle has only a type and momentum, instantiate the
* rest of the information.
*/
void initFull();
//@}
public:
/** @name Input and output functions. */
//@{
/**
* Standard function for writing to a persistent stream.
*/
void persistentOutput(PersistentOStream &) const;
/**
* Standard function for reading from a persistent stream.
*/
void persistentInput(PersistentIStream &, int);
//@}
/**
* Print particle info to a stream \a os. The \a step is used to
* access information about colour neighbors and other struff.
*/
ostream & print(ostream & os, tcStepPtr step = tcStepPtr()) const;
/**
* Print a range of particles.
*/
template <typename Iterator>
static void PrintParticles(ostream & os, Iterator first, Iterator last,
tcStepPtr step = tcStepPtr());
/**
* Print a container of particles.
*/
template <typename Cont>
static inline void PrintParticles(ostream & os, const Cont & c,
tcStepPtr step = tcStepPtr()) {
PrintParticles(os, c.begin(), c.end(), step);
}
/**
* Standard Init function. @see Base::Init().
*/
static void Init();
/**
* Specify how to print particles. The format string is analogous to
* the one used by eg. the unix 'date' command as described above.
*/
static string outputFormat;
private:
/**
* Standard clone function.
*/
virtual PPtr clone() const;
/**
* Rebind to cloned objects. When an Event is cloned, a shallow
* copy is done first, then all <code>Particle</code>s etc, are
* cloned, and finally this method is used to see to that the
* pointers in the cloned Particle points to the cloned objects.
*/
virtual void rebind(const EventTranslationMap &);
/**
* Set the order-number for this particle in the current event.
*/
void number(int n) { rep().theNumber = n; }
/**
* Remove the given particle from the list of children.
*/
void removeChild(tPPtr c) {
if ( hasRep() )
rep().theChildren.erase(remove(rep().theChildren.begin(),
rep().theChildren.end(), c),
rep().theChildren.end());
}
/**
* Remove the given particle from the list of parents.
*/
void removeParent(tPPtr p) {
if ( hasRep() )
rep().theParents.erase(remove(rep().theParents.begin(),
rep().theParents.end(), p),
rep().theParents.end());
}
/**
* Set the mass of this particle.
*/
void mass(Energy m) { theMomentum.setMass(m); }
/**
* Set the invaiant life time of this particle.
*/
void lifeTime(Length t) { rep().theLifeLength.setTau(t); }
/**
* Return a reference to the bulk information of this particle. if
* no ParticleRep object exists, one is created.
*/
ParticleRep & rep() {
if ( !hasRep() ) initFull();
return *theRep;
}
/**
* Return a reference to the bulk information of this particle. if
* no ParticleRep object exists, we return the default values.
*/
const ParticleRep & rep() const {
static const ParticleRep null;
return hasRep() ? *theRep : null;
}
/**
* The pointer to the ParticleData object
*/
cEventPDPtr theData;
/**
* The momentum.
*/
Lorentz5Momentum theMomentum;
/**
* The rest of the information in this particle is only instantiated
* if needed.
*/
ParticleRep * theRep;
+ /**
+ * The status code of the particle
+ */
+ int theStatus;
+
public:
/**
* This class is used internally in the Particle class to represent
* information besides momentum and type. A corresponding object
* will only be instantiated if needed to save memory and time when
* temporarily creating particles.
*/
struct ParticleRep {
/**
* Default constructor.
*/
ParticleRep() : theScale(-1.0*GeV2), theVetoScale(-1.0*GeV2), theNumber(0) {}
/**
* Copy constructor.
*/
ParticleRep(const ParticleRep &);
/**
* The pointers to the parents.
*/
tParticleVector theParents;
/**
* The pointers to the children.
*/
ParticleVector theChildren;
/**
* The pointer to the previous instance.
*/
tPPtr thePrevious;
/**
* The pointer to the next instance.
*/
PPtr theNext;
/**
* If this particle has decayed this is the pointer to the
* corresponding decay mode.
*/
tDMPtr theDecayMode;
/**
* The pointer to the first step where this particle occurred.
*/
tStepPtr theBirthStep;
/**
* The creation point.
*/
LorentzPoint theVertex;
/**
* The life time/length.
*/
Lorentz5Distance theLifeLength;
/**
* the resolution scale.
*/
Energy2 theScale;
/**
* the veto scale.
*/
Energy2 theVetoScale;
/**
* The order-number for this particle in the current event.
*/
int theNumber;
/**
* A pointer to the colour information object.
*/
CBPtr theColourInfo;
/**
* Spin information
*/
SpinPtr theSpinInfo;
/**
* Additional used-defined information.
*/
EIVector theExtraInfo;
};
public:
/**
* Print out debugging information for this object on std::cerr. To
* be called from within a debugger via the debug() function.
*/
virtual void debugme() const;
protected:
/**
* Private default constructor must only be used by the
* PersistentIStream class via the ClassTraits<Particle> class.
*/
- Particle() : theRep(0) {}
+ Particle() : theRep(0), theStatus(0) {}
/**
* The ClassTraits<Particle> class must be a friend to be able to
* use the private default constructor.
*/
friend struct ClassTraits<Particle>;
private:
/**
* Private and non-existent assignment.
*/
Particle & operator=(const Particle &) = delete;
/**
* Describe concrete class with persistent data.
*/
static ClassDescription<Particle> initParticle;
};
/**
* Write a Particle object to a stream.
*/
ostream & operator<<(ostream &, const Particle &);
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base class of Particle. */
template <>
struct BaseClassTrait<Particle,1>: public ClassTraitsType {
/** Typedef of the first base class of Collision. */
typedef EventRecordBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the Particle class and how to create it. */
template <>
struct ClassTraits<Particle>: public ClassTraitsBase<Particle> {
/** Return a platform-independent class name */
static string className() { return "ThePEG::Particle"; }
/** Create a Particle object. */
static TPtr create() { return TPtr::Create(Particle()); }
};
/** @endcond */
}
#ifndef ThePEG_TEMPLATES_IN_CC_FILE
#include "Particle.tcc"
#endif
#endif /* ThePEG_Particle_H */
diff --git a/Vectors/HepMCConverter.tcc b/Vectors/HepMCConverter.tcc
--- a/Vectors/HepMCConverter.tcc
+++ b/Vectors/HepMCConverter.tcc
@@ -1,337 +1,337 @@
// -*- C++ -*-
//
// HepMCConverter.tcc is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2017 Leif Lonnblad
//
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HepMCConverter class.
//
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/EventRecord/StandardSelectors.h"
#include "ThePEG/EventRecord/Collision.h"
#include "ThePEG/EventRecord/Step.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/Handlers/XComb.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "ThePEG/PDF/PDF.h"
#include "ThePEG/PDT/StandardMatchers.h"
#include "ThePEG/Utilities/Throw.h"
namespace ThePEG {
template <typename HepMCEventT, typename Traits>
typename HepMCConverter<HepMCEventT,Traits>::GenEvent *
HepMCConverter<HepMCEventT,Traits>::
convert(const Event & ev, bool nocopies, Energy eunit, Length lunit) {
HepMCConverter<HepMCEventT,Traits> converter(ev, nocopies, eunit, lunit);
return converter.geneve;
}
template <typename HepMCEventT, typename Traits>
void HepMCConverter<HepMCEventT,Traits>::
convert(const Event & ev, GenEvent & gev, bool nocopies) {
HepMCConverter<HepMCEventT,Traits>
converter(ev, gev, nocopies,
Traits::momentumUnit(gev), Traits::lengthUnit(gev));
}
template <typename HepMCEventT, typename Traits>
void HepMCConverter<HepMCEventT,Traits>::
convert(const Event & ev, GenEvent & gev, bool nocopies,
Energy eunit, Length lunit) {
HepMCConverter<HepMCEventT,Traits> converter(ev, gev, nocopies, eunit, lunit);
}
template <typename HepMCEventT, typename Traits>
HepMCConverter<HepMCEventT,Traits>::
HepMCConverter(const Event & ev, bool nocopies, Energy eunit, Length lunit)
: energyUnit(eunit), lengthUnit(lunit) {
geneve = Traits::newEvent(ev.number(), ev.weight(), ev.optionalWeights());
init(ev, nocopies);
}
template <typename HepMCEventT, typename Traits>
HepMCConverter<HepMCEventT,Traits>::
HepMCConverter(const Event & ev, GenEvent & gev, bool nocopies,
Energy eunit, Length lunit)
: energyUnit(eunit), lengthUnit(lunit) {
geneve = &gev;
Traits::resetEvent(geneve, ev.number(), ev.weight(), ev.optionalWeights());
init(ev, nocopies);
}
struct ParticleOrderNumberCmp {
bool operator()(tcPPtr a, tcPPtr b) const {
return a->number() < b->number();
}
};
template <typename HepMCEventT, typename Traits>
void HepMCConverter<HepMCEventT,Traits>::init(const Event & ev, bool nocopies) {
if ( lengthUnit != millimeter && lengthUnit != centimeter )
Throw<HepMCConverterException>()
<< "Length unit used for HepMC::GenEvent was not MM nor CM."
<< Exception::runerror;
if ( energyUnit != GeV && energyUnit != MeV )
Throw<HepMCConverterException>()
<< "Momentum unit used for HepMC::GenEvent was not GEV nor MEV."
<< Exception::runerror;
Traits::setUnits(*geneve, energyUnit, lengthUnit);
tcEHPtr eh;
if ( ev.primaryCollision() && ( eh =
dynamic_ptr_cast<tcEHPtr>(ev.primaryCollision()->handler()) ) ) {
// Get general event info if present.
Traits::setScaleAndAlphas(*geneve, eh->lastScale(),
eh->lastAlphaS(),eh->lastAlphaEM(),
energyUnit);
}
// Extract all particles and order them.
tcPVector all;
ev.select(back_inserter(all), SelectAll());
stable_sort(all.begin(), all.end(), ParticleOrderNumberCmp());
vertices.reserve(all.size()*2);
// Create GenParticle's and map them to the ThePEG particles.
for ( int i = 0, N = all.size(); i < N; ++i ) {
tcPPtr p = all[i];
if ( nocopies && p->next() ) continue;
if ( pmap.find(p) != pmap.end() ) continue;
pmap[p] = createParticle(p);
if ( !p->children().empty() || p->next() ) {
// If the particle has children it should have a decay vertex:
vertices.push_back(Vertex());
decv[p] = &vertices.back();
vertices.back().in.insert(p);
}
if ( !p->parents().empty() || p->previous() ||
(p->children().empty() && !p->next()) ) {
// If the particle has parents it should have a production
// vertex. If neither parents or children it should still have a
// dummy production vertex.
vertices.push_back(Vertex());
prov[p] = &vertices.back();
vertices.back().out.insert(p);
}
}
// Now go through the the particles again, and join the vertices.
for ( int i = 0, N = all.size(); i < N; ++i ) {
tcPPtr p = all[i];
if ( nocopies ) {
if ( p->next() ) continue;
for ( int i = 0, N = p->children().size(); i < N; ++i )
join(p, p->children()[i]->final());
tcPPtr pp = p;
while ( pp->parents().empty() && pp->previous() ) pp = pp->previous();
for ( int i = 0, N = pp->parents().size(); i < N; ++i )
join(pp->parents()[i]->final(), p);
} else {
for ( int i = 0, N = p->children().size(); i < N; ++i )
join(p, p->children()[i]);
if ( p->next() ) join(p, p->next());
for ( int i = 0, N = p->parents().size(); i < N; ++i )
join(p->parents()[i], p);
if ( p->previous() ) join(p->previous(), p);
}
}
// Time to create the GenVertex's
for ( typename VertexMap::iterator it = prov.begin(); it != prov.end(); ++it )
if ( !member(vmap, it->second) )
vmap[it->second] = createVertex(it->second);
for ( typename VertexMap::iterator it = decv.begin(); it != decv.end(); ++it )
if ( !member(vmap, it->second) )
vmap[it->second] = createVertex(it->second);
// Now find the primary signal process vertex defined to be the
// decay vertex of the first parton coming into the primary hard
// sub-collision.
tSubProPtr sub = ev.primarySubProcess();
if ( sub && sub->incoming().first ) {
const Vertex * prim = decv[sub->incoming().first];
Traits::setSignalProcessVertex(*geneve, vmap[prim]);
vmap.erase(prim);
}
// Then add the rest of the vertices.
for ( typename GenVertexMap::iterator it = vmap.begin();
it != vmap.end(); ++it )
Traits::addVertex(*geneve, it->second);
// and the incoming beam particles
Traits::setBeamParticles(*geneve,pmap[ev.incoming().first],
pmap[ev.incoming().second]);
// and the PDF info
setPdfInfo(ev);
// and the cross section info
Traits::setCrossSection(*geneve,
eh->integratedXSec()/picobarn,
eh->integratedXSecErr()/picobarn);
for ( int i = 0, N = all.size(); i < N; ++i ) {
tcPPtr p = all[i];
if ( pmap.find(p) == pmap.end() ) continue;
GenParticlePtrT gp = pmap[p];
if ( p->hasColourInfo() ) {
// Check if the particle is connected to colour lines, in which
// case the lines are mapped to an integer and set in the
// GenParticle's Flow info.
tcColinePtr l;
if ( (l = p->colourLine()) ) {
if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
Traits::setColourLine(*gp, 1, flowmap[l]);
}
if ( (l = p->antiColourLine()) ) {
if ( !member(flowmap, l) ) flowmap[l] = flowmap.size() + 500;
Traits::setColourLine(*gp, 2, flowmap[l]);
}
}
if ( p->spinInfo() && p->spinInfo()->hasPolarization() ) {
DPair pol = p->spinInfo()->polarization();
Traits::setPolarization(*gp, pol.first, pol.second);
}
}
}
template <typename HepMCEventT, typename Traits>
typename HepMCConverter<HepMCEventT,Traits>::GenParticlePtrT
HepMCConverter<HepMCEventT,Traits>::createParticle(tcPPtr p) const {
int status = 1;
size_t nChildren = p->children().size();
if ( nChildren > 0 || p->next() ) status = 11;
if ( nChildren > 1 ) {
long id = p->data().id();
if ( BaryonMatcher::Check(id) || MesonMatcher::Check(id) ||
id == ParticleID::muminus || id == ParticleID::muplus ||
id == ParticleID::tauminus || id == ParticleID::tauplus ) {
bool child = false;
for(unsigned int ix=0;ix<nChildren;++ix) {
if(p->children()[ix]->id()==id) {
child = true;
break;
}
}
if ( !child ) {
if(p->data().widthCut()!=ZERO) {
if(p->mass() <= p->data().massMax() &&
p->mass() >= p->data().massMin() )
status = 2;
}
else {
status = 2;
}
}
}
}
GenParticlePtrT gp =
- Traits::newParticle(p->momentum(), p->id(), status, energyUnit);
+ Traits::newParticle(p->momentum(), p->id(), p->status() ? p->status() : status, energyUnit);
if ( p->spinInfo() && p->spinInfo()->hasPolarization() ) {
DPair pol = p->spinInfo()->polarization();
Traits::setPolarization(*gp, pol.first, pol.second);
}
return gp;
}
template <typename HepMCEventT, typename Traits>
void HepMCConverter<HepMCEventT,Traits>::join(tcPPtr parent, tcPPtr child) {
Vertex * dec = decv[parent];
Vertex * pro = prov[child];
if ( !pro || !dec ) Throw<HepMCConverterException>()
<< "Found a reference to a ThePEG::Particle which was not in the Event."
<< Exception::eventerror;
if ( pro == dec ) return;
while ( !pro->in.empty() ) {
dec->in.insert(*(pro->in.begin()));
decv[*(pro->in.begin())] = dec;
pro->in.erase(pro->in.begin());
}
while ( !pro->out.empty() ) {
dec->out.insert(*(pro->out.begin()));
prov[*(pro->out.begin())] = dec;
pro->out.erase(pro->out.begin());
}
}
template <typename HepMCEventT, typename Traits>
typename HepMCConverter<HepMCEventT,Traits>::GenVertexPtrT
HepMCConverter<HepMCEventT,Traits>::createVertex(Vertex * v) {
if ( !v ) Throw<HepMCConverterException>()
<< "Found internal null Vertex." << Exception::abortnow;
GenVertexPtrT gv = Traits::newVertex();
// We assume that the vertex position is the average of the decay
// vertices of all incoming and the creation vertices of all
// outgoing particles in the lab. Note that this will probably not
// be useful information for very small distances.
LorentzPoint p;
for ( tcParticleSet::iterator it = v->in.begin();
it != v->in.end(); ++it ) {
p += (**it).labDecayVertex();
Traits::addIncoming(*gv, pmap[*it]);
}
for ( tcParticleSet::iterator it = v->out.begin();
it != v->out.end(); ++it ) {
p += (**it).labVertex();
Traits::addOutgoing(*gv, pmap[*it]);
}
p /= double(v->in.size() + v->out.size());
Traits::setPosition(*gv, p, lengthUnit);
return gv;
}
template <typename HepMCEventT, typename Traits>
void HepMCConverter<HepMCEventT,Traits>::setPdfInfo(const Event & e) {
// ids of the partons going into the primary sub process
tSubProPtr sub = e.primarySubProcess();
int id1 = sub->incoming().first ->id();
int id2 = sub->incoming().second->id();
// get the event handler
tcEHPtr eh = dynamic_ptr_cast<tcEHPtr>(e.handler());
// get the values of x
double x1 = eh->lastX1();
double x2 = eh->lastX2();
// get the pdfs
pair<PDF,PDF> pdfs;
pdfs.first = eh->pdf<PDF>(sub->incoming().first );
pdfs.second = eh->pdf<PDF>(sub->incoming().second);
// get the scale
Energy2 scale = eh->lastScale();
// get the values of the pdfs
double xf1 = pdfs.first.xfx(sub->incoming().first->dataPtr(), scale, x1);
double xf2 = pdfs.second.xfx(sub->incoming().second->dataPtr(), scale, x2);
Traits::setPdfInfo(*geneve, id1, id2, x1, x2, sqrt(scale/GeV2), xf1, xf2);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 6:43 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4983123
Default Alt Text
(59 KB)
Attached To
rTHEPEGHG thepeghg
Event Timeline
Log In to Comment