eic-smear  1.0.3
A collection of ROOT classes for Monte Carlo events and a fast-smearing code simulating detector effects for the Electron-Ion Collider task force
Pythia6EventBuilder.cxx
Go to the documentation of this file.
1 
11 
12 #include <cmath>
13 #include <iostream>
14 #include <memory>
15 #include <string>
16 
17 #include <TBranch.h>
18 #include <TClass.h>
19 #include <TMCParticle.h>
20 #include <TObjArray.h>
21 #include <TProcessID.h>
22 #include <TPythia6.h>
23 #include <TTree.h>
24 
30 
31 namespace erhic {
32 
34 : mNGenerated(0)
35 , mNTrials(0)
36 , mFilter(filter)
37 , mEvent(NULL) {
38 }
39 
41  delete mFilter;
42  mFilter = NULL;
43 }
44 
46  std::auto_ptr<EventPythia> event(BuildEvent());
47  if (mFilter) {
48  while (!mFilter->Accept(*event)) {
49  event.reset(BuildEvent());
50  } // while
51  } // if
52  return event.release();
53 }
54 
55 EventPythia* Pythia6EventBuilder::BuildEvent() {
56  // Save current object count
57  int objectNumber = TProcessID::GetObjectCount();
58  // Generate a new PYTHIA event
59  TPythia6* pythia = TPythia6::Instance();
60  pythia->GenerateEvent();
61  // Import all particles (not just final-state)
62  TObjArray* particles = pythia->ImportParticles("All");
63  // Construct the EventPythia object from the current
64  // state of TPythia6.
65  std::auto_ptr<EventPythia> event(new EventPythia);
66  // Extract the event-wise quantities:
67  event->SetNucleon(pythia->GetMSTI(12));
68  event->SetTargetParton(pythia->GetMSTI(16));
69  event->SetBeamParton(pythia->GetMSTI(15));
70  event->SetGenEvent(1);
71  event->SetTargetPartonX(pythia->GetPARI(34));
72  event->SetBeamPartonX(pythia->GetPARI(33));
73  event->SetBeamPartonTheta(pythia->GetPARI(53));
74  event->SetLeptonPhi(pythia->GetVINT(313));
75  event->SetHardS(pythia->GetPARI(14));
76  event->SetHardT(pythia->GetPARI(15));
77  event->SetHardU(pythia->GetPARI(16));
78  event->SetHardQ2(pythia->GetPARI(22));
79  event->SetHardPt2(pythia->GetPARI(18));
80  event->SetPhotonFlux(pythia->GetVINT(319));
81  event->SetProcess(pythia->GetMSTI(1));
82  // We need the beam energies to compute the true x, W2 and nu.
83  // The beam lepton should be the first particle
84  // and the beam hadron the second particle.
85  const double eLepton =
86  static_cast<TMCParticle*>(particles->At(0))->GetEnergy();
87  const double eHadron =
88  static_cast<TMCParticle*>(particles->At(1))->GetEnergy();
89  const double mHadron =
90  static_cast<TMCParticle*>(particles->At(1))->GetMass();
91  // x, W2 and nu are calculated from y, Q2 and the beam energies.
92  // y and Q2 come from PYTHIA.
93  // Use (approximate expression) Q2 = sxy, where s = 4.E_e.E_h
94  double y = pythia->GetVINT(309);
95  double Q2 = pythia->GetVINT(307);
96  double x = Q2 / y / 4. / eLepton / eHadron;
97  double W2 = pow(mHadron, 2.) + Q2 * (1. / x - 1.);
98  double nu = (W2 + Q2 - pow(mHadron, 2.)) / 2. / mHadron;
99  event->SetTrueY(y);
100  event->SetTrueQ2(Q2);
101  event->SetTrueX(x);
102  event->SetTrueW2(W2);
103  event->SetTrueNu(nu);
104  // Set the number of event generation trials taken since the last call
105  event->SetN(pythia->GetMSTI(5));
106  event->SetGenEvent(pythia->GetPyint5()->NGEN[2][0] - mNTrials);
107  mNTrials = pythia->GetPyint5()->NGEN[2][0];
108  // Now populate the particle list.
109  Pythia6ParticleBuilder builder;
110  for (int i(0); i < particles->GetEntries(); ++i) {
111  TMCParticle* p =
112  static_cast<TMCParticle*>(particles->At(i));
113  std::auto_ptr<ParticleMC> particle = builder.Create(*p);
114  particle->SetIndex(i + 1);
115  particle->SetEvent(event.get());
116  event->AddLast(particle.get());
117  } // for
118  // Compute derived event kinematics
119  DisKinematics* nm = LeptonKinematicsComputer(*event).Calculate();
120  DisKinematics* jb = JacquetBlondelComputer(*event).Calculate();
121  DisKinematics* da = DoubleAngleComputer(*event).Calculate();
122  if (nm) {
123  event->SetLeptonKinematics(*nm);
124  } // if
125  if (jb) {
126  event->SetJacquetBlondelKinematics(*jb);
127  } // if
128  if (da) {
129  event->SetDoubleAngleKinematics(*da);
130  } // if
131  // We also have to set the remaining variables not taken care of
132  // by the general DIS event kinematic computations.
133  // Find the beams, exchange boson, scattered lepton.
134  BeamParticles beams;
135  if (ParticleIdentifier::IdentifyBeams(*event, beams)) {
136  const TLorentzVector h = beams.BeamHadron();
137  TLorentzVector l = beams.BeamLepton();
138  TLorentzVector s = beams.ScatteredLepton();
139  TVector3 boost = -h.BoostVector();
140  l.Boost(boost);
141  s.Boost(boost);
142  event->SetELeptonInNuclearFrame(l.E());
143  event->SetEScatteredInNuclearFrame(s.E());
144  } // if
145  for (unsigned i(0); i < event->GetNTracks(); ++i) {
146  event->GetTrack(i)->ComputeEventDependentQuantities(*event);
147  } // for
148  // Restore Object count
149  // See example in $ROOTSYS/test/Event.cxx
150  // To save space in the table keeping track of all referenced objects
151  // we assume that our events do not address each other. We reset the
152  // object count to what it was at the beginning of the event.
153  TProcessID::SetObjectCount(objectNumber);
154  return event.release();
155 }
156 
157 std::string Pythia6EventBuilder::EventName() const {
158  return EventPythia::Class()->GetName();
159 }
160 
161 TBranch* Pythia6EventBuilder::Branch(TTree& tree, const std::string& name) {
162  EventPythia* event(NULL);
163  TBranch* branch =
164  tree.Branch(name.c_str(), EventName().c_str(), &event, 32000, 99);
165  tree.ResetBranchAddress(branch);
166  return branch;
167 }
168 
169 void Pythia6EventBuilder::Fill(TBranch& branch) {
170  if (mEvent) {
171  branch.ResetAddress();
172  delete mEvent;
173  mEvent = NULL;
174  } // if
175  mEvent = Create();
176  branch.SetAddress(&mEvent);
177 }
178 
179 } // namespace erhic
Pythia 6 DIS event.
Definition: EventPythia.h:28
virtual void Fill(TBranch &)
virtual TBranch * Branch(TTree &, const std::string &)
Factory class for Monte Carlo particles.
virtual std::string EventName() const
Pythia6EventBuilder(EventMCFilterABC *=NULL)
virtual EventPythia * Create()
std::auto_ptr< ParticleMC > Create(const TMCParticle &) const
static bool IdentifyBeams(const erhic::VirtualEvent &, BeamParticles &)
virtual bool Accept(const VirtualEvent &) const =0