EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Pythia6EventBuilder.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Pythia6EventBuilder.cxx
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::unique_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 
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::unique_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::unique_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
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