diff --git a/PDT/PDT.h b/PDT/PDT.h --- a/PDT/PDT.h +++ b/PDT/PDT.h @@ -1,244 +1,254 @@ // -*- C++ -*- // // PDT.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 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_PDT_H #define ThePEG_PDT_H // This is the declaration of the PDT class. #include "ThePEG/Config/ThePEG.h" namespace ThePEG { /** * PDT is a helper class implementing enumerations for charge, colour * and spin to be used by the ParticleData class. In addition, some * static utility functions are provided. * * @see ParticleData */ class PDT { public: /** * Definition of enumerated values used for spin information. THe * integer values are given according to 2s+1. */ enum Spin { SpinNA = -1, /**< Spin is not applicable. */ SpinUnknown = 0, /**< Unknown spin */ SpinUndefined = 0, /**< Undefined spin */ Spin0 = 1, /**< Spin zero. */ Spin1Half = 2, /**< Spin 1/2. */ Spin1 = 3, /**< Spin 1. */ Spin3Half = 4, /**< Spin 3/2. */ Spin2 = 5, /**< Spin 2. */ Spin5Half = 6, /**< Spin 5/2. */ Spin3 = 7, /**< Spin 4. */ Spin7Half = 8, /**< Spin 7/2. */ Spin4 = 9 /**< Spin 5. */ }; /** * Definition of enumerated values used for charge information. The * integer values are given in units of e/3. */ enum Charge { ChargeUnknown = -999999, /**< Unknown charge. */ ChargeUndefined = -999999, /**< Undefined charge. */ Charged = 999990, /**< Is charged. */ Positive = 900000, /**< Is positively charged. */ Negative = -900000, /**< Is negatively charged. */ ChargeNeutral = 0, /**< Uncharged. */ Charge0 = 0, /**< Uncharged. */ Plus1Third = 1, /**< e/3. */ Plus2Third = 2, /**< 2e/3. */ Plus1 = 3, /**< e. */ Minus1Third = -1, /**< -e/3. */ Minus2Third = -2, /**< -2e/3. */ Minus1 = -3, /**< -e. */ Plus4Third = 4, /**< 4e/3. */ Plus5Third = 5, /**< 5e/3. */ Plus2 = 6, /**< 2e. */ Minus4Third = -4, /**< -4e/3. */ Minus5Third = -5, /**< -5e/3. */ Minus2 = -6, /**< -3e. */ Plus7Third = 7, /**< 7e/3. */ Plus8Third = 8, /**< 8e/3. */ Plus3 = 9, /**< 3e. */ Minus7Third = -7, /**< -7e/3. */ Minus8Third = -8, /**< -8e/3. */ Minus3 = -9, /**< -3e. */ Plus4 = 12, /**< 4e. */ Plus5 = 15, /**< 5e. */ Plus6 = 18, /**< 6e. */ Plus7 = 21, /**< 7e. */ Plus8 = 24, /**< 8e. */ Minus4 = -12, /**< -4e. */ Minus5 = -15, /**< -5e. */ Minus6 = -18, /**< -6e. */ Minus7 = -21, /**< -7e. */ Minus8 = -24 /**< -8e. */ }; /** *Definition of enumerated values used for colour information. */ enum Colour { ColourUnknown = -1, /**< Unknown colour */ ColourUndefined = -1, /**< Undefined colour */ ColourNeutral = 0, /**< Colour-singlet */ Colour0 = 0, /**< Colour-singlet */ Coloured = 1, /**< Coloured */ Colour3 = 3, /**< Colour-triplet */ Colour3bar = -3, /**< Colour-anti-triplet */ Colour6 = 6, /**< Colour-sextet */ Colour6bar = -6, /**< Colour-anti-sextet */ Colour8 = 8 /**< Colour-octet */ }; /** + * Define type of nonabelian interactions + */ + enum ColouredInteraction { + ColouredUnknown = -2, + ColouredUndefined = -2, + NotColoured = -1, + ColouredQCD = 0 + }; + + /** * True if the argument corresponds to a non-zero charge. */ static bool charged(Charge c) { return c != ChargeNeutral && c != ChargeUndefined; } /** * True if the argument corresponds to a positive charge. */ static bool positive(Charge c) { return c > ChargeNeutral && c != Charged; } /** * True if the argument corresponds to a negative charge. */ static bool negative(Charge c) { return c < ChargeNeutral && c != ChargeUndefined; } /** * True if the argument corresponds to a non-zero colour charge. */ static bool coloured(Colour c) { return c != ColourNeutral && c != ColourUnknown; } /** * Return the anti-colour of the specified colour. */ static Colour antiColour(Colour c) { if ( c == Colour3 || c == Colour3bar ) return Colour(-c); if ( c == Colour6 || c == Colour6bar ) return Colour(-c); return c; } /** * Return the flavour content of the given particle. The flavours * will be given in decreasing mass with flavour before * anti-flavour. */ static vector flavourContent(long id); /** * Return the flavour content of the given particle. The flavours * will be given in decreasing mass with flavour before * anti-flavour. */ static vector flavourContent(tcPDPtr); /** * Return the flavour content of the given particle. The flavours * will be given in decreasing mass with flavour before * anti-flavour. */ static vector flavourContent(tcPPtr); /** * Return the flavour content of the given particle. The flavours * will be given in decreasing mass with flavour before * anti-flavour. */ static vector flavourContent(const ParticleData &); /** * Return the flavour content of the given particle. The flavours * will be given in decreasing mass with flavour before * anti-flavour. */ static vector flavourContent(const Particle &); }; /** Input a colour from a stream. */ template IStream & operator>>(IStream & is, PDT::Colour & c) { int ci; is >> ci; c = PDT::Colour(ci); return is; } /** Input a charge from a stream. */ template IStream & operator>>(IStream & is, PDT::Charge & c) { int ci; is >> ci; c = PDT::Charge(ci); return is; } /** Input a spin from a stream. */ template IStream & operator>>(IStream & is, PDT::Spin & s) { int si; is >> si; s = PDT::Spin(si); return is; } /// Type traits for built-in types template <> struct TypeTraits { /** Enum for dimensions*/ enum { hasDimension = false }; /// Type switch set to standard type. typedef EnumT DimType; /// Base unit static constexpr PDT::Spin baseunit() { return PDT::Spin(1); } }; /// Type traits for built-in types template <> struct TypeTraits { /** Enum for dimensions*/ enum { hasDimension = false }; /// Type switch set to standard type. typedef EnumT DimType; /// Base unit static constexpr PDT::Charge baseunit() { return PDT::Charge(1); } }; /// Type traits for built-in types template <> struct TypeTraits { /** Enum for dimensions*/ enum { hasDimension = false }; /// Type switch set to standard type. typedef EnumT DimType; /// Base unit static constexpr PDT::Colour baseunit() { return PDT::Colour(3); } }; } #endif /* ThePEG_PDT_H */ diff --git a/PDT/ParticleData.cc b/PDT/ParticleData.cc --- a/PDT/ParticleData.cc +++ b/PDT/ParticleData.cc @@ -1,1038 +1,1077 @@ // -*- C++ -*- // // ParticleData.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 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 ParticleData class. // #include "ParticleData.h" #include "ParticleData.xh" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/Utilities/HoldFlag.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Utilities/StringUtils.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Repository/Repository.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Config/algorithm.h" #include "ThePEG/Utilities/Exception.h" #include "ThePEG/Utilities/EnumIO.h" #include "ThePEG/Repository/UseRandom.h" namespace ThePEG { ParticleData::ParticleData() : theId(0), thePDGName(""), theMass(-1.0*GeV), theWidth(-1.0*GeV), theHardProcessMass(-1.0*GeV), hardProcessMassSet(false), theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false), theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm), theCharge(PDT::ChargeUnknown), - theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), isStable(true), + theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), theColouredInteraction(PDT::ColouredUnknown), + isStable(true), theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV), theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm), theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown), - theDefColour(PDT::ColourUnknown) {} + theDefColour(PDT::ColourUnknown), theDefColouredInteraction(PDT::ColouredUnknown) {} ParticleData:: ParticleData(PID newId, const string & newPDGName) : theId(newId), thePDGName(newPDGName), theMass(-1.0*GeV), theWidth(-1.0*GeV), theHardProcessMass(-1.0*GeV), hardProcessMassSet(false), theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false), theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm), theCharge(PDT::ChargeUnknown), - theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), isStable(true), + theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), theColouredInteraction(PDT::ColouredUnknown), + isStable(true), theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV), theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm), theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown), - theDefColour(PDT::ColourUnknown) {} + theDefColour(PDT::ColourUnknown), theDefColouredInteraction(PDT::ColouredUnknown) {} ParticleData::~ParticleData() {} PDPtr ParticleData::Create(PID newId, const string & newPDGName) { return new_ptr(ParticleData(newId, newPDGName)); } PDPair ParticleData:: Create(PID newId, const string & newPDGName, const string & newAntiPDGName) { PDPair pap; pap.first = new_ptr(ParticleData(newId, newPDGName)); pap.second = new_ptr(ParticleData(-newId, newAntiPDGName)); antiSetup(pap); return pap; } void ParticleData::readSetup(istream & is) { long id; is >> id >> thePDGName >> iunit(theDefMass, GeV) >> iunit(theDefWidth, GeV) >> iunit(theDefCut, GeV) >> iunit(theDefCTau, mm) >> ienum(theDefCharge) >> ienum(theDefColour) >> ienum(theDefSpin) >> ienum(isStable); theId = id; theMass = theDefMass; theWidth = theDefWidth; theWidthUpCut = theDefCut; theWidthLoCut = theDefCut; theCTau = theDefCTau; theCharge = theDefCharge; theColour = theDefColour; + theColouredInteraction = PDT::NotColoured; + if ( abs(long(theId)) < 9 || long(theId) == ParticleID::g ) + theColouredInteraction = PDT::ColouredQCD; theSpin = theDefSpin; if ( PDGName() == "-" ) thePDGName = name(); return; } - + void ParticleData::antiSetup(const PDPair & pap) { pap.first->theAntiPartner = pap.second; pap.second->theAntiPartner = pap.first; pap.first->syncAnti = pap.second->syncAnti = true; } PDPtr ParticleData::pdclone() const { return new_ptr(*this); } IBPtr ParticleData::clone() const { return pdclone(); } - + IBPtr ParticleData::fullclone() const { PDPtr pd = pdclone(); Repository::Register(pd); pd->theDecaySelector.clear(); pd->theDecayModes.clear(); pd->isStable = true; PDPtr apd; if ( CC() ) { apd = CC()->pdclone(); Repository::Register(apd); apd->theDecaySelector.clear(); apd->theDecayModes.clear(); apd->isStable = true; pd->theAntiPartner = apd; apd->theAntiPartner = pd; pd->syncAnti = syncAnti; apd->syncAnti = CC()->syncAnti; } HoldFlag<> dosync(pd->syncAnti, true); for ( DecaySet::const_iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) pd->addDecayMode(*it); return pd; } Energy ParticleData::mass(Energy mi) { theMass = mi; if ( synchronized() && CC() ) CC()->theMass = theMass; return theMass; } Energy ParticleData::width(Energy wi) { theWidth = wi; if ( synchronized() && CC() ) CC()->theWidth = theWidth; return theWidth; } Energy ParticleData::widthUpCut(Energy wci) { theWidthUpCut = wci; if ( synchronized() && CC() ) CC()->theWidthUpCut = theWidthUpCut; return theWidthUpCut; } Energy ParticleData::widthLoCut(Energy wci) { theWidthLoCut = wci; if ( synchronized() && CC() ) CC()->theWidthLoCut = theWidthLoCut; return theWidthLoCut; } Length ParticleData::cTau(Length ti) { theCTau = ti; if ( synchronized() && CC() ) CC()->theCTau = theCTau; return theCTau; } PDT::Charge ParticleData::iCharge(PDT::Charge ci) { theCharge = ci; if ( synchronized() && CC() ) CC()->theCharge = PDT::Charge(-ci); return theCharge; } PDT::Spin ParticleData::iSpin(PDT::Spin si) { theSpin = si; if ( synchronized() && CC() ) CC()->theSpin = si; return si; } PDT::Colour ParticleData::iColour(PDT::Colour ci) { theColour = ci; if ( synchronized() && CC() ) CC()->theColour = PDT::Colour(-ci); return theColour; } void ParticleData::stable(bool s) { isStable = s; if ( synchronized() && CC() ) CC()->isStable = s; } void ParticleData::synchronized(bool h) { syncAnti = h; if ( CC() ) CC()->syncAnti = h; } void ParticleData::variableRatio(bool varRatio) { theVariableRatio=varRatio; } void ParticleData::addDecayMode(tDMPtr dm) { if ( member(theDecayModes, dm) ) return; cPDPtr parent = dm->parent(); if ( !parent ) parent = this; if ( parent != this ) { dm = dm->clone(this); } theDecayModes.insert(dm); theDecaySelector.insert(dm->brat(), dm); if ( CC() ) { if ( !synchronized() ) dm->CC()->switchOff(); CC()->theDecayModes.insert(dm->CC()); CC()->theDecaySelector.insert(dm->CC()->brat(), dm->CC()); } } void ParticleData::removeDecayMode(tDMPtr dm) { theDecayModes.erase(theDecayModes.find(dm)); if(theDecayModes.empty()) isStable = true; theDecaySelector.erase(dm); if ( !CC() ) return; CC()->theDecayModes.erase(dm->CC()); if(CC()->theDecayModes.empty()) CC()->isStable = true; CC()->theDecaySelector.erase(dm->CC()); } void ParticleData::synchronize() { if ( !CC() ) return; isStable = CC()->isStable; theMass = CC()->theMass; theHardProcessMass = CC()->theHardProcessMass; hardProcessMassSet = CC()->hardProcessMassSet; theWidth = CC()->theWidth; theHardProcessWidth = CC()->theHardProcessWidth; hardProcessWidthSet = CC()->hardProcessWidthSet; theWidthUpCut = CC()->theWidthUpCut; theWidthLoCut = CC()->theWidthLoCut; theCTau = CC()->theCTau; theCharge = PDT::Charge(-CC()->theCharge); theSpin = CC()->theSpin; theColour = PDT::antiColour(CC()->theColour); + theColouredInteraction = CC()->theColouredInteraction; theMassGenerator = CC()->theMassGenerator; theWidthGenerator = CC()->theWidthGenerator; syncAnti = CC()->syncAnti; theDecaySelector.clear(); for ( DecaySet::iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) { (*it)->synchronize(); theDecaySelector.insert((*it)->brat(), *it); } } void ParticleData::doupdate() { Interfaced::doupdate(); bool redo = touched(); for_each(theDecayModes, UpdateChecker(redo)); UpdateChecker::check(theMassGenerator, redo); UpdateChecker::check(theWidthGenerator, redo); if ( !redo ) return; theDecaySelector.clear(); for ( DecaySet::const_iterator dit = theDecayModes.begin(); dit != theDecayModes.end(); ++dit ) { tDMPtr dm = *dit; dm->resetOverlap(); for ( DecaySet::const_iterator dit2 = theDecayModes.begin(); dit2 != theDecayModes.end(); ++dit2 ) if ( dit2 != dit ) dm->addOverlap(dm); if ( dm->brat() > 0.0 ) theDecaySelector.insert(dm->brat(), dm); } if ( theMassGenerator && !theMassGenerator->accept(*this) ) throw UpdateException(); if ( theWidthGenerator && !theWidthGenerator->accept(*this) ) throw UpdateException(); if ( theWidthGenerator ) theDecaySelector = theWidthGenerator->rate(*this); touch(); } tDMPtr ParticleData::selectMode(Particle & p) const { if ( &(p.data()) != this ) return tDMPtr(); try { if ( !theWidthGenerator || !theVariableRatio ) return theDecaySelector.select(UseRandom::current()); DecaySelector local; if ( theWidthGenerator ) local = theWidthGenerator->rate(p); else for ( DecaySet::const_iterator mit = theDecayModes.begin(); mit != theDecayModes.end(); ++mit ) local.insert((*mit)->brat(p), *mit); return local.select(UseRandom::current()); } catch (range_error & e) { return tDMPtr(); } } void ParticleData::rebind(const TranslationMap & trans) { if ( CC() ) theAntiPartner = trans.translate(theAntiPartner); DecaySet newModes; DecaySelector newSelector; for ( DecaySet::iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) { DMPtr dm; dm = trans.translate(*it); if ( !dm ) throw RebindException(); newModes.insert(dm); newSelector.insert(dm->brat(), dm); } theDecayModes.swap(newModes); theDecaySelector.swap(newSelector); } IVector ParticleData::getReferences() { IVector refs = Interfaced::getReferences(); if ( CC() ) refs.push_back(CC()); refs.insert(refs.end(), theDecayModes.begin(), theDecayModes.end()); return refs; } void ParticleData::massGenerator(tMassGenPtr mg) { if ( mg && !mg->accept(*this) ) return; if ( mg && synchronized() && CC() && !mg->accept(*CC()) ) return; theMassGenerator = mg; if ( synchronized() && CC() ) CC()->theMassGenerator = mg; } void ParticleData::widthGenerator(tWidthGeneratorPtr newGen) { if ( newGen && !newGen->accept(*this) ) return; if ( newGen && synchronized() && CC() && !newGen->accept(*CC()) ) return; theWidthGenerator = newGen; if ( synchronized() && CC() ) CC()->theWidthGenerator = newGen; } Energy ParticleData::generateMass() const { return massGenerator()? massGenerator()->mass(*this): mass(); } Energy ParticleData::generateWidth(Energy m) const { return widthGenerator()? widthGenerator()->width(*this, m): width(); } Length ParticleData::generateLifeTime(Energy m, Energy w) const { - return widthGenerator() ? + return widthGenerator() ? widthGenerator()->lifeTime(*this, m, w) : UseRandom::rndExp(cTau()); } PPtr ParticleData::produceParticle(const Lorentz5Momentum & pp) const { PPtr p = new_ptr(Particle(this)); p->set5Momentum(pp); return p; } PPtr ParticleData::produceParticle(const LorentzMomentum & pp) const { PPtr p(produceParticle(Lorentz5Momentum(pp))); return p; } PPtr ParticleData::produceParticle(const LorentzMomentum & pp, Energy m) const { PPtr p(produceParticle(Lorentz5Momentum(pp, m))); return p; } PPtr ParticleData::produceParticle(Energy m, const Momentum3 & pp) const { PPtr p(produceParticle(Lorentz5Momentum(m, pp))); return p; } PPtr ParticleData::produceParticle(const Momentum3 & pp) const { PPtr p(produceParticle(Lorentz5Momentum(generateMass(), pp))); return p; } PPtr ParticleData:: produceParticle(Energy plus, Energy minus, Energy px, Energy py) const { PPtr p(produceParticle(LorentzMomentum(px, py, 0.5*(plus-minus), 0.5*(plus+minus)))); return p; } void ParticleData::setMass(Energy mi) { mass(mi); } void ParticleData::setHardProcessMass(Energy mi) { theHardProcessMass = mi; hardProcessMassSet = true; ParticleData * apd = CC().operator->(); if ( synchronized() && apd ) { apd->theHardProcessMass = theHardProcessMass; apd->hardProcessMassSet = true; } } void ParticleData::setHardProcessWidth(Energy mi) { theHardProcessWidth = mi; hardProcessWidthSet = true; ParticleData * apd = CC().operator->(); if ( synchronized() && apd ) { apd->theHardProcessWidth = theHardProcessWidth; apd->hardProcessWidthSet = true; } } string ParticleData::doUnsetHardProcessMass(string) { - hardProcessMassSet = false; + hardProcessMassSet = false; theHardProcessMass = -1.*GeV; return ""; } string ParticleData::doAdjustNominalMass(string) { if ( hardProcessMassSet ) setMass(theHardProcessMass); return ""; } - + string ParticleData::doUnsetHardProcessWidth(string) { - hardProcessWidthSet = false; + hardProcessWidthSet = false; theHardProcessWidth = -1.*GeV; return ""; } Energy ParticleData::defMass() const { return theDefMass; } void ParticleData::setWidth(Energy wi) { width(wi); } Energy ParticleData::getWidth() const { return width(); } Energy ParticleData::defWidth() const { return theDefWidth; } void ParticleData::setCut(Energy ci) { widthCut(ci); } Energy ParticleData::getCut() const { return (theWidthUpCut >= ZERO && theWidthLoCut >= ZERO)? max(theWidthUpCut, theWidthLoCut): min(theWidthUpCut, theWidthLoCut); } Energy ParticleData::defCut() const { return theDefCut; } void ParticleData::setUpCut(Energy ci) { widthUpCut(ci); } Energy ParticleData::getUpCut() const { return theWidthUpCut; } void ParticleData::setLoCut(Energy ci) { widthLoCut(ci); } Energy ParticleData::getLoCut() const { return theWidthLoCut; } void ParticleData::setCTau(Length ti) { cTau(ti); } Length ParticleData::getCTau() const { return cTau(); } Length ParticleData::defCTau() const { return theDefCTau; } void ParticleData::setStable(long is) { stable(is); } long ParticleData::getStable() const { return stable(); } void ParticleData::setSync(long is) { synchronized(is); } long ParticleData::getSync() const { return synchronized(); } void ParticleData::setVariableRatio(long is) { variableRatio(is); } long ParticleData::getVariableRatio() const { return variableRatio(); } string ParticleData::doSync(string) { synchronize(); return ""; } void ParticleData::setMassGenerator(MassGenPtr gi) { massGenerator(gi); } void ParticleData::setWidthGenerator(WidthGeneratorPtr wg) { widthGenerator(wg); } void ParticleData::setColour(long c) { theColour = PDT::Colour(c); } long ParticleData::getColour() const { return theColour; } long ParticleData::defColour() const { return theDefColour; } +void ParticleData::setColouredInteraction(long c) { + theColouredInteraction = PDT::ColouredInteraction(c); +} + +long ParticleData::getColouredInteraction() const { + return theColouredInteraction; +} + +long ParticleData::defColouredInteraction() const { + return theDefColour; +} + + void ParticleData::setCharge(int c) { theCharge = PDT::Charge(c); } string ParticleData::ssetCharge(string arg) { istringstream is(arg); long i; if ( is >> i ) { theCharge = PDT::Charge(i); return "New charge is " + arg; } if ( arg == "unknown" ) theCharge = PDT::ChargeUnknown; else if ( arg == "charged" ) theCharge = PDT::Charged; else if ( arg == "positive" ) theCharge = PDT::Positive; else if ( arg == "negative" ) theCharge = PDT::Negative; else throw ParticleChargeCommand(*this, arg); return "New charge is " + arg; } int ParticleData::getCharge() const { return theCharge; } int ParticleData::defCharge() const { return theDefCharge; } void ParticleData::setSpin(int s) { theSpin = PDT::Spin(s); } int ParticleData::getSpin() const { return theSpin; } int ParticleData::defSpin() const { return theDefSpin; } ClassDescription ParticleData::initParticleData; struct ParticleOrdering { bool operator()(tcPDPtr p1, tcPDPtr p2) const { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } }; struct ModeOrdering { bool operator()(const tcDMPtr & d1, const tcDMPtr & d2) const { ParticleOrdering ord; return ord(d1->parent(), d2->parent()) || ( !ord(d2->parent(), d1->parent()) && ( d1->tag() < d2->tag() || ( d1->tag() == d2->tag() && d1->fullName() < d2->fullName() ) ) ); } }; void ParticleData::persistentOutput(PersistentOStream & os) const { multiset modes(theDecayModes.begin(), theDecayModes.end()); os << long(theId) << thePDGName << ounit(theMass, GeV) << ounit(theWidth, GeV) << ounit(theHardProcessMass,GeV) << hardProcessMassSet << ounit(theHardProcessWidth,GeV) << hardProcessWidthSet << ounit(theWidthUpCut, GeV) << ounit(theWidthLoCut, GeV) << ounit(theCTau, mm) << oenum(theCharge) << oenum(theSpin) - << oenum(theColour); + << oenum(theColour) << oenum(theColouredInteraction); os << theMassGenerator << isStable << modes << theDecaySelector << theWidthGenerator << theVariableRatio << theAntiPartner << syncAnti << ounit(theDefMass, GeV) << ounit(theDefWidth, GeV) << ounit(theDefCut, GeV) << ounit(theDefCTau, mm) << oenum(theDefColour) - << oenum(theDefCharge) << oenum(theDefSpin); + << oenum(theDefCharge) << oenum(theDefSpin) << oenum(theDefColouredInteraction); } void ParticleData::persistentInput(PersistentIStream & is, int) { long id; is >> id >> thePDGName >> iunit(theMass, GeV) >> iunit(theWidth, GeV) >> iunit(theHardProcessMass,GeV) >> hardProcessMassSet >> iunit(theHardProcessWidth,GeV) >> hardProcessWidthSet >> iunit(theWidthUpCut, GeV) >> iunit(theWidthLoCut, GeV) >> iunit(theCTau, mm) >> ienum(theCharge) >> ienum(theSpin) - >> ienum(theColour) >> theMassGenerator >> isStable + >> ienum(theColour) >> ienum(theColouredInteraction) >> theMassGenerator >> isStable >> theDecayModes >> theDecaySelector >> theWidthGenerator >> theVariableRatio >> theAntiPartner >> syncAnti >> iunit(theDefMass, GeV) >> iunit(theDefWidth, GeV) >> iunit(theDefCut, GeV) >> iunit(theDefCTau, mm) >> ienum(theDefColour) >> ienum(theDefCharge) - >> ienum(theDefSpin); + >> ienum(theDefSpin) >> ienum(theDefColouredInteraction); theId = id; } void ParticleData::Init() { static ClassDocumentation documentation ("There is no documentation for the ThePEG::ParticleData class"); static Parameter interfaceMass ("NominalMass", "The nominal mass in GeV of the particle. The actual mass " "of a particle instance is generated depending on the " "nominal mass and the width and is generated by the " "Mass_generator object associated with the " "particle.", &ParticleData::theMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setMass, 0, 0, 0, &ParticleData::defMass); static Parameter interfaceHardProcessMass ("HardProcessMass", "The mass in GeV of the particle to be used in calculating hard process cross sections.", &ParticleData::theHardProcessMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setHardProcessMass, 0, 0, 0, 0); static Parameter interfaceDefMass ("DefaultMass", "The default nominal mass in GeV of the particle. The actual mass " "of a particle instance is generated depending on the " "nominal mass and the width and is generated by the " "Mass_generator object associated with the " "particle.", &ParticleData::theDefMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefMass.setHasDefault(false); static Parameter interfaceWidth ("Width", "The width of the particle in GeV.", 0, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setWidth, &ParticleData::getWidth, 0, 0, &ParticleData::defWidth); static Parameter interfaceHardProcessWidth ("HardProcessWidth", "The width in GeV of the particle to be used in calculating hard process cross sections.", &ParticleData::theHardProcessWidth, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setHardProcessWidth, 0, 0, 0, 0); static Parameter interfaceDefWidth ("DefaultWidth", "The default width of the particle in GeV.", &ParticleData::theDefWidth, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefWidth.setHasDefault(false); static Parameter interfaceWidthUpCut ("WidthUpCut", "The upper hard cutoff in GeV in generated mass, which is the maximum " "allowed upwards deviation from the nominal mass. A negative value " "corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setUpCut, &ParticleData::getUpCut, 0, 0, &ParticleData::defCut); - + static Parameter interfaceWidthLoCut ("WidthLoCut", "The lower hard cutoff in GeV in generated mass, which is the maximum " "allowed downwards deviation from the nominal mass. A negative value " "corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setLoCut, &ParticleData::getLoCut, 0, 0, &ParticleData::defCut); - + static Parameter interfaceWidthCut ("WidthCut", "The hard cutoff in GeV in generated mass, which is the maximum " "allowed deviation from the nominal mass. Sets both the upper and lower " "cut. (The displayed value is the maximium of the upper and lower cut.) " "A negative value corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setCut, &ParticleData::getCut, 0, 0, &ParticleData::defCut); interfaceWidthCut.setHasDefault(false); - + static Parameter interfaceDefWidthCut ("DefaultWidthCut", "The default hard cutoff in GeV in generated mass, which is the maximum " "allowed deviation from the nominal mass. For the actual cutoff, the " "upper and lower cut can be set separately.", &ParticleData::theDefCut, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefWidthCut.setHasDefault(false); - + static Parameter interfaceCTau ("LifeTime", "c times the average lifetime of the particle measuerd in mm." "The actual lifetime of a particle instance is generated " "from this number by the Mass_generator " "object associated with the particle.", 0, mm, ZERO, ZERO, Constants::MaxLength, false, false, Interface::lowerlim, &ParticleData::setCTau, &ParticleData::getCTau, 0, 0, &ParticleData::defCTau); interfaceCTau.setHasDefault(false); static Parameter interfaceDefCTau ("DefaultLifeTime", "c times the default average lifetime of the particle measuerd in mm." "The actual lifetime of a particle instance is generated " "from this number by the Mass_generator " "object associated with the particle.", &ParticleData::theDefCTau, mm, ZERO, ZERO, Constants::MaxLength, false, true, Interface::lowerlim); interfaceDefCTau.setHasDefault(false); static Switch interfaceColour ("Colour", "The colour quantum number of this particle type.", 0, -1, false, false, &ParticleData::setColour, &ParticleData::getColour, &ParticleData::defColour); static SwitchOption interfaceColourUndefined (interfaceColour, "Undefined", "The coulur is undefined.", -1); static SwitchOption interfaceColourNeutral (interfaceColour, "Neutral", "This particle is colour neutral.", 0); static SwitchOption interfaceColour3 (interfaceColour, "Triplet", "This particle is a colour triplet.", 3); static SwitchOption interfaceColour3bar (interfaceColour, "AntiTriplet", "This particle is a colour anti-triplet.", -3); static SwitchOption interfaceColour6 (interfaceColour, "Sextet", "This particle is a colour sextet.", 6); static SwitchOption interfaceColour6bar (interfaceColour, "AntiSextet", "This particle is a colour anti-sextet.", -6); static SwitchOption interfaceColour8 (interfaceColour, "Octet", "This particle is a colour octet.", 8); - + static Switch interfaceDefColour ("DefaultColour", "The default colour quantum number of this particle type.", &ParticleData::theDefColour, PDT::Colour(-1), false, true); static SwitchOption interfaceDefColourUndefined (interfaceDefColour, "Undefined", "The coulur is undefined.", -1); static SwitchOption interfaceDefColourNeutral (interfaceDefColour, "Neutral", "This particle is colour neutral.", 0); static SwitchOption interfaceDefColour3 (interfaceDefColour, "Triplet", "This particle is a colour triplet.", 3); static SwitchOption interfaceDefColour3bar (interfaceDefColour, "AntiTriplet", "This particle is a colour anti-triplet.", -3); static SwitchOption interfaceDefColour6 (interfaceDefColour, "Sextet", "This particle is a colour sextet.", 6); static SwitchOption interfaceDefColour6bar (interfaceDefColour, "AntiSextet", "This particle is a colour anti-sextet.", -6); static SwitchOption interfaceDefColour8 (interfaceDefColour, "Octet", "This particle is a colour octet.", 8); - interfaceDefColour.setHasDefault(false); + interfaceDefColour.setHasDefault(false); + static Switch interfaceColouredInteraction + ("ColouredInteraction", + "The coloured interaction of this particle type.", + 0, -1, false, false, &ParticleData::setColouredInteraction, &ParticleData::getColouredInteraction, + &ParticleData::defColouredInteraction); + static SwitchOption interfaceColouredInteractionUndefined + (interfaceColouredInteraction, "Undefined", "The coloured interaction is undefined.", -2); + static SwitchOption interfaceColouredInteractionNotColoured + (interfaceColouredInteraction, "NotColoured", "There are no coloured interactions.", -1); + static SwitchOption interfaceColouredInteractionQCD + (interfaceColouredInteraction, "QCD", "This particle is a QCD particle.", 0); + + static Switch interfaceDefColouredInteraction + ("DefaultColouredInteraction", + "The default coloured interaction of this particle type.", + &ParticleData::theDefColouredInteraction, PDT::ColouredInteraction(-1), false, true); + static SwitchOption interfaceDefColouredInteractionUndefined + (interfaceDefColouredInteraction, "Undefined", "The coloured interaction is undefined.", -2); + static SwitchOption interfaceDefColouredInteractionNotColoured + (interfaceDefColouredInteraction, "NotColoured", "There are no coloured interactions.", -1); + static SwitchOption interfaceDefColouredInteractionQCD + (interfaceDefColouredInteraction, "QCD", "This particle is a QCD particle.", 0); + static Parameter interfaceCharge ("Charge", "The charge of this particle in units of e/3. " "See also the command interface SetCharge.", 0, 0, -24, 24, false, false, true, &ParticleData::setCharge, &ParticleData::getCharge, 0, 0, &ParticleData::defCharge); static Parameter interfaceDefCharge ("DefaultCharge", "The default charge of this particle in units of e/3. " "See also the command interface SetCharge.", &ParticleData::theDefCharge, PDT::Charge(0), PDT::Charge(-24), PDT::Charge(24), false, true, true); interfaceDefCharge.setHasDefault(false); static Command interfaceSetCharge ("SetCharge", "Set the charge of this particle. The argument should be given as an " "interger giving three times the unit charge, or 'unknown', " "'charged', 'positive' or 'negative'", &ParticleData::ssetCharge); static Parameter interfaceSpin ("Spin", "The spin quantim number of this particle on the form 2j+1.", 0, 0, 0, 9, false, false, true, &ParticleData::setSpin, &ParticleData::getSpin, 0, 0, &ParticleData::defSpin); static Parameter interfaceDefSpin ("DefaultSpin", "The default spin quantim number of this particle on the form 2j+1.", &ParticleData::theDefSpin, PDT::Spin(0), PDT::Spin(0), PDT::Spin(9), false, true, true); interfaceDefSpin.setHasDefault(false); static Switch interfaceStable ("Stable", "Indicates if the particle is stable or not.", 0, 0, false, false, &ParticleData::setStable, &ParticleData::getStable, 0); static SwitchOption interfaceStableYes (interfaceStable, "Stable", "This particle is stable", 1); static SwitchOption interfaceStableNo (interfaceStable, "Unstable", "This particle is not stable", 0); interfaceStable.setHasDefault(false); static Switch interfaceVariableRatio ("VariableRatio", "Indicates if the branching ratios of the particle are allowed" " to vary for given Particle instances depending on the mass of the instance.", 0, 0, false, false, &ParticleData::setVariableRatio, &ParticleData::getVariableRatio, 0); static SwitchOption interfaceVariableRatioYes (interfaceVariableRatio, "Yes", "The branching ratio varies.", 1); static SwitchOption interfaceVariableRatioNo (interfaceVariableRatio, "No", "The branching ratio does not vary.", 0); static Switch interfaceSync ("Synchronized", "Indicates if the changes to this particle is propagated to " "its anti-partner or not. Note that setting this switch does not " "actually synchronize the properties with the anti-partner, " "it only assures that following changes are propagated. " "To sync the particle with its anti-particle, use the " "Synchronize command.", 0, 1, false, false, &ParticleData::setSync, &ParticleData::getSync, 0); static SwitchOption interfaceSyncYes (interfaceSync, "Synchronized", "Changes to this particle will propagate to its " "anti-partner", 1); static SwitchOption interfaceSyncNo (interfaceSync, "Not_synchronized", "Changes to this particle will propagate to its " "anti-partner", 0); interfaceSync.setHasDefault(false); static Command interfaceSynchronize ("Synchronize", "Synchronizes this particle so that all its properties " "correspond to those of its anti-partner", &ParticleData::doSync, false); static Reference interfaceMassGenerator ("Mass_generator", "An object derived from the ThePEG::MassGenerator" "class, which is able to generate a mass for a given " "particle instance", &ParticleData::theMassGenerator, false, false, true, true, &ParticleData::setMassGenerator, 0, 0); static Reference interfaceWidthGenerator ("Width_generator", "An object derived from the ThePEG::WidthGenerator class, " "which is able to calculate the full and partial widths for" "this particle type and for a given instance of this " "particle type.", &ParticleData::theWidthGenerator, false, false, true, true, &ParticleData::setWidthGenerator, 0, 0); static RefVector interfaceDecayModes ("DecayModes", "The list of decay modes defined for this particle type.", 0, -1, false, false, false, false, 0, &ParticleData::insDecayModes, &ParticleData::delDecayModes, &ParticleData::getDecayModes); static Command interfaceSelectDecayModes ("SelectDecayModes", "Only the decay modes which are given as (white-space separated) " "decay tags will be switched on, all others will be switched off. " "If no argument or 'none' is given, all decay modes are switched off. " "If the argument is 'all', all decay modes are switched on.", &ParticleData::doSelectDecayModes, false); static Command interfacePrintDecayModes ("PrintDecayModes", "Print all decay modes of this particle.", &ParticleData::doPrintDecayModes, true); - - static Command interfaceUnsetHardProcessMass ("UnsetHardProcessMass", "Unset a previously set hard process mass.", &ParticleData::doUnsetHardProcessMass, false); static Command interfaceAdjustNominalMass ("AdjustNominalMass", "Unset a previously set hard process mass.", &ParticleData::doAdjustNominalMass, false); static Command interfaceUnsetHardProcessWidth ("UnsetHardProcessWidth", "Unset a previously set hard process width.", &ParticleData::doUnsetHardProcessWidth, false); interfaceStable.rank(14); interfaceDecayModes.rank(13); interfaceMass.rank(12); interfaceWidth.rank(11); interfaceWidthCut.rank(10); interfaceCTau.rank(9); interfaceMassGenerator.rank(8); interfaceWidthGenerator.rank(7); interfaceWidthUpCut.rank(-0.1); interfaceWidthLoCut.rank(-0.1); - } string ParticleData::doPrintDecayModes(string) { multimap > sorted; for ( DecaySet::iterator it = decayModes().begin(); it != decayModes().end(); ++it ) sorted.insert(make_pair((**it).brat(), *it)); ostringstream os; - for ( multimap >::iterator it = sorted.begin(); it != sorted.end(); ++it ) os << it->second->tag() << (it->second->on()? " ": " (off) ") << it->first << endl; return os.str(); } string ParticleData::doSelectDecayModes(string args) { DecaySet on; while ( !args.empty() ) { string arg = StringUtils::car(args); if ( arg == "all" ) { on = decayModes(); break; } if ( arg == "none" ) { on.clear(); break; } string name = arg; args = StringUtils::cdr(args); if ( arg.empty() ) continue; if ( arg[0] != '/' ) arg = fullName() + "/" + arg; DMPtr dm = Repository::GetPtr(arg); if ( !dm ) return "Error: No decay mode with tag '" + name + "' exists."; on.insert(dm); } for ( DecaySet::iterator it = decayModes().begin(); it != decayModes().end(); ++it ) { if ( on.find(*it) != on.end() ) { (**it).switchOn(); on.erase(*it); } else { (**it).switchOff(); } } if ( !on.empty() ) return "Error: decay mode '" + (**on.begin()).tag() + "'was not available."; return ""; } void ParticleData::insDecayModes(DMPtr dm, int) { addDecayMode(dm); } void ParticleData::delDecayModes(int i) { vector mv = getDecayModes(); if ( i >= 0 && static_cast(i) < mv.size() ) removeDecayMode(mv[i]); } vector ParticleData::getDecayModes() const { return vector(theDecayModes.begin(), theDecayModes.end()); } ParticleChargeCommand:: ParticleChargeCommand(const ParticleData & pd, string arg) { theMessage << "Cannot set the charge of particle '" << pd.name() << "' to '" << arg << "'."; severity(warning); } void ParticleData::doinit() { Interfaced::doinit(); if( theMassGenerator ) theMassGenerator->init(); if( theWidthGenerator ) theWidthGenerator->init(); } void ParticleData::doinitrun() { Interfaced::doinitrun(); if( theMassGenerator ) theMassGenerator->initrun(); if( theWidthGenerator ) theWidthGenerator->initrun(); } } diff --git a/PDT/ParticleData.h b/PDT/ParticleData.h --- a/PDT/ParticleData.h +++ b/PDT/ParticleData.h @@ -1,968 +1,1004 @@ // -*- C++ -*- // // ParticleData.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 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_ParticleData_H #define ThePEG_ParticleData_H // This is the declaration of the ParticleData class. #include "ThePEG/Config/ThePEG.h" #include "ThePEG/PDT/PDT.h" #include "ThePEG/PDT/PID.h" #include "ThePEG/Vectors/LorentzVector.h" #include "ThePEG/Vectors/ThreeVector.h" #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Utilities/Selector.h" #include "ThePEG/PDT/WidthGenerator.h" #include "ThePEG/PDT/MassGenerator.h" #include "ThePEG/PDT/DecayMode.fh" #include "ThePEG/Utilities/ClassTraits.h" #include "ThePEG/Utilities/ClassDescription.h" namespace ThePEG { /** * ParticleData inherits from InterfacedBase and represents the * properties of a particle type. It is also able to produce instances * of this Particle type and, among other things, to decay them. * * @see \ref ParticleDataInterfaces "The interfaces" * defined for ParticleData. */ class ParticleData: public Interfaced { public: /** The Repository is a friend. */ friend class Repository; /** The EventGenerator is a friend. */ friend class EventGenerator; /** DecayMode is a friend. */ friend class DecayMode; /** A selector of DecayMode objects. */ typedef Selector DecaySelector; public: /** @name Standard constructors and destructors. */ //@{ /** * Default constructor. */ ParticleData(); /** * Destructor. */ virtual ~ParticleData(); //@} /** @name The Create methods are special interfaces for ParticleData classes. */ //@{ /** * Create a Particle which is its own anti-particle. */ static PDPtr Create(PID newId, const string & newPDGName); /** * Create a particle - anti particle pair. */ static PDPair Create(PID newId, const string & newPDGName, const string & newAntiPDGName); //@} public: /** @name Acces to number and name. */ //@{ /** * Return the PDG id number. */ long id() const { return theId; } /** * Return the generic PDG name. Note that this is not really * standardised. */ const string & PDGName() const { return thePDGName; } /** * Return the generic PDG name. Note that this is not really * standardised. */ const string & genericName() const { return thePDGName; } //@} /** @name Functions used for producing Particle instances. */ //@{ /** * Produce a particle specifying momentum. */ PPtr produceParticle(const Lorentz5Momentum &) const; /** * Produce a particle specifying momentum. */ PPtr produceParticle(const LorentzMomentum &) const; /** * Produce a particle specifying 4-momentum and a mass. */ PPtr produceParticle(const LorentzMomentum &, Energy m) const; /** * Produce a particle specifying 3-momentum. */ PPtr produceParticle(const Momentum3 & pp = Momentum3()) const; /** * Produce a particle specifying mass and 3-momentum. */ PPtr produceParticle(Energy m, const Momentum3 & pp = Momentum3()) const; /** * Produce a particle specifying light-cone momentum components and * transverse momentum components. */ PPtr produceParticle(Energy plus, Energy minus, Energy px, Energy py) const; /** * Generate a mass for an instance of this particle type. */ Energy generateMass() const; /** * Generate a width for an instance of this particle type. Given a * \a mass of an instance of this particle type, calculate its width. */ Energy generateWidth(Energy mass) const; /** * Generate a mass for an instance of this particle type. Given a \a * mass and a \a width of an instance of this particle type, * generate a life time. */ Length generateLifeTime(Energy mass, Energy width) const; // Given a mass and a width of an instance of this particle type, // generate a life time. //@} /** @name Access the decay modes. */ //@{ /** * Return the nominal decay selector for this particle. Ie. the * decay modes weighted by their nominal branching ratios. */ const DecaySelector & decaySelector() const { return theDecaySelector; } /** * Selects a decay mode randomly according to the branching * ratios. The nominal branching ratios may be changed for the * particular Particle instance \a p, iether by an assigned * WidthGenerator or the respective Decayers. */ tDMPtr selectMode(Particle & p) const; /** * Access all the decay modes, including those which are * switched off, or have zero branching ratio */ const DecaySet & decayModes() const { return theDecayModes; } //@} /** * Set the nominal mass */ Energy mass(Energy); /** * Return the nominal mass. */ Energy mass() const { return theMass; } /** * Return the mass to be used when evaluating hard process cross sections. */ Energy hardProcessMass() const { return hardProcessMassSet ? theHardProcessMass : mass(); } /** * Return the maximum possible mass of this particle type. */ Energy massMax() const { return mass() + widthUpCut(); } /** * Return the minimum possible mass of this particle type. */ Energy massMin() const { return max(mass() - widthLoCut(), ZERO); } /** * Return the constituent mass of this particle if relevant. This * version simply returns the nominal mass. */ virtual Energy constituentMass() const { return mass(); } /** * Set the width. */ Energy width(Energy); /** * Get the width. If no width is specified, it is calculated from * the lifetime. */ Energy width() const { return theWidth >= ZERO ? theWidth : ( theCTau > Length() ? hbarc/theCTau : ( theCTau == Length() ? Constants::MaxEnergy : ZERO ) ); } /** * Set the width cut. Both upper and lower cut is set. */ Energy widthCut(Energy wci) { widthUpCut(wci); return widthLoCut(wci); } /** * Get the width cut. */ Energy widthCut() const { return max(widthUpCut(), widthLoCut()); } /** * Set the upper width cut. */ Energy widthUpCut(Energy); /** * Get the upper width cut. */ Energy widthUpCut() const { return theWidthUpCut >= ZERO? theWidthUpCut: Constants::MaxEnergy; } /** * Set the lower width cut. */ Energy widthLoCut(Energy); /** * Get the lower width cut. */ Energy widthLoCut() const { return theWidthLoCut >= ZERO? theWidthLoCut: Constants::MaxEnergy; } /** * Set the life time cTau. */ Length cTau(Length); /** * Get the life time cTau cTau. If no life time is specified, it is * calculated from the width. If the width is also not specified, * the lifetime is assumed to be zero for ustable particles and * infinite for stable ones. */ Length cTau() const { return theCTau > Length() ? theCTau : ( theWidth > ZERO ? hbarc/theWidth : ( stable() ? Constants::MaxLength : Length() ) ); } /** * Return the width to be used when evaluating hard process cross sections. */ Energy hardProcessWidth() const { return hardProcessWidthSet ? theHardProcessWidth : width(); } /** * Set the charge. The charge should be given * in units of e/3 using the PDT::Charge enum. */ PDT::Charge iCharge(PDT::Charge); /** * Get the charge. The charge is returned in standard units and in * iCharge the charge is returned in units of e/3. */ Charge charge() const { return eplus*double(theCharge)/3.0; } /** * Get the charge. The charge is returned in units of e/3. */ PDT::Charge iCharge() const { return theCharge; } /** * Return true if charged. */ bool charged() const { return PDT::charged(theCharge); } /** * Return true if positively charged. */ bool positive() const { return PDT::positive(theCharge); } /** * Return true if negatively charged. */ bool negative() const { return PDT::negative(theCharge); } /** * Set the spin. The spin should be given as 2J+1 (in units of * hbar/2) using the PDT::Spin enum. */ PDT::Spin iSpin(PDT::Spin); /** * Get the spin.The spin is returned in standard units. */ AngularMomentum spin() const { return hbar_Planck*double(theSpin-1)*0.5; } /** * Get the spin. The spin is returned as 2J+1 in units of hbar/2. */ PDT::Spin iSpin() const { return theSpin; } /** * Set the colour of the particle in units of PDT::Colour. */ PDT::Colour iColour(PDT::Colour); /** * Get the colour of the particle in units of PDT::Colour. */ PDT::Colour iColour() const { return theColour; } /** * Return true if coloured. */ bool coloured() const { return PDT::coloured(iColour()); } /** * Return true if (\a anti) coloured or colour-octet. */ bool hasColour(bool anti = false) const { return anti? hasAntiColour(): ( iColour() == PDT::Colour3 || iColour() == PDT::Colour6 || iColour() == PDT::Colour8 ); } /** * Return true if anti coloured or colour-octet. */ bool hasAntiColour() const { return iColour() == PDT::Colour3bar || iColour() == PDT::Colour6bar || iColour() == PDT::Colour8; } /** + * Return what kind of colour charge this particle carries + */ + PDT::ColouredInteraction colouredInteraction() const { + return theColouredInteraction; + } + + /** * Specify if particle is to be considered stable according to \a * stab. */ void stable(bool stab); /** * Return true if particle is to be considered stable. If the decay * table is empty the function always returns true, even if the * member variable is false. */ bool stable() const { return isStable; } /** * Get the pointer to the corresponding anti partner. */ tPDPtr CC() const { return theAntiPartner; } /** * Specify if the anti partner chould be changed automatically when * this object is changed according to \a sync. */ void synchronized(bool sync); /** * Return true if the anti partner chould be changed automatically * when this object is changed. */ bool synchronized() const { return syncAnti; } /** * If there is an anti-partner, update this object to have correct * anti-properties. */ void synchronize(); /** * Set the mass generator object. */ void massGenerator(tMassGenPtr); /** * Get the mass generator object. */ tMassGenPtr massGenerator() const { return theMassGenerator; } /** * Set the width generator object. */ void widthGenerator(tWidthGeneratorPtr); /** * Get the width generator object. */ tWidthGeneratorPtr widthGenerator() const { return theWidthGenerator; } /** * Specify if the branching ratio of the Particle instances should vary with their * masses. */ void variableRatio(bool varRatio); /** * Return true if the branching ratio should vary with the mass of the Particle * instance. */ bool variableRatio() const { return theVariableRatio; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} /** * Special clone function used by the Repository. Also makes copies * the decay modes and the anti-partner if it exists and if * synchronized() is true. */ virtual PDPtr pdclone() const; /** * Protected constructor only to be used by subclasses or by the * Create method. */ ParticleData(PID newId, const string & newPDGName); /** * Read setup info from a standard stream. The following information * must be supplied in a white-space separated list: PDG number, * generic name, default mass (GeV), default width (GeV), width cut * (GeV), the lifetime ctau (mm), the charge, the colour, the spin, * stable (true) or not (false). Note that if a minus sign is given * instead of a generic name, the name of the object will be used * instead. */ virtual void readSetup(istream & is); /** * Used by subclasses or by the Create method to setup * anti-relationship. */ static void antiSetup(const PDPair & pap); protected: /** @name Standard Interfaced functions. */ //@{ /** * Check sanity of the object during the setup phase. */ virtual void doupdate(); /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans) ; /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} protected: /** * Add a decay mode for this particle. */ void addDecayMode(tDMPtr); /** * Remove a decay mode for this particle. */ void removeDecayMode(tDMPtr); private: /** * Id number according to the STDHEP/PDG standard. */ PID theId; /** * Name and Id number according to the STDHEP/PDG standard. */ string thePDGName; /** * Nominal mass. */ Energy theMass; /** * Width. */ Energy theWidth; /** * The mass to be used when evaluating hard process cross sections. */ Energy theHardProcessMass; /** * True, if a hard process mass has been set. */ bool hardProcessMassSet; /** * The width to be used when evaluating hard process cross sections. */ Energy theHardProcessWidth; /** * True, if a hard process width has been set. */ bool hardProcessWidthSet; /** * Upper width cut. */ Energy theWidthUpCut; /** * Lower width cut. */ Energy theWidthLoCut; /** * Lifetime. */ Length theCTau; /** * Three times the charge. */ PDT::Charge theCharge; /** * 2 times the spin plus one. */ PDT::Spin theSpin; /** * The colour for this particle. */ PDT::Colour theColour; /** + * The coloured interaction of this particle + */ + PDT::ColouredInteraction theColouredInteraction; + + /** + * The nonabelian interaction of this particle + */ + + /** * A pointer to an object capable to generate a mass for a particle * of this type. */ MassGenPtr theMassGenerator; /** * True if the particle is considered stable. */ bool isStable; /** * A selector of decay modes weighted by the nominal branching * ratios. */ DecaySelector theDecaySelector; /** * The set of all decay modes. */ DecaySet theDecayModes; /** * A pointer to an object capable to generate the branching * fractions for different decay modes for this particle type. The * object will be asked to generate branching fractions every time * the ParticleData object it updated and will modify the branching * fractions for every particle instance if variableRatio is true. */ WidthGeneratorPtr theWidthGenerator; /** * Determine whether the branching fractions are allowed to change * on a particle-by-particle basis. */ bool theVariableRatio; /** * Pointer to the object corresponding to the antiparticle. Set to * null if it is its own antiparticle. */ tPDPtr theAntiPartner; /** * If syncAnti is true all changes to this object will be transfered * to the antiParticle. */ bool syncAnti; /** * Helper variable to keep track of the default mass. */ Energy theDefMass; /** * Helper variable to keep track of the default width. */ Energy theDefWidth; /** * Helper variable to keep track of the default width cut. */ Energy theDefCut; /** * Helper variable to keep track of the default lifetime. */ Length theDefCTau; /** * Helper variable to keep track of the default charge. */ PDT::Charge theDefCharge; /** * Helper variable to keep track of the default spin. */ PDT::Spin theDefSpin; /** * Helper variable to keep track of the default colour. */ PDT::Colour theDefColour; /** + * Helper variable to keep track of the default coloured interaction. + */ + PDT::ColouredInteraction theDefColouredInteraction; + + /** * Utility function for the interface. */ void setMass(Energy); /** * Utility function for the interface. */ void setHardProcessMass(Energy); /** * Reset the hard process mass */ string doUnsetHardProcessMass(string); /** * Adjust the nominal mass to the hard process mass if a reshuffling * is not desirable. */ string doAdjustNominalMass(string); /** * Utility function for the interface. */ Energy defMass() const; /** * Utility function for the interface. */ void setWidth(Energy); /** * Utility function for the interface. */ void setHardProcessWidth(Energy); /** * Reset the hard process mass */ string doUnsetHardProcessWidth(string); /** * Utility function for the interface. */ Energy getWidth() const; /** * Utility function for the interface. */ Energy defWidth() const; /** * Utility function for the interface. */ void setCut(Energy); /** * Utility function for the interface. */ Energy getCut() const; /** * Utility function for the interface. */ Energy defCut() const; /** * Utility function for the interface. */ void setUpCut(Energy); /** * Utility function for the interface. */ Energy getUpCut() const; /** * Utility function for the interface. */ void setLoCut(Energy); /** * Utility function for the interface. */ Energy getLoCut() const; /** * Utility function for the interface. */ void setCTau(Length); /** * Utility function for the interface. */ Length getCTau() const; /** * Utility function for the interface. */ Length defCTau() const; /** * Utility function for the interface. */ void setStable(long); /** * Utility function for the interface. */ long getStable() const; /** * Utility function for the interface. */ void setSync(long); /** * Utility function for the interface. */ long getSync() const; /** * Utility function for the interface. */ void setVariableRatio(long); /** * Utility function for the interface. */ long getVariableRatio() const; /** * Utility function for the interface. */ string doSync(string); /** * Utility function for the interface. */ void setMassGenerator(MassGenPtr); /** * Utility function for the interface. */ void setWidthGenerator(WidthGeneratorPtr); /** * Utility function for the interface. */ void setCharge(int); /** * Utility function for the interface. */ string ssetCharge(string); /** * Utility function for the interface. */ int getCharge() const; /** * Utility function for the interface. */ int defCharge() const; /** * Utility function for the interface. */ void setSpin(int); /** * Utility function for the interface. */ int getSpin() const; /** * Utility function for the interface. */ int defSpin() const; /** * Utility function for the interface. */ void setColour(long); /** * Utility function for the interface. */ long getColour() const; /** * Utility function for the interface. */ long defColour() const; /** * Utility function for the interface. */ + void setColouredInteraction(long); + + /** + * Utility function for the interface. + */ + long getColouredInteraction() const; + + /** + * Utility function for the interface. + */ + long defColouredInteraction() const; + + /** + * Utility function for the interface. + */ void insDecayModes(DMPtr dm, int); /** * Utility function for the interface. */ void delDecayModes(int i); /** * Utility function for the interface. */ vector getDecayModes() const; /** * Utility function for the interface. */ string doSelectDecayModes(string); /** * Utility function for the interface. */ string doPrintDecayModes(string); /** * Describe a concrete class with persistent data. */ static ClassDescription initParticleData; }; /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of ParticleData. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of ParticleData. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of the * ParticleData class. */ template <> struct ClassTraits: public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::ParticleData"; } }; /** @endcond */ } #endif /* ThePEG_ParticleData_H */