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
functions.cxx
Go to the documentation of this file.
1 
10 #include "eicsmear/functions.h"
11 
12 #include <cmath>
13 #include <fstream>
14 #include <set>
15 #include <sstream>
16 #include <string>
17 
18 #include <TLorentzVector.h>
19 #include <TMath.h>
20 #include <TParticlePDG.h>
21 #include <TVector2.h>
22 #include <TVector3.h>
23 
24 #include "eicsmear/erhic/EventMC.h"
26 
31 char getFirstNonBlank(const std::string& line) {
32  char first('\0'); // NULL character by default
33  // Find the index first non-blank character.
34  size_t index = line.find_first_not_of(" \t");
35 
36  if (index != std::string::npos) {
37  first = line.at(index);
38  } // if
39 
40  return first;
41 }
42 
51 double
52 computeHermesPhiH(const TLorentzVector& hadronInPrf,
53  const TLorentzVector& leptonInPrf,
54  const TLorentzVector& photonInPrf) {
55  const TVector3& q = photonInPrf.Vect();
56  const TVector3& k = leptonInPrf.Vect();
57  const TVector3& Ph = hadronInPrf.Vect();
58  const TVector3& qCrossK = q.Cross(k);
59  const TVector3& qCrossPh = q.Cross(Ph);
60  // Used to determine spin direction:
61  double qCrossKDotPh = qCrossK.Dot(Ph);
62  if (::fabs(qCrossKDotPh) < 1.0e-5) return -999.0;
63 
64  // First get phi in the range [0,pi]:
65  double phi = TMath::ACos(qCrossK.Dot(qCrossPh)
66  / qCrossK.Mag()
67  / qCrossPh.Mag());
68 
69  // Handle spin direction to get result in range [-pi,pi] by
70  // scaling by [-1,+1], depending on hemisphere.
71  phi *= qCrossKDotPh / ::fabs(qCrossKDotPh);
72 
73  return TVector2::Phi_0_2pi(phi);
74 }
75 
76 //
77 // class EventToDot.
78 //
79 
80 struct Pair {
81  int a;
82  int b;
83  Pair(int x, int y) : a(x), b(y) { }
84  // Less-than operator required for entry in sorted container.
85  bool operator<(const Pair& other) const {
86  if (other.a == a) return b < other.b;
87  return a < other.a;
88  }
89 };
90 
91 
93  const std::string& name) const {
94  std::ofstream file(name.c_str());
95  std::ostringstream oss;
96 
97  file << "digraph G {" << std::endl;
98  oss << " label = \"Event " << event.GetN() << "\"';";
99  file << oss.str() << std::endl;
100 
101  std::set<Pair> pairs;
102 
103  // Keep track of which particles we use in the diagram
104  // so we can set node attributes at the end.
105  // Use a set to avoid worrying about adding duplicates.
106  std::set<const erhic::ParticleMC*> used;
107 
108  // Loop over all tracks in the event and accumulate indices giving
109  // parent/child relationships.
110  // We look from parent->child and child->parent because they
111  // aren't always fully indexed both ways.
112  for (unsigned i(0); i < event.GetNTracks(); ++i) {
113  // Check parent of particle
114  const erhic::ParticleMC* parent = event.GetTrack(i)->GetParent();
115  if (parent) {
116  pairs.insert(Pair(parent->GetIndex(), event.GetTrack(i)->GetIndex()));
117  used.insert(parent);
118  used.insert(event.GetTrack(i));
119  } // if
120  // Check children of particle
121  for (unsigned j(0); j < event.GetTrack(i)->GetNChildren(); ++j) {
122  pairs.insert(Pair(event.GetTrack(i)->GetIndex(),
123  event.GetTrack(i)->GetChild(j)->GetIndex()));
124  used.insert(event.GetTrack(i));
125  used.insert(event.GetTrack(i)->GetChild(j));
126  } // for
127  } // for
128  // Insert relationships between particles.
129  for (std::set<Pair>::const_iterator i = pairs.begin();
130  i != pairs.end();
131  ++i) {
132  const erhic::ParticleMC* a = event.GetTrack(i->a - 1);
133  const erhic::ParticleMC* b = event.GetTrack(i->b - 1);
134  oss.str("");
135  oss << " " << a->GetIndex() << " -> " <<
136  b->GetIndex();
137  file << oss.str() << std::endl;
138  } // for
139  file << "# Node attributes" << std::endl;
140  // Apply labels, formatting to used particles.
141  for (std::set<const erhic::ParticleMC*>::const_iterator i = used.begin();
142  i != used.end();
143  ++i) {
144  std::string shape("ellipse");
145  if ((*i)->GetStatus() == 1) {
146  shape = "box";
147  } // if
148  if ((*i)->GetIndex() < 3) {
149  shape = "diamond";
150  } // if
151  oss.str("");
152  oss << " " << (*i)->GetIndex() << " [label=\"" << (*i)->GetIndex() << " ";
153  if ((*i)->Id().Info()) {
154  oss << (*i)->Id().Info()->GetName();
155  } else {
156  oss << "unknown PDG " << (*i)->Id().Code();
157  } // if
158  oss << "\", shape=" << shape << "];";
159  file << oss.str() << std::endl;
160  } // for
161  file << "}";
162 }
char getFirstNonBlank(const std::string &line)
Definition: functions.cxx:31
virtual const ParticleMC * GetParent() const
Definition: ParticleMC.cxx:205
virtual const ParticleMC * GetChild(UShort_t) const
Definition: ParticleMC.cxx:184
virtual const ParticleMC * GetTrack(UInt_t) const
Definition: EventMC.h:225
void Generate(const erhic::EventMC &, const std::string &outputName) const
Definition: functions.cxx:92
virtual UInt_t GetIndex() const
Definition: ParticleMC.h:412
double computeHermesPhiH(const TLorentzVector &hadronInPrf, const TLorentzVector &leptonInPrf, const TLorentzVector &photonInPrf)
Definition: functions.cxx:52