File indexing completed on 2024-04-06 12:13:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "GeneratorInterface/Pythia8Interface/interface/SuepShower.h"
0016
0017
0018 SuepShower::SuepShower(double mass, double temperature, Pythia8::Rndm* rndmPtr) {
0019 edm::LogInfo("Pythia8Interface") << "Creating a SuepShower module";
0020
0021 darkmeson_mass_ = mass;
0022 fRndmPtr_ = rndmPtr;
0023
0024 mass_over_T_ = darkmeson_mass_ / temperature;
0025
0026
0027 tolerance_ = boost::math::tools::eps_tolerance<double>(128);
0028
0029
0030 p_m_ = sqrt(2 / (mass_over_T_ * mass_over_T_) * (1 + sqrt(1 + mass_over_T_ * mass_over_T_)));
0031 double pmax = sqrt(2 + 2 * sqrt(1 + mass_over_T_ * mass_over_T_)) / mass_over_T_;
0032
0033 p_plus_ = (boost::math::tools::bisect(
0034 boost::bind(&SuepShower::logTestFunction, this, boost::placeholders::_1), pmax, 50.0, tolerance_))
0035 .first;
0036 p_minus_ = (boost::math::tools::bisect(
0037 boost::bind(&SuepShower::logTestFunction, this, boost::placeholders::_1), 0.0, pmax, tolerance_))
0038 .first;
0039
0040 lambda_plus_ = -fMaxwellBoltzmann(p_plus_) / fMaxwellBoltzmannPrime(p_plus_);
0041 lambda_minus_ = fMaxwellBoltzmann(p_minus_) / fMaxwellBoltzmannPrime(p_minus_);
0042 q_plus_ = lambda_plus_ / (p_plus_ - p_minus_);
0043 q_minus_ = lambda_minus_ / (p_plus_ - p_minus_);
0044 q_m_ = 1 - (q_plus_ + q_minus_);
0045 }
0046
0047 SuepShower::~SuepShower() {}
0048
0049
0050 std::vector<Pythia8::Vec4> SuepShower::generateShower(double energy) {
0051 mediator_energy_ = energy;
0052 std::vector<Pythia8::Vec4> shower;
0053 double shower_energy = 0.0;
0054
0055
0056 while (shower_energy < mediator_energy_ || shower.size() < 2) {
0057 shower.push_back(generateFourVector());
0058 shower_energy += (shower.back()).e();
0059 }
0060
0061
0062
0063 Pythia8::Vec4 correction = Pythia8::Vec4(0., 0., 0., 0.);
0064 for (const auto& daughter : shower) {
0065 correction = correction + daughter;
0066 }
0067 correction = correction / shower.size();
0068
0069 correction.e(0);
0070 for (auto& daughter : shower) {
0071 daughter = daughter - correction;
0072 }
0073
0074
0075 double scale;
0076 double minscale = 0.0;
0077 double maxscale = 2.0;
0078 while (SuepShower::reballanceFunction(minscale, shower) * SuepShower::reballanceFunction(maxscale, shower) > 0) {
0079 minscale = maxscale;
0080 maxscale *= 2;
0081 }
0082
0083 scale =
0084 (boost::math::tools::bisect(boost::bind(&SuepShower::reballanceFunction, this, boost::placeholders::_1, shower),
0085 minscale,
0086 maxscale,
0087 tolerance_))
0088 .first;
0089
0090 for (auto& daughter : shower) {
0091 daughter.px(daughter.px() * scale);
0092 daughter.py(daughter.py() * scale);
0093 daughter.pz(daughter.pz() * scale);
0094
0095 daughter.e(sqrt(daughter.pAbs2() + darkmeson_mass_ * darkmeson_mass_));
0096 }
0097 return shower;
0098 }
0099
0100
0101
0102 const double SuepShower::fMaxwellBoltzmann(double p) {
0103 return p * p * exp(-mass_over_T_ * p * p / (1 + sqrt(1 + p * p)));
0104 }
0105
0106
0107 const double SuepShower::fMaxwellBoltzmannPrime(double p) {
0108 return exp(-mass_over_T_ * p * p / (1 + sqrt(1 + p * p))) * p * (2 - mass_over_T_ * p * p / sqrt(1 + p * p));
0109 }
0110
0111
0112 const double SuepShower::logTestFunction(double p) { return log(fMaxwellBoltzmann(p) / fMaxwellBoltzmann(p_m_)) + 1.0; }
0113
0114
0115 const Pythia8::Vec4 SuepShower::generateFourVector() {
0116 double en, phi, theta, momentum;
0117
0118
0119 double U, V, X, Y, E;
0120 int i = 0;
0121 while (i < 100) {
0122
0123 U = fRndmPtr_->flat();
0124 V = fRndmPtr_->flat();
0125
0126 if (U < q_m_) {
0127 Y = U / q_m_;
0128 X = (1 - Y) * (p_minus_ + lambda_minus_) + Y * (p_plus_ - lambda_plus_);
0129 if (V < fMaxwellBoltzmann(X) / fMaxwellBoltzmann(p_m_) && X > 0) {
0130 break;
0131 }
0132 } else {
0133 if (U < q_m_ + q_plus_) {
0134 E = -log((U - q_m_) / q_plus_);
0135 X = p_plus_ - lambda_plus_ * (1 - E);
0136 if (V < exp(E) * fMaxwellBoltzmann(X) / fMaxwellBoltzmann(p_m_) && X > 0) {
0137 break;
0138 }
0139 } else {
0140 E = -log((U - (q_m_ + q_plus_)) / q_minus_);
0141 X = p_minus_ + lambda_minus_ * (1 - E);
0142 if (V < exp(E) * fMaxwellBoltzmann(X) / fMaxwellBoltzmann(p_m_) && X > 0) {
0143 break;
0144 }
0145 }
0146 }
0147 }
0148
0149 momentum = X * darkmeson_mass_;
0150
0151
0152 phi = 2.0 * M_PI * (fRndmPtr_->flat());
0153 theta = acos(2.0 * (fRndmPtr_->flat()) - 1.0);
0154
0155
0156 en = sqrt(momentum * momentum + darkmeson_mass_ * darkmeson_mass_);
0157 Pythia8::Vec4 daughterFourMomentum =
0158 Pythia8::Vec4(momentum * cos(phi) * sin(theta), momentum * sin(phi) * sin(theta), momentum * sin(theta), en);
0159 return daughterFourMomentum;
0160 }
0161
0162
0163
0164
0165 const double SuepShower::reballanceFunction(double scale, const std::vector<Pythia8::Vec4>& shower) {
0166 double showerEnergy = 0.0;
0167 for (const auto& daughter : shower) {
0168 showerEnergy += sqrt(scale * scale * daughter.pAbs2() + darkmeson_mass_ * darkmeson_mass_);
0169 }
0170 return showerEnergy - mediator_energy_;
0171 }