CMS 3D CMS Logo

TopRecoilHook.h
Go to the documentation of this file.
1 // TopRecoilHook.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Includes a user hook that corrects emission in top decay for dipole
7 // from gluon to W, to instead be from gluon to top.
8 
9 // Important: the top mass shift analysis encoded here is very primitive,
10 // does not perform well at all, and should not be taken seriously.
11 // The important part is that you see how the different scenarios
12 // should be set up to operate as intended.
13 
14 #include "Pythia8/Pythia.h"
15 namespace Pythia8 {
16 
17  //==========================================================================
18 
19  // Write own derived UserHooks class for modified emission in top decay.
20 
21  class TopRecoilHook : public UserHooks {
22  public:
23  // Constructor.
24  // doTopRecoil : eikonal correction in GW dipole on/off when no MEC applied.
25  // useOldDipole : in GW dipole, use partons before or after branching.
26  // doList : diagnostic output; set false for production runs.
27  TopRecoilHook(bool doTopRecoilIn = true, bool useOldDipoleIn = false, bool doListIn = false) {
28  doTopRecoil = doTopRecoilIn;
29  useOldDipole = useOldDipoleIn;
30  doList = doListIn;
31  // Constructor also creates some histograms for analysis inside User Hook.
32  wtCorr = new Hist("corrective weight", 100, 0., 2.);
33  }
34 
35  // Destructor prints histogram.
36  ~TopRecoilHook() override { delete wtCorr; }
37 
38  // Initialise. Only use hook for simple showers with recoilToColoured = off.
39  bool initAfterBeams() override {
40  // Switch off if recoilToColoured = on.
41  bool recoilToColoured = settingsPtr->flag("TimeShower:recoilToColoured");
42  if (recoilToColoured)
43  doTopRecoil = false;
44  // Flag if W mass term is already accounted for (true) or not (false).
45  recoilDeadCone = settingsPtr->flag("TimeShower:recoilDeadCone");
46  // All ok.
47  return true;
48  }
49 
50  // Allow a veto after an FSR emission
51  bool canVetoFSREmission() override { return doTopRecoil; }
52 
53  // Access the event after an FSR emission, specifically inside top decay.
54  bool doVetoFSREmission(int sizeOld, const Event& event, int iSys, bool inResonance) override {
55  // Check that we are inside a resonance decay.
56  if (!inResonance)
57  return false;
58 
59  // Check that it is a top decay.
60  int iTop = partonSystemsPtr->getInRes(iSys);
61  if (iTop == 0 || event[iTop].idAbs() != 6)
62  return false;
63 
64  // Skip first emission, where ME corrections are already made.
65  int sizeOut = partonSystemsPtr->sizeOut(iSys);
66  if (sizeOut == 2)
67  return false;
68 
69  // Location of trial new particles: radiator, emitted, recoiler.
70  int iRad = sizeOld;
71  int iEmt = sizeOld + 1;
72  int iRec = sizeOld + 2;
73 
74  // The above partons are after emission;
75  // alternatively use the ones before.
76  if (useOldDipole) {
77  iRad = event[iRad].mother1();
78  iRec = event[iRec].mother1();
79  }
80 
81  // Check if newly emitted gluon matches (anti)top colour line.
82  if (event[iEmt].id() != 21)
83  return false;
84  if (event[iTop].id() == 6) {
85  if (event[iEmt].col() != event[iTop].col())
86  return false;
87  } else {
88  if (event[iEmt].acol() != event[iTop].acol())
89  return false;
90  }
91 
92  // Recoiler should now be a W, else something is wrong.
93  if (event[iRec].idAbs() != 24) {
94  return false;
95  }
96 
97  // Denominator: eikonal weight with W as recoiler.
98  double pRadRec = event[iRad].p() * event[iRec].p();
99  double pRadEmt = event[iRad].p() * event[iEmt].p();
100  double pRecEmt = event[iRec].p() * event[iEmt].p();
101  double wtW = 2. * pRadRec / (pRadEmt * pRecEmt) - pow2(event[iRad].m() / pRadEmt);
102  // If recoilDeadCone = on, include W mass term in denominator.
103  if (recoilDeadCone)
104  wtW -= pow2(event[iRec].m() / pRecEmt);
105 
106  // Numerator: eikonal weight with top as recoiler.
107  double pRadTop = event[iRad].p() * event[iTop].p();
108  double pTopEmt = event[iTop].p() * event[iEmt].p();
109  double wtT =
110  2. * pRadTop / (pRadEmt * pTopEmt) - pow2(event[iRad].m() / pRadEmt) - pow2(event[iTop].m() / pTopEmt);
111 
112  // Histogram weight ratio.
113  wtCorr->fill(wtT / wtW);
114 
115  // List relevant properties.
116  if (doList) {
117  partonSystemsPtr->list();
118  event.list();
119  }
120  //std::cout << "BEGIN TOP TEST: " << (wtT / wtW) << " | END TOP TEST" << endl;
121 
122  // Accept/reject emission. Smooth suppression or step function.
123  return (wtT < wtW * rndmPtr->flat());
124  }
125 
126  private:
127  // Options and Histograms.
130  };
131 
132 } // namespace Pythia8
bool doVetoFSREmission(int sizeOld, const Event &event, int iSys, bool inResonance) override
Definition: TopRecoilHook.h:54
constexpr int pow2(int x)
Definition: TauNNIdHW.h:59
bool initAfterBeams() override
Definition: TopRecoilHook.h:39
TopRecoilHook(bool doTopRecoilIn=true, bool useOldDipoleIn=false, bool doListIn=false)
Definition: TopRecoilHook.h:27
cms::cuda::HistoContainer< uint8_t, 256, 16000, 8, uint16_t > Hist
bool canVetoFSREmission() override
Definition: TopRecoilHook.h:51
col
Definition: cuy.py:1009
Definition: event.py:1