Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881264
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
41 KB
Subscribers
None
View Options
diff --git a/Hadronization/Ropewalk.cc b/Hadronization/Ropewalk.cc
--- a/Hadronization/Ropewalk.cc
+++ b/Hadronization/Ropewalk.cc
@@ -1,265 +1,296 @@
// -*- 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) {
+ Energy scale, bool deb)
+ : R0(width), m0(scale), debug(deb) {
for ( int is = 0, Ns = singlets.size(); is < Ns; ++is )
stringdipoles[new ColourSinglet(singlets[is])];
getDipoles();
+ if ( debug ) CurrentGenerator::log() << singlets.size() << "s "
+ << dipoles.size() << "d ";
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);
if ( sp.size() < 2 ) continue;
bool forward = sp[0]->colourLine() &&
sp[0]->colourLine() == sp[1]->antiColourLine();
for ( int i = 0, N = sp.size(); i < (N - 1); ++i ) {
if ( forward )
dipoles.push_back(Dipole(sp[i], sp[i + 1], string));
else
dipoles.push_back(Dipole(sp[i + 1], sp[i], string));
}
if ( !forward && sp.front()->colourLine() &&
sp.front()->colourLine() == sp.back()->antiColourLine() )
dipoles.push_back(Dipole(sp.front(), sp.back(), string));
else if ( forward && 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]);
}
double Ropewalk::limitrap(const LorentzMomentum & p) const {
if ( p.z() == ZERO ) return 0.0;
Energy mt = sqrt(max(p.perp2() + p.m2(), sqr(m0)));
double rap = log((p.t() + abs(p.z()))/mt);
return p.z() > ZERO? rap: -rap;
}
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 = limitrap(pc1);
double ya1 = limitrap(pa1);
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 = limitrap(pc2);
double ya2 = limitrap(pa2);
// 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 + 1);
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;
+ if ( !breakable() || 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);
+ PPtr dic = CurrentGenerator()->getParticle(flav);
+ PPtr dia = 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(news->partons().begin(), news->partons().end());
vector<Dipole *> & newd = stringdipoles[news];
for ( int id = 0, Nd = oldd.size(); id < Nd; ++id ) {
if ( pset.find(oldd[id]->pc) != pset.end() ) {
newd.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());
+ double toty = 0.0;
+ double totyh = 0.0;
+ double toth = 0.0;
+ double toth2 = 0.0;
+ double minh = 10.0;
+ double maxh = 0.0;
// 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;
}
- if ( sumyh > 0.0 ) ret.push_back(make_pair(*it->first, sumy/sumyh));
- else ret.push_back(make_pair(*it->first, 1.0));
+ toty += sumy;
+ totyh += sumyh;
+
+ if ( sumy > 0.0 ) {
+ ret.push_back(make_pair(*it->first, sumyh/sumy));
+ toth += sumyh/sumy;
+ toth2 += sqr(sumyh/sumy);
+ minh = min(minh, sumyh/sumy);
+ maxh = max(maxh, sumyh/sumy);
+ } else {
+ ret.push_back(make_pair(*it->first, 1.0));
+ toth += 1.0;
+ toth2 += 1.0;
+ minh = min(minh, 1.0);
+ maxh = max(maxh, 1.0);
+ }
}
+ if ( debug )
+ CurrentGenerator::log() << ret.size() << "ns "
+ << totyh/max(toty, 0.00001) << "hwa "
+ << minh << "<h "
+ << toth/ret.size() << "ha "
+ << maxh << ">h "
+ << sqrt(toth2/ret.size() - sqr(toth/ret.size())) << "hsd " << endl;
+
return ret;
+
}
diff --git a/Hadronization/Ropewalk.h b/Hadronization/Ropewalk.h
--- a/Hadronization/Ropewalk.h
+++ b/Hadronization/Ropewalk.h
@@ -1,217 +1,222 @@
// -*- 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
+ * and the fraction of overlapping dipoles which are able 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));
+ return max(0.5*log(s()/sqr(m0)), 0.0);
}
/**
* 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);
+ Energy scale, bool deb = false);
/**
* 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;
/**
* Calculate the rapidity of a Lorentz vector but limit the
* transverse mass to be above m0.
*/
double limitrap(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;
+ /**
+ * Debug flag.
+ */
+ bool debug;
+
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 */
diff --git a/Hadronization/StringFragmentation.cc b/Hadronization/StringFragmentation.cc
--- a/Hadronization/StringFragmentation.cc
+++ b/Hadronization/StringFragmentation.cc
@@ -1,639 +1,639 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the StringFragmentation class.
//
#include "StringFragmentation.h"
#include "Ropewalk.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/PDT/RemnantDecayer.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/EventRecord/Step.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DebugItem.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include <algorithm> // std::sort
using namespace TheP8I;
StringFragmentation::StringFragmentation()
: pythia(), overlapN(0), testPow(1.0), stringR0(0.5*femtometer), stringyCut(2.0), stringpTCut(6*GeV), fragmentationMass(0.134), baryonSuppression(2.), window(false), useThrustAxis(0), fragmentationScheme("none"), maxTries(2), doAnalysis(0), analysisPath(""),
#include "StringFragmentation-init.h"
{
}
StringFragmentation::~StringFragmentation() {
}
void StringFragmentation::handle(EventHandler & eh, const tPVector & tagged,
const Hint & h) {
++nev;
// Get the event
tPVector all = RemnantDecayer::decayRemnants(tagged, *newStep());
if(_eventShapes) _eventShapes->reset(all);
vector<ColourSinglet> singlets;
//singlets.clear();
//singlets = ColourSinglet::getSinglets(all.begin(), all.end());
// for (vector<ColourSinglet>::iterator sItr= singlets.begin(); sItr!=singlets.end();++sItr){
// cout << sItr->momentum().m2() / (GeV*GeV) << " " << sItr->momentum().perp() / GeV << endl;
// }
double havg = 0;
singlets.clear();
if ( theCollapser ) singlets = theCollapser->collapse(all, newStep());
else singlets = ColourSinglet::getSinglets(all.begin(), all.end());
// /* How to use the dipole-based overlap calculator */
- // Ropewalk ropewalk(singlets, 0.5*femtometer, 1.0*GeV);
+ // Ropewalk ropewalk(singlets, 0.5*femtometer, 1.0*GeV, true);
// vector< pair<ColourSinglet,double> > strings = ropewalk.getSingets();
// singlets.clear();
// singlets.reserve(strings.size());
// for ( int i = 0, N = strings.size(); i < N; ++i )
// singlets.push_back(strings[i].first);
enhance->clear();
vector<StringPipe> pipes;
vector<double> maxpT;
vector<size_t> position;
size_t ind = 0;
for(vector<ColourSinglet>::iterator sItr = singlets.begin(); sItr!=singlets.end(); ++sItr){
pipes.push_back(StringPipe(&(*sItr),stringR0,_eventShapes));
// maxpT.push_back(pipes.back().MaxpT()/GeV * pipes.back().MaxpT()/GeV + pipes.back().MaxpTRapidity() * pipes.back().MaxpTRapidity()); // Using pT*pT + y*y to sort
maxpT.push_back(pipes.back().MaxpT()/GeV); // using pT to sort
position.push_back(ind++);
}
// std::sort(position.begin(),position.end(),CompareDoubles(maxpT));
// Loop over singlets, find their h-factor using the handler, send them to the correct pythia
enhance->SetEvent(pipes);
//int cut = 0;
//int total = 0;
Pythia8Interface * pytone = opHandler->GetPythiaPtr(1.0,nev%10000==0);
forcerun = false;
// cout << "---" << endl;
int alls = 0;
int keep = 0;
for(vector<size_t>::iterator it = position.begin(); it!=position.end(); ++it){
vector<ColourSinglet> toHadronization;
//double h = 1.0;
//if(pipes[*it].MaxpT() > stringpTCut && abs(pipes[*it].MaxpTRapidity()) < stringyCut){
// cout << "pT = " << pipes[*it].MaxpT()/GeV << " y = " << pipes[*it].MaxpTRapidity() << endl;
//cout << generator()->currentEvent()->weight() << " " << pipes[*it]._internalOverlap.first << " " << pipes[*it]._internalOverlap.second << endl;
// cut++;
//}
//total++;
alls++;
double h = enhance->KappaEnhancement(pipes[*it]);
if(h > -998.0){
keep++;
Pythia8Interface * pytp = opHandler->GetPythiaPtr(h,nev%10000==0);
toHadronization.push_back(*(pipes[*it].GetSingletPtr()));
if(!hadronizeSystems(*pytp,toHadronization,all)) hadronizeSystems(*pytone,toHadronization,all);
}
/*{
int npartons = toHadronization.back().partons().size();
if(toHadronization.back().nPieces() > 1){
// Dont do any tricks if we have a junction
//cout << "Junction!" << endl;
hadronizeSystems(*pytp,toHadronization,all);
}
else if(npartons>10){
hadronizeSystems(*pytp,toHadronization,all);
}
else{
hadronizeSystems(*pytone,toHadronization,all);
}
}
*/
toHadronization.clear();
// Do short analysis here:
if(doAnalysis){
if(singlets.size() > 10){
ofstream out((analysisPath + "matlabstrings.txt").c_str(),ios::app);
out << "<event>" << endl;
out << PrintStringsToMatlab(singlets) << endl;
out << "</event>" << endl;
out.close();
}
}
}
ofstream out3("ratio.txt",ios::app);
// out3 << generator()->currentEvent()->weight() << " " << alls << " " << keep << endl;
if(doAnalysis){
ofstream out2((analysisPath + "/stringplot.txt").c_str(),ios::app);
out2 << generator()->maximumCMEnergy()/GeV << " " << generator()->currentEvent()->weight() << " " << singlets.size() << " " << havg/singlets.size() << endl;
}
}
void StringFragmentation::dofinish(){
if(doAnalysis!=0){
YODA::mkWriter("yoda");
YODA::WriterYODA::write(analysisPath + generator()->runName() + "1D.yoda",_histograms.begin(),_histograms.end());
YODA::WriterYODA::write(analysisPath + generator()->runName() + "2D.yoda",_histograms2D.begin(),_histograms2D.end());
}
}
bool StringFragmentation::
hadronizeSystems(Pythia8Interface & pyt, const vector<ColourSinglet> & singlets, const tPVector & all) {
TheP8EventShapes * _es = NULL;
Pythia8::Event & event = pyt.event();
pyt.clearEvent();
for ( int i = 0, N = singlets.size(); i < N; ++i ) {
if ( singlets[i].nPieces() == 3 ) {
// Simple junction.
// Save place where we will store dummy particle.
int nsave = event.size();
event.append(22, -21, 0, 0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0);
int npart = 0;
for ( int ip = 1; ip <= 3; ++ip )
for ( int j = 0, M = singlets[i].piece(ip).size(); j < M; ++j ) {
pyt.addParticle(singlets[i].piece(ip)[j], 23, nsave, 0);
++npart;
}
event[nsave].daughters(nsave + 1, nsave + npart);
}
else if ( singlets[i].nPieces() == 5 ) {
// Double, connected junction
// Save place where we will store dummy beam particles.
int nb1 = event.size();
int nb2 = nb1 + 1;
event.append(2212, -21, 0, 0, nb1 + 2, nb1 + 4, 0, 0,
0.0, 0.0, 0.0, 0.0);
event.append(-2212, -21, 0, 0, nb2 + 4, nb2 + 6, 0, 0,
0.0, 0.0, 0.0, 0.0);
// Find the string piece connecting the junctions, and the
// other loose string pieces.
int connector = 0;
int q1 = 0;
int q2 = 0;
int aq1 = 0;
int aq2 = 0;
for ( int ip = 1; ip <= 5; ++ip ) {
if ( singlets[i].sink(ip).first && singlets[i].source(ip).first )
connector = ip;
else if ( singlets[i].source(ip).first ) {
if ( q1 ) q2 = ip;
else q1 = ip;
}
else if ( singlets[i].sink(ip).first ) {
if ( aq1 ) aq2 = ip;
else aq1 = ip;
}
}
if ( !connector || !q1 || !q2 || !aq1 || ! aq2 )
Throw<StringFragError>()
<< name() << " found complicated junction string. Although Pythia8 can "
<< "hadronize junction strings, this one was too complicated."
<< Exception::runerror;
// Insert the partons of the loose triplet ends.
int start = event.size();
for ( int j = 0, M = singlets[i].piece(q1).size(); j < M; ++j )
pyt.addParticle(singlets[i].piece(q1)[j], 23, nb1, 0);
for ( int j = 0, M = singlets[i].piece(q2).size(); j < M; ++j )
pyt.addParticle(singlets[i].piece(q2)[j], 23, nb1, 0);
// Insert dummy triplet incoming parton with correct colour code.
int col1 = singlets[i].piece(connector).empty()? event.nextColTag():
pyt.addColourLine(singlets[i].piece(connector).front()->colourLine());
int dum1 = event.size();
event.append(2, -21, nb1, 0, 0, 0, col1, 0, 0.0, 0.0, 0.0, 0.0, 0.0);
event[nb1].daughters(start, start + singlets[i].piece(q1).size() +
singlets[i].piece(q2).size());
// Insert the partons of the loose anti-triplet ends.
start = event.size();
for ( int j = 0, M = singlets[i].piece(aq1).size(); j < M; ++j )
pyt.addParticle(singlets[i].piece(aq1)[j], 23, nb2, 0);
for ( int j = 0, M = singlets[i].piece(aq2).size(); j < M; ++j )
pyt.addParticle(singlets[i].piece(aq2)[j], 23, nb2, 0);
// Insert dummy anti-triplet incoming parton with correct colour code.
int col2 = singlets[i].piece(connector).empty()? col1:
pyt.addColourLine(singlets[i].piece(connector).back()->antiColourLine());
int dum2 = event.size();
event.append(-2, -21, nb2, 0, 0, 0, 0, col2, 0.0, 0.0, 0.0, 0.0, 0.0);
event[nb2].daughters(start, start + singlets[i].piece(aq1).size() +
singlets[i].piece(aq2).size());
// Add the partons from the connecting string piece.
for ( int j = 0, M = singlets[i].piece(connector).size(); j < M; ++j )
pyt.addParticle(singlets[i].piece(connector)[j], 23, dum1, dum2);
}
else if ( singlets[i].nPieces() > 1 ) {
// We don't know how to handle other junctions yet.
Throw<StringFragError>()
<< name() << " found complicated junction string. Although Pythia8 can "
<< "hadronize junction strings, that interface is not ready yet."
<< Exception::runerror;
} else {
// Normal string
for ( int j = 0, M = singlets[i].partons().size(); j < M; ++j )
pyt.addParticle(singlets[i].partons()[j], 23, 0, 0);
}
}
for ( int i = 0, N = all.size(); i < N; ++i )
if ( !all[i]->coloured() )
pyt.addParticle(all[i], 23, 0, 0);
int oldsize = event.size();
Pythia8::Event saveEvent = event;
int ntry = maxTries;
CurrentGenerator::Redirect stdout(cout, false);
while ( !pyt.go() && --ntry ) event = saveEvent;
if ( !ntry ) {
static DebugItem printfailed("TheP8I::PrintFailed", 10);
if ( printfailed ) {
double ymax = -1000.0;
double ymin = 1000.0;
double sumdy = 0.0;
for ( int i = 0, N = singlets.size(); i < N; ++i )
for ( int j = 0, M = singlets[i].partons().size(); j < M; ++j ) {
const Particle & p = *singlets[i].partons()[j];
ymax = max(ymax, (_es ? _es->yT(p.momentum()) : p.momentum().rapidity()));
//ymax = max(ymax, p.momentum().rapidity());
ymin = min(ymin,(_es ? _es->yT(p.momentum()) : p.momentum().rapidity()));
//ymin = min(ymin, p.momentum().rapidity());
cerr << setw(5) << j << setw(14) << p.momentum().rapidity()
<< setw(14) << p.momentum().perp()/GeV
<< setw(14) << p.momentum().m()/GeV;
if ( j == 0 && p.data().iColour() == PDT::Colour8 ) {
cerr << setw(14) << (p.momentum() + singlets[i].partons().back()->momentum()).m()/GeV;
sumdy += abs((_es ? _es->yT(p.momentum()) : p.momentum().rapidity()) ) -(_es ? _es->yT(singlets[i].partons().back()->momentum())
: singlets[i].partons().back()->momentum().rapidity());
//sumdy += abs(p.momentum().rapidity() - singlets[i].partons().back()->momentum().rapidity());
}
else if ( j > 0 ) {
cerr << setw(14) << (p.momentum() + singlets[i].partons()[j-1]->momentum()).m()/GeV;
sumdy += abs((_es ? _es->yT(p.momentum()) : p.momentum().rapidity()) ) -(_es ? _es->yT(singlets[i].partons()[j-i]->momentum())
: singlets[i].partons()[j-i]->momentum().rapidity());
//sumdy += abs(p.momentum().rapidity() - singlets[i].partons()[j-1]->momentum().rapidity());
if ( j + 1 < M )
cerr << setw(14) << (p.momentum() + singlets[i].partons()[j-1]->momentum()).m()*
(p.momentum() + singlets[i].partons()[j+1]->momentum()).m()/
(p.momentum() + singlets[i].partons()[j+1]->momentum() +
singlets[i].partons()[j-1]->momentum()).m()/GeV;
}
cerr << endl;
}
cerr << setw(14) << ymax - ymin << setw(14) << sumdy/(ymax - ymin) << endl;
}
CurrentGenerator::Redirect stdout2(cout, true);
//event.list();
pyt.errorlist();
cout << "ThePEG event listing:\n" << *(generator()->currentEvent());
Throw<StringFragError>()
<< "Pythia8 failed to hadronize partonic state:\n"
<< stdout2.str() << "This event will be discarded!\n"
<< Exception::warning;
throw Veto();
}
if(window){
// cout << stringyCut << " " << stringpTCut/GeV << endl;
if(forcerun) forcerun = false;
else{
for ( int i = 1, N = event.size(); i < N; ++i ) {
tPPtr p = pyt.getParticle(i);
// cout << p->momentum().perp()/GeV << " " << p->rapidity() << " " << p->id() << endl;
if (p->momentum().perp() > stringpTCut && abs(p->rapidity()) < stringyCut ){
forcerun = true;
return false;
}
}
}
}
// event.list(cerr);
map<tPPtr, set<tPPtr> > children;
map<tPPtr, set<tPPtr> > parents;
for ( int i = 1, N = event.size(); i < N; ++i ) {
tPPtr p = pyt.getParticle(i);
int d1 = event[i].daughter1();
if ( d1 <= 0 ) continue;
children[p].insert(pyt.getParticle(d1));
parents[pyt.getParticle(d1)].insert(p);
int d2 = event[i].daughter2();
if ( d2 > 0 ) {
children[p].insert(pyt.getParticle(d2));
parents[pyt.getParticle(d2)].insert(p);
}
for ( int di = d1 + 1; di < d2; ++di ) {
children[p].insert(pyt.getParticle(di));
parents[pyt.getParticle(di)].insert(p);
}
}
for ( int i = oldsize, N = event.size(); i < N; ++i ) {
PPtr p = pyt.getParticle(i);
set<tPPtr> & pars = parents[p];
if ( !p ) {
Throw<StringFragError>()
<< "Failed to reconstruct hadronized state from Pythia8:\n"
<< stdout.str() << "This event will be discarded!\n" << Exception::warning;
throw Veto();
}
if ( isnan(p->momentum().perp()/GeV) ){
Throw<StringFragError>()
<< "Failed to reconstruct hadronized state from Pythia8:\n"
<< stdout.str() << "This event will be discarded!\n" << Exception::warning;
throw Veto();
}
if ( pars.empty() ) {
Pythia8::Particle & pyp = event[i];
if ( pyp.mother1() > 0 ) pars.insert(pyt.getParticle(pyp.mother1()));
if ( pyp.mother2() > 0 ) pars.insert(pyt.getParticle(pyp.mother2()));
for ( int im = pyp.mother1() + 1; im < pyp.mother2(); ++im )
pars.insert(pyt.getParticle(im));
if ( pars.empty() ) {
Throw<StringFragError>()
<< "Failed to reconstruct hadronized state from Pythia8:\n"
<< stdout.str() << "This event will be discarded!\n" << Exception::warning;
throw Veto();
}
}
if ( pars.size() == 1 ) {
tPPtr par = *pars.begin();
if ( children[par].size() == 1 &&
*children[par].begin() == p && par->id() == p->id() )
newStep()->setCopy(par, p);
else
newStep()->addDecayProduct(par, p);
} else {
newStep()->addDecayProduct(pars.begin(), pars.end(), p);
}
}
return true;
}
string StringFragmentation::PrintStringsToMatlab(vector<ColourSinglet>& singlets) {
stringstream ss;
vector<vector<double> > drawit;
vector<char> names;
for(int i=0;i<26;++i) names.push_back(char(i+97));
vector<char>::iterator nItr = names.begin();
for(vector<ColourSinglet>::iterator sItr = singlets.begin(); sItr!=singlets.end(); ++sItr){
drawit.clear();
for (tcPVector::iterator pItr = sItr->partons().begin(); pItr!=sItr->partons().end();++pItr) {
vector<double> tmp;
tmp.clear();
tmp.push_back((*pItr)->rapidity());
tmp.push_back((*pItr)->vertex().x()/femtometer);
tmp.push_back((*pItr)->vertex().y()/femtometer);
drawit.push_back(tmp);
}
ss << *nItr << " = [";
for(int i=0, N=drawit.size();i<N;++i){
ss << drawit[i].at(0) << ", " << drawit[i].at(1) << ", " << drawit[i].at(2) << ";" << endl;
}
ss << "]';\n\n" << endl;
++nItr;
}
return ss.str();
}
IBPtr StringFragmentation::clone() const {
return new_ptr(*this);
}
IBPtr StringFragmentation::fullclone() const {
return new_ptr(*this);
}
void StringFragmentation::doinitrun() {
HadronizationHandler::doinitrun();
theAdditionalP8Settings.push_back("ProcessLevel:all = off");
theAdditionalP8Settings.push_back("HadronLevel:Decay = off");
theAdditionalP8Settings.push_back("Check:event = off");
theAdditionalP8Settings.push_back("Next:numberCount = 0");
theAdditionalP8Settings.push_back("Next:numberShowLHA = 0");
theAdditionalP8Settings.push_back("Next:numberShowInfo = 0");
theAdditionalP8Settings.push_back("Next:numberShowProcess = 0");
theAdditionalP8Settings.push_back("Next:numberShowEvent = 0");
theAdditionalP8Settings.push_back("Init:showChangedSettings = 0");
theAdditionalP8Settings.push_back("Init:showAllSettings = 0");
theAdditionalP8Settings.push_back("Init:showChangedParticleData = 0");
theAdditionalP8Settings.push_back("Init:showChangedResonanceData = 0");
theAdditionalP8Settings.push_back("Init:showAllParticleData = 0");
theAdditionalP8Settings.push_back("Init:showOneParticleData = 0");
theAdditionalP8Settings.push_back("Init:showProcesses = 0");
vector<string> moresettings = theAdditionalP8Settings;
moresettings.push_back("StringPT:sigma = " + convert(theStringPT_sigma));
moresettings.push_back("StringZ:aLund = " + convert(theStringZ_aLund));
moresettings.push_back("StringZ:bLund = " + convert(theStringZ_bLund));
moresettings.push_back("StringFlav:probStoUD = " +
convert(theStringFlav_probStoUD));
moresettings.push_back("StringFlav:probSQtoQQ = " +
convert(theStringFlav_probSQtoQQ));
moresettings.push_back("StringFlav:probQQ1toQQ0 = " +
convert(theStringFlav_probQQ1toQQ0));
moresettings.push_back("StringFlav:probQQtoQ = " +
convert(theStringFlav_probQQtoQ));
moresettings.push_back("OverlapStrings:fragMass = " +
convert(fragmentationMass));
moresettings.push_back("OverlapStrings:baryonSuppression = " + convert(baryonSuppression));
nev = 0;
// Initialize the OverlapPythia Handler
opHandler = new OverlapPythiaHandler(this,moresettings);
// Should we do event shapes?
_eventShapes = NULL;
if(useThrustAxis==1){
_eventShapes = new TheP8EventShapes();
}
// Select hadronization scheme
// test only to remain backwards compatible.
// TODO: change automated run procedure and adapt
if(fragmentationScheme.find("rope")!=string::npos || fragmentationScheme.find("test")!=string::npos){
enhance = new RandomAverageHandler(stringR0,_eventShapes);
}
else if(fragmentationScheme.find("random")!=string::npos){
enhance = new RandomHandler(stringR0,_eventShapes);
}
else{
enhance = new VanillaPythiaHandler();
}
if( doAnalysis ) {
/*_histograms.push_back(new YODA::Histo1D(20,1,10, "/enhancement" ,"enhancement"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterA", "parameterA"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterB", "parameterB"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterRHO", "parameterRHO"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterXI", "parameterXI"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterX", "parameterX"));
_histograms.push_back(new YODA::Histo1D(100,0,1., "/parameterY", "parameterY"));
*/
_histograms.push_back(new YODA::Histo1D(100,1,15,"/h_lowpT","h_lowpT"));
_histograms.push_back(new YODA::Histo1D(100,1,15,"/h_midpT","h_midpT"));
_histograms.push_back(new YODA::Histo1D(100,1,15,"/h_highpT","h_highpT"));
_histograms2D.push_back(new YODA::Histo2D(10,0.,15,10,0,15,"/m_vs_pT","m_vs_pT"));
}
}
void StringFragmentation::persistentOutput(PersistentOStream & os) const {
os
#include "StringFragmentation-output.h"
<< overlapN << testPow << ounit(stringR0,femtometer) << stringyCut << ounit(stringpTCut,GeV) << fragmentationMass << baryonSuppression << ounit(window,true) << useThrustAxis << fragmentationScheme << maxTries << theCollapser << doAnalysis << analysisPath;
}
void StringFragmentation::persistentInput(PersistentIStream & is, int) {
is
#include "StringFragmentation-input.h"
>> overlapN >> testPow >> iunit(stringR0,femtometer) >> stringyCut >> iunit(stringpTCut,GeV) >> fragmentationMass >> baryonSuppression >> iunit(window,true) >> useThrustAxis >> fragmentationScheme >> maxTries >> theCollapser >> doAnalysis >> analysisPath;
}
ClassDescription<StringFragmentation> StringFragmentation::initStringFragmentation;
// Definition of the static class description member.
void StringFragmentation::Init() {
#include "StringFragmentation-interfaces.h"
static Reference<StringFragmentation,ClusterCollapser> interfaceCollapser
("Collapser",
"A ThePEG::ClusterCollapser object used to collapse colour singlet "
"clusters which are too small to fragment. If no object is given the "
"MinistringFragmentetion of Pythia8 is used instead.",
&StringFragmentation::theCollapser, true, false, true, true, false);
static Parameter<StringFragmentation, string> interfaceFragmentationScheme
("FragmentationScheme",
" Choose between hadronization schemes. Choices are: "
" One way strings overlapping in central rapidity bin [OneY], "
" One way strings with cylindrical containers in (b,Y)-space [OnebY], "
" Two way strings with cylindrical containers in (b,Y)-space [TwobY], "
" Ordinary Pythia 8 (no overlap) string hadronization [default]." ,
&StringFragmentation::fragmentationScheme, "");
static Parameter<StringFragmentation,int> interfaceOverlapN
("OverlapN",
"If positive, use the string overlap model with different "
"parameters for up to overlapN strings.",
&StringFragmentation::overlapN, 0, 0, 0,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,int> interfaceUseThrustAxis
("UseThrustAxis",
"Whether or not to use rapidity wrt. Thrust Axis when counting strings "
"(put 1 or 0).",
&StringFragmentation::useThrustAxis, 0, 0, 0,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,int> interfaceDoAnalysis
("DoAnalysis",
"Can do a short analysis where histograms of the effective parameters are "
"plotted, and the strings in (bx,by,y)-space are printed for a couple of events. "
"(put 1 or 0).",
&StringFragmentation::doAnalysis, 0, 0, 0,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,string> interfaceAnalysisPath
("AnalysisPath",
"Set the system path where the (optional) analysis output should appear "
" (directory must exist!)" ,
&StringFragmentation::analysisPath, "");
static Switch<StringFragmentation,bool> interfaceWindow
("StringWindow",
"Enable the 'window'-cut procedure, off by default."
"Parameters will only affect if this is switched on. " ,
&StringFragmentation::window, false, true, false);
static SwitchOption interfaceWindowTrue
(interfaceWindow,"True","enabled.",true);
static SwitchOption interfaceWindowFalse
(interfaceWindow,"False","disabled.",false);
static Parameter<StringFragmentation,Energy> interfaceStringpTCut
("StringpTCut",
"No enhancement of strings with a constituent pT higher than StringpTCut (GeV), and within "
" StringyCut (in GeV).",
&StringFragmentation::stringpTCut, GeV, 6.0*GeV,
0.0*GeV, 0*GeV,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,double> interfaceStringyCut
("StringyCut",
"No enhancement of strings with a constituent pT higher than StringpTCut (GeV), and within "
" StringyCut.",
&StringFragmentation::stringyCut, 0, 2.0,
0.0, 0,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,Length> interfaceStringR0
("StringR0",
"In the string overlap model the string R0 dictates the minimum radius "
" of a string (in fm).",
&StringFragmentation::stringR0, femtometer, 0.5*femtometer,
0.0*femtometer, 0*femtometer,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,double> interfaceFragmentationMass
("FragmentationMass",
"Set the mass used for the f(z) integral in the overlap string model "
" default is pion mass (units GeV).",
&StringFragmentation::fragmentationMass, 0, 0.135,
0., 1.,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,double> interfaceBaryonSuppression
("BaryonSuppression",
"Set the fudge factor used for baryon suppression in the overlap string model. "
" One day this should be calculated properly. This day is not today. Probably around 2...",
&StringFragmentation::baryonSuppression, 0, 2.0,
1., 10.,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,double> interfaceOverlapTestPow
("OverlapTestPow",
"Initial value for the exponent used for the string overlap model.",
&StringFragmentation::testPow, 0.5, 0.0, 0,
true, false, Interface::lowerlim);
static Parameter<StringFragmentation,int> interfaceMaxTries
("MaxTries",
"Sometimes Pythia gives up on an event too easily. We therefore allow "
"it to re-try a couple of times.",
&StringFragmentation::maxTries, 2, 1, 0,
true, false, Interface::lowerlim);
}
string StringFragmentation::convert(double d) {
ostringstream os;
os << d;
return os.str();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 6:04 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4982923
Default Alt Text
(41 KB)
Attached To
rTHEPEGPEIGHTIHG thepegpeightihg
Event Timeline
Log In to Comment