Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F19250542
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
69 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/Hadronization/HadronSelector.cc b/Hadronization/HadronSelector.cc
--- a/Hadronization/HadronSelector.cc
+++ b/Hadronization/HadronSelector.cc
@@ -1,1078 +1,1087 @@
// -*- C++ -*-
//
// HadronSelector.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HadronSelector class.
//
#include "HadronSelector.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include <ThePEG/PDT/EnumParticles.h>
#include <ThePEG/Repository/EventGenerator.h>
#include <ThePEG/Repository/CurrentGenerator.h>
#include <ThePEG/Repository/Repository.h>
#include "CheckId.h"
#include <ThePEG/Utilities/DescribeClass.h>
using namespace Herwig;
DescribeAbstractClass<HadronSelector,Interfaced>
describeHadronSelector("Herwig::HadronSelector","Herwig.so");
namespace {
// // debug helper
// void dumpTable(const HadronSelector::HadronTable & tbl) {
// typedef HadronSelector::HadronTable::const_iterator TableIter;
// for (TableIter it = tbl.begin(); it != tbl.end(); ++it) {
// cerr << it->first.first << ' '
// << it->first.second << '\n';
// for (HadronSelector::KupcoData::const_iterator jt = it->second.begin();
// jt != it->second.end(); ++jt) {
// cerr << '\t' << *jt << '\n';
// }
// }
// }
bool weightIsLess (pair<long,double> a, pair<long,double> b) {
return a.second < b.second;
}
}
ostream & operator<< (ostream & os,
const HadronSelector::HadronInfo & hi ) {
os << std::scientific << std::showpoint
<< std::setprecision(4)
<< setw(2)
<< hi.id << '\t'
// << hi.ptrData << ' '
<< hi.swtef << '\t'
<< hi.wt << '\t'
<< hi.overallWeight << '\t'
<< ounit(hi.mass,GeV);
return os;
}
HadronSelector::HadronSelector(unsigned int opt)
: _pwtDquark( 1.0 ),_pwtUquark( 1.0 ),_pwtSquark( 1.0 ),_pwtCquark( 0.0 ),
_pwtBquark( 0.0 ),_pwtDIquarkS0( 1.0 ),_pwtDIquarkS1( 1.0 ),
_weight1S0(Nmax,1.),_weight3S1(Nmax,1.),_weight1P1(Nmax,1.),_weight3P0(Nmax,1.),
_weight3P1(Nmax,1.),_weight3P2(Nmax,1.),_weight1D2(Nmax,1.),_weight3D1(Nmax,1.),
_weight3D2(Nmax,1.),_weight3D3(Nmax,1.),
_repwt(Lmax,vector<vector<double> >(Jmax,vector<double>(Nmax))),
- _sngWt( 1.0 ),_decWt( 1.0 ),
+ _sngWt( 1.0 ),_octWt(1.0), _decWt( 1.0 ),
_topt(opt),_trial(0),
_limBottom(), _limCharm(), _limExotic(), belowThreshold_(0)
{
// The mixing angles
// the ideal mixing angle
const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi;
// \eta-\eta' mixing angle
_etamix = -23.0;
// phi-omega mixing angle
_phimix = +36.0;
// h_1'-h_1 mixing angle
_h1mix = idealAngleMix;
// f_0(1710)-f_0(1370) mixing angle
_f0mix = idealAngleMix;
// f_1(1420)-f_1(1285)\f$ mixing angle
_f1mix = idealAngleMix;
// f'_2-f_2\f$ mixing angle
_f2mix = +26.0;
// eta_2(1870)-eta_2(1645) mixing angle
_eta2mix = idealAngleMix;
// phi(???)-omega(1650) mixing angle
_omhmix = idealAngleMix;
// phi_3-omega_3 mixing angle
_ph3mix = +28.0;
// eta(1475)-eta(1295) mixing angle
_eta2Smix = idealAngleMix;
// phi(1680)-omega(1420) mixing angle
_phi2Smix = idealAngleMix;
}
void HadronSelector::persistentOutput(PersistentOStream & os) const {
os << _partons << _pwtDquark << _pwtUquark << _pwtSquark
<< _pwtCquark << _pwtBquark << _pwtDIquarkS0 << _pwtDIquarkS1
<< _etamix << _phimix << _h1mix << _f0mix << _f1mix << _f2mix
<< _eta2mix << _omhmix << _ph3mix << _eta2Smix << _phi2Smix
<< _weight1S0 << _weight3S1 << _weight1P1 << _weight3P0 << _weight3P1
<< _weight3P2 << _weight1D2 << _weight3D1 << _weight3D2 << _weight3D3
- << _forbidden << _sngWt << _decWt << _repwt << _pwt
+ << _forbidden << _sngWt << _octWt << _decWt << _repwt << _pwt
<< _limBottom << _limCharm << _limExotic << belowThreshold_
<< _table;
}
void HadronSelector::persistentInput(PersistentIStream & is, int) {
is >> _partons >> _pwtDquark >> _pwtUquark >> _pwtSquark
>> _pwtCquark >> _pwtBquark >> _pwtDIquarkS0 >> _pwtDIquarkS1
>> _etamix >> _phimix >> _h1mix >> _f0mix >> _f1mix >> _f2mix
>> _eta2mix >> _omhmix >> _ph3mix >> _eta2Smix >> _phi2Smix
>> _weight1S0 >> _weight3S1 >> _weight1P1 >> _weight3P0 >> _weight3P1
>> _weight3P2 >> _weight1D2 >> _weight3D1 >> _weight3D2 >> _weight3D3
- >> _forbidden >> _sngWt >> _decWt >> _repwt >> _pwt
+ >> _forbidden >> _sngWt >> _octWt >> _decWt >> _repwt >> _pwt
>> _limBottom >> _limCharm >> _limExotic >> belowThreshold_
>> _table;
}
void HadronSelector::Init() {
static ClassDocumentation<HadronSelector> documentation
("There is no documentation for the HadronSelector class");
static Parameter<HadronSelector,double>
interfacePwtDquark("PwtDquark","Weight for choosing a quark D",
&HadronSelector::_pwtDquark, 0, 1.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtUquark("PwtUquark","Weight for choosing a quark U",
&HadronSelector::_pwtUquark, 0, 1.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtSquark("PwtSquark","Weight for choosing a quark S",
&HadronSelector::_pwtSquark, 0, 1.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtCquark("PwtCquark","Weight for choosing a quark C",
&HadronSelector::_pwtCquark, 0, 0.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtBquark("PwtBquark","Weight for choosing a quark B",
&HadronSelector::_pwtBquark, 0, 0.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtDIquarkS0("PwtDIquarkS0","Weight for choosing a spin-0 DIquark",
&HadronSelector::_pwtDIquarkS0, 0, 1.0, 0.0, 100.0,
false,false,false);
static Parameter<HadronSelector,double>
interfacePwtDIquarkS1("PwtDIquarkS1","Weight for choosing a spin-1 DIquark",
&HadronSelector::_pwtDIquarkS1, 0, 1.0, 0.0, 100.0,
false,false,false);
static Parameter<HadronSelector,double>
interfaceSngWt("SngWt","Weight for singlet baryons",
&HadronSelector::_sngWt, 0, 1.0, 0.0, 10.0,
false,false,false);
static Parameter<HadronSelector,double>
+ interfaceOctWt("OctWt","Weight for octet baryons",
+ &HadronSelector::_octWt, 0, 1.0, 0.0, 10.0,
+ false,false,false);
+
+ static Parameter<HadronSelector,double>
interfaceDecWt("DecWt","Weight for decuplet baryons",
&HadronSelector::_decWt, 0, 1.0, 0.0, 10.0,
false,false,false);
static RefVector<HadronSelector,ParticleData> interfacePartons
("Partons",
"The partons which are to be considered as the consistuents of the hadrons.",
&HadronSelector::_partons, -1, false, false, true, false, false);
static RefVector<HadronSelector,ParticleData> interfaceForbidden
("Forbidden",
"The PDG codes of the particles which cannot be produced in the hadronization.",
&HadronSelector::_forbidden, -1, false, false, true, false, false);
//
// mixing angles
//
// the ideal mixing angle
const double idealAngleMix = atan( sqrt(0.5) ) * 180.0 / Constants::pi;
static Parameter<HadronSelector,double> interface11S0Mixing
("11S0Mixing",
"The mixing angle for the I=0 mesons from the 1 1S0 multiplet,"
" i.e. eta and etaprime.",
&HadronSelector::_etamix, -23., -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13S1Mixing
("13S1Mixing",
"The mixing angle for the I=0 mesons from the 1 3S1 multiplet,"
" i.e. phi and omega.",
&HadronSelector::_phimix, +36., -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface11P1Mixing
("11P1Mixing",
"The mixing angle for the I=0 mesons from the 1 1P1 multiplet,"
" i.e. h_1' and h_1.",
&HadronSelector::_h1mix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13P0Mixing
("13P0Mixing",
"The mixing angle for the I=0 mesons from the 1 3P0 multiplet,"
" i.e. f_0(1710) and f_0(1370).",
&HadronSelector::_f0mix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13P1Mixing
("13P1Mixing",
"The mixing angle for the I=0 mesons from the 1 3P1 multiplet,"
" i.e. f_1(1420) and f_1(1285).",
&HadronSelector::_f1mix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13P2Mixing
("13P2Mixing",
"The mixing angle for the I=0 mesons from the 1 3P2 multiplet,"
" i.e. f'_2 and f_2.",
&HadronSelector::_f2mix, 26.0, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface11D2Mixing
("11D2Mixing",
"The mixing angle for the I=0 mesons from the 1 1D2 multiplet,"
" i.e. eta_2(1870) and eta_2(1645).",
&HadronSelector::_eta2mix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13D0Mixing
("13D0Mixing",
"The mixing angle for the I=0 mesons from the 1 3D0 multiplet,"
" i.e. eta_2(1870) phi(?) and omega(1650).",
&HadronSelector::_omhmix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface13D1Mixing
("13D1Mixing",
"The mixing angle for the I=0 mesons from the 1 3D1 multiplet,"
" i.e. phi_3 and omega_3.",
&HadronSelector::_ph3mix, 28.0, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface21S0Mixing
("21S0Mixing",
"The mixing angle for the I=0 mesons from the 2 1S0 multiplet,"
" i.e. eta(1475) and eta(1295).",
&HadronSelector::_eta2Smix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
static Parameter<HadronSelector,double> interface23S1Mixing
("23S1Mixing",
"The mixing angle for the I=0 mesons from the 1 3S1 multiplet,"
" i.e. phi(1680) and omega(1420).",
&HadronSelector::_phi2Smix, idealAngleMix, -180., 180.,
false, false, Interface::limited);
//
// the meson weights
//
static ParVector<HadronSelector,double> interface1S0Weights
("1S0Weights",
"The weights for the 1S0 multiplets start with n=1.",
&HadronSelector::_weight1S0, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3S1Weights
("3S1Weights",
"The weights for the 3S1 multiplets start with n=1.",
&HadronSelector::_weight3S1, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface1P1Weights
("1P1Weights",
"The weights for the 1P1 multiplets start with n=1.",
&HadronSelector::_weight1P1, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3P0Weights
("3P0Weights",
"The weights for the 3P0 multiplets start with n=1.",
&HadronSelector::_weight3P0, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3P1Weights
("3P1Weights",
"The weights for the 3P1 multiplets start with n=1.",
&HadronSelector::_weight3P1, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3P2Weights
("3P2Weights",
"The weights for the 3P2 multiplets start with n=1.",
&HadronSelector::_weight3P2, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface1D2Weights
("1D2Weights",
"The weights for the 1D2 multiplets start with n=1.",
&HadronSelector::_weight1D2, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3D1Weights
("3D1Weights",
"The weights for the 3D1 multiplets start with n=1.",
&HadronSelector::_weight3D1, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3D2Weights
("3D2Weights",
"The weights for the 3D2 multiplets start with n=1.",
&HadronSelector::_weight3D2, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static ParVector<HadronSelector,double> interface3D3Weights
("3D3Weights",
"The weights for the 3D3 multiplets start with n=1.",
&HadronSelector::_weight3D3, Nmax, 1.0, 0.0, 100.0,
false, false, Interface::limited);
static Switch<HadronSelector,unsigned int> interfaceTrial
("Trial",
"A Debugging option to only produce certain types of hadrons",
&HadronSelector::_trial, 0, false, false);
static SwitchOption interfaceTrialAll
(interfaceTrial,
"All",
"Produce all the hadrons",
0);
static SwitchOption interfaceTrialPions
(interfaceTrial,
"Pions",
"Only produce pions",
1);
static SwitchOption interfaceTrialSpin2
(interfaceTrial,
"Spin2",
"Only mesons with spin less than or equal to two are produced",
2);
static SwitchOption interfaceTrialSpin3
(interfaceTrial,
"Spin3",
"Only hadrons with spin less than or equal to three are produced",
3);
static Parameter<HadronSelector,double>
interfaceSingleHadronLimitBottom ("SingleHadronLimitBottom",
"Threshold for one-hadron decay of b-cluster",
&HadronSelector::_limBottom,
0, 0.0, 0.0, 100.0,false,false,false);
static Parameter<HadronSelector,double>
interfaceSingleHadronLimitCharm ("SingleHadronLimitCharm",
"threshold for one-hadron decay of c-cluster",
&HadronSelector::_limCharm,
0, 0.0, 0.0, 100.0,false,false,false);
static Parameter<HadronSelector,double>
interfaceSingleHadronLimitExotic ("SingleHadronLimitExotic",
"threshold for one-hadron decay of exotic cluster",
&HadronSelector::_limExotic,
0, 0.0, 0.0, 100.0,false,false,false);
static Switch<HadronSelector,unsigned int> interfaceBelowThreshold
("BelowThreshold",
"Option fo the selection of the hadrons if the cluster is below the pair threshold",
&HadronSelector::belowThreshold_, 0, false, false);
static SwitchOption interfaceBelowThresholdLightest
(interfaceBelowThreshold,
"Lightest",
"Force cluster to decay to the lightest hadron with the appropriate flavours",
0);
static SwitchOption interfaceBelowThresholdAll
(interfaceBelowThreshold,
"All",
"Select from all the hadrons below the two hadron threshold according to their spin weights",
1);
}
double HadronSelector::mixingStateWeight(long id) const {
switch(id) {
case ParticleID::eta: return 0.5*probabilityMixing(_etamix ,1);
case ParticleID::etaprime: return 0.5*probabilityMixing(_etamix ,2);
case ParticleID::phi: return 0.5*probabilityMixing(_phimix ,1);
case ParticleID::omega: return 0.5*probabilityMixing(_phimix ,2);
case ParticleID::hprime_1: return 0.5*probabilityMixing(_h1mix ,1);
case ParticleID::h_1: return 0.5*probabilityMixing(_h1mix ,2);
case 10331: return 0.5*probabilityMixing(_f0mix ,1);
case 10221: return 0.5*probabilityMixing(_f0mix ,2);
case ParticleID::fprime_1: return 0.5*probabilityMixing(_f1mix ,1);
case ParticleID::f_1: return 0.5*probabilityMixing(_f1mix ,2);
case ParticleID::fprime_2: return 0.5*probabilityMixing(_f2mix ,1);
case ParticleID::f_2: return 0.5*probabilityMixing(_f2mix ,2);
case 10335: return 0.5*probabilityMixing(_eta2mix ,1);
case 10225: return 0.5*probabilityMixing(_eta2mix ,2);
// missing phi member of 13D1 should be here
case 30223: return 0.5*probabilityMixing(_omhmix ,2);
case 337: return 0.5*probabilityMixing(_ph3mix ,1);
case 227: return 0.5*probabilityMixing(_ph3mix ,2);
case 100331: return 0.5*probabilityMixing(_eta2mix ,1);
case 100221: return 0.5*probabilityMixing(_eta2mix ,2);
case 100333: return 0.5*probabilityMixing(_phi2Smix,1);
case 100223: return 0.5*probabilityMixing(_phi2Smix,2);
default: return 1./3.;
}
}
void HadronSelector::doinit() {
Interfaced::doinit();
// the default partons allowed
// the quarks
for ( int ix=1; ix<=5; ++ix ) {
_partons.push_back(getParticleData(ix));
}
// the diquarks
for(unsigned int ix=1;ix<=5;++ix) {
for(unsigned int iy=1; iy<=ix;++iy) {
_partons.push_back(getParticleData(CheckId::makeDiquarkID(ix,iy,long(3))));
if(ix!=iy)
_partons.push_back(getParticleData(CheckId::makeDiquarkID(ix,iy,long(1))));
}
}
// set the weights for the various excited mesons
// set all to one to start with
for (int l = 0; l < Lmax; ++l ) {
for (int j = 0; j < Jmax; ++j) {
for (int n = 0; n < Nmax; ++n) {
_repwt[l][j][n] = 1.0;
}
}
}
// set the others from the relevant vectors
for( int ix=0;ix<max(int(_weight1S0.size()),int(Nmax));++ix)
_repwt[0][0][ix]=_weight1S0[ix];
for( int ix=0;ix<max(int(_weight3S1.size()),int(Nmax));++ix)
_repwt[0][1][ix]=_weight3S1[ix];
for( int ix=0;ix<max(int(_weight1P1.size()),int(Nmax));++ix)
_repwt[1][1][ix]=_weight1P1[ix];
for( int ix=0;ix<max(int(_weight3P0.size()),int(Nmax));++ix)
_repwt[1][0][ix]=_weight3P0[ix];
for( int ix=0;ix<max(int(_weight3P1.size()),int(Nmax));++ix)
_repwt[1][1][ix]=_weight3P1[ix];
for( int ix=0;ix<max(int(_weight3P2.size()),int(Nmax));++ix)
_repwt[1][2][ix]=_weight3P2[ix];
for( int ix=0;ix<max(int(_weight1D2.size()),int(Nmax));++ix)
_repwt[2][2][ix]=_weight1D2[ix];
for( int ix=0;ix<max(int(_weight3D1.size()),int(Nmax));++ix)
_repwt[2][1][ix]=_weight3D1[ix];
for( int ix=0;ix<max(int(_weight3D2.size()),int(Nmax));++ix)
_repwt[2][2][ix]=_weight3D2[ix];
for( int ix=0;ix<max(int(_weight3D3.size()),int(Nmax));++ix)
_repwt[2][3][ix]=_weight3D3[ix];
// weights for the different quarks etc
for(unsigned int ix=0; ix<_partons.size(); ++ix) {
_pwt[_partons[ix]->id()]=1.;
}
_pwt[1] = _pwtDquark;
_pwt[2] = _pwtUquark;
_pwt[3] = _pwtSquark;
_pwt[4] = _pwtCquark;
_pwt[5] = _pwtBquark;
_pwt[1103] = _pwtDIquarkS1 * _pwtDquark * _pwtDquark;
_pwt[2101] = 0.5 * _pwtDIquarkS0 * _pwtUquark * _pwtDquark;
_pwt[2103] = 0.5 * _pwtDIquarkS1 * _pwtUquark * _pwtDquark;
_pwt[2203] = _pwtDIquarkS1 * _pwtUquark * _pwtUquark;
_pwt[3101] = 0.5 * _pwtDIquarkS0 * _pwtSquark * _pwtDquark;
_pwt[3103] = 0.5 * _pwtDIquarkS1 * _pwtSquark * _pwtDquark;
_pwt[3201] = 0.5 * _pwtDIquarkS0 * _pwtSquark * _pwtUquark;
_pwt[3203] = 0.5 * _pwtDIquarkS1 * _pwtSquark * _pwtUquark;
_pwt[3303] = _pwtDIquarkS1 * _pwtSquark * _pwtSquark;
// Commenting out heavy di-quark weights
_pwt[4101] = 0.0;
_pwt[4201] = 0.0;
_pwt[4301] = 0.0;
_pwt[4403] = 0.0;
_pwt[5101] = 0.0;
_pwt[5201] = 0.0;
_pwt[5301] = 0.0;
_pwt[5401] = 0.0;
_pwt[5503] = 0.0;
// find the maximum
map<long,double>::iterator pit =
max_element(_pwt.begin(),_pwt.end(),weightIsLess);
const double pmax = pit->second;
for(pit=_pwt.begin(); pit!=_pwt.end(); ++pit) {
pit->second/=pmax;
}
// construct the hadron tables
constructHadronTable();
// for debugging
// dumpTable(table());
}
void HadronSelector::constructHadronTable() {
// initialise the table
_table.clear();
for(unsigned int ix=0; ix<_partons.size(); ++ix) {
for(unsigned int iy=0; iy<_partons.size(); ++iy) {
if (!(DiquarkMatcher::Check(_partons[ix]->id())
&& DiquarkMatcher::Check(_partons[iy]->id())))
_table[make_pair(_partons[ix]->id(),_partons[iy]->id())] = KupcoData();
}
}
// get the particles from the event generator
ParticleMap particles = generator()->particles();
// loop over the particles
double maxdd(0.),maxss(0.),maxrest(0.);
for(ParticleMap::iterator it=particles.begin();
it!=particles.end(); ++it) {
long pid = it->first;
tPDPtr particle = it->second;
int pspin = particle->iSpin();
// Don't include hadrons which are explicitly forbidden
if(find(_forbidden.begin(),_forbidden.end(),particle)!=_forbidden.end())
continue;
// Don't include non-hadrons or antiparticles
if(pid < 100) continue;
// remove diffractive particles
if(pspin == 0) continue;
// K_0S and K_0L not made make K0 and Kbar0
if(pid==ParticleID::K_S0||pid==ParticleID::K_L0) continue;
// Debugging options
// Only include those with 2J+1 less than...5
if(_trial==2 && pspin >= 5) continue;
// Only include those with 2J+1 less than...7
if(_trial==3 && pspin >= 7) continue;
// Only include pions
if(_trial==1 && pid!=111 && pid!=211) continue;
// shouldn't be coloured
if(particle->coloured()) continue;
// Get the flavours
const int x4 = (pid/1000)%10;
const int x3 = (pid/100 )%10;
const int x2 = (pid/10 )%10;
const int x7 = (pid/1000000)%10;
const bool wantSusy = x7 == 1 || x7 == 2;
int flav1;
int flav2;
// Skip non-hadrons (susy particles, etc...)
if(x3 == 0 || x2 == 0) continue;
else if(x4 == 0) { // meson
flav1 = x2;
flav2 = x3;
}
else { // baryon
long rndSpin;
if(x2 == x3) rndSpin = 3;
else rndSpin = UseRandom::rnd() > 0.5 ? 1 : 3;
flav1 = CheckId::makeDiquarkID(x2,x3,rndSpin);
flav2 = x4;
}
if (wantSusy) flav2 += 1000000 * x7;
HadronInfo a(pid,
particle,
- specialWeight(pid,flav1),
+ specialWeight(pid,flav1,flav2),
particle->mass());
// set the weight to the number of spin states
a.overallWeight = pspin;
// identical light flavours
if(flav1 == flav2 && flav1<=3) {
// ddbar> uubar> admixture states
if(flav1==1) {
if(_topt != 0) a.overallWeight *= 0.5*a.swtef;
_table[make_pair(1,1)].insert(a);
_table[make_pair(2,2)].insert(a);
if(_topt == 0 && a.overallWeight > maxdd) maxdd = a.overallWeight;
}
// load up ssbar> uubar> ddbar> admixture states
else {
a.wt = mixingStateWeight(pid);
a.overallWeight *= a.wt;
if(_topt != 0) a.overallWeight *= a.swtef;
_table[make_pair(1,1)].insert(a);
_table[make_pair(2,2)].insert(a);
if(_topt == 0 && a.overallWeight > maxdd) maxdd = a.overallWeight;
a.wt = (_topt != 0) ? 1.- 2.*a.wt : 1 - a.wt;
if(a.wt > 0) {
a.overallWeight = a.wt * a.swtef * pspin;
_table[make_pair(3,3)].insert(a);
if(_topt == 0 && a.overallWeight > maxss) maxss = a.overallWeight;
}
}
}
// light baryons with all quarks identical
else if((flav1 == 1 && flav2 == 1103) || (flav1 == 1103 && flav2 == 1) ||
(flav1 == 2 && flav2 == 2203) || (flav1 == 2203 && flav2 == 2) ||
(flav1 == 3 && flav2 == 3303) || (flav1 == 3303 && flav2 == 3)) {
if(_topt != 0) a.overallWeight *= 1.5*a.swtef;
_table[make_pair(flav1,flav2)].insert(a);
_table[make_pair(flav2,flav1)].insert(a);
if(_topt == 0 && a.overallWeight > maxrest) maxrest = a.overallWeight;
}
// all other cases
else {
if(_topt != 0) a.overallWeight *=a.swtef;
_table[make_pair(flav1,flav2)].insert(a);
if(flav1 != flav2) _table[make_pair(flav2,flav1)].insert(a);
if(_topt == 0 && a.overallWeight > maxrest) maxrest = a.overallWeight;
}
}
// Account for identical combos of diquark/quarks and symmetrical elements
// e.g. U UD = D UU
HadronTable::iterator tit;
for(tit=_table.begin();tit!=_table.end();++tit) {
if(tit->first.first>ParticleID::c) continue;
if(!DiquarkMatcher::Check(tit->first.second)) continue;
long k, l, sub;
if(tit->first.second>=ParticleID::bd_0) {
k = ParticleID::b;
sub = ParticleID::bd_0/100;
}
else if(tit->first.second>=ParticleID::cd_0) {
k = ParticleID::c;
sub = ParticleID::cd_0/100;
}
else if(tit->first.second>=ParticleID::sd_0) {
k = ParticleID::s;
sub = ParticleID::sd_0/100;
}
else if(tit->first.second>=ParticleID::ud_0) {
k = ParticleID::u;
sub = ParticleID::ud_0/100;
}
else if(tit->first.second==ParticleID::dd_1) {
k = ParticleID::d;
sub = ParticleID::dd_1/100;
}
else continue;
sub=tit->first.second/100-sub+1;
if(sub > tit->first.first) {
l = 1000*sub+100*tit->first.first+1;
}
else if(sub==tit->first.first) {
l = 1000*sub+ 100*tit->first.first+3;
}
else {
l = 100*sub +1000*tit->first.first+1;
}
if(tit->second.empty()) {
pair<long,long> newpair(k,l);
tit->second=_table[newpair];
newpair=make_pair(tit->first.second,tit->first.first);
_table[newpair]=tit->second;
};
}
// normalise weights to one for first option
if(_topt == 0) {
HadronTable::const_iterator tit;
KupcoData::iterator it;
for(tit=_table.begin();tit!=_table.end();++tit) {
double weight;
if(tit->first.first==tit->first.second) {
if(tit->first.first==1||tit->first.first==2) weight=1./maxdd;
else if (tit->first.first==3) weight=1./maxss;
else weight=1./maxrest;
}
else weight=1./maxrest;
for(it = tit->second.begin(); it!=tit->second.end(); ++it) {
it->rescale(weight);
}
}
}
}
-double HadronSelector::specialWeight(long id, int part1) const {
+double HadronSelector::specialWeight(long id, int part1, int part2) const {
const int pspin = id % 10;
- // Get the flavours
- const int x4 = (id/1000)%10;
- const int x3 = (id/100 )%10;
- const int x2 = (id/10 )%10;
// Clebsch-Gordan coefficients of baryons
double CGcoefficient(1.);
// Only K0L and K0S have pspin == 0, should
// not get them until Decay step
assert( pspin != 0 );
// Baryon : J = 1/2 or 3/2
if(pspin == 2) {
// Singlet (Lambda-like) baryon
if( (id/100)%10 < (id/10 )%10 ) return sqr(_sngWt);
// octet
else {
// return 1 if part1 is not a diquark
- if(part1 < 1100) return 1.;
+ if(part1 < 1100) return sqr(_octWt);
// if part1 is a diquark
int diquarkSpin = (part1%10 == 1) ? 1 : 3;
+ // Get the flavours
+ const int x4 = (part1/1000)%10;
+ const int x3 = (part1/100 )%10;
+ const int x2 = (part2 )%10;
// ud0+u
if(x4 != x3 && (x2 == x3 || x2 == x4) && diquarkSpin==1)
CGcoefficient = 3./4.;
// ud0+s
else if(x4 != x3 && (x2 != x3 || x2 != x4) && diquarkSpin==1)
CGcoefficient = 1./2.;
// uu1+u
else if(x4 == x3 && x4 == x2 && diquarkSpin==3)
CGcoefficient = 0.;
// uu1+d
else if(x4 == x3 && x4 != x2 && diquarkSpin==3)
CGcoefficient = 1./6.;
// ud1+u
else if(x4 != x3 && (x2 == x3 || x2 == x4) && diquarkSpin==3)
CGcoefficient = 1./12.;
// ud1+s
else if(x4 != x3 && (x2 != x3 || x2 != x4) && diquarkSpin==3)
CGcoefficient = 1./6.;
- return CGcoefficient;
+ return sqr(_octWt)*CGcoefficient;
}
}
// Decuplet baryon
else if (pspin == 4) {
// return 1 if part1 is not a diquark
if(part1 < 1100) return sqr(_decWt);
// if part1 is a diquark
int diquarkSpin = (part1%10 == 1) ? 1 : 3;
+ // Get the flavours
+ const int x4 = (part1/1000)%10;
+ const int x3 = (part1/100 )%10;
+ const int x2 = (part2 )%10;
// ud0+u
if(x4 != x3 && (x2 == x3 || x2 == x4) && diquarkSpin==1)
CGcoefficient = 0.;
// ud0+s
else if(x4 != x3 && (x2 != x3 || x2 != x4) && diquarkSpin==1)
CGcoefficient = 0.;
// uu1+u
else if(x4 == x3 && x4 == x2 && diquarkSpin==3)
CGcoefficient = 1.;
// uu1+d
else if(x4 == x3 && x4 != x2 && diquarkSpin==3)
CGcoefficient = 1./3.;
// ud1+u
else if(x4 != x3 && (x2 == x3 || x2 == x4) && diquarkSpin==3)
CGcoefficient = 2./3.;
// ud1+s
else if(x4 != x3 && (x2 != x3 || x2 != x4) && diquarkSpin==3)
CGcoefficient = 1./3.;
return sqr(_decWt)*CGcoefficient;
}
// Meson
else if(pspin % 2 == 1) {
// Total angular momentum
int j = (pspin - 1) / 2;
// related to Orbital angular momentum l
int nl = (id/10000 )%10;
int l = -999;
int n = (id/100000)%10; // Radial excitation
if(j == 0) l = nl;
else if(nl == 0) l = j - 1;
else if(nl == 1 || nl == 2) l = j;
else if(nl == 3) l = j + 1;
// Angular or Radial excited meson
if((l||j||n) && l>=0 && l<Lmax && j<Jmax && n<Nmax) {
return sqr(_repwt[l][j][n]);
}
}
// rest is not excited or
// has spin >= 5/2 (ispin >= 6), haven't got those
return 1.0;
}
int HadronSelector::signHadron(tcPDPtr idQ1, tcPDPtr idQ2,
tcPDPtr hadron) const {
// This method receives in input three PDG ids, whose the
// first two have proper signs (corresponding to particles, id > 0,
// or antiparticles, id < 0 ), whereas the third one must
// be always positive (particle not antiparticle),
// corresponding to:
// --- quark-antiquark, or antiquark-quark, or
// quark-diquark, or diquark-quark, or
// antiquark-antidiquark, or antidiquark-antiquark
// for the first two input (idQ1, idQ2);
// --- meson or baryon for the third input (idHad):
// The method returns:
// --- + 1 if the two partons (idQ1, idQ2) are exactly
// the constituents for the hadron idHad;
// --- - 1 if the two partons (idQ1, idQ2) are exactly
// the constituents for the anti-hadron -idHad;
// --- + 0 otherwise.
// The method it is therefore useful to decide the
// sign of the id of the produced hadron as appeared
// in the vector _vecHad (where only hadron idHad > 0 are present)
// given the two constituent partons.
int sign = 0;
long idHad = hadron->id();
assert(idHad > 0);
int chargeIn = idQ1->iCharge() + idQ2->iCharge();
int chargeOut = hadron->iCharge();
// same charge
if( chargeIn == chargeOut && chargeIn !=0 ) sign = +1;
else if(chargeIn == -chargeOut && chargeIn !=0 ) sign = -1;
else if(chargeIn == 0 && chargeOut == 0 ) {
// In the case of same null charge, there are four cases:
// i) K0-like mesons, B0-like mesons, Bs-like mesons
// the PDG convention is to consider them "antiparticle" (idHad < 0)
// if the "dominant" (heavier) flavour (respectively, s, b)
// is a quark (idQ > 0): for instance, B0s = (b, sbar) has id < 0
// Remember that there is an important exception for K0L (id=130) and
// K0S (id=310): they don't have antiparticles, therefore idHad > 0
// always. We use below the fact that K0L and K0S are the unique
// hadrons having 0 the first (less significant) digit of their id.
// 2) D0-like mesons: the PDG convention is to consider them "particle"
// (idHad > 0) if the charm flavour is carried by a c: (c,ubar) has id>0
// 3) the remaining mesons should not have antiparticle, therefore their
// sign is always positive.
// 4) for baryons, that is when one of idQ1 and idQ2 is a (anti-) quark and
// the other one is a (anti-) diquark the sign is negative when both
// constituents are "anti", that is both with id < 0; positive otherwise.
// meson
if(abs(int(idQ1->iColour()))== 3 && abs(int(idQ2->iColour())) == 3 &&
!DiquarkMatcher::Check(idQ1->id()) && !DiquarkMatcher::Check(idQ2->id()))
{
int idQa = abs(idQ1->id());
int idQb = abs(idQ2->id());
int dominant = idQ2->id();
if(idQa > idQb) {
swap(idQa,idQb);
dominant = idQ1->id();
}
if((idQa==ParticleID::d && idQb==ParticleID::s) ||
(idQa==ParticleID::d && idQb==ParticleID::b) ||
(idQa==ParticleID::s && idQb==ParticleID::b)) {
// idHad%10 is zero for K0L,K0S
if (dominant < 0 || idHad%10 == 0) sign = +1;
else if(dominant > 0) sign = -1;
}
else if((idQa==ParticleID::u && idQb==ParticleID::c) ||
(idQa==ParticleID::u && idQb==ParticleID::t) ||
(idQa==ParticleID::c && idQb==ParticleID::t)) {
if (dominant > 0) sign = +1;
else if(dominant < 0) sign = -1;
}
else if(idQa==idQb) sign = +1;
// sets sign for Susy particles
else sign = (dominant > 0) ? +1 : -1;
}
// baryon
else if(DiquarkMatcher::Check(idQ1->id()) || DiquarkMatcher::Check(idQ2->id())) {
if (idQ1->id() > 0 && idQ2->id() > 0) sign = +1;
else if(idQ1->id() < 0 && idQ2->id() < 0) sign = -1;
}
}
if (sign == 0) {
cerr << "Could not work out sign for "
<< idQ1->PDGName() << ' '
<< idQ2->PDGName() << " => "
<< hadron->PDGName() << '\n';
assert(false);
}
return sign;
}
pair<tcPDPtr,tcPDPtr> HadronSelector::lightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2,
tcPDPtr ptr3) const {
// throw exception of id3!=0 as doesn't work
if ( ptr3 ) throw Exception()
<< "ptr3!=0 not yet implemented in HadronSelector::lightestHadronPair"
<< Exception::abortnow;
// charge
int totalcharge = ptr1->iCharge() + ptr2->iCharge();
if ( ptr3 ) totalcharge += ptr3->iCharge();
tcPDPtr vIdHad1[2]={tcPDPtr(),tcPDPtr()},vIdHad2[2]={tcPDPtr(),tcPDPtr()};
bool vOk[2] = {false, false};
Energy vMassPair[2] = { ZERO, ZERO };
for (int i = 0; i < 2; i++) {
tcPDPtr idPartner = i==0 ? getParticleData(ParticleID::d) : getParticleData(ParticleID::u);
// Change sign to idPartner (transform it into a anti-quark) if it is not
// possible to form a meson or a baryon.
assert (ptr1 && idPartner);
if (!CheckId::canBeHadron(ptr1, idPartner)) idPartner = idPartner->CC();
vIdHad1[i] = lightestHadron(ptr1, idPartner);
vIdHad2[i] = lightestHadron(ptr2, idPartner->CC());
if ( vIdHad1[i] && vIdHad2[i] &&
vIdHad1[i]->iCharge() + vIdHad2[i]->iCharge() == totalcharge ) {
vOk[i] = true;
vMassPair[i] = vIdHad1[i]->mass() + vIdHad2[i]->mass();
}
}
// Take the lightest pair compatible with charge conservation.
if ( vOk[0] && ( ! vOk[1] || vMassPair[0] <= vMassPair[1] ) ) {
return make_pair(vIdHad1[0],vIdHad2[0]);
}
else if ( vOk[1] && ( ! vOk[0] || vMassPair[1] < vMassPair[0] ) ) {
return make_pair(vIdHad1[1],vIdHad2[1]);
}
else {
return make_pair(tcPDPtr(),tcPDPtr());
}
}
Energy HadronSelector::massLightestBaryonPair(tcPDPtr ptr1, tcPDPtr ptr2) const {
// Make sure that we don't have any diquarks as input, return arbitrarily
// large value if we do
Energy currentSum = Constants::MaxEnergy;
for(unsigned int ix=0; ix<_partons.size(); ++ix) {
if(!DiquarkMatcher::Check(_partons[ix]->id())) continue;
HadronTable::const_iterator
tit1=_table.find(make_pair(abs(ptr1->id()),_partons[ix]->id())),
tit2=_table.find(make_pair(_partons[ix]->id(),abs(ptr2->id())));
if( tit1==_table.end() || tit2==_table.end()) continue;
if(tit1->second.empty()||tit2->second.empty()) continue;
Energy s = tit1->second.begin()->mass + tit2->second.begin()->mass;
if(currentSum > s) currentSum = s;
}
return currentSum;
}
tcPDPtr HadronSelector::lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2,
#ifndef NDEBUG
tcPDPtr ptr3) const {
#else
tcPDPtr ) const {
#endif
// The method assumes ptr3 == 0 rest not implemented
assert(ptr1 && ptr2 && !ptr3);
// find entry in the table
pair<long,long> ids = make_pair(abs(ptr1->id()),abs(ptr2->id()));
HadronTable::const_iterator tit=_table.find(ids);
// throw exception if flavours wrong
if (tit==_table.end())
throw Exception() << "Could not find "
<< ids.first << ' ' << ids.second
<< " in _table. "
<< "In HadronSelector::lightestHadron()"
<< Exception::eventerror;
if(tit->second.empty())
throw Exception() << "HadronSelector::lightestHadron "
<< "could not find any hadrons containing "
<< ptr1->id() << ' ' << ptr2->id() << '\n'
<< tit->first.first << ' '
<< tit->first.second << Exception::eventerror;
// find the lightest hadron
int sign = signHadron(ptr1,ptr2,tit->second.begin()->ptrData);
tcPDPtr candidate = sign > 0 ?
tit->second.begin()->ptrData : tit->second.begin()->ptrData->CC();
// \todo 20 GeV limit is temporary fudge to let SM particles go through.
// \todo Use isExotic instead?
if (candidate->mass() > 20*GeV
&& candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) {
generator()->log() << "HadronSelector::lightestHadron: "
<< "chosen candidate " << candidate->PDGName()
<< " is lighter than its constituents "
<< ptr1->PDGName() << ", " << ptr2->PDGName() << '\n'
<< candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV
<< " + " << ptr2->constituentMass()/GeV << '\n'
<< "Check your particle data tables.\n";
assert(false);
}
return candidate;
}
vector<pair<tcPDPtr,double> >
HadronSelector::hadronsBelowThreshold(Energy threshold, tcPDPtr ptr1,
tcPDPtr ptr2,
#ifndef NDEBUG
tcPDPtr ptr3) const {
#else
tcPDPtr ) const {
#endif
// The method assumes ptr3 == 0 rest not implemented
assert(ptr1 && ptr2 && !ptr3);
// find entry in the table
pair<long,long> ids = make_pair(abs(ptr1->id()),abs(ptr2->id()));
HadronTable::const_iterator tit=_table.find(ids);
// throw exception if flavours wrong
if (tit==_table.end())
throw Exception() << "Could not find "
<< ids.first << ' ' << ids.second
<< " in _table. "
<< "In HadronSelector::hadronsBelowThreshold()"
<< Exception::eventerror;
if(tit->second.empty())
throw Exception() << "HadronSelector::hadronsBelowThreshold() "
<< "could not find any hadrons containing "
<< ptr1->id() << ' ' << ptr2->id() << '\n'
<< tit->first.first << ' '
<< tit->first.second << Exception::eventerror;
vector<pair<tcPDPtr,double> > candidates;
KupcoData::const_iterator hit = tit->second.begin();
// find the hadrons
while(hit!=tit->second.end()&&hit->mass<threshold) {
// find the hadron
int sign = signHadron(ptr1,ptr2,hit->ptrData);
tcPDPtr candidate = sign > 0 ? hit->ptrData : hit->ptrData->CC();
// \todo 20 GeV limit is temporary fudge to let SM particles go through.
// \todo Use isExotic instead?
if (candidate->mass() > 20*GeV
&& candidate->mass() < ptr1->constituentMass() + ptr2->constituentMass()) {
generator()->log() << "HadronSelector::hadronsBelowTheshold: "
<< "chosen candidate " << candidate->PDGName()
<< " is lighter than its constituents "
<< ptr1->PDGName() << ", " << ptr2->PDGName() << '\n'
<< candidate->mass()/GeV << " < " << ptr1->constituentMass()/GeV
<< " + " << ptr2->constituentMass()/GeV << '\n'
<< "Check your particle data tables.\n";
assert(false);
}
candidates.push_back(make_pair(candidate,hit->overallWeight));
++hit;
}
return candidates;
}
tcPDPtr HadronSelector::chooseSingleHadron(tcPDPtr par1, tcPDPtr par2,
Energy mass) const {
// Determine the sum of the nominal masses of the two lightest hadrons
// with the right flavour numbers as the cluster under consideration.
// Notice that we don't need real masses (drawn by a Breit-Wigner
// distribution) because the lightest pair of hadrons does not involve
// any broad resonance.
Energy threshold = massLightestHadronPair(par1,par2);
// Special: it allows one-hadron decays also above threshold.
if (CheckId::isExotic(par1,par2))
threshold *= (1.0 + UseRandom::rnd()*_limExotic);
else if (CheckId::hasBottom(par1,par2))
threshold *= (1.0 + UseRandom::rnd()*_limBottom);
else if (CheckId::hasCharm(par1,par2))
threshold *= (1.0 + UseRandom::rnd()*_limCharm);
// only do one hadron decay is mass less than the threshold
if(mass>=threshold) return tcPDPtr();
// select the hadron
tcPDPtr hadron;
// old option pick the lightest hadron
if(belowThreshold_ == 0) {
hadron= lightestHadron(par1,par2);
}
// new option select from those available
else if(belowThreshold_ == 1) {
vector<pair<tcPDPtr,double> > hadrons =
hadronsBelowThreshold(threshold,par1,par2);
if(hadrons.size()==1) {
hadron = hadrons[0].first;
}
else if(hadrons.empty()) {
hadron= lightestHadron(par1,par2);
}
else {
double totalWeight=0.;
for(unsigned int ix=0;ix<hadrons.size();++ix) {
totalWeight += hadrons[ix].second;
}
totalWeight *= UseRandom::rnd();
for(unsigned int ix=0;ix<hadrons.size();++ix) {
if(totalWeight<=hadrons[ix].second) {
hadron = hadrons[ix].first;
break;
}
else
totalWeight -= hadrons[ix].second;
}
assert(hadron);
}
}
else
assert(false);
return hadron;
}
diff --git a/Hadronization/HadronSelector.h b/Hadronization/HadronSelector.h
--- a/Hadronization/HadronSelector.h
+++ b/Hadronization/HadronSelector.h
@@ -1,827 +1,833 @@
// -*- C++ -*-
//
// HadronSelector.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_HadronSelector_H
#define HERWIG_HadronSelector_H
//
// This is the declaration of the HadronSelector class.
//
#include "ThePEG/Interface/Interfaced.h"
#include <ThePEG/Persistency/PersistentOStream.h>
#include <ThePEG/Persistency/PersistentIStream.h>
#include <ThePEG/PDT/ParticleData.h>
#include <ThePEG/PDT/StandardMatchers.h>
#include <ThePEG/Repository/EventGenerator.h>
#include "HadronSelector.fh"
namespace Herwig {
using namespace ThePEG;
/**\ingroup Hadronization
* \class HadronSelector
* \brief This class selects the hadron flavours of a cluster decay.
* \author Philip Stephens
* \author Alberto Ribon
* \author Peter Richardson
*
* This is the base class for the selection of either a pair of hadrons, or
* in some cases a single hadron. The different approaches which were
* previously implemented in this class are now implemented in the
* HwppSelector and Hw64Selector which inherit from this class.
*
* This class implements a number of methods which are needed by all models
* and in addition contains the weights for the different meson multiplets and
* mixing of the light \f$I=0\f$ mesons.
*
* @see \ref HadronSelectorInterfaces "The interfaces"
* defined for HadronSelector.
* @see HwppSelector
* @see Hw64Selector
*/
class HadronSelector: public Interfaced {
public:
/** \ingroup Hadronization
* \class HadronInfo
* \brief Class used to store all the hadron information for easy access.
* \author Philip Stephens
*
* Note that:
* - the hadrons in _table can be filled in any ordered
* w.r.t. the mass value, and flavours for different
* groups (for instance, (u,s) hadrons don't need to
* be placed after (d,s) or any other flavour), but
* all hadrons with the same flavours must be consecutive
* ( for instance you cannot alternate hadrons of type
* (d,s) with those of flavour (u,s) ).
* Furthermore, it is assumed that particle and antiparticle
* have the same weights, and therefore only one of them
* must be entered in the table: we have chosen to refer
* to the particle, defined as PDG id > 0, although if
* an anti-particle is provided in input it is automatically
* transform to its particle, simply by taking the modulus
* of its id.
*/
class HadronInfo {
public:
/**
* Constructor
* @param idin The PDG code of the hadron
* @param datain The pointer to the ParticleData object
* @param swtin The singlet/decuplet/orbital factor
* @param massin The mass of the hadron
*/
HadronInfo(long idin=0, tPDPtr datain=tPDPtr(),
double swtin=1., Energy massin=ZERO)
: id(idin), ptrData(datain), swtef(swtin), wt(1.0), overallWeight(0.0),
mass(massin)
{}
/**
* Comparision operator on mass
*/
bool operator<(const HadronInfo &x) const {
if(mass!=x.mass) return mass < x.mass;
else return id < x.id;
}
/**
* The hadrons id.
*/
long id;
/**
* pointer to ParticleData, to get the spin, etc...
*/
tPDPtr ptrData;
/**
* singlet/decuplet/orbital factor
*/
double swtef;
/**
* mixing factor
*/
double wt;
/**
* (2*J+1)*wt*swtef
*/
double overallWeight;
/**
* The hadrons mass
*/
Energy mass;
/**
* Rescale the weight for a given hadron
*/
void rescale(double x) const {
const_cast<HadronInfo*>(this)->overallWeight *= x;
}
/**
* Friend method used to print the value of a table element.
*/
friend PersistentOStream & operator<< (PersistentOStream & os,
const HadronInfo & hi ) {
os << hi.id << hi.ptrData << hi.swtef << hi.wt
<< hi.overallWeight << ounit(hi.mass,GeV);
return os;
}
/**
* debug output
*/
friend ostream & operator<< (ostream & os, const HadronInfo & hi );
/**
* Friend method used to read in the value of a table element.
*/
friend PersistentIStream & operator>> (PersistentIStream & is,
HadronInfo & hi ) {
is >> hi.id >> hi.ptrData >> hi.swtef >> hi.wt
>> hi.overallWeight >> iunit(hi.mass,GeV);
return is;
}
};
/** \ingroup Hadronization
* \class Kupco
* \brief Class designed to make STL routines easy to use.
* \author Philip Stephens
*
* This class is used to generate a list of the hadron pairs which can
* be produced that allows easy traversal and quick access.
*/
class Kupco {
public:
/**
* Constructor
* @param inidQ PDG code of the quark drawn from the vacuum.
* @param inhad1 ParticleData for the first hadron produced.
* @param inhad2 ParticleData for the second hadron produced.
* @param inwgt The weight for the hadron pair
*/
Kupco(tcPDPtr inidQ,tcPDPtr inhad1,tcPDPtr inhad2, Energy inwgt)
: idQ(inidQ),hadron1(inhad1),hadron2(inhad2),weight(inwgt)
{}
/**
* id of the quark drawn from the vacuum.
*/
tcPDPtr idQ;
/**
* The ParticleData object for the first hadron produced.
*/
tcPDPtr hadron1;
/**
* The ParticleData object for the second hadron produced.
*/
tcPDPtr hadron2;
/**
* Weight factor of this componation.
*/
Energy weight;
};
public:
/**
* The helper classes
*/
//@{
/**
* The type is used to contain all the hadrons info of a given flavour.
*/
typedef set<HadronInfo> KupcoData;
//@}
/**
* The hadron table type.
*/
typedef map<pair<long,long>,KupcoData> HadronTable;
public:
/**
* The default constructor.
*/
HadronSelector(unsigned int);
/**
* Method to return a pair of hadrons given the PDG codes of
* two or three constituents
* @param cluMass The mass of the cluster
* @param par1 The first constituent
* @param par2 The second constituent
* @param par3 The third constituent
*/
virtual pair<tcPDPtr,tcPDPtr> chooseHadronPair(const Energy cluMass, tcPDPtr par1,
tcPDPtr par2,tcPDPtr par3 = PDPtr()) const
= 0;
/**
* Select the single hadron for a cluster decay
* return null pointer if not a single hadron decay
* @param par1 1st constituent
* @param par2 2nd constituent
* @param mass Mass of the cluster
*/
tcPDPtr chooseSingleHadron(tcPDPtr par1, tcPDPtr par2, Energy mass) const;
/**
* This returns the lightest pair of hadrons given by the flavours.
*
* Given the two (or three) constituents of a cluster, it returns
* the two lightest hadrons with proper flavour numbers.
* Furthermore, the first of the two hadrons must have the constituent with
* par1, and the second must have the constituent with par2.
* \todo At the moment it does *nothing* in the case that also par3 is present.
*
* The method is implemented by calling twice lightestHadron,
* once with (par1,quarktopick->CC()) ,and once with (par2,quarktopick)
* where quarktopick is either the pointer to
* d or u quarks . In fact, the idea is that whatever the flavour of par1
* and par2, no matter if (anti-)quark or (anti-)diquark, the lightest
* pair of hadrons containing flavour par1 and par2 will have either
* flavour d or u, being the lightest quarks.
* The method returns the pair (PDPtr(),PDPtr()) if anything goes wrong.
*
* \todo The method assumes par3 == PDPtr() (otherwise we don't know how to proceed: a
* possible, trivial way would be to randomly select two of the three
* (anti-)quarks and treat them as a (anti-)diquark, reducing the problem
* to two components as treated below.
* In the normal (two components) situation, the strategy is the following:
* treat in the same way the two possibilities: (d dbar) (i=0) and
* (u ubar) (i=1) as the pair quark-antiquark necessary to form a
* pair of hadrons containing the input flavour par1 and par2; finally,
* select the one that produces the lightest pair of hadrons, compatible
* with the charge conservation constraint.
*/
pair<tcPDPtr,tcPDPtr> lightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2,
tcPDPtr ptr3 = PDPtr ()) const;
/**
* Returns the mass of the lightest pair of hadrons with the given particles
* @param ptr1 is the first constituent
* @param ptr2 is the second constituent
* @param ptr3 is the third constituent
*/
Energy massLightestHadronPair(tcPDPtr ptr1, tcPDPtr ptr2,
tcPDPtr ptr3 = PDPtr ()) const {
pair<tcPDPtr,tcPDPtr> pairData = lightestHadronPair(ptr1, ptr2, ptr3);
if ( ! pairData.first || ! pairData.second ) return ZERO;
return ( pairData.first->mass() + pairData.second->mass() );
}
/**
* Returns the lightest hadron formed by the given particles.
*
* Given the id of two (or three) constituents of a cluster, it returns
* the lightest hadron with proper flavour numbers.
* At the moment it does *nothing* in the case that also 'ptr3' present.
* @param ptr1 is the first constituent
* @param ptr2 is the second constituent
* @param ptr3 is the third constituent
*/
tcPDPtr lightestHadron(tcPDPtr ptr1, tcPDPtr ptr2,
tcPDPtr ptr3 = PDPtr ()) const;
/**
* Returns the hadrons below the constituent mass threshold formed by the given particles,
* together with their total weight
*
* Given the id of two (or three) constituents of a cluster, it returns
* the lightest hadron with proper flavour numbers.
* At the moment it does *nothing* in the case that also 'ptr3' present.
* @param threshold The theshold
* @param ptr1 is the first constituent
* @param ptr2 is the second constituent
* @param ptr3 is the third constituent
*/
vector<pair<tcPDPtr,double> >
hadronsBelowThreshold(Energy threshold,
tcPDPtr ptr1, tcPDPtr ptr2,
tcPDPtr ptr3 = PDPtr ()) const;
/**
* Return the nominal mass of the hadron returned by lightestHadron()
* @param ptr1 is the first constituent
* @param ptr2 is the second constituent
* @param ptr3 is the third constituent
*/
Energy massLightestHadron(tcPDPtr ptr1, tcPDPtr ptr2,
#ifndef NDEBUG
tcPDPtr ptr3 = PDPtr ()) const {
#else
tcPDPtr = PDPtr ()) const {
#endif
// The method assumes ptr3 == empty
assert(!(ptr3));
// find entry in the table
pair<long,long> ids(abs(ptr1->id()),abs(ptr2->id()));
HadronTable::const_iterator tit=_table.find(ids);
// throw exception if flavours wrong
if(tit==_table.end()||tit->second.empty())
throw Exception() << "HadronSelector::massLightestHadron "
<< "failed for particle" << ptr1->id() << " "
<< ptr2->id()
<< Exception::eventerror;
// return the mass
return tit->second.begin()->mass;
}
/**
* Returns the mass of the lightest pair of baryons.
* @param ptr1 is the first constituent
* @param ptr2 is the second constituent
*/
Energy massLightestBaryonPair(tcPDPtr ptr1, tcPDPtr ptr2) const;
/**
* Return the weights for the different quarks and diquarks
*/
//@{
/**
* The down quark weight.
*/
double pwtDquark() const {
return _pwtDquark;
}
/**
* The up quark weight.
*/
double pwtUquark() const {
return _pwtUquark;
}
/**
* The strange quark weight.
*/
double pwtSquark() const {
return _pwtSquark;
}
/**
* The charm quark weight.
*/
double pwtCquark() const {
return _pwtCquark;
}
/**
* The bottom quark weight.
*/
double pwtBquark() const {
return _pwtBquark;
}
/**
* The diquark weight for spin-0 diquarks.
*/
double pwtDIquarkS0() const {
return _pwtDIquarkS0;
}
/**
* The diquark weight for spin-1 diquarks.
*/
double pwtDIquarkS1() const {
return _pwtDIquarkS1;
}
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* 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 Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
*
* The array _repwt is initialized using the interfaces to set different
* weights for different meson multiplets and the constructHadronTable()
* method called to complete the construction of the hadron tables.
*
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
protected:
/**
* Construct the table of hadron data
* This is the main method to initialize the hadron data (mainly the
* weights associated to each hadron, taking into account its spin,
* eventual isoscalar-octect mixing, singlet-decuplet factor). This is
* the method that one should update when new or updated hadron data is
* available.
*
* This class implements the construction of the basic table but can be
* overridden if needed in inheriting classes.
*
* The rationale for factors used for diquarks involving different quarks can
* be can be explained by taking a prototype example that in the exact SU(2) limit,
* in which:
* \f[m_u=m_d\f]
* \f[M_p=M_n=M_\Delta\f]
* and we will have equal numbers of u and d quarks produced.
* Suppose that we weight 1 the diquarks made of the same
* quark and 1/2 those made of different quarks, the fractions
* of u and d baryons (p, n, Delta) we get are the following:
* - \f$\Delta^{++}\f$: 1 possibility only u uu with weight 1
* - \f$\Delta^- \f$: 1 possibility only d dd with weight 1
* - \f$p,\Delta^+ \f$: 2 possibilities u ud with weight 1/2
* d uu with weight 1
* - \f$n,\Delta^0 \f$: 2 possibilities d ud with weight 1/2
* u dd with weight 1
* In the latter two cases, we have to take into account the
* fact that p and n have spin 1/2 whereas Delta+ and Delta0
* have spin 3/2 therefore from phase space we get a double weight
* for Delta+ and Delta0 relative to p and n respectively.
* Therefore the relative amount of these baryons that is
* produced is the following:
* # p = # n = ( 1/2 + 1 ) * 1/3 = 1/2
* # Delta++ = # Delta- = 1 = ( 1/2 + 1) * 2/3 # Delta+ = # Delta0
* which is correct, and therefore the weight 1/2 for the
* diquarks of different types of quarks is justified (at least
* in this limit of exact SU(2) ).
*/
virtual void constructHadronTable();
/**
* Access to the table of hadrons
*/
const HadronTable & table() const {
return _table;
}
/**
* Access to the list of partons
*/
const vector<PDPtr> & partons() const {
return _partons;
}
/**
* Access the parton weights
*/
double pwt(long pid) const {
map<long,double>::const_iterator it = _pwt.find(abs(pid));
assert( it != _pwt.end() );
return it->second;
}
/**
* Methods for the mixing of \f$I=0\f$ mesons
*/
//@{
/**
* Return the probability of mixing for Octet-Singlet isoscalar mixing,
* the probability of the
* \f$\frac1{\sqrt{2}}(|u\bar{u}\rangle + |d\bar{d}\rangle)\f$ component
* is returned.
* @param angleMix The mixing angle in degrees (not radians)
* @param order is 0 for no mixing, 1 for the first resonance of a pair,
* 2 for the second one.
* The mixing is defined so that for example with \f$\eta-\eta'\f$ mixing where
* the mixing angle is \f$\theta=-23^0$ with $\eta\f$ as the first particle
* and \f$\eta'\f$ the second one.
* The convention used is
* \f[\eta = \cos\theta|\eta_{\rm octet }\rangle
* -\sin\theta|\eta_{\rm singlet}\rangle\f]
* \f[\eta' = \sin\theta|\eta_{\rm octet }\rangle
* -\cos\theta|\eta_{\rm singlet}\rangle\f]
* with
* \f[|\eta_{\rm singlet}\rangle = \frac1{\sqrt{3}}
* \left[|u\bar{u}\rangle + |d\bar{d}\rangle + |s\bar{s}\rangle\right]\f]
* \f[|\eta_{\rm octet }\rangle = \frac1{\sqrt{6}}
* \left[|u\bar{u}\rangle + |d\bar{d}\rangle - 2|s\bar{s}\rangle\right]\f]
*/
double probabilityMixing(const double angleMix,
const int order) const {
static double convert=Constants::pi/180.0;
if (order == 1)
return sqr( cos( angleMix*convert + atan( sqrt(2.0) ) ) );
else if (order == 2)
return sqr( sin( angleMix*convert + atan( sqrt(2.0) ) ) );
else
return 1.;
}
/**
* Returns the weight of given mixing state.
* @param id The PDG code of the meson
*/
virtual double mixingStateWeight(long id) const;
//@}
/**
* Calculates a special weight specific to a given hadron.
* @param id The PDG code of the hadron
* @param part1 The PDG code of the first particle componant of the hadron
+ * @param part2 The PDG code of the second particle componant of the hadron
*/
- double specialWeight(long id, int part1) const;
+ double specialWeight(long id, int part1, int part2) const;
/**
* This method returns the proper sign ( > 0 hadron; < 0 anti-hadron )
* for the input PDG id idHad > 0, suppose to be made by the
* two constituent particle pointers: par1 and par2 (both with proper sign).
*/
int signHadron(tcPDPtr ptr1, tcPDPtr ptr2, tcPDPtr hadron) const;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
HadronSelector & operator=(const HadronSelector &) = delete;
private:
/**
* The PDG codes of the constituent particles allowed
*/
vector<PDPtr> _partons;
/**
* The PDG codes of the hadrons which cannot be produced in the hadronization
*/
vector<PDPtr> _forbidden;
/**
* The weights for the different quarks and diquarks
*/
//@{
/**
* The probability of producting a down quark.
*/
double _pwtDquark;
/**
* The probability of producting an up quark.
*/
double _pwtUquark;
/**
* The probability of producting a strange quark.
*/
double _pwtSquark;
/**
* The probability of producting a charm quark.
*/
double _pwtCquark;
/**
* The probability of producting a bottom quark.
*/
double _pwtBquark;
/**
* The probability of producting a spin-0 diquark.
*/
double _pwtDIquarkS0;
/**
* The probability of producting a spin-1 diquark.
*/
double _pwtDIquarkS1;
/**
* Weights for quarks and diquarks.
*/
map<long,double> _pwt;
//@}
/**
* The mixing angles for the \f$I=0\f$ mesons containing light quarks
*/
//@{
/**
* The \f$\eta-\eta'\f$ mixing angle
*/
double _etamix;
/**
* The \f$\phi-\omega\f$ mixing angle
*/
double _phimix;
/**
* The \f$h_1'-h_1\f$ mixing angle
*/
double _h1mix;
/**
* The \f$f_0(1710)-f_0(1370)\f$ mixing angle
*/
double _f0mix;
/**
* The \f$f_1(1420)-f_1(1285)\f$ mixing angle
*/
double _f1mix;
/**
* The \f$f'_2-f_2\f$ mixing angle
*/
double _f2mix;
/**
* The \f$\eta_2(1870)-\eta_2(1645)\f$ mixing angle
*/
double _eta2mix;
/**
* The \f$\phi(???)-\omega(1650)\f$ mixing angle
*/
double _omhmix;
/**
* The \f$\phi_3-\omega_3\f$ mixing angle
*/
double _ph3mix;
/**
* The \f$\eta(1475)-\eta(1295)\f$ mixing angle
*/
double _eta2Smix;
/**
* The \f$\phi(1680)-\omega(1420)\f$ mixing angle
*/
double _phi2Smix;
//@}
/**
* The weights for the various meson multiplets to be used to supress the
* production of particular states
*/
//@{
/**
* The weights for the \f$\phantom{1}^1S_0\f$ multiplets
*/
vector<double> _weight1S0;
/**
* The weights for the \f$\phantom{1}^3S_1\f$ multiplets
*/
vector<double> _weight3S1;
/**
* The weights for the \f$\phantom{1}^1P_1\f$ multiplets
*/
vector<double> _weight1P1;
/**
* The weights for the \f$\phantom{1}^3P_0\f$ multiplets
*/
vector<double> _weight3P0;
/**
* The weights for the \f$\phantom{1}^3P_1\f$ multiplets
*/
vector<double> _weight3P1;
/**
* The weights for the \f$\phantom{1}^3P_2\f$ multiplets
*/
vector<double> _weight3P2;
/**
* The weights for the \f$\phantom{1}^1D_2\f$ multiplets
*/
vector<double> _weight1D2;
/**
* The weights for the \f$\phantom{1}^3D_1\f$ multiplets
*/
vector<double> _weight3D1;
/**
* The weights for the \f$\phantom{1}^3D_2\f$ multiplets
*/
vector<double> _weight3D2;
/**
* The weights for the \f$\phantom{1}^3D_3\f$ multiplets
*/
vector<double> _weight3D3;
//@}
/**
* The weights for the excited meson multiplets
*/
vector<vector<vector<double> > > _repwt;
/**
* Singlet and Decuplet weights
*/
//@{
/**
* The singlet weight
*/
double _sngWt;
/**
+ * The octet weight
+ */
+ double _octWt;
+
+ /**
* The decuplet weight
*/
double _decWt;
//@}
/**
* The table of hadron data
*/
HadronTable _table;
/**
* Enums so arrays can be statically allocated
*/
//@{
/**
* Defines values for array sizes. L,J,N max values for excited mesons.
*/
enum MesonMultiplets { Lmax = 3, Jmax = 4, Nmax = 4};
//@}
/**
* Option for the construction of the tables
*/
unsigned int _topt;
/**
* Which particles to produce for debugging purposes
*/
unsigned int _trial;
/**
* @name A parameter used for determining when clusters are too light.
*
* This parameter is used for setting the lower threshold, \f$ t \f$ as
* \f[ t' = t(1 + r B^1_{\rm lim}) \f]
* where \f$ r \f$ is a random number [0,1].
*/
//@{
double _limBottom;
double _limCharm;
double _limExotic;
//@}
/**
* Option for the selection of hadrons below the pair threshold
*/
unsigned int belowThreshold_;
};
}
#endif /* HERWIG_HadronSelector_H */
diff --git a/src/defaults/Hadronization.in b/src/defaults/Hadronization.in
--- a/src/defaults/Hadronization.in
+++ b/src/defaults/Hadronization.in
@@ -1,101 +1,102 @@
# -*- ThePEG-repository -*-
############################################################
# Setup of default hadronization
#
# There are no user servicable parts inside.
#
# Anything that follows below should only be touched if you
# know what you're doing.
#############################################################
cd /Herwig/Particles
create ThePEG::ParticleData Cluster
setup Cluster 81 Cluster 0.00990 0.0 0.0 0.0 0 0 0 1
create ThePEG::ParticleData Remnant
setup Remnant 82 Remnant 0.00990 0.0 0.0 0.0 0 0 0 1
mkdir /Herwig/Hadronization
cd /Herwig/Hadronization
create Herwig::ClusterHadronizationHandler ClusterHadHandler
create Herwig::PartonSplitter PartonSplitter
create Herwig::ClusterFinder ClusterFinder
create Herwig::ColourReconnector ColourReconnector
create Herwig::ClusterFissioner ClusterFissioner
create Herwig::LightClusterDecayer LightClusterDecayer
create Herwig::ClusterDecayer ClusterDecayer
create Herwig::HwppSelector HadronSelector
newdef ClusterHadHandler:PartonSplitter PartonSplitter
newdef ClusterHadHandler:ClusterFinder ClusterFinder
newdef ClusterHadHandler:ColourReconnector ColourReconnector
newdef ClusterHadHandler:ClusterFissioner ClusterFissioner
newdef ClusterHadHandler:LightClusterDecayer LightClusterDecayer
newdef ClusterHadHandler:ClusterDecayer ClusterDecayer
newdef ClusterHadHandler:MinVirtuality2 0.1*GeV2
newdef ClusterHadHandler:MaxDisplacement 1.0e-10*millimeter
newdef ClusterHadHandler:UnderlyingEventHandler NULL
newdef ClusterFissioner:HadronSelector HadronSelector
newdef LightClusterDecayer:HadronSelector HadronSelector
newdef ClusterDecayer:HadronSelector HadronSelector
newdef ColourReconnector:ColourReconnection Yes
newdef ColourReconnector:ReconnectionProbabilityBaryonic 0.7
newdef ColourReconnector:ReconnectionProbability 0.95
newdef ColourReconnector:Algorithm Baryonic
newdef ColourReconnector:OctetTreatment All
# Clustering parameters for light quarks
newdef ClusterFissioner:ClMaxLight 3.649
newdef ClusterFissioner:ClPowLight 2.780
newdef ClusterFissioner:PSplitLight 0.899
newdef ClusterDecayer:ClDirLight 1
newdef ClusterDecayer:ClSmrLight 0.78
# Clustering parameters for b-quarks
newdef ClusterFissioner:ClMaxBottom 3.757
newdef ClusterFissioner:ClPowBottom 0.547
newdef ClusterFissioner:PSplitBottom 0.625
newdef ClusterDecayer:ClDirBottom 1
newdef ClusterDecayer:ClSmrBottom 0.078
newdef HadronSelector:SingleHadronLimitBottom 0.000
# Clustering parameters for c-quarks
newdef ClusterFissioner:ClMaxCharm 3.950
newdef ClusterFissioner:ClPowCharm 2.559
newdef ClusterFissioner:PSplitCharm 0.994
newdef ClusterDecayer:ClDirCharm 1
newdef ClusterDecayer:ClSmrCharm 0.163
newdef HadronSelector:SingleHadronLimitCharm 0.000
# Clustering parameters for exotic quarks
# (e.g. hadronizing Susy particles)
newdef ClusterFissioner:ClMaxExotic 2.7*GeV
newdef ClusterFissioner:ClPowExotic 1.46
newdef ClusterFissioner:PSplitExotic 1.00
newdef ClusterDecayer:ClDirExotic 1
newdef ClusterDecayer:ClSmrExotic 0.
newdef HadronSelector:SingleHadronLimitExotic 0.
#
newdef PartonSplitter:SplitPwtSquark 0.824135
newdef PartonSplitter:Split uds
#
newdef HadronSelector:PwtDquark 1.0
newdef HadronSelector:PwtUquark 1.0
newdef HadronSelector:PwtSquark 0.291717
newdef HadronSelector:PwtCquark 0.0
newdef HadronSelector:PwtBquark 0.0
newdef HadronSelector:PwtDIquarkS0 0.2
newdef HadronSelector:PwtDIquarkS1 0.1
newdef HadronSelector:SngWt 1.
+newdef HadronSelector:OctWt 1.
newdef HadronSelector:DecWt 1.
newdef HadronSelector:Mode 1
newdef HadronSelector:BelowThreshold All
newdef HadronSelector:scHadronWtFactor 2.5
newdef HadronSelector:sbHadronWtFactor 2.5
create Herwig::SpinHadronizer SpinHadronizer
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Sep 30, 5:42 AM (1 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6566257
Default Alt Text
(69 KB)
Attached To
Mode
rHERWIGHG herwighg
Attached
Detach File
Event Timeline
Log In to Comment