Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F9514739
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Subscribers
None
View Options
diff --git a/Hadronization/Makefile.am b/Hadronization/Makefile.am
--- a/Hadronization/Makefile.am
+++ b/Hadronization/Makefile.am
@@ -1,21 +1,21 @@
if PYTHIA8WORKS
-mySOURCES = StringFragmentation.cc TheP8EventShapes.cc StringPipe.cc OverlapPythiaHandler.cc RandomAverageHandler.cc RandomHandler.cc VanillaPythiaHandler.cc
+mySOURCES = StringFragmentation.cc TheP8EventShapes.cc StringPipe.cc OverlapPythiaHandler.cc RandomAverageHandler.cc RandomHandler.cc VanillaPythiaHandler.cc Ropewalk.cc
-DOCFILES = StringFragmentation.h TheP8EventShapes.h OverlapEnhancementHandler.h StringPipe.h OverlapPythiaHandler.h RandomAverageHandler.h RandomHandler.h VanillaPythiaHandler.h
+DOCFILES = StringFragmentation.h TheP8EventShapes.h OverlapEnhancementHandler.h StringPipe.h OverlapPythiaHandler.h RandomAverageHandler.h RandomHandler.h VanillaPythiaHandler.h Ropewalk.h
AUTOGENERATED = StringFragmentation-var.h StringFragmentation-init.h \
StringFragmentation-input.h StringFragmentation-output.h \
StringFragmentation-interfaces.h
INCLUDEFILES = $(DOCFILES) $(AUTOGENERATED)
AM_CPPFLAGS += -I/usr/local/new/include/
noinst_LTLIBRARIES = libTheP8IString.la
libTheP8IString_la_SOURCES = $(mySOURCES) $(INCLUDEFILES)
endif
include $(top_srcdir)/Config/Makefile.aminclude
diff --git a/Hadronization/Ropewalk.cc b/Hadronization/Ropewalk.cc
new file mode 100644
--- /dev/null
+++ b/Hadronization/Ropewalk.cc
@@ -0,0 +1,257 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the Ropewalk class.
+//
+
+#include "Ropewalk.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/EventRecord/Step.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/CurrentGenerator.h"
+#include "ThePEG/PDT/EnumParticles.h"
+#include "ThePEG/Utilities/Selector.h"
+#include "ThePEG/Utilities/SimplePhaseSpace.h"
+#include "ThePEG/Utilities/UtilityBase.h"
+#include "ThePEG/Handlers/StepHandler.h"
+
+
+
+using namespace TheP8I;
+
+Ropewalk::Ropewalk(const vector<ColourSinglet> & singlets, Length width,
+ Energy scale)
+ : R0(width), m0(scale) {
+ for ( int is = 0, Ns = singlets.size(); is < Ns; ++is )
+ stringdipoles[new ColourSinglet(singlets[is])];
+ getDipoles();
+ calculateOverlaps();
+ doBreakups();
+}
+
+Ropewalk::~Ropewalk() {
+ for ( DipoleMap::iterator it = stringdipoles.begin();
+ it != stringdipoles.end(); ++it ) delete it->first;
+}
+
+LorentzPoint Ropewalk::
+propagate(const LorentzPoint & b, const LorentzMomentum & p) const {
+ return b + p/(p.e()*max(m0, p.m())/hbarc);
+}
+
+void Ropewalk::getDipoles() {
+
+ // First extract all dipoles from all strings (pieces).
+ for ( DipoleMap::iterator it = stringdipoles.begin();
+ it != stringdipoles.end(); ++it ) {
+ ColourSinglet & string = *it->first;
+ for ( int isp = 1, Nsp = string.nPieces(); isp <= Nsp; ++isp ) {
+ const ColourSinglet::StringPiece & sp = string.piece(isp);
+ for ( int i = 0, N = sp.size(); i < (N - 1); ++i ) {
+ if ( sp[i]->colourLine() &&
+ sp[i]->colourLine() == sp[i+1]->antiColourLine() )
+ dipoles.push_back(Dipole(sp[i], sp[i +1 ], string));
+ else if ( sp[i]->antiColourLine() &&
+ sp[i]->antiColourLine() == sp[i+1]->colourLine() )
+ dipoles.push_back(Dipole(sp[i + 1], sp[i], string));
+ }
+ if ( sp.front()->colourLine() &&
+ sp.front()->colourLine() == sp.back()->antiColourLine() )
+ dipoles.push_back(Dipole(sp.front(), sp.back(), string));
+ else if ( sp.front()->antiColourLine() &&
+ sp.front()->antiColourLine() == sp.back()->colourLine() )
+ dipoles.push_back(Dipole(sp.back(), sp.front(), string));
+ }
+ }
+
+ for ( int i = 0, N = dipoles.size(); i < N; ++i )
+ stringdipoles[dipoles[i].string].push_back(&dipoles[i]);
+
+}
+
+void Ropewalk::calculateOverlaps() {
+
+ // Then calculate all overlaps between pairs of dipoles.
+ for ( int i1 = 0, Nd = dipoles.size(); i1 < Nd; ++i1 ) {
+ Dipole & d1 = dipoles[i1];
+ // Get the boost to dipoles rest frame and calculate rapidities.
+ LorentzMomentum pc1 = d1.pc->momentum();
+ LorentzMomentum pa1 = d1.pa->momentum();
+ LorentzRotation R = Utilities::getBoostToCM(make_pair(&pc1, &pa1));
+ LorentzPoint bc1 = R*propagate(d1.pc->vertex(), d1.pc->momentum());
+ LorentzPoint ba1 = R*propagate(d1.pa->vertex(), d1.pa->momentum());
+ double yc1 = log((pc1.e() + pc1.z())/max(m0, pc1.m()));
+ double ya1 = log((pa1.e() - pa1.z())/max(m0, pa1.m()));
+ double n = 0.0;
+ double m = 0.0;
+ if ( yc1 <= ya1 ) continue; // don't care about too small strings.
+ for ( int i2 = 0; i2 < Nd; ++i2 ) {
+ if ( i1 == i2 ) continue;
+ // Boost to the rest frame of dipole 1.
+ Dipole & d2 = dipoles[i2];
+ // Get the boost to dipoles rest frame and calculate rapidities.
+ LorentzMomentum pc2 = R*d2.pc->momentum();
+ LorentzMomentum pa2 = R*d2.pa->momentum();
+ LorentzPoint bc2 = R*propagate(d2.pc->vertex(), d2.pc->momentum());
+ LorentzPoint ba2 = R*propagate(d2.pa->vertex(), d2.pa->momentum());
+ double yc2 = log((pc2.e() + pc2.z())/max(m0, pc2.m()));
+ double ya2 = log((pa2.e() - pa2.z())/max(m0, pa2.m()));
+ // Ignore if not overlapping in rapidity.
+ if ( min(yc2, ya2) > yc1 || max(yc2, ya2) < ya1 ) continue;
+ // Calculate rapidity overlap.
+ double yomax = min(max(yc2, ya2), yc1);
+ double yomin = max(min(yc2, ya2), ya1);
+ // Sample a random point in the rapidity overlap region and get
+ // position in space.
+ double y = UseRandom::rnd(yomin, yomax);
+ LorentzPoint b1 = ba1 + (bc1 - ba1)*(y - ya1)/(yc1 - ya1);
+ LorentzPoint b2 = ba2 + (bc2 - ba2)*(y - ya2)/(yc2 - ya2);
+ // Skip if there is no overlap in transverse position.
+ if ( (b1 - b2).perp() > R0 ) continue;
+ // Register the overlap.
+ double yfrac = (yomax - yomin)/(yc1 - ya1);
+ if ( yc2 > ya2 ) {
+ d1.overlaps.push_back(make_pair(&d2, yfrac));
+ n += yfrac;
+ } else {
+ d1.overlaps.push_back(make_pair(&d2, -yfrac));
+ m += yfrac;
+ }
+ }
+ d1.n = int(n + UseRandom::rnd());
+ d1.m = int(m + UseRandom::rnd());
+ d1.initMultiplet();
+ }
+}
+
+void Ropewalk::Dipole::initMultiplet() {
+ typedef pair<int,int> Plet;
+
+ int ns = 0;
+ int ms = 0;
+ while ( ns < n || ms < m ) {
+ Plet diff;
+ double octetveto = double(ns + ms + 1 - p - q)/double(ns + ms + q);
+ if ( ns < n && ( ms == m || UseRandom::rndbool() ) ) {
+ Selector<Plet> sel;
+ sel.insert(multiplicity(p + 1, q), Plet(1, 0));
+ sel.insert(multiplicity(p, q - 1)*octetveto, Plet(0, -1));
+ sel.insert(multiplicity(p - 1, q + 1), Plet(-1, 1));
+ diff = sel[UseRandom::rnd()];
+ ++ns;
+ } else {
+ Selector<Plet> sel;
+ sel.insert(multiplicity(p, q + 1), Plet(0, 1));
+ sel.insert(multiplicity(p - 1, q)*octetveto, Plet(-1, 0));
+ sel.insert(multiplicity(p + 1, q - 1), Plet(1, -1));
+ diff = sel[UseRandom::rnd()];
+ ++ms;
+ }
+ p += diff.first;
+ q += diff.second;
+ }
+ /* *** ATTENTION *** maybe better if Christian implements this */
+
+}
+
+double Ropewalk::Dipole::breakupProbability() const {
+ if ( n + m <= 0.0 || n + m + 1 == p + q ) return 0.0;
+ double sum = 0.0;
+ for (int j = 0, N = overlaps.size(); j < N; ++j )
+ if ( overlaps[j].first->breakable() )
+ sum += abs(overlaps[j].second);
+ if ( sum <= 0.0 ) return 1.0;
+ return double(n + m + 1 - p - q)/(sum + 1.0);
+}
+
+Step & Ropewalk::step() const {
+ return *(CurrentGenerator()->currentStepHandler()->newStep());
+}
+
+
+
+void Ropewalk::doBreakups() {
+
+ // We need to be able to select diquarks.
+ Selector<int> disel;
+ disel.insert(1.0, ParticleID::ud_0);
+ disel.insert(3.0, ParticleID::dd_1);
+ disel.insert(3.0, ParticleID::ud_1);
+ disel.insert(3.0, ParticleID::uu_1);
+
+ typedef multimap<double, const Dipole *> BMap;
+ BMap breakups;
+
+ // First order alldipoles in increasing probability of breaking
+ for ( int i = 0, N = dipoles.size(); i < N; ++i )
+ breakups.insert(make_pair(dipoles[i].breakupProbability(), &dipoles[i]));
+
+ // Then start breaking in reverse order
+ for ( BMap::reverse_iterator it = breakups.rbegin();
+ it != breakups.rend(); ++it ) {
+ const Dipole & d = *it->second;
+ if ( d.breakupProbability() < UseRandom::rnd() ) continue;
+ // Select di-quarks
+ int flav = disel[UseRandom::rnd()];
+ PPtr dia = CurrentGenerator()->getParticle(flav);
+ PPtr dic = CurrentGenerator()->getParticle(-flav);
+ // Get boost to dipole rest frame and place the di-quarks there.
+ LorentzRotation R = Utilities::getBoostFromCM(make_pair(d.pc, d.pa));
+ SimplePhaseSpace::CMS(dic, dia, d.s(), 1.0, 0.0);
+ dia->transform(R);
+ dic->transform(R);
+ // Add the di-quarks as children to the decayed gluons and split
+ // the resulting string.
+ step().addDecayProduct(d.pc, dic, true);
+ step().addDecayProduct(d.pa, dia, true);
+ step().addDecayProduct(d.pc, dia, false);
+ step().addDecayProduct(d.pa, dic, false);
+ tcParticleSet pset(d.string->partons().begin(), d.string->partons().end());
+ pset.erase(d.pc);
+ pset.erase(d.pa);
+ pset.insert(dic);
+ pset.insert(dia);
+ // remove the old stringand insert the new ones fixing the
+ // pointers from the dipoles.
+ ColourSinglet * olds = d.string;
+ const vector<Dipole *> & oldd = stringdipoles[olds];
+ vector<ColourSinglet> newstrings =
+ ColourSinglet::getSinglets(pset.begin(), pset.end());
+ for ( int is = 0, Ns = newstrings.size(); is < Ns; ++is ) {
+ ColourSinglet * news = new ColourSinglet(newstrings[is]);
+ tcParticleSet pset(newstrings[is].partons().begin(),
+ newstrings[is].partons().end());
+ for ( int id = 0, Nd = oldd.size(); id < Nd; ++id ) {
+ if ( pset.find(oldd[id]->pc) != pset.end() ) {
+ stringdipoles[news].push_back(oldd[id]);
+ oldd[id]->string = news;
+ }
+ }
+ }
+ stringdipoles.erase(olds);
+ delete olds;
+ }
+}
+
+vector< pair<ColourSinglet,double> > Ropewalk::getSingets() const {
+ vector< pair<ColourSinglet,double> > ret;
+ ret.reserve(stringdipoles.size());
+ // Calculate the kappa-enhancement of the remaining strings.
+ for ( DipoleMap::const_iterator it = stringdipoles.begin();
+ it != stringdipoles.end(); ++it ) {
+ double sumyh = 0.0;
+ double sumy = 0.0;
+ for ( int id = 0, Nd = it->second.size(); id < Nd; ++id ) {
+ double y = it->second[id]->yspan(m0);
+ double h = it->second[id]->kappaEnhancement();
+ sumy += y;
+ sumyh += y*h;
+ }
+ ret.push_back(make_pair(*it->first, sumy/sumyh));
+ }
+ return ret;
+}
+
+
+
diff --git a/Hadronization/Ropewalk.h b/Hadronization/Ropewalk.h
new file mode 100644
--- /dev/null
+++ b/Hadronization/Ropewalk.h
@@ -0,0 +1,210 @@
+// -*- C++ -*-
+#ifndef TheP8I_Ropewalk_H
+#define TheP8I_Ropewalk_H
+//
+// This is the declaration of the Ropewalk class.
+//
+
+#include "TheP8I/Config/Pythia8Interface.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/EventRecord/ColourSinglet.h"
+
+namespace TheP8I {
+
+using namespace ThePEG;
+
+/**
+ * Here is the documentation of the Ropewalk class.
+ */
+class Ropewalk {
+
+public:
+
+ /**
+ * Container class containing information about individual dipole overlaps.
+ */
+ struct Dipole {
+
+ /**
+ * Constructor.
+ */
+ Dipole(tcPPtr p1, tcPPtr p2, ColourSinglet & str)
+ : pc(p1), pa(p2), string(&str), n(0), m(0), p(1), q(0) {}
+
+ /**
+ * Return true if this dipole is breakable. Only dipoles between
+ * gluons (not belonging to other dipoles which have broken) and
+ * which has a mass above 2 GeV can break.
+ */
+ bool breakable() const {
+ return pc->id() == ParticleID::g && pa->id() == ParticleID::g &&
+ !pc->decayed() && !pa->decayed() && s() > 4.0*GeV2;
+ }
+
+ /**
+ * Calculate the probability that this dipole should break. Taking
+ * into account the number of negative steps in the colour space
+ * and the fraction of overlapping dipoles which are ablle to
+ * break.
+ */
+ double breakupProbability() const;
+
+ /**
+ * Set and return the effective multiplet.
+ */
+ void initMultiplet();
+
+ /**
+ * Calculate the multiplicity given pp and qq;
+ */
+ static double multiplicity(int pp, int qq) {
+ return ( pp < 0 || qq < 0 || pp + qq == 0 )? 0.0:
+ 0.5*(pp + 1)*(qq + 1)*(pp + qq + 2);
+ }
+
+ /**
+ * Calculate the kappa-enhancement.
+ */
+ double kappaEnhancement() const {
+ return 0.25*(p + q + 3 - p*q/double(p + q));
+ }
+
+ /**
+ * Return the squared invariant mass of this dipole.
+ */
+ Energy2 s() const {
+ return (pc->momentum() + pa->momentum()).m2();
+ }
+
+ /**
+ * Return the effective rapidityspan of this dipole.
+ */
+ double yspan(Energy m0) const {
+ return 0.5*log(s()/sqr(m0));
+ }
+
+ /**
+ * The coloured particle.
+ */
+ tcPPtr pc;
+
+ /**
+ * The anti-coloured particle.
+ */
+ tcPPtr pa;
+
+ /**
+ * The overlapping dipoles with the amount of overlap (negative
+ * means anti overlap).
+ */
+ vector< pair<const Dipole *, double> > overlaps;
+
+ /**
+ * The string to which this Dipole belongs.
+ */
+ ColourSinglet * string;
+
+ /**
+ * The summed parallel (n) and anti-parallel (m) overlaps from
+ * other dipoles.
+ */
+ int n, m;
+
+ /**
+ * The multiplet.
+ */
+ int p, q;
+
+ };
+
+
+ /**
+ * Convenient typedef
+ */
+ typedef map<ColourSinglet *, vector<Dipole *> > DipoleMap;
+
+public:
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ Ropewalk(const vector<ColourSinglet> & singlets, Length width,
+ Energy scale);
+
+ /**
+ * The destructor.
+ */
+ virtual ~Ropewalk();
+ //@}
+
+
+ /**
+ * Return all ColourSinglet objects with their kappa enhancement.
+ */
+ vector< pair<ColourSinglet,double> > getSingets() const;
+
+protected:
+
+ /**
+ * Extract all dipoles.
+ */
+ void getDipoles();
+
+ /**
+ * Calculate all overlaps and initialize multiplets in all dipoles.
+ */
+ void calculateOverlaps();
+
+ /**
+ * Break dipoles (and strings)
+ */
+ void doBreakups();
+
+ /**
+ * Propagate a parton a finite time inthe lab-system.
+ */
+ LorentzPoint propagate(const LorentzPoint & b,
+ const LorentzMomentum & p) const;
+ /**
+ * Return the current step.
+ */
+ Step & step() const;
+
+
+private:
+
+ /**
+ * The assumed radius of a string.
+ */
+ Length R0;
+
+ /**
+ * The assumed mass for calculating rapidities
+ */
+ Energy m0;
+
+ /**
+ * The vector of all Dipoles
+ */
+ vector<Dipole> dipoles;
+
+ /**
+ * All Dipoles in all string
+ */
+ DipoleMap stringdipoles;
+
+private:
+
+ /**
+ * The assignment operator is private and must never be called.
+ * In fact, it should not even be implemented.
+ */
+ Ropewalk & operator=(const Ropewalk &);
+
+};
+
+}
+
+#endif /* TheP8I_Ropewalk_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Feb 24, 6:39 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4494584
Default Alt Text
(14 KB)
Attached To
rTHEPEGPEIGHTIHG thepegpeightihg
Event Timeline
Log In to Comment