Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ReadEICFiles.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ReadEICFiles.cc
1 #include "ReadEICFiles.h"
2 
3 #include "EicEventHeader.h"
4 #include "EicEventHeaderv1.h"
5 
7 
9 #include <phool/PHIODataNode.h>
10 #include <phool/PHNode.h> // for PHNode
11 #include <phool/PHNodeIterator.h>
12 #include <phool/PHObject.h> // for PHObject
13 #include <phool/getClass.h>
14 #include <phool/phool.h> // for PHWHERE
15 
16 #pragma GCC diagnostic push
17 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
18 #include <HepMC/GenEvent.h>
19 #include <HepMC/GenVertex.h>
20 #pragma GCC diagnostic pop
21 
22 #include <HepMC/GenParticle.h> // for GenParticle
23 #include <HepMC/PdfInfo.h> // for PdfInfo
24 #include <HepMC/SimpleVector.h> // for FourVector
25 #include <HepMC/Units.h> // for GEV, MM
26 
27 // eicsmear classes
28 #include <eicsmear/erhic/EventMC.h>
29 #include <eicsmear/erhic/EventMilou.h>
30 #include <eicsmear/erhic/ParticleMC.h> // for ParticleMC
31 #include <eicsmear/erhic/Pid.h> // for Pid
32 
33 #include <eicsmear/erhic/EventDEMP.h>
34 
35 // General Root and C++ classes
36 #include <TBranch.h> // for TBranch
37 #include <TChain.h>
38 #include <TVector3.h> // for TVector3
39 
40 #include <iostream> // for operator<<, endl, basic_ostream
41 #include <vector> // for vector
42 
43 class PHHepMCGenEvent;
44 
45 using namespace std;
46 
48 
50  : SubsysReco(name)
51  , filename("")
52  , Tin(nullptr)
53  , nEntries(0)
54  , entry(0)
55  , m_EvtGenId(EvtGen::Unknown)
56  , GenEvent(nullptr)
57  , _node_name("PHHepMCGenEvent")
58 {
59  PHHepMCGenHelper::set_embedding_id(1); // default embedding ID to 1
60  return;
61 }
62 
64 
66 {
67  delete Tin;
68 }
69 
71 
72 bool ReadEICFiles::OpenInputFile(const string &name)
73 {
74  filename = name;
75  Tin = new TChain("EICTree", "EICTree");
76  Tin->Add(name.c_str());
77  GetTree();
78  return true;
79 }
80 
82 
84 {
85  /* Print the actual class of the event branch record,
86  i.e. erhic::EventMilou or other */
87  string EventClass(Tin->GetBranch("event")->GetClassName());
88  if (Verbosity() > 0)
89  {
90  cout << "ReadEICFiles: Input Branch Event Class = "
91  << EventClass << endl;
92  }
93  if (EventClass.find("Milou") != string::npos)
94  {
95  m_EvtGenId = EvtGen::Milou;
96  }
97 
98  if (EventClass.find("DEMP") != string::npos)
99  {
100  m_EvtGenId = EvtGen::DEMP;
101  }
102 
103  Tin->SetBranchAddress("event", &GenEvent);
104  nEntries = Tin->GetEntries();
105 }
106 
108 {
109  /* Create node tree */
110  CreateNodeTree(topNode);
111  return 0;
112 }
113 
115 {
116  /* Check if there is an unused event left in input file */
117  if (entry >= nEntries)
118  {
119  if (filename.size() > 0)
120  {
121  cout << "input file " << filename << " exhausted" << endl;
122  }
123  else
124  {
125  cout << "no file opened" << endl;
126  }
128  }
129 
130  /* Get event record from input file */
131  Tin->GetEntry(entry);
132 
133  EicEventHeader *evthead = findNode::getClass<EicEventHeader>(topNode, "EicEventHeader");
134  switch (m_EvtGenId)
135  {
136  case EvtGen::Milou:
137  {
138  erhic::EventMilou *gen = dynamic_cast<erhic::EventMilou *>(GenEvent);
139  evthead->set_eventgenerator_type(EicEventHeader::EvtGen::Milou);
140  evthead->set_milou_weight(gen->weight);
141  evthead->set_milou_trueX(gen->trueX);
142  evthead->set_milou_trueQ2(gen->trueQ2);
143  }
144  break;
145  case EvtGen::DEMP:
146  {
147  erhic::EventDEMP *gen = dynamic_cast<erhic::EventDEMP *>(GenEvent);
148  evthead->set_eventgenerator_type(EicEventHeader::EvtGen::DEMP);
149  evthead->set_demp_weight(gen->weight);
150  }
151  break;
152  case EvtGen::Unknown:
153  cout << "unknown event generator" << endl;
154  break;
155  default:
156  cout << "what is this " << m_EvtGenId << " ????" << endl;
157  break;
158  }
159 
160  /* Create GenEvent */
161  HepMC::GenEvent *evt = new HepMC::GenEvent();
162 
163  /* define the units (Pythia uses GeV and mm) */
164  evt->use_units(HepMC::Units::GEV, HepMC::Units::MM);
165 
166  /* add global information to the event */
167  evt->set_event_number(entry);
168 
169  /* process ID from pythia */
170  evt->set_signal_process_id(GenEvent->GetProcess());
171 
172  /* Set the PDF information */
173  HepMC::PdfInfo pdfinfo;
174  pdfinfo.set_x1(1);
175  pdfinfo.set_x2(GenEvent->GetX());
176  pdfinfo.set_scalePDF(GenEvent->GetQ2());
177  evt->set_pdf_info(pdfinfo);
178 
179  /* Loop over all particles for this event in input file and fill
180  * vector with HepMC particles */
181  vector<HepMC::GenParticle *> hepmc_particles;
182  vector<unsigned> origin_index;
183 
184  /* save pointers to beam particles */
185  HepMC::GenParticle *hepmc_beam1 = nullptr;
186  HepMC::GenParticle *hepmc_beam2 = nullptr;
187 
188  for (unsigned ii = 0; ii < GenEvent->GetNTracks(); ii++)
189  {
190  /* Get particle / track from event records.
191  * Class documentation for erhic::VirtualParticle at
192  * http://www.star.bnl.gov/~tpb/eic-smear/classerhic_1_1_virtual_particle.html */
193  erhic::ParticleMC *track_ii = GenEvent->GetTrack(ii);
194 
195  if (Verbosity() > 1)
196  {
197  cout << __PRETTY_FUNCTION__ << " : " << __LINE__ << endl;
198  cout << "\ttrack " << ii << endl;
199  cout << "\t4mom\t" << track_ii->GetPx() << "\t" << track_ii->GetPy() << "\t" << track_ii->GetPz() << "\t" << track_ii->GetE() << endl;
200  cout << "\tstatus= " << track_ii->GetStatus() << "\tindex= " << track_ii->GetIndex() << "\tmass= " << track_ii->GetM() << endl;
201  }
202 
203  /* Create HepMC particle record */
204  HepMC::GenParticle *hepmcpart = new HepMC::GenParticle(HepMC::FourVector(track_ii->GetPx(),
205  track_ii->GetPy(),
206  track_ii->GetPz(),
207  track_ii->GetE()),
208  track_ii->Id());
209 
210  /* translate eic-smear status codes to HepMC status codes */
211  switch (track_ii->GetStatus())
212  {
213  case 1:
214  hepmcpart->set_status(1);
215  break; // 'stable particle'
216 
217  case 21:
218  hepmcpart->set_status(3);
219  break; // 'documentation line'
220 
221  default:
222  hepmcpart->set_status(0);
223  break; // 'null entry'
224  }
225 
226  /* assume the first two particles are the beam particles (which getsHepMC status 4)*/
227  if (ii < 2)
228  hepmcpart->set_status(4);
229 
230  /* add particle information */
231  hepmcpart->setGeneratedMass(track_ii->GetM());
232 
233  /* append particle to vector */
234  hepmc_particles.push_back(hepmcpart);
235  origin_index.push_back(track_ii->GetIndex());
236 
237  /* if first particle, call this the first beam particle */
238  if (ii == 0)
239  hepmc_beam1 = hepmcpart;
240 
241  /* if second particle, call this the second beam particle */
242  if (ii == 1)
243  hepmc_beam2 = hepmcpart;
244  }
245 
246  /* Check if hepmc_particles and origin_index vectors are the same size */
247  if (hepmc_particles.size() != origin_index.size())
248  {
249  cout << "ReadEICFiles::process_event - Lengths of HepMC particles and Origin index vectors do not match!" << endl;
250 
251  delete evt;
253  }
254 
255  /* add HepMC particles to Hep MC vertices; skip first two particles
256  * in loop, assuming that they are the beam particles */
257  vector<HepMC::GenVertex *> hepmc_vertices;
258 
259  for (unsigned p = 2; p < hepmc_particles.size(); p++)
260  {
261  HepMC::GenParticle *pp = hepmc_particles.at(p);
262 
263  /* continue if vertices for particle are already set */
264  if (pp->production_vertex() && pp->end_vertex())
265  continue;
266 
267  /* access mother particle vertex */
268  erhic::ParticleMC *track_pp = GenEvent->GetTrack(p);
269 
270  unsigned parent_index = track_pp->GetParentIndex();
271 
272  HepMC::GenParticle *pmother = nullptr;
273  for (unsigned m = 0; m < hepmc_particles.size(); m++)
274  {
275  if (origin_index.at(m) == parent_index)
276  {
277  pmother = hepmc_particles.at(m);
278  break;
279  }
280  }
281 
282  /* if mother does not exist: create new vertex and add this particle as outgoing to vertex */
283  if (!pmother)
284  {
285  HepMC::GenVertex *hepmcvtx = new HepMC::GenVertex(HepMC::FourVector(track_pp->GetVertex()[0],
286  track_pp->GetVertex()[1],
287  track_pp->GetVertex()[2],
288  0));
289  hepmc_vertices.push_back(hepmcvtx);
290  hepmcvtx->add_particle_out(pp);
291  continue;
292  }
293  /* if mother exists and has end vertex: add this particle as outgoing to the mother's end vertex */
294  else if (pmother->end_vertex())
295  {
296  pmother->end_vertex()->add_particle_out(pp);
297  }
298  /* if mother exists and has no end vertex: create new vertex */
299  else
300  {
301  HepMC::GenVertex *hepmcvtx = new HepMC::GenVertex(HepMC::FourVector(track_pp->GetVertex()[0],
302  track_pp->GetVertex()[1],
303  track_pp->GetVertex()[2],
304  0));
305  hepmc_vertices.push_back(hepmcvtx);
306  hepmcvtx->add_particle_in(pmother);
307  pmother->end_vertex()->add_particle_out(pp);
308  }
309  }
310 
311  /* Add end vertex to beam particles if they don't have one yet */
312  for (unsigned p = 0; p < 2; p++)
313  {
314  HepMC::GenParticle *pp = hepmc_particles.at(p);
315 
316  if (!pp->end_vertex())
317  {
318  /* create collision vertex */
319  HepMC::GenVertex *hepmcvtx = new HepMC::GenVertex(HepMC::FourVector(0,
320  0,
321  0,
322  0));
323  hepmc_vertices.push_back(hepmcvtx);
324  hepmcvtx->add_particle_in(pp);
325  }
326  }
327 
328  /* Check that all particles (except beam particles) have a production vertex */
329  for (unsigned p = 2; p < hepmc_particles.size(); p++)
330  {
331  if (!hepmc_particles.at(p)->production_vertex())
332  {
333  cout << "ReadEICFiles::process_event - Missing production vertex for one or more non-beam particles!" << endl;
334  delete evt;
336  }
337  }
338 
339  /* Add HepMC vertices to event */
340  for (unsigned v = 0; v < hepmc_vertices.size(); v++)
341  {
342  evt->add_vertex(hepmc_vertices.at(v));
343  }
344 
345  /* set beam particles */
346  evt->set_beam_particles(hepmc_beam1, hepmc_beam2);
347 
348  /* pass HepMC to PHNode*/
350  if (Verbosity() > 1)
351  {
352  cout << __PRETTY_FUNCTION__ << " : " << __LINE__ << endl;
353  evt->print();
354  cout << endl << endl;
355  }
356 
357  if (!success)
358  {
359  cout << "ReadEICFiles::process_event - Failed to add event to HepMC record!" << endl;
361  }
362  /* Count up number of 'used' events from input file */
363  entry++;
364 
365  /* Done */
366  return 0;
367 }
368 
370 {
372 
373  PHNodeIterator iter(topNode);
374  // Looking for the DST node
375  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
376  if (!dstNode)
377  {
378  cout << PHWHERE << "DST Node missing, doing nothing." << endl;
380  }
381  EicEventHeader *evthead = findNode::getClass<EicEventHeader>(topNode, "EicEventHeader");
382  if (!evthead)
383  {
384  evthead = new EicEventHeaderv1();
385  PHIODataNode<PHObject> *HeaderNode = new PHIODataNode<PHObject>(evthead, "EicEventHeader", "PHObject");
386  dstNode->addNode(HeaderNode);
387  }
389 }