Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881298
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
68 KB
Subscribers
None
View Options
diff --git a/Config/Makefile.am b/Config/Makefile.am
--- a/Config/Makefile.am
+++ b/Config/Makefile.am
@@ -1,13 +1,13 @@
mySOURCES = RndmEngine.cc Pythia8Interface.cc
-DOCFILES = TheP8I.h RndmEngine.h Pythia8Interface.h
+DOCFILES = TheP8I.h RndmEngine.h Pythia8Interface.h RopeUserHooks.h
INCLUDEFILES = $(DOCFILES)
noinst_LTLIBRARIES = libTheP8IConfig.la
libTheP8IConfig_la_SOURCES = $(mySOURCES) $(INCLUDEFILES)
Pythia8Interface.cc: interfaces.pl
include $(top_srcdir)/Config/Makefile.aminclude
diff --git a/Config/Pythia8Interface.cc b/Config/Pythia8Interface.cc
--- a/Config/Pythia8Interface.cc
+++ b/Config/Pythia8Interface.cc
@@ -1,211 +1,217 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Pythia8Interface class.
//
-
#include "Pythia8Interface.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Handlers/StepHandler.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
using namespace TheP8I;
-Pythia8Interface::Pythia8Interface(): pythia(0) {}
+Pythia8Interface::Pythia8Interface(): pythia(NULL), hooks(NULL), doHooks(false) {}
Pythia8Interface::~Pythia8Interface() {
if ( pythia ) delete pythia;
+ if ( hooks ) delete hooks;
}
bool Pythia8Interface::initialized = false;
string Pythia8Interface::installDir = PYTHIA8_DIR;
RndmEngine Pythia8Interface::rnd;
void Pythia8Interface::Init() {
if ( initialized ) return;
if ( installDir[installDir.length() - 1] != '/' ) installDir += '/';
initialized = true;
}
void Pythia8Interface::errorlist() {
pythia->info.errorStatistics();
}
bool Pythia8Interface::go() {
try {
return pythia->next();
} catch ( ... ) {
Throw<Pythia8ExecException>()
<< "Pythia8 threw an exception while executing 'Pythia::next()'."
<< Exception::runerror;
}
return false;
}
void Pythia8Interface::
setParameters(const Interfaced & handler, const vector<string> & additional) {
if ( !pythia ) return;
InterfaceMap ifs = BaseRepository::getInterfaces(typeid(handler));
for ( InterfaceMap::iterator it = ifs.begin(); it != ifs.end(); ++it ) {
string name = it->first;
string::size_type i = name.find('_');
ostringstream cmd;
if ( i == string::npos ) continue;
while ( ( i = name.find('_') ) != string::npos ) name[i] = ':';
if ( const SwitchBase * si = dynamic_cast<const SwitchBase *>(it->second) ) {
if ( si->get(handler) == si->def(handler) ) continue;
cmd << name << " = " << si->get(handler);
}
else if ( const ParameterTBase<double> * pi =
dynamic_cast<const ParameterTBase<double> *>(it->second) ) {
if ( pi->tget(handler) == pi->tdef(handler) ) continue;
cmd << name << " = " << pi->tget(handler);
}
else if ( const ParameterTBase<int> * pi =
dynamic_cast<const ParameterTBase<int> *>(it->second) ) {
if ( pi->tget(handler) == pi->tdef(handler) ) continue;
cmd << name << " = " << pi->tget(handler);
}
else
continue;
pythia->readString(cmd.str());
}
for ( int i = 0, N = additional.size(); i < N; ++i )
pythia->readString(additional[i]);
}
void Pythia8Interface::debug() {
event().list();
}
void Pythia8Interface::
init(const Interfaced & handler, const vector<string> & additional) {
if ( pythia ) delete pythia;
+ if( hooks ) delete hooks;
Init();
CurrentGenerator::Redirect stdout(cout);
pythia = new Pythia8::Pythia(installDir + "xmldoc");
pythia->setRndmEnginePtr(&rnd);
CurrentGenerator eg;
for ( ParticleMap::const_iterator it = eg.current().particles().begin();
it != eg.current().particles().end(); ++it ) {
ParticleData & pd = *it->second;
ostringstream oss;
if ( pd.id() == 0 ) Throw<Pythia8InitException>()
<< "The particle " << pd.name()
<< " was found to have an PDG id of zero." << Exception::warning;
oss << pd.id();
if ( pythia->particleData.isParticle(pd.id()) )
oss << " all ";
else
oss << " new ";
oss << pd.PDGName() << " ";
if ( pd.CC() ) {
if ( pd.id() < 0 ) continue;
ParticleData & apd = *pd.CC();
oss << apd.PDGName() << " ";
if ( pd.iSpin() != apd.iSpin() ||
pd.iColour() != -apd.iColour() ||
pd.iCharge() != -apd.iCharge() ||
pd.mass() != apd.mass() ||
pd.width() != apd.width() ||
pd.massMax() != apd.massMax() ||
pd.massMin() != apd.massMin() ||
pd.cTau() != apd.cTau() )
Throw<Pythia8InitException>()
<< "The particle " << pd.PDGName()
<< " did not have the the same properties as its anti-particle. "
<< "Pythia8 will be initialized with the anti-particle having "
<< "the same properties as the particle." << Exception::warning;
}
else {
oss << "void ";
}
oss << pd.iSpin() << " "
<< pd.iCharge() << " "
<< ( pd.iColour() == PDT::Colour3? 1:
( pd.iColour() == PDT::Colour3bar? -1:
( pd.iColour() == PDT::Colour8? 2: 0) ) ) << " "
<< pd.mass()/GeV << " "
<< pd.width()/GeV << " "
<< pd.massMin()/GeV << " "
<< pd.massMax()/GeV << " "
<< pd.cTau()/millimeter;
if ( !pythia->particleData.readString(oss.str(), false) )
Throw<Pythia8InitException>()
<< "Something went wrong when initializing the particle data table "
<< "of Pythia8. The settings line was:\n" << oss.str()
<< "\n" << Exception::runerror;
pythia->particleData.hasChanged(pd.id(), false);
}
setParameters(handler, additional);
+
+ if(doHooks){
+ hooks = new RopeUserHooks();
+ pythia->setUserHooksPtr(hooks);
+ }
pythia->init();
}
int Pythia8Interface::addParticle(tPPtr p, int status, int mother1, int mother2) {
if ( particleIndex.included(p) ) return particleIndex(p);
int idx = event().size();
particleIndex(idx, p);
int pos = event().append(p->id(), status, mother1, mother2, 0, 0,
addColourLine(p->colourLine()),
addColourLine(p->antiColourLine()),
p->momentum().x()/GeV, p->momentum().y()/GeV,
p->momentum().z()/GeV, p->momentum().e()/GeV,
p->momentum().mass()/GeV);
if ( !(p->vertex() == LorentzPoint()) ) {
event()[pos].vProd(p->vertex().x()/millimeter, p->vertex().y()/millimeter,
p->vertex().z()/millimeter, p->vertex().t()/millimeter);
event()[pos].tau(p->lifeLength().tau()/millimeter);
}
return idx;
}
int Pythia8Interface::addColourLine(tColinePtr c) {
if ( colourIndex.included(c) ) return colourIndex(c);
int ctag = event().nextColTag();
colourIndex(ctag, c);
return ctag;
}
PPtr Pythia8Interface::getParticle(int idx) {
if ( particleIndex.included(idx) ) return particleIndex.find(idx);
tcPDPtr pd = CurrentGenerator::current().getParticleData(event()[idx].id());
if ( !pd ) return PPtr();
PPtr p = pd->produceParticle(Lorentz5Momentum(event()[idx].px()*GeV,
event()[idx].py()*GeV,
event()[idx].pz()*GeV,
event()[idx].e()*GeV,
event()[idx].m()*GeV));
if ( event()[idx].hasVertex() )
p->setVertex(LorentzPoint(event()[idx].xProd()*millimeter,
event()[idx].yProd()*millimeter,
event()[idx].zProd()*millimeter,
event()[idx].tProd()*millimeter));
if ( event()[idx].tau() > 0.0 && event()[idx].m() > 0.0 )
p->setLifeLength(event()[idx].tau()*millimeter
*p->momentum()/p->momentum().mass());
tColinePtr c = colourIndex(event()[idx].col());
if ( c ) c->addColoured(p);
c = colourIndex(event()[idx].acol());
if ( c ) c->addAntiColoured(p);
particleIndex(idx, p);
return p;
}
diff --git a/Config/Pythia8Interface.h b/Config/Pythia8Interface.h
--- a/Config/Pythia8Interface.h
+++ b/Config/Pythia8Interface.h
@@ -1,196 +1,215 @@
// -*- C++ -*-
+
+
#ifndef THEP8I_Pythia8Interface_H
#define THEP8I_Pythia8Interface_H
//
// This is the declaration of the Pythia8Interface class.
//
#include "ThePEG/Utilities/Throw.h"
#include "TheP8I/Config/TheP8I.h"
#include "TheP8I/Config/RndmEngine.h"
#include "ThePEG/Utilities/ObjectIndexer.h"
+#include "RopeUserHooks.h"
#include "Pythia.h"
-
namespace TheP8I {
/**
* The Pythia8Interface class is a wrapper around a static Pythia8
* object. All communication between ThePEG and Pythia8 is handled by
* static functions of the Pythia8Interface class.
*/
class Pythia8Interface: public Base {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
Pythia8Interface();
/**
* The destructor.
*/
~Pythia8Interface();
//@}
public:
/**
* Initialize the main Pythia8 object setting all parameters which
* are not default by copying them from the corresponding
* interfaces..
*/
void init(const Interfaced &, const vector<string> &);
/**
* Set parameters which are not default in the main Pythia8 object
* by copying them from the corresponding interfaces..
*/
void setParameters(const Interfaced &, const vector<string> &);
/**
* Access the local Pythia8 object.
*/
Pythia8::Pythia & operator()() {
return *pythia;
}
/**
* Access the event object of the local Pythia8 object.
*/
Pythia8::Event & event() {
return pythia->event;
}
/**
* Check if the local Pythia8 object has been created.
*/
bool created() const {
return pythia != 0;
}
/**
* Prepare for introducing a new event.
*/
void clearEvent() {
event().reset();
colourIndex.clear();
colourIndex(0, tColinePtr());
particleIndex.clear();
}
/**
* Add a ThePEG::Particle to the Pythia8 event (if it hasn't been
* added already) and return its index.
*/
int addParticle(tPPtr p, int status, int mother1, int mother2);
/**
* Add a ThePEG::Particle to the Pythia8 event (if it hasn't been
* added already) and return its index.
*/
int addParticle(tcPPtr p, int status, int mother1, int mother2) {
return addParticle(const_ptr_cast<tPPtr>(p), status, mother1, mother2);
}
/**
* Get the colour Pythia8 colour index for a given colour
* line. Generate a new index if the line has not been seen before.
*/
int addColourLine(tColinePtr c);
/**
* Return index of the given particle \a p.
* @return -1 if not found.
*/
int indexOf(tPPtr p) {
return particleIndex.included(p)? particleIndex(p): -1;
}
/**
* Return a particle corresponding to the given entry in the Pythia8 event.
*/
PPtr getParticle(int idx);
/**
* After the event has been filled, let Pythia8 do its thing. Return
* true if everything was OK.
*/
bool go();
+ /*
+ * Get a pointer to the UserHooks object (for ropes), pointer is NULL if not initialized
+ */
+ RopeUserHooks * getRopeUserHooksPtr(){
+ return hooks;
+ }
+
+ void enableHooks(){
+ doHooks = true;
+ }
+
void errorlist();
/**
* Retrieve the version number of Pythia.
*/
double version() const {
return pythia? pythia->settings.parm("Pythia:versionNumber"): -1.0;
}
/**
* Print out debugging information.
*/
void debug();
/**
* Perform all static initializations.
*/
static void Init();
private:
/**
* The main Pythia8 object.
*/
Pythia8::Pythia * pythia;
/**
+ * Pythia 8 user hooks object for fooling around with ropes.
+ */
+ RopeUserHooks * hooks;
+
+ bool doHooks;
+ /**
* Association between ColourLines and colour indices.
*/
ObjectIndexer<int,ColourLine> colourIndex;
/**
* Association between Particles and indices.
*/
ObjectIndexer<int,Particle> particleIndex;
/**
* True if the static members have been initialized.
*/
static bool initialized;
/**
* The place where Pythia 8 is installed.
*/
static string installDir;
/**
* The interface to the random generatorof ThePEG.
*/
static RndmEngine rnd;
/**
* Internal Exception class.
*/
struct Pythia8InitException: public Exception {};
/**
* Internal Exception class.
*/
struct Pythia8ExecException: public Exception {};
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
Pythia8Interface & operator=(const Pythia8Interface &);
};
}
#endif /* THEP8I_Pythia8Interface_H */
diff --git a/Config/RopeUserHooks.h b/Config/RopeUserHooks.h
new file mode 100644
--- /dev/null
+++ b/Config/RopeUserHooks.h
@@ -0,0 +1,94 @@
+
+#ifndef THEP8I_RopeUserHooks_H
+#define THEP8I_RopeUserHooks_H
+
+#include "Pythia.h"
+#include "TheP8I/Hadronization/ParameterHandler.h"
+#include "TheP8I/Hadronization/Ropewalk.h"
+
+
+namespace TheP8I {
+
+class RopeUserHooks : public Pythia8::UserHooks {
+
+
+// Convenient typedef
+typedef map<string,double> PytPars;
+
+ public:
+
+ RopeUserHooks() : _ph(NULL), _rw(NULL), _h(-1.0) {
+ }
+
+ ~RopeUserHooks() {
+ }
+
+ virtual bool canChangeFragPar() {return true;}
+
+
+ virtual bool doChangeFragPar(Pythia8::StringFlav* flavPtr, Pythia8::StringZ* zPtr, Pythia8::StringPT * pTPtr, pair<int,int> steps, double rap) {
+
+ // Get new parameters
+ PytPars newPar = fetchParameters(steps,rap);
+ for(PytPars::iterator itr = newPar.begin(); itr!=newPar.end();++itr) settingsPtr->parm(itr->first,itr->second);
+
+ // debugging purposes, TODO: will go later
+ //settingsPtr->listAll();
+
+ // Re-initialize all three
+ flavPtr->init(*settingsPtr,rndmPtr);
+ zPtr->init(*settingsPtr,*particleDataPtr,rndmPtr);
+ pTPtr->init(*settingsPtr,*particleDataPtr,rndmPtr);
+
+ return true;
+ }
+
+ void setParameterHandler(ParameterHandler * ph){
+ _ph = ph;
+ }
+
+ void setEnhancement(double h){ // This is for testing, TODO: Change over a singlet
+ _h = h;
+ }
+
+ void setRopewalk(Ropewalk * rw){
+ _rw = rw;
+ // If we set the ropewalk, we should also use it.
+ _h = -1.0;
+ }
+
+ private:
+
+ PytPars fetchParameters(pair<int,int> steps, double rap){
+
+ // Did we remember to set the callback pointer? If we don't, we're gonna have a bad time.
+ // Do not just construct a new one, as there will be no sensible initial values, resulting
+ // in very subtle errors.
+ if(!(_ph)){
+ cout << "You failed to set the ParameterHandler callback pointer in your user-hook. Shame on you." << endl;
+ PytPars p;
+ p.insert(make_pair<const string,double>("null",0.));
+ return p;
+ }
+ // If we have manually set enhancement, we should just use that, and avoid complicated behavior.
+ if(_h > 0) return _ph->GetEffectiveParameters(_h);
+
+ if(!(_rw)){
+ cout << "You failed to set the Ropewalk callback pointer in your user-hook. Shame on you." << endl;
+ PytPars p;
+ p.insert(make_pair<const string,double>("null",0.));
+ return p;
+ }
+ // Make ropewalk stuff here!
+
+ return _ph->GetEffectiveParameters(1.0);
+
+ }
+
+ ParameterHandler * _ph;
+ Ropewalk * _rw;
+ double _h;
+};
+
+}
+#endif
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 Ropewalk.cc
+mySOURCES = StringFragmentation.cc TheP8EventShapes.cc StringPipe.cc OverlapPythiaHandler.cc ParameterHandler.cc RandomAverageHandler.cc RandomHandler.cc Ropewalk.cc
-DOCFILES = StringFragmentation.h TheP8EventShapes.h StringPipe.h OverlapPythiaHandler.h RandomAverageHandler.h RandomHandler.h Ropewalk.h
+DOCFILES = StringFragmentation.h TheP8EventShapes.h StringPipe.h OverlapPythiaHandler.h ParameterHandler.h RandomAverageHandler.h RandomHandler.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/ParameterHandler.cc b/Hadronization/ParameterHandler.cc
new file mode 100644
--- /dev/null
+++ b/Hadronization/ParameterHandler.cc
@@ -0,0 +1,134 @@
+// -*- C++ -*-
+//
+// This is the implementation of the non-inlined, non-templated member
+// functions of the ParameterHandler class.
+//
+
+#include "ParameterHandler.h"
+
+using namespace TheP8I;
+
+typedef map<string,double> PytPars;
+
+ParameterHandler::ParameterHandler(){
+
+}
+
+ParameterHandler::~ParameterHandler(){
+
+}
+
+void ParameterHandler::init(double m2, double bsparameter, PytPars pars){
+ _m2 = m2;
+ _bsparameter = bsparameter;
+ _parameters.insert(make_pair<double,PytPars>(1.0,pars));
+
+ for (PytPars::iterator itr = pars.begin(); itr!=pars.end(); ++itr){
+
+ if(itr->first.find("StringPT:sigma")!=string::npos) sigma = itr->second;
+
+ else if(itr->first.find("StringZ:aLund")!=string::npos) a = itr->second;
+
+ else if(itr->first.find("StringZ:bLund")!=string::npos) b = itr->second;
+
+ else if(itr->first.find("StringFlav:probStoUD")!=string::npos) rho = itr->second;
+
+ else if(itr->first.find("StringFlav:probSQtoQQ")!=string::npos) x = itr->second;
+
+ else if(itr->first.find("StringFlav:probQQ1toQQ0")!=string::npos) y = itr->second;
+
+ else if(itr->first.find("StringFlav:probQQtoQ")!=string::npos) xi = itr->second;
+
+ else{
+ cout << "Broken arrow!" << endl;
+ }
+ }
+ // Sanity check of parameters
+ if (rho < 0 || rho > 1 || x < 0 || x > 1 || y < 0 || y > 1 || xi < 0 ||
+ xi > 1 || sigma < 0 || sigma > 1 || a < 0.0 || a > 2.0 || b < 0.2 || b > 2.0){
+ cout << "Did you set up sensible initial Pythia 8 values? Remember:" << endl;
+ cout << "0 < a < 2; 0.2 < b < 2; 0 < sigma < 1; 0 < xi < 1; 0 < y < 1; 0 < x < 1; 0 < rho < 1" << endl;
+ }
+}
+
+PytPars ParameterHandler::GetEffectiveParameters(double h){
+ map<double,PytPars>::iterator it = _parameters.find(h);
+ if(it!=_parameters.end()) return it->second;
+
+ if(!CalculateEffectiveParameters(h)){
+ cout << "Something went wrong calculating effective Pythia parameters!" << endl;
+ return _parameters.find(1.0)->second;
+ }
+ if(!InsertEffectiveParameters(h)){
+ cout << "Something went wrong inserting effective Pythia parameters!" << endl;
+ return _parameters.find(1.0)->second;
+ }
+ return GetEffectiveParameters(h);
+ }
+
+bool ParameterHandler::InsertEffectiveParameters(double h){
+ PytPars p;
+ p.insert(make_pair<const string,double>("StringPT:sigma",sigma_eff));
+ p.insert(make_pair<const string,double>("StringZ:aLund",sigma_eff));
+ p.insert(make_pair<const string,double>("StringZ:bLund",b_eff));
+ p.insert(make_pair<const string,double>("StringFlav:probStoUD",rho_eff));
+ p.insert(make_pair<const string,double>("StringFlav:probSQtoQQ",x_eff));
+ p.insert(make_pair<const string,double>("StringFlav:probQQ1toQQ0",y_eff));
+ p.insert(make_pair<const string,double>("StringFlav:probQQtoQ",xi_eff));
+ return (_parameters.insert(make_pair<double,PytPars>(h,p)).second);
+}
+
+bool ParameterHandler::CalculateEffectiveParameters(double h){
+ if (h <= 0) return false;
+
+ double hinv = 1.0 / h;
+
+ rho_eff = pow(rho, hinv);
+ x_eff = pow(x, hinv);
+ y_eff = pow(3.0 * y, hinv) / 3.0;
+ sigma_eff = sigma * sqrt(h);
+
+ double C1 = _bsparameter * xi * (2 + rho) / (3 + 2*x*rho + 9*y + 6*x*rho*y + x*x*rho*rho +
+ 3*y*x*x*rho*rho);
+ xi_eff = (pow(C1, hinv)/_bsparameter) * (3 + 2*x_eff*rho_eff + 9*y_eff +
+ 6*x_eff*rho_eff*y_eff + x_eff*x_eff*rho_eff*rho_eff +
+ 3*y_eff*x_eff*x_eff*rho_eff*rho_eff) / (2 + rho_eff);
+ if (xi_eff > 1.0) xi_eff = 1.0;
+
+ C1 = b / (2 + rho);
+ b_eff = C1 * (2 + rho_eff);
+ if (b_eff < 0.2) b_eff = 0.2;
+ if (b_eff > 2.0) b_eff = 2.0;
+
+ double N = IFragmentationF(a, b);
+ double N_eff = IFragmentationF(a, b_eff);
+ int s = (N - N_eff) < 0 ? -1 : 1;
+ double da = 0.1;
+ a_eff = a - s * da;
+ do {
+ N_eff = IFragmentationF(a_eff, b_eff);
+ if (((N - N_eff) < 0 ? -1 : 1) != s) {
+ s = (N - N_eff) < 0 ? -1 : 1;
+ da /= 10.0;
+ }
+ a_eff -= s * da;
+ if (a_eff < 0.0) {a_eff = 0.0; break;}
+ if (a_eff > 2.0) {a_eff = 2.0; break;}
+ } while (da > 0.00001);
+
+
+
+ return true;
+}
+
+double ParameterHandler::IFragmentationF(double a, double b){
+ const int N = 100000;
+ const double dz = 1.0 / N; //increment of z variable
+ double Integral = 0.0;
+ for (double z = dz; z < 1; z += dz) {
+ //numerical integral calculation
+ Integral += pow(1 - z, a) * exp(- b * m2 / z) / z;
+ }
+ return Integral * dz;
+ }
+
diff --git a/Hadronization/ParameterHandler.h b/Hadronization/ParameterHandler.h
new file mode 100644
--- /dev/null
+++ b/Hadronization/ParameterHandler.h
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+
+#ifndef THEP8I_ParameterHandler_H
+#define THEP8I_ParameterHandler_H
+
+#include "TheP8I/Config/TheP8I.h"
+
+
+namespace TheP8I {
+
+using namespace ThePEG;
+
+class ParameterHandler {
+
+
+public:
+ typedef map<string,double> PytPars;
+
+ /** @name Standard constructors and destructors. */
+ //@{
+ /**
+ * The default constructor.
+ */
+ ParameterHandler();
+
+ /**
+ * The destructor.
+ */
+ virtual ~ParameterHandler();
+ //@}
+
+ void init(double m2, double bsparameter, PytPars pars);
+
+ PytPars GetEffectiveParameters(double h);
+
+protected:
+
+private:
+
+ bool InsertEffectiveParameters(double h);
+
+ bool CalculateEffectiveParameters(double h);
+
+ double IFragmentationF(double a, double b);
+
+ // sets of parameters, ordered in h
+ map<double, PytPars> _parameters;
+
+ double a, b, rho, x, y, xi, sigma, m2;
+ double a_eff, b_eff, rho_eff, x_eff, y_eff, xi_eff, sigma_eff;
+ double _m2, _bsparameter;
+};
+
+}
+
+
+#endif
\ No newline at end of file
diff --git a/Hadronization/Ropewalk.h b/Hadronization/Ropewalk.h
--- a/Hadronization/Ropewalk.h
+++ b/Hadronization/Ropewalk.h
@@ -1,235 +1,235 @@
// -*- C++ -*-
#ifndef TheP8I_Ropewalk_H
#define TheP8I_Ropewalk_H
//
// This is the declaration of the Ropewalk class.
//
-#include "TheP8I/Config/Pythia8Interface.h"
+#include "TheP8I/Config/TheP8I.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 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 s() > sqr(m0)? 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, bool throwaway = true, bool deb = false);
/**
* The destructor.
*/
virtual ~Ropewalk();
//@}
/**
* Return all ColourSinglet objects with their kappa enhancement.
*/
vector< pair<ColourSinglet,double> > getSinglets(double DeltaY = 0.0) 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;
/**
* Make a copy of a ColourSinglet making sure all partons are final.
*/
static ColourSinglet * cloneToFinal(const ColourSinglet & cs);
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;
public:
mutable double strl0;
mutable double strl;
mutable double avh;
mutable double avp;
mutable double avq;
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,740 +1,761 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the StringFragmentation class.
//
#include "StringFragmentation.h"
#include "Ropewalk.h"
#include "RandomAverageHandler.h"
#include "RandomHandler.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(), stringR0(0.5*femtometer), stringm0(1.0*GeV), stringyCut(2.0), stringpTCut(6*GeV), fragmentationMass(0.134), baryonSuppression(2.), window(false), throwaway(false),
useThrustAxis(0), fragmentationScheme("none"), opHandler(0), maxTries(2), doAnalysis(0), analysisPath(""),
#include "StringFragmentation-init.h"
{
}
StringFragmentation::~StringFragmentation() {
+ if ( opHandler ) delete opHandler;
+
}
void StringFragmentation::handle(EventHandler & eh, const tPVector & tagged,
const Hint & h) {
++nev;
static unsigned long lastEventId = 0;
bool secondary = false;
// Get the event
tPVector all = RemnantDecayer::decayRemnants(tagged, *newStep());
// Prevent funny behavior if hadronizing decays of eg. Upsilon.
if ( newStep()->collision()->uniqueId == lastEventId ){
secondary = true;
fScheme = 0;
}
else
lastEventId = newStep()->collision()->uniqueId;
if(_eventShapes) _eventShapes->reset(all);
vector<ColourSinglet> singlets;
singlets.clear();
if ( theCollapser && !secondary )
singlets = theCollapser->collapse(all, newStep());
else
singlets = ColourSinglet::getSinglets(all.begin(), all.end());
// Goto correct hadronization scheme
switch(fScheme){
case 0: // Pythia
{
hadronizeSystems(*opHandler->GetPythiaPtr(1.0,nev%10000==0), singlets, all);
break;
}
case 1: // Pipes with full random walk, and without any further ado
{
RandomHandler enhancer(throwaway);
enhancer.clear();
vector<StringPipe> pipes;
// Make all the pipes
for(vector<ColourSinglet>::iterator sItr = singlets.begin(); sItr!=singlets.end(); ++sItr)
pipes.push_back(StringPipe(&(*sItr),stringR0,_eventShapes));
enhancer.SetEvent(pipes);
forcerun = false;
// Hadronize all pipes
for(vector<StringPipe>::iterator it = pipes.begin(); it!=pipes.end(); ++it){
vector<ColourSinglet> toHadronization;
double h = enhancer.KappaEnhancement(*it);
if(h > -998.0){
toHadronization.push_back(*(*it).GetSingletPtr());
if(!hadronizeSystems(*(opHandler->GetPythiaPtr(h,nev%10000==0)),toHadronization,all))
hadronizeSystems(*(opHandler->GetPythiaPtr(1.0,nev%10000==0)),toHadronization,all);
}
toHadronization.clear();
}
break;
}
case 2: // Ropewalk/Dipole
{
Ropewalk ropewalk(singlets, stringR0, stringm0, throwaway, false);
vector< pair<ColourSinglet,double> > strings = ropewalk.getSinglets(stringyCut);
vector<ColourSinglet> toHadronization;
for(int i = 0, N = strings.size(); i < N; ++i ){
Pythia8Interface * pytp = opHandler->GetPythiaPtr(strings[i].second,nev%10000==0);
toHadronization.clear();
toHadronization.push_back(strings[i].first);
hadronizeSystems(*pytp,toHadronization,all);
}
break;
}
case 3: // Pipes with average
{
RandomAverageHandler avg_enhancer(throwaway);
// TODO: Implement throwaway functionality in this
avg_enhancer.clear();
vector<StringPipe> pipes;
// Make all the pipes
for(vector<ColourSinglet>::iterator sItr = singlets.begin(); sItr!=singlets.end(); ++sItr)
pipes.push_back(StringPipe(&(*sItr),stringR0,_eventShapes));
avg_enhancer.SetEvent(pipes);
for(vector<StringPipe>::iterator it = pipes.begin(); it!=pipes.end(); ++it){
vector<ColourSinglet> toHadronization;
double h = avg_enhancer.KappaEnhancement(*it);
toHadronization.push_back(*(*it).GetSingletPtr());
forcerun = true;
hadronizeSystems(*(opHandler->GetPythiaPtr(h,nev%10000==0)),toHadronization,all);
}
break;
}
case 4: // Testing hadronization with tweaked version of Pythia.
{
Ropewalk ropewalk(singlets, stringR0, stringm0, throwaway, false);
- vector< pair<ColourSinglet,double> > strings = ropewalk.getSinglets();
+ vector< pair<ColourSinglet,double> > strings = ropewalk.getSinglets(stringyCut);
+ vector<ColourSinglet> toHadronization;
for(int i = 0, N = strings.size(); i < N; ++i ){
- Pythia8Interface * pytp = opHandler->GetPythiaPtr(strings[i].second,nev%10000==0);
- hadronizeTweak(*pytp,strings[i].first,all);
+ pythia.getRopeUserHooksPtr()->setEnhancement(strings[i].second);
+ toHadronization.clear();
+ toHadronization.push_back(strings[i].first);
+ hadronizeSystems(pythia,toHadronization,all);
}
-
break;
}
+
default:
cout << "We should really not be here. This is bad..." << endl;
}
// Do short analysis here:
if(doAnalysis){
ofstream out((analysisPath + "analysis.txt").c_str(),ios::app);
// out << "<event>" << endl;
// out << PrintStringsToMatlab(singlets) << endl;
// out << "</event>" << endl;
out.close();
}
}
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;
}
void StringFragmentation::
hadronizeTweak(Pythia8Interface & pyt, const ColourSinglet & singlet, const tPVector & all) {
Pythia8::Event & event = pyt.event();
pyt.clearEvent();
-
if (singlet.nPieces() > 1) Throw<StringFragError>() << name() << " Junction string. Abort. " << Exception::runerror;
else for(int j = 0, M = singlet.partons().size(); j < M; ++j) pyt.addParticle(singlet.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;
CurrentGenerator::Redirect stdout2(cout, true);
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);
}
}
}
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
- if ( opHandler ) delete opHandler;
- opHandler = new OverlapPythiaHandler(this,moresettings);
-
- // Should we do event shapes?
- _eventShapes = NULL;
- if(useThrustAxis==1){
- _eventShapes = new TheP8EventShapes();
- }
// Select hadronization scheme
if(fragmentationScheme.find("pythia")!=string::npos ||
fragmentationScheme.find("none")!=string::npos) fScheme = 0;
else if(fragmentationScheme.find("rope")!=string::npos ||
fragmentationScheme.find("test")!=string::npos) fScheme = 1;
else if(fragmentationScheme.find("dipole")!=string::npos ||
fragmentationScheme.find("ropewalk")!=string::npos) fScheme = 2;
else if(fragmentationScheme.find("average")!=string::npos) fScheme = 3;
- else if(fragmentationScheme.find("stringy")!=string::npos){
- fScheme = 4;
- cout << "You have selected hadronization with the tweaked version of Pythia!\n ThePEG needs to be configured with the tweaked Pythia 8 for this to work. Please ensure that this is the case." << endl;
- }
+ else if(fragmentationScheme.find("stringy")!=string::npos) fScheme = 4;
+
else{
cout << "You failed to provide a hadronization scheme. I shall use Vanilla Pythia 8." << endl;
fScheme = 0;
}
+ 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");
+
+ if(fScheme==4){ // We don't need multiple Pythia objects anymore!
+ pythia.enableHooks();
+ pythia.init(*this,theAdditionalP8Settings);
+ if(pythia.version() > 0 && pythia.version() - 1.234 > 1.0){
+ cout << "Pythia version: " << pythia.version() << endl;
+ cout << "Reconfigure with tweaked Pythia v. 1.234 for option 'stringy'. I will default you to option 'pythia'." << endl;
+ fScheme = 0;
+ }
+ else{
+ PytPars p;
+
+ p.insert(make_pair<const string,double>("StringPT:sigma",theStringPT_sigma));
+ p.insert(make_pair<const string,double>("StringZ:aLund",theStringZ_aLund));
+ p.insert(make_pair<const string,double>("StringZ:bLund",theStringZ_bLund));
+ p.insert(make_pair<const string,double>("StringFlav:probStoUD",theStringFlav_probStoUD));
+ p.insert(make_pair<const string,double>("StringFlav:probSQtoQQ",theStringFlav_probSQtoQQ));
+ p.insert(make_pair<const string,double>("StringFlav:probQQ1toQQ0",theStringFlav_probQQ1toQQ0));
+ p.insert(make_pair<const string,double>("StringFlav:probQQtoQ",theStringFlav_probQQtoQ));
+
+ phandler.init(fragmentationMass*fragmentationMass,baryonSuppression,p);
+ pythia.getRopeUserHooksPtr()->setParameterHandler(&phandler);
+ }
+ }
+ if(fScheme!=4){ // Not 'else' as it can change above...
+
+ 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));
+
+ // Initialize the OverlapPythia Handler
+ if ( opHandler ) delete opHandler;
+ opHandler = new OverlapPythiaHandler(this,moresettings);
+
+ }
+
+ // Should we do event shapes?
+ if(_eventShapes) delete _eventShapes;
+ _eventShapes = NULL;
+ if(useThrustAxis==1){
+ _eventShapes = new TheP8EventShapes();
+ }
+
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"));
-
-
}
-
+ nev = 0;
+
}
void StringFragmentation::persistentOutput(PersistentOStream & os) const {
os
#include "StringFragmentation-output.h"
<< ounit(stringR0,femtometer) << ounit(stringm0,GeV) << stringyCut << ounit(stringpTCut,GeV) << fragmentationMass << baryonSuppression << ounit(window,true) << ounit(throwaway,true) << useThrustAxis << fragmentationScheme << maxTries << theCollapser << doAnalysis << analysisPath;
}
void StringFragmentation::persistentInput(PersistentIStream & is, int) {
is
#include "StringFragmentation-input.h"
>> iunit(stringR0,femtometer) >> iunit(stringm0,GeV) >> stringyCut >> iunit(stringpTCut,GeV) >> fragmentationMass >> baryonSuppression >> iunit(window,true) >> iunit(throwaway,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." ,
&StringFragmentation::fragmentationScheme, "");
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> interfaceThrowAway
("ThrowAway",
"Throw away strings with weight:"
"Use 1 - (p + q)/(m + n) for (0,-1) configuration." ,
&StringFragmentation::throwaway, false, true, false);
static SwitchOption interfaceThrowAwayTrue
(interfaceThrowAway,"True","enabled.",true);
static SwitchOption interfaceThrowAwayFalse
(interfaceThrowAway,"False","disabled.",false);
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,Energy> interfaceStringm0
("Stringm0",
".",
&StringFragmentation::stringm0, GeV, 1.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,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();
}
diff --git a/Hadronization/StringFragmentation.h b/Hadronization/StringFragmentation.h
--- a/Hadronization/StringFragmentation.h
+++ b/Hadronization/StringFragmentation.h
@@ -1,292 +1,299 @@
// -*- C++ -*-
#ifndef THEP8I_StringFragmentation_H
#define THEP8I_StringFragmentation_H
//
// This is the declaration of the StringFragmentation class.
//
#include "ThePEG/Handlers/HadronizationHandler.h"
#include "ThePEG/Handlers/ClusterCollapser.h"
#include "TheP8I/Config/Pythia8Interface.h"
#include "OverlapPythiaHandler.h"
#include "TheP8EventShapes.h"
#include <sstream>
#include "YODA/Histo1D.h"
#include "YODA/Histo2D.h"
#include "YODA/Writer.h"
#include "YODA/WriterYODA.h"
namespace TheP8I {
using namespace ThePEG;
/**
* Here is the documentation of the StringFragmentation class.
*
* @see \ref StringFragmentationInterfaces "The interfaces"
* defined for StringFragmentation.
*/
class StringFragmentation: public HadronizationHandler {
+typedef map<string, double> PytPars;
+
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
StringFragmentation();
/**
* The destructor.
*/
virtual ~StringFragmentation();
//@}
public:
/**
* The main function called by the EventHandler class to
* perform the Hadronization step.
* @param eh the EventHandler in charge of the Event generation.
* @param tagged if not empty these are the only particles which should
* be considered by the StepHandler.
* @param hint a Hint object with possible information from previously
* performed steps.
* @throws Veto if the StepHandler requires the current step to be
* discarded.
* @throws Stop if the generation of the current Event should be stopped
* after this call.
* @throws Exception if something goes wrong.
*/
virtual void handle(EventHandler & eh, const tPVector & tagged,
const Hint & hint);
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Let the given Pythia8Interface hadronize the ColourSinglet
* systems provided.
*/
bool hadronizeSystems(Pythia8Interface & pyt, const vector<ColourSinglet> & singlets,
const tPVector & all);
void hadronizeTweak(Pythia8Interface & pyt, const ColourSinglet & singlet,
const tPVector & all);
/**
* 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);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
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;
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
private:
/**
* The interface to the Pythia 8 object,
*/
Pythia8Interface pythia;
/**
* Internal switch for the fragmentation scheme
*/
int fScheme;
/**
+ * Object that handles calculation of new Pythia parameters
+ */
+ ParameterHandler phandler;
+
+ /**
* The intrinsic string radius
*/
Length stringR0;
/**
* The assumed mass for calculating rapidities in the reeperbahn scheme
*/
Energy stringm0;
/**
* If **window** is set, this determines the abs(y) window for which no enhancement will be made
*/
double stringyCut;
/**
* If **window** is set, this determines the pT window for which no enhancement will be made
*/
Energy stringpTCut;
/**
* Assumed m0 value in calculation of normalization of f(z) the Lund splitting function.
*/
double fragmentationMass;
/**
* Parameter surpressing baryonic content further in calculation of effective parameters
*/
double baryonSuppression;
// Force hadronize systems to run to the end, regardless of windows
bool forcerun;
/**
* Can provide a window in y and pT where no enhancement is made, in order to not include
* very hard gluons in central rapidity region in a rope
*/
bool window;
/**
* Throw away some string entirely while making ropes
*/
bool throwaway;
TheP8EventShapes * _eventShapes;
/**
* Use thrust axis to calculate rapidities; useful for LEP validation
*/
int useThrustAxis;
/**
* Choose which fragmentation scheme to use
*/
string fragmentationScheme;
/**
* Additional interfaces to Pythia8 objects in case the string
* overlap model is to be used.
*/
OverlapPythiaHandler * opHandler;
/**
* Sometimes Pythia gives up on an event too easily. We allow it to
* re-try a couple of times.
*/
int maxTries;
// Keep track of how many events we already hadronized using this object, in order to clean up
int nev;
// Can do a small analysis
int doAnalysis;
vector<YODA::Histo1D*> _histograms;
vector<YODA::Histo2D*> _histograms2D;
string analysisPath;
void dofinish();
// Can print the strings of the event in a matlab friendly format
string PrintStringsToMatlab(vector<ColourSinglet>& singlets);
string convert(double d);
#include "StringFragmentation-var.h"
/**
* The object used to avoid too small strings in the hadronization.
*/
ClusterCollapserPtr theCollapser;
public:
/**
* Exception class declaration.
*/
struct StringFragError: public Exception {};
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<StringFragmentation> initStringFragmentation;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
StringFragmentation & operator=(const StringFragmentation &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of StringFragmentation. */
template <>
struct BaseClassTrait<TheP8I::StringFragmentation,1> {
/** Typedef of the first base class of StringFragmentation. */
typedef HadronizationHandler NthBase;
};
/** This template specialization informs ThePEG about the name of
* the StringFragmentation class and the shared object where it is defined. */
template <>
struct ClassTraits<TheP8I::StringFragmentation>
: public ClassTraitsBase<TheP8I::StringFragmentation> {
/** Return a platform-independent class name */
static string className() { return "TheP8I::StringFragmentation"; }
/**
* The name of a file containing the dynamic library where the class
* StringFragmentation is implemented. It may also include several, space-separated,
* libraries if the class StringFragmentation depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "libTheP8I.so"; }
};
/** @endcond */
}
#endif /* THEP8I_StringFragmentation_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 6:08 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4976495
Default Alt Text
(68 KB)
Attached To
rTHEPEGPEIGHTIHG thepegpeightihg
Event Timeline
Log In to Comment