File indexing completed on 2025-09-17 09:08:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef Pythia8_HISubCollisionModel_H
0018 #define Pythia8_HISubCollisionModel_H
0019
0020 #include "Pythia8/Pythia.h"
0021 #include "Pythia8/HINucleusModel.h"
0022
0023 namespace Pythia8 {
0024
0025
0026
0027
0028
0029
0030 class SubCollision {
0031
0032 public:
0033
0034
0035 enum CollisionType {
0036 NONE,
0037 ELASTIC,
0038 SDEP,
0039 SDET,
0040 DDE,
0041 CDE,
0042 ABS
0043 };
0044
0045
0046 SubCollision(Nucleon & projIn, Nucleon & targIn,
0047 double bIn, double bpIn, CollisionType typeIn)
0048 : proj(&projIn), targ(&targIn), b(bIn), bp(bpIn), type(typeIn),
0049 failed(false) {}
0050
0051
0052 SubCollision()
0053 : proj(0), targ(0), b(0.0), bp(0.0), type(NONE) {}
0054
0055
0056 bool operator< (const SubCollision& s) const { return b < s.b; }
0057
0058
0059
0060 int nucleons() const {return ( abs(targ->id()) == 2112? 1: 0 ) +
0061 ( abs(proj->id()) == 2112? 2: 0 );}
0062
0063
0064 Nucleon* proj;
0065
0066
0067 Nucleon* targ;
0068
0069
0070 double b;
0071
0072
0073
0074 double bp;
0075
0076
0077 CollisionType type;
0078
0079
0080 mutable bool failed;
0081
0082 };
0083
0084
0085
0086
0087
0088 class SubCollisionSet {
0089
0090 public:
0091
0092
0093 SubCollisionSet() = default;
0094
0095
0096 SubCollisionSet(multiset<SubCollision> subCollisionsIn, double TIn,
0097 double T12In = 0.0, double T21In = 0.0, double T22In = 0.0)
0098 : subCollisionsSave(subCollisionsIn), TSave({TIn, T12In, T21In, T22In}) {}
0099
0100
0101 bool empty() const { return subCollisionsSave.empty(); }
0102
0103
0104
0105 double T(unsigned i = 0) const { return TSave[i]; }
0106
0107
0108 multiset<SubCollision>::const_iterator begin() const {
0109 return subCollisionsSave.begin(); }
0110 multiset<SubCollision>::const_iterator end() const {
0111 return subCollisionsSave.end(); }
0112
0113 private:
0114
0115
0116 multiset<SubCollision> subCollisionsSave;
0117
0118
0119
0120 vector<double> TSave = {};
0121
0122 };
0123
0124
0125
0126
0127
0128
0129
0130 class SubCollisionModel {
0131
0132 public:
0133
0134
0135 struct SigEst {
0136
0137 vector<double> sig;
0138
0139
0140 vector<double> dsig2;
0141
0142
0143 vector<bool> fsig;
0144
0145
0146
0147 double avNDb, davNDb2;
0148
0149
0150 SigEst(): sig(8, 0.0), dsig2(8, 0.0), fsig(8, false),
0151 avNDb(0.0), davNDb2(0.0) {}
0152
0153 };
0154
0155
0156
0157 SubCollisionModel(int nParm): sigTarg(8, 0.0), sigErr(8, 0.05),
0158 parmSave(nParm),
0159 NInt(100000), NPop(20), sigFuzz(0.2), impactFudge(1),
0160 fitPrint(true), avNDb(1.0),
0161 projPtr(), targPtr(), sigTotPtr(), settingsPtr(), infoPtr(), rndmPtr() {}
0162
0163
0164 virtual ~SubCollisionModel() {}
0165
0166
0167 static shared_ptr<SubCollisionModel> create(int model);
0168
0169
0170 virtual bool init(int idAIn, int idBIn, double eCMIn);
0171
0172
0173 void initPtr(NucleusModel & projIn, NucleusModel & targIn,
0174 SigmaTotal & sigTotIn, Settings & settingsIn,
0175 Info & infoIn, Rndm & rndmIn) {
0176 projPtr = &projIn;
0177 targPtr = &targIn;
0178 sigTotPtr = &sigTotIn;
0179 settingsPtr = &settingsIn;
0180 infoPtr = &infoIn;
0181 rndmPtr = &rndmIn;
0182 loggerPtr = infoIn.loggerPtr;
0183 }
0184
0185
0186
0187
0188
0189 double sigTot() const { return sigTarg[0]; }
0190
0191
0192 double sigEl() const { return sigTarg[6]; }
0193
0194
0195 double sigCDE() const { return sigTarg[5]; }
0196
0197
0198 double sigSDE() const { return sigTarg[3] + sigTarg[4]; }
0199
0200
0201 double sigSDEP() const { return sigTarg[3]; }
0202
0203
0204 double sigSDET() const { return sigTarg[4]; }
0205
0206
0207 double sigDDE() const { return sigTarg[2]; }
0208
0209
0210 double sigND() const { return sigTarg[1]; }
0211
0212
0213 double bSlope() const { return sigTarg[7]; }
0214
0215
0216 double avNDB() const { return avNDb; }
0217
0218
0219 void updateSig();
0220
0221
0222 double Chi2(const SigEst & sigs, int npar) const;
0223
0224
0225 void setKinematics(double eCMIn);
0226
0227
0228 void setIDA(int idA);
0229
0230
0231 bool evolve(int nGenerations, double eCM, int idANow);
0232
0233
0234 int nParms() const { return parmSave.size(); }
0235
0236
0237 void setParm(const vector<double>& parmIn) {
0238 for (size_t i = 0; i < parmSave.size(); ++i)
0239 parmSave[i] = parmIn[i];
0240 }
0241
0242
0243 vector<double> getParm() const { return parmSave; }
0244
0245
0246 virtual vector<double> minParm() const = 0;
0247
0248
0249 virtual vector<double> defParm() const = 0;
0250
0251
0252 virtual vector<double> maxParm() const = 0;
0253
0254
0255
0256 virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) = 0;
0257
0258
0259 virtual SigEst getSig() const = 0;
0260
0261 private:
0262
0263
0264
0265 vector<double> sigTarg, sigErr;
0266
0267
0268 bool genParms();
0269
0270
0271 bool saveParms(string fileName) const;
0272 bool loadParms(string fileName);
0273
0274 protected:
0275
0276
0277 vector<double> parmSave;
0278
0279
0280
0281 int NInt, NPop;
0282 double sigFuzz;
0283 double impactFudge;
0284 bool fitPrint;
0285
0286
0287
0288 double avNDb;
0289
0290
0291 NucleusModel* projPtr;
0292 NucleusModel* targPtr;
0293 SigmaTotal* sigTotPtr;
0294 Settings* settingsPtr;
0295 Info* infoPtr;
0296 Rndm* rndmPtr;
0297 Logger* loggerPtr;
0298
0299
0300 int idASave, idBSave;
0301 bool doVarECM, doVarBeams;
0302 double eMin, eMax, eSave;
0303 int eCMPts;
0304
0305
0306 vector<int> idAList;
0307
0308
0309
0310 vector<LogInterpolator> *subCollParms;
0311
0312
0313 map<int, vector<LogInterpolator>> subCollParmsMap;
0314
0315 };
0316
0317
0318
0319
0320
0321
0322
0323 class BlackSubCollisionModel : public SubCollisionModel {
0324
0325 public:
0326
0327
0328 BlackSubCollisionModel() : SubCollisionModel(0) {}
0329
0330
0331 virtual ~BlackSubCollisionModel() override {}
0332
0333
0334 vector<double> minParm() const override { return vector<double>(); }
0335 vector<double> defParm() const override { return vector<double>(); }
0336 vector<double> maxParm() const override { return vector<double>(); }
0337
0338
0339 virtual SigEst getSig() const override {
0340 SigEst s;
0341 s.sig[0] = 56.52;
0342 s.sig[1] = sigND();
0343 s.sig[6] = s.sig[0] - s.sig[1];
0344 s.sig[7] = bSlope();
0345 return s;
0346 }
0347
0348
0349 virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
0350
0351 };
0352
0353
0354
0355
0356
0357
0358
0359 class NaiveSubCollisionModel : public SubCollisionModel {
0360
0361 public:
0362
0363
0364 NaiveSubCollisionModel() : SubCollisionModel(0) {}
0365
0366
0367 virtual ~NaiveSubCollisionModel() override {}
0368
0369
0370 vector<double> minParm() const override { return vector<double>(); }
0371 vector<double> defParm() const override { return vector<double>(); }
0372 vector<double> maxParm() const override { return vector<double>(); }
0373
0374
0375 virtual SigEst getSig() const override {
0376 SigEst s;
0377 s.sig[0] = sigTot();
0378 s.sig[1] = sigND();
0379 s.sig[3] = sigSDEP();
0380 s.sig[4] = sigSDET();
0381 s.sig[2] = sigDDE();
0382 s.sig[6] = sigEl();
0383 s.sig[7] = bSlope();
0384 return s;
0385 }
0386
0387
0388 virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
0389
0390 };
0391
0392
0393
0394
0395
0396
0397
0398
0399 class FluctuatingSubCollisionModel : public SubCollisionModel {
0400
0401 public:
0402
0403
0404 FluctuatingSubCollisionModel(int nParmIn, int modein)
0405 : SubCollisionModel(nParmIn + 2), opacityMode(modein),
0406 sigd(parmSave[nParmIn]), alpha(parmSave[nParmIn + 1]) {}
0407
0408
0409
0410 virtual ~FluctuatingSubCollisionModel() override {}
0411
0412
0413
0414 virtual SubCollisionSet getCollisions(Nucleus& proj, Nucleus& targ) override;
0415
0416
0417 virtual SigEst getSig() const override;
0418
0419 protected:
0420
0421
0422 virtual double pickRadiusProj() const = 0;
0423 virtual double pickRadiusTarg() const = 0;
0424
0425
0426 int opacityMode;
0427
0428 private:
0429
0430
0431 double& sigd;
0432
0433
0434 double& alpha;
0435
0436
0437 double opacity(double sig) const {
0438 sig /= sigd;
0439 if ( opacityMode == 1 )
0440 return pow(-expm1(-sig), alpha);
0441 return sig > numeric_limits<double>::epsilon() ?
0442 pow(-expm1(-1.0/sig), alpha) : 1.0;
0443 }
0444
0445
0446
0447 double Tpt(const Nucleon::State & p,
0448 const Nucleon::State & t, double b) const {
0449 double sig = M_PI*pow2(p[0] + t[0]);
0450 double grey = opacity(sig);
0451 return sig/grey > b*b*2.0*M_PI? grey: 0.0;
0452 }
0453
0454 };
0455
0456
0457
0458
0459
0460
0461 class DoubleStrikmanSubCollisionModel : public FluctuatingSubCollisionModel {
0462
0463 public:
0464
0465
0466 DoubleStrikmanSubCollisionModel(int modeIn = 0)
0467 : FluctuatingSubCollisionModel(1, modeIn), k0(parmSave[0]) {}
0468
0469
0470 virtual ~DoubleStrikmanSubCollisionModel() override {}
0471
0472
0473 vector<double> minParm() const override { return { 0.01, 1.0, 0.0 }; }
0474 vector<double> defParm() const override { return { 2.15, 17.24, 0.33 }; }
0475 vector<double> maxParm() const override {
0476 return { 60.00, 60.0, (opacityMode == 0? 20.0: 2.0 ) }; }
0477
0478 protected:
0479
0480 double pickRadiusProj() const override {
0481 double r = rndmPtr->gamma(k0, r0());
0482 return (r < numeric_limits<double>::epsilon() ?
0483 numeric_limits<double>::epsilon() : r);
0484 }
0485 double pickRadiusTarg() const override {
0486 double r = rndmPtr->gamma(k0, r0());
0487 return (r < numeric_limits<double>::epsilon() ?
0488 numeric_limits<double>::epsilon() : r);
0489 }
0490
0491 private:
0492
0493
0494 double& k0;
0495
0496
0497
0498 double r0() const {
0499 return sqrt(sigTot() / (M_PI * (2.0 * k0 + 4.0 * k0 * k0)));
0500 }
0501
0502 };
0503
0504
0505
0506
0507
0508
0509
0510
0511 class ImpactParameterGenerator {
0512
0513 public:
0514
0515
0516
0517 ImpactParameterGenerator() = default;
0518
0519
0520 virtual ~ImpactParameterGenerator() {}
0521
0522
0523 virtual bool init();
0524 void initPtr(Info & infoIn, SubCollisionModel & collIn,
0525 NucleusModel & projIn, NucleusModel & targIn);
0526
0527
0528 virtual Vec4 generate(double & weight) const;
0529
0530
0531
0532
0533 virtual double xSecScale() const {
0534 return forceUnitWeight? M_PI*pow2(width()*cut): 2.0*M_PI *pow2(width());
0535 }
0536
0537
0538 void width(double widthIn) { widthSave = widthIn; }
0539
0540
0541 double width() const { return widthSave; }
0542
0543
0544 void updateWidth();
0545
0546 private:
0547
0548
0549 double widthSave = 0.0;
0550
0551
0552
0553 double cut = 3.0;
0554
0555
0556 bool forceUnitWeight = false;
0557
0558 protected:
0559
0560
0561 Info* infoPtr{};
0562 SubCollisionModel* collPtr{};
0563 NucleusModel* projPtr{};
0564 NucleusModel* targPtr{};
0565 Settings* settingsPtr{};
0566 Rndm* rndmPtr{};
0567 Logger* loggerPtr{};
0568
0569 };
0570
0571
0572
0573
0574
0575
0576
0577
0578 class LogNormalSubCollisionModel : public FluctuatingSubCollisionModel {
0579
0580 public:
0581
0582
0583 LogNormalSubCollisionModel(int modeIn = 0)
0584 : FluctuatingSubCollisionModel(4, modeIn),
0585 kProj(parmSave[0]), kTarg(parmSave[1]),
0586 rProj(parmSave[2]), rTarg(parmSave[3]) {}
0587
0588
0589 virtual ~LogNormalSubCollisionModel() {}
0590
0591
0592
0593
0594 vector<double> minParm() const override {
0595 return { 0.01, 0.01, 0.10, 0.10, 1.00, 0.00 }; }
0596 vector<double> defParm() const override {
0597 return { 1.00, 1.00, 0.54, 0.54, 17.24, 0.33 }; }
0598 vector<double> maxParm() const override {
0599 return { 2.00, 2.00, 4.00, 4.00, 20.00, 2.00 }; }
0600
0601 protected:
0602
0603 double pickRadiusProj() const override { return pickRadius(kProj, rProj); }
0604 double pickRadiusTarg() const override { return pickRadius(kTarg, rTarg); }
0605
0606 private:
0607
0608
0609 double& kProj;
0610 double& kTarg;
0611
0612
0613 double& rProj;
0614 double& rTarg;
0615
0616 double pickRadius(double k0, double r0) const {
0617 double logSig = log(M_PI * pow2(r0)) + k0 * rndmPtr->gauss();
0618 return sqrt(exp(logSig) / M_PI);
0619 }
0620 };
0621
0622
0623
0624 }
0625
0626 #endif