File indexing completed on 2026-08-06 09:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef Herwig_PhaseSpaceChannel_H
0010 #define Herwig_PhaseSpaceChannel_H
0011
0012
0013
0014
0015 #include "ThePEG/Config/ThePEG.h"
0016 #include "ThePEG/PDT/ParticleData.h"
0017 #include "ThePEG/Persistency/PersistentOStream.h"
0018 #include "ThePEG/Persistency/PersistentIStream.h"
0019 #include "ThePEG/Utilities/EnumIO.h"
0020 #include "PhaseSpaceMode.fh"
0021 #include "ThePEG/MatrixElement/Tree2toNDiagram.h"
0022
0023 namespace Herwig {
0024
0025 using namespace ThePEG;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 class PhaseSpaceChannel {
0053
0054 public:
0055
0056 friend PersistentOStream;
0057 friend PersistentIStream;
0058
0059
0060
0061
0062 struct PhaseSpaceResonance {
0063
0064
0065
0066
0067 enum Jacobian {BreitWigner,Power,OnShell};
0068
0069
0070
0071
0072 PhaseSpaceResonance() {};
0073
0074
0075
0076 PhaseSpaceResonance(cPDPtr part) :particle(part), mass2(sqr(part->mass())), mWidth(part->mass()*part->width()),
0077 jacobian(BreitWigner), power(0.), children(make_pair(0,0))
0078 {};
0079
0080
0081
0082 cPDPtr particle;
0083
0084
0085
0086
0087 Energy2 mass2;
0088
0089
0090
0091
0092 Energy2 mWidth;
0093
0094
0095
0096
0097 Jacobian jacobian;
0098
0099
0100
0101
0102 double power;
0103
0104
0105
0106
0107 pair<int,int> children;
0108
0109
0110
0111
0112 vector<int> descendents;
0113
0114 };
0115
0116 public:
0117
0118
0119
0120
0121 PhaseSpaceChannel() : weight_(1.), initialized_(false), skipFirst_(false) {};
0122
0123
0124
0125
0126 PhaseSpaceChannel(tPhaseSpaceModePtr inm, bool skip=false);
0127
0128
0129
0130
0131
0132 PhaseSpaceChannel & operator , (tPDPtr res) {
0133 if(intermediates_.size()==1&&skipFirst_) {
0134 skipFirst_=false;
0135 }
0136 else
0137 intermediates_.push_back(PhaseSpaceResonance(res));
0138 if(iAdd_<0) return *this;
0139 if(intermediates_[iAdd_].children.first==0)
0140 intermediates_[iAdd_].children.first = 1-int(intermediates_.size());
0141 else
0142 intermediates_[iAdd_].children.second = 1-int(intermediates_.size());
0143 iAdd_=-1;
0144 return *this;
0145 }
0146
0147
0148
0149
0150
0151 PhaseSpaceChannel & operator , (int o) {
0152 if(iAdd_<0) iAdd_ = o;
0153 else if(o>=0) {
0154 if(intermediates_[iAdd_].children.first==0)
0155 intermediates_[iAdd_].children.first = o;
0156 else
0157 intermediates_[iAdd_].children.second = o;
0158 iAdd_=-1;
0159 }
0160 else if(o<0) {
0161 assert(false);
0162 }
0163 return *this;
0164 }
0165
0166
0167
0168
0169 void setJacobian(unsigned int ires, PhaseSpaceResonance::Jacobian jac, double power) {
0170 intermediates_[ires].jacobian = jac;
0171 intermediates_[ires].power = power;
0172 }
0173
0174 public:
0175
0176
0177
0178
0179 void init(tPhaseSpaceModePtr mode);
0180
0181
0182
0183
0184 void initrun(tPhaseSpaceModePtr mode);
0185
0186
0187
0188
0189 bool checkKinematics();
0190
0191
0192
0193
0194 const double & weight() const {return weight_;}
0195
0196
0197
0198
0199 void weight(double in) {weight_=in;}
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 void resetIntermediate(tcPDPtr part,Energy mass,Energy width) {
0211 if(!part) return;
0212 for(PhaseSpaceResonance & res : intermediates_) {
0213 if(res.particle!=part) continue;
0214 res.mass2 = sqr(mass);
0215 res.mWidth = mass*width;
0216 }
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 vector<Lorentz5Momentum> generateMomenta(const Lorentz5Momentum & pin,
0228 const vector<Energy> & massext) const;
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 double generateWeight(const vector<Lorentz5Momentum> & output) const;
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 void generateIntermediates(bool cc,const Particle & in, ParticleVector & out);
0252
0253
0254
0255
0256 ThePEG::Ptr<ThePEG::Tree2toNDiagram>::pointer createDiagram() const;
0257
0258 public:
0259
0260
0261
0262
0263
0264
0265 inline friend PersistentOStream & operator<<(PersistentOStream & os,
0266 const PhaseSpaceChannel & x) {
0267 os << x.weight_ << x.initialized_ << x.intermediates_;
0268 return os;
0269 }
0270
0271
0272
0273
0274
0275
0276 inline friend PersistentIStream & operator>>(PersistentIStream & is,
0277 PhaseSpaceChannel & x) {
0278 is >> x.weight_ >> x.initialized_ >> x.intermediates_;
0279 return is;
0280 }
0281
0282
0283
0284
0285
0286 friend ostream & operator<<(ostream & os, const PhaseSpaceChannel & channel);
0287
0288 private:
0289
0290
0291
0292
0293 void findChildren(const PhaseSpaceResonance & res,
0294 vector<int> & children) {
0295 if(res.children.first>0)
0296 children.push_back(res.children.first);
0297 else
0298 findChildren(intermediates_[abs(res.children.first)],children);
0299 if(!res.particle) return;
0300 if(res.children.second>0)
0301 children.push_back(res.children.second);
0302 else
0303 findChildren(intermediates_[abs(res.children.second)],children);
0304 }
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 void twoBodyDecay(const Lorentz5Momentum & p,
0316 const Energy m1, const Energy m2,
0317 Lorentz5Momentum & p1, Lorentz5Momentum & p2) const;
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 Energy generateMass(const PhaseSpaceResonance & res,
0328 Energy lower,Energy upper,
0329 const double & rnd) const;
0330
0331
0332
0333
0334
0335
0336
0337
0338 InvEnergy2 massWeight(const PhaseSpaceResonance & res,
0339 Energy moff,Energy lower,Energy upper) const;
0340
0341
0342
0343
0344
0345
0346
0347 double atanhelper(const PhaseSpaceResonance & res, Energy limit) const;
0348
0349 private:
0350
0351
0352
0353
0354 tPhaseSpaceModePtr mode_;
0355
0356
0357
0358
0359 vector<PhaseSpaceResonance> intermediates_;
0360
0361
0362
0363
0364 int iAdd_ = -1;
0365
0366
0367
0368
0369 double weight_;
0370
0371
0372
0373
0374 bool initialized_;
0375
0376
0377
0378
0379 bool skipFirst_;
0380
0381 };
0382
0383
0384
0385
0386
0387
0388
0389 inline PersistentOStream & operator<<(PersistentOStream & os,
0390 const PhaseSpaceChannel::PhaseSpaceResonance & x) {
0391 os << x.particle << ounit(x.mass2,GeV2) << ounit(x.mWidth,GeV2)
0392 << oenum(x.jacobian) << x.power << x.children << x.descendents;
0393 return os;
0394 }
0395
0396
0397
0398
0399
0400
0401 inline PersistentIStream & operator>>(PersistentIStream & is,
0402 PhaseSpaceChannel::PhaseSpaceResonance & x) {
0403 is >> x.particle >> iunit(x.mass2,GeV2) >> iunit(x.mWidth,GeV2)
0404 >> ienum(x.jacobian) >> x.power >> x.children >> x.descendents;
0405 return is;
0406 }
0407
0408
0409
0410
0411
0412 ostream & operator<<(ostream & os, const PhaseSpaceChannel & channel);
0413
0414
0415
0416
0417 class PhaseSpaceError: public Exception {};
0418
0419 }
0420
0421 #endif