File indexing completed on 2025-09-17 09:08:36
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef Pythia8_VinciaMergingHooks_H
0009 #define Pythia8_VinciaMergingHooks_H
0010
0011 #include "Pythia8/MergingHooks.h"
0012 #include "Pythia8/PartonLevel.h"
0013 #include "Pythia8/UserHooks.h"
0014 #include "Pythia8/VinciaCommon.h"
0015
0016 namespace Pythia8 {
0017
0018
0019
0020
0021
0022 struct MultiParticle {
0023 vector<int> pidList;
0024 vector<int> coltypes;
0025
0026 int id;
0027
0028 int charge;
0029 bool isRes, isFCN;
0030 };
0031
0032
0033
0034
0035
0036 struct ParticleLocator {
0037
0038 int level;
0039
0040 int pos;
0041 };
0042
0043
0044
0045
0046
0047
0048 class HardProcessParticleList;
0049 class HardProcessParticle {
0050
0051 friend class HardProcessParticleList;
0052
0053 public:
0054
0055
0056 HardProcessParticle(int idIn, ParticleDataEntryPtr pdata,
0057 ParticleLocator locIn, HardProcessParticleList* listPtrIn,
0058 vector<ParticleLocator>& mothersIn) :
0059 isMultiparticle(false), pid(idIn), multiPtr(nullptr),
0060 loc(locIn), listPtr(listPtrIn), mothers(mothersIn) {
0061 isResSav = pdata->isResonance(); coltype = pdata->colType(pid);
0062 charge = pdata->chargeType(pid); isColSav = coltype != 0;
0063 nameSav = pdata->name(pid);}
0064
0065
0066 HardProcessParticle(string nameIn, const MultiParticle* multiPtrIn,
0067 ParticleLocator locIn, HardProcessParticleList * listPtrIn,
0068 vector<ParticleLocator> & mothersIn) :
0069 isMultiparticle(true), nameSav(nameIn), multiPtr(multiPtrIn),
0070 loc(locIn), listPtr(listPtrIn), mothers(mothersIn) {
0071 pid = multiPtr->id; charge = multiPtr->charge;
0072 isResSav = multiPtr->isRes;
0073 coltype = multiPtr->coltypes.size() != 0 ? multiPtr->coltypes.at(0) : 0;
0074 isColSav = coltype !=0;}
0075
0076
0077 bool isFinal() const {return daughters.size() == 0;}
0078
0079
0080 bool isBeam() const {return loc.level == 0;}
0081
0082
0083 bool isIntermediate() const {return !isBeam() && !isFinal();}
0084
0085
0086 bool isRes() const {return isResSav;}
0087 bool isCol() const {return isColSav;}
0088 bool isMulti() const { return isMultiparticle;}
0089 string name() const {return nameSav;}
0090 int id() const {return pid;}
0091 int chargeType() const {return charge;}
0092 int colType() const {return coltype;}
0093 vector<ParticleLocator> getDaughters() const {return daughters;}
0094 const MultiParticle* getMulti() const {return multiPtr;}
0095
0096
0097 void print() const;
0098
0099 private:
0100
0101 bool isMultiparticle;
0102 bool isResSav;
0103 bool isColSav;
0104 string nameSav;
0105
0106
0107 int pid;
0108 int coltype;
0109
0110
0111 int charge;
0112
0113
0114
0115 const MultiParticle* multiPtr;
0116
0117
0118 ParticleLocator loc;
0119
0120 HardProcessParticleList* listPtr;
0121
0122
0123 vector<ParticleLocator> mothers;
0124
0125
0126 vector<ParticleLocator> daughters;
0127
0128 };
0129
0130
0131
0132
0133
0134 class HardProcessParticleList {
0135
0136 public:
0137
0138
0139 void list() const;
0140
0141
0142 pair<HardProcessParticle*, HardProcessParticle*> getBeams() {
0143 HardProcessParticle* beamAPtr{nullptr}, *beamBPtr{nullptr};
0144 if (!particles.empty() && particles[0].size() == 2) {
0145 beamAPtr = &particles[0][0]; beamBPtr = &particles[0][1];}
0146 return make_pair(beamAPtr,beamBPtr);}
0147
0148
0149 vector<HardProcessParticle>* getLevel(int i) {
0150 if (particles.find(i) != particles.end()) return &particles[i];
0151 else return nullptr;}
0152
0153
0154 HardProcessParticle* getPart(ParticleLocator loc) {
0155 if (particles.find(loc.level) != particles.end() &&
0156 int(particles[loc.level].size()) > loc.pos)
0157 return &particles[loc.level].at(loc.pos);
0158 return nullptr;}
0159
0160
0161 ParticleLocator add(int level, string nameIn, const MultiParticle* multiPtr,
0162 vector<ParticleLocator>& mothersIn);
0163
0164
0165 ParticleLocator add(int level, int idIn, ParticleDataEntryPtr pdata,
0166 vector<ParticleLocator>& mothersIn);
0167
0168
0169 void setDaughters(ParticleLocator& mother,
0170 vector<ParticleLocator>& daughters);
0171
0172
0173 ParticleLocator getNextLoc(int level) {
0174
0175 if (particles.find(level) == particles.end())
0176 particles[level] = vector<HardProcessParticle>();
0177 ParticleLocator loc; loc.level = level; loc.pos = particles[level].size();
0178 return loc;}
0179
0180 private:
0181
0182
0183
0184 map<int, vector<HardProcessParticle>> particles;
0185
0186 };
0187
0188
0189
0190
0191
0192 struct ColourStructure {
0193
0194 HardProcessParticle* beamA{};
0195 HardProcessParticle* beamB{};
0196
0197
0198 vector<HardProcessParticle*> coloured;
0199 vector<HardProcessParticle*> leptons;
0200
0201
0202 vector<int> resPlusHad;
0203 vector<int> resMinusHad;
0204 vector<int> resNeutralFCHad;
0205 vector<int> resNeutralFNHad;
0206
0207
0208 vector<int> resPlusLep;
0209 vector<int> resMinusLep;
0210 vector<int> resNeutralFCLep;
0211 vector<int> resNeutralFNLep;
0212
0213
0214
0215 vector<int> resPlusUndecayed;
0216 vector<int> resMinusUndecayed;
0217 vector<int> resNeutralUndecayed;
0218
0219
0220 int nQQbarPairs{0};
0221 int nColoured{0};
0222
0223
0224 int nMinBeamChains{0};
0225 int nMaxBeamChains{0};
0226 };
0227
0228
0229
0230
0231
0232 class VinciaHardProcess : public HardProcess {
0233
0234 public:
0235
0236
0237 VinciaHardProcess(Logger* loggerPtrIn, int verboseIn, bool resolveDecaysIn,
0238 bool doHEFTIn, bool doVBFIn) :
0239 verbose(verboseIn), loggerPtr(loggerPtrIn),
0240 resolveDecays(resolveDecaysIn), doHEFT(doHEFTIn), doVBF(doVBFIn),
0241 isInit(false) {defineMultiparticles();}
0242
0243
0244 void initOnProcess(string process, ParticleData* particleData) override;
0245
0246
0247 void storeCandidates(const Event&, string) override {;}
0248 bool matchesAnyOutgoing(int, const Event&) override {return false;}
0249 bool findOtherCandidates(int, const Event&, bool) override {return false;}
0250
0251
0252 void list() const {parts.list();}
0253 void listLookup() const;
0254
0255
0256 void setVerbose(int verboseIn) {verbose = verboseIn;}
0257
0258
0259 bool initSuccess() {return isInit;}
0260
0261
0262 void getColourStructure(ColourStructure& colStructNow);
0263
0264 private:
0265
0266
0267 void defineMultiparticles();
0268
0269 bool isBeamID(int id);
0270
0271 void initLookup(ParticleData* particleData);
0272
0273
0274 bool splitProcess(string process, vector<string>& inWords,
0275 vector<string>& outWords);
0276
0277
0278 void splitbyWhitespace(string wordIn, vector<string>& wordsOut,
0279 bool atFront = false);
0280
0281
0282 bool getParticles(ParticleData* particleDataPtr,
0283 vector<string> inWords,
0284 vector<string> outWords);
0285
0286
0287 bool getParticles(ParticleData* particleDataPtr,
0288 vector<string> inWords,
0289 vector<string> outWords,
0290 int levelNow,
0291 vector<ParticleLocator>& mothersIn,
0292 vector<ParticleLocator>& mothersNow);
0293
0294
0295 bool addParticle(ParticleData* particleDataPtr,int level, bool isIncoming,
0296 string name, vector<ParticleLocator>& mothersIn, ParticleLocator& loc);
0297
0298
0299 void setDaughters(ParticleLocator& mother,
0300 vector<ParticleLocator>& daughters) {parts.setDaughters(mother,daughters);}
0301
0302
0303 int verbose;
0304
0305
0306 Logger* loggerPtr{};
0307
0308
0309 bool resolveDecays;
0310
0311
0312 bool doHEFT, doVBF;
0313
0314
0315 map<string, int> lookupIDfromName;
0316
0317
0318 map<int, bool> isFCNres;
0319
0320
0321 map<string, MultiParticle> multiparticles;
0322
0323
0324 HardProcessParticleList parts;
0325
0326
0327 bool isInit;
0328
0329 };
0330
0331
0332
0333
0334
0335 class VinciaMergingHooks : public MergingHooks {
0336
0337 public:
0338
0339
0340 VinciaMergingHooks() : vinHardProcessPtr(nullptr), isInit(false) {;}
0341
0342 ~VinciaMergingHooks() {if (hardProcess) delete hardProcess;}
0343
0344
0345 void init() override;
0346
0347
0348 bool setShowerStartingScales(bool isTrial, bool,
0349 double& pTscaleIn, const Event& event, double& pTmaxFSRIn, bool&,
0350 double& pTmaxISRIn, bool&, double& pTmaxMPIIn, bool&) override;
0351
0352
0353 virtual bool usesVincia() override {return true;}
0354
0355
0356 virtual double tmsNow(const Event& event) override;
0357
0358
0359 virtual bool doVetoStep(const Event& process,
0360 const Event& event, bool) override;
0361
0362
0363 virtual bool doVetoEmission(const Event&) override;
0364
0365
0366 virtual double dampenIfFailCuts(const Event& ) override {return 0.;}
0367 virtual int getNumberOfClusteringSteps(const Event&, bool) override;
0368 virtual bool canCutOnRecState() override {return false;}
0369 virtual bool doCutOnRecState(const Event&) override {return false;}
0370 virtual bool canVetoTrialEmission() override {return false;}
0371 virtual bool doVetoTrialEmission(const Event&, const Event&) override {
0372 return false;}
0373 virtual bool useShowerPlugin() override {return false;}
0374 virtual double hardProcessME(const Event&) override {return 0;}
0375
0376
0377 void setVerbose(int verboseIn) {verbose = verboseIn;}
0378 int getVerbose() {return verbose;}
0379
0380
0381 bool initSuccess() {return isInit;}
0382
0383
0384 vector<HardProcessParticle*> getLeptons() {return colStructSav.leptons;}
0385
0386
0387 int getNResPlusUndecayed() {
0388 return int(colStructSav.resPlusUndecayed.size());}
0389 int getNResMinusUndecayed() {
0390 return int(colStructSav.resMinusUndecayed.size());}
0391 int getNResNeutralUndecayed() {
0392 return int(colStructSav.resNeutralUndecayed.size());}
0393
0394
0395 vector<int> getResPlusUndecayed() {
0396 return colStructSav.resPlusUndecayed;}
0397 vector<int> getResMinusUndecayed() {
0398 return colStructSav.resMinusUndecayed;}
0399 vector<int> getResNeutralUndecayed() {
0400 return colStructSav.resNeutralUndecayed;}
0401
0402
0403 vector<int> getResPlusLep() {return colStructSav.resPlusLep;}
0404 vector<int> getResMinusLep() {return colStructSav.resMinusLep;}
0405 vector<int> getResNeutralFCLep() {return colStructSav.resNeutralFCLep;}
0406 vector<int> getResNeutralFNLep() {return colStructSav.resNeutralFNLep;}
0407
0408
0409 vector<int> getResPlusHad() {return colStructSav.resPlusHad;}
0410 vector<int> getResMinusHad() {return colStructSav.resMinusHad;}
0411 vector<int> getResNeutralFCHad() {return colStructSav.resNeutralFCHad;}
0412 vector<int> getResNeutralFNHad() {return colStructSav.resNeutralFNHad;}
0413
0414
0415 int getNResPlusHad() {return colStructSav.resPlusHad.size();}
0416 int getNResMinusHad() {return colStructSav.resMinusHad.size();}
0417 int getNResNeutralFCHad() {return colStructSav.resNeutralFCHad.size();}
0418 int getNResNeutralFNHad() {return colStructSav.resNeutralFNHad.size();}
0419 int getNResHad() {return getNResPlusHad() + getNResMinusHad() +
0420 getNResNeutralFCHad() + getNResNeutralFNHad();}
0421
0422
0423
0424 int getNResPlus() {return colStructSav.resPlusHad.size() +
0425 colStructSav.resPlusLep.size();}
0426 int getNResMinus() {return colStructSav.resMinusHad.size() +
0427 colStructSav.resMinusLep.size();}
0428 int getNResNeutralFC() {return colStructSav.resNeutralFCHad.size() +
0429 colStructSav.resNeutralFCLep.size();}
0430 int getNResNeutralFN() {return colStructSav.resNeutralFNHad.size() +
0431 colStructSav.resNeutralFNLep.size();}
0432
0433
0434 int getNChainsMin() {return colStructSav.nMinBeamChains;}
0435 int getNChainsMax() {return colStructSav.nMaxBeamChains;}
0436 int getNPartons() {return colStructSav.nColoured;}
0437 int getNQPairs() {return colStructSav.nQQbarPairs;}
0438
0439
0440 bool hasSetColourStructure() {return hasColStruct;}
0441
0442
0443 bool canMergeRes() {return doMergeRes;}
0444
0445
0446 bool doMergeInVBF() {return doVBF;}
0447
0448
0449 bool allowHEFT() {return doHEFT;}
0450
0451
0452 int nMaxJetsRes() {return nJetMaxResSave;}
0453
0454
0455 void setScaleRes(int iRes, double scale) {resSysRestartScale[iRes] = scale;}
0456
0457
0458 double getScaleRes(int iRes, const Event&) {
0459 return resSysRestartScale.find(iRes) != resSysRestartScale.end() ?
0460 resSysRestartScale[iRes] : tmsCut();}
0461
0462
0463 bool canClusFF() {return doFF;}
0464 bool canClusRF() {return doRF;}
0465 bool canClusII() {return doII;}
0466 bool canClusIF() {return doIF;}
0467
0468
0469 bool isAboveMS(const Event& event);
0470
0471
0472
0473 VinciaHardProcess* vinHardProcessPtr{};
0474
0475 protected:
0476
0477
0478 int nJetMaxResSave;
0479
0480
0481 int nMergeResSys;
0482
0483
0484 bool doMergeRes;
0485
0486
0487 bool doVetoNotInResSav;
0488
0489
0490 map<int,double> resSysRestartScale;
0491
0492 private:
0493
0494
0495 double pTlast(const Event& event);
0496 double pTvincia(const Event& event, int ii, int ij, int ik);
0497 double kTmin(const Event& event);
0498 vector<double> cutsMin(const Event& event);
0499
0500
0501 ColourStructure getColourStructure();
0502 bool setColourStructure();
0503 void printColStruct();
0504
0505
0506 bool isResDecayProd(int iPtcl, const Event& event);
0507
0508
0509 vector<int> getJetsInEvent(const Event& event);
0510
0511
0512 bool isInit;
0513
0514
0515 int verbose;
0516
0517
0518 bool hasColStruct;
0519 ColourStructure colStructSav;
0520
0521
0522 bool doFF, doRF, doII, doIF;
0523
0524
0525 bool doHEFT{false}, doVBF{false};
0526
0527 };
0528
0529
0530
0531
0532
0533
0534 class MergeResScaleHook : public UserHooks {
0535
0536 public:
0537
0538
0539 MergeResScaleHook( MergingHooksPtr mergingHooksPtrIn) {
0540
0541 vinMergingHooksPtr
0542 = dynamic_pointer_cast<VinciaMergingHooks>(mergingHooksPtrIn);
0543 if (vinMergingHooksPtr == nullptr || !vinMergingHooksPtr->initSuccess() )
0544 canMergeRes = false;
0545 else canMergeRes = vinMergingHooksPtr->canMergeRes();}
0546
0547
0548 bool canSetResonanceScale() override {return canMergeRes;}
0549 double scaleResonance(int iRes, const Event& event) override {
0550 return vinMergingHooksPtr->getScaleRes(iRes,event);}
0551
0552 private:
0553
0554 bool canMergeRes;
0555 shared_ptr<VinciaMergingHooks> vinMergingHooksPtr;
0556
0557 };
0558
0559
0560
0561 }
0562
0563 #endif