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
ParticleID.cxx
Go to the documentation of this file.
1 
11 
12 #include <sstream>
13 #include <string>
14 #include <vector>
15 
16 namespace Smear {
17 
19 : Ran(0)
20 , PMatPath("PIDMatrix.dat")
21 , bUseMC(false) {
22  ReadP(PMatPath);
23 }
24 
25 ParticleID::ParticleID(TString filename)
26 : Ran(0)
27 , PMatPath(filename)
28 , bUseMC(false) {
29  ReadP(PMatPath);
30 }
31 
33 }
34 
36  std::cout.setf(std::ios::fixed);
37  std::cout.precision(6);
38  for (unsigned i(0); i < PMax.size(); i++) {
39  for (unsigned k(0); k < FalseIdent.size(); k++) {
40  std::cout << 1 << '\t' << i + 1 << '\t' << PMin.at(i) << '\t' <<
41  PMax.at(i) << '\t' << k + 1;
42  for (unsigned j(0); j < TrueIdent.size(); j++) {
43  std::cout << '\t' << PMatrix.at(i).at(j).at(k);
44  } // for
45  std::cout << std::endl;
46  } // for
47  } // for
48 }
49 
51  PMatrix.resize(PMin.size());
52  for (unsigned i(0); i < PMatrix.size(); i++) {
53  PMatrix.at(i).resize(TrueIdent.size());
54  for (unsigned j(0); j < PMatrix.at(i).size(); j++) {
55  PMatrix.at(i).at(j).resize(FalseIdent.size());
56  } // for
57  } // for
58 }
59 
61  double t = 0.;
62  Range.resize(PMatrix.size());
63  for (unsigned i(0); i < Range.size(); i++) {
64  Range.at(i).resize(PMatrix.at(i).size());
65  for (unsigned j(0); j < Range.at(i).size(); j++) {
66  Range.at(i).at(j).resize(PMatrix.at(i).at(j).size());
67  for (unsigned k = 0; k < Range.at(i).at(j).size(); k++) {
68  t += PMatrix.at(i).at(j).at(k);
69  Range.at(i).at(j).at(k) = t;
70  } // for
71  t = 0.;
72  } // for
73  } // for
74 }
75 
76 int ParticleID::Wild(int pbin, int trueID) {
77  const double r = Ran.Rndm();
78  const int k = InListOfTrue(trueID);
79  int falseid(-999999999);
80  // Get the cumulative probability values for this momentum bin
81  // and true ID
82  const std::vector<double>& values = Range.at(pbin).at(k);
83  for (unsigned i(0); i < values.size(); i++) {
84  if (0 == i) {
85  if (r < values.at(i)) {
86  falseid = FalseIdent.at(i);
87  } // if
88  } else if (r > values.at(i-1) && r < values.at(i)) {
89  falseid = FalseIdent.at(i);
90  } // if
91  } // for
92  return falseid;
93 }
94 
95 int ParticleID::InListOfTrue(int ID) {
96  for (unsigned i(0); i < TrueIdent.size(); i++) {
97  if (TrueIdent.at(i) == abs(ID)) {
98  return i;
99  } // if
100  } // for
101  return -1;
102 }
103 
104 int ParticleID::InListOfFalse(int ID) {
105  for (unsigned i(0); i < FalseIdent.size(); i++) {
106  if (FalseIdent.at(i) == abs(ID)) {
107  return i;
108  } // if
109  } // for
110  // This is to accomodate the old HERMES format
111  if (ID < 5 && ID > 0) {
112  return ID - 1;
113  } // for
114  return -1;
115 }
116 
117 void ParticleID::Clear(Option_t* /* option */) {
118  TrueIdent.clear();
119  FalseIdent.clear();
120  PMin.clear();
121  PMax.clear();
122  PMatrix.clear();
123  Range.clear();
124 }
125 
126 void ParticleID::ReadP(TString filename) {
127  Clear("");
128  // Open the file and check for errors
129  std::ifstream Qfile;
130  Qfile.open(filename);
131  if (!Qfile.good()) {
132  std::cerr << "Error in ParticleID: unable to open file "
133  << filename << std::endl;
134  return;
135  } // if
136  // Returns true if s begins with pattern.
137  struct StartsWith {
138  bool operator()(const std::string& s,
139  const std::string& pattern) const {
140  return s.find(pattern, 0) == 0;
141  }
142  }
143  starts;
144  std::stringstream ss;
145  std::string line, dummy;
146  bool gotTrue(false), gotFalse(false), gotBins(false);
147  while (std::getline(Qfile, line).good()) {
148  // Strip leading whitespace
149  line.erase(0, line.find_first_not_of(" \t"));
150  // Feed the line to the stringstream, clearing existing contents first
151  ss.str(""); // Remove contents
152  ss.clear(); // Clear flags
153  ss << line;
154  int tmpint(0);
155  // Read true particle IDs
156  if (starts(line, "!T")) {
157  ss >> dummy;
158  while ((ss >> tmpint).good()) {
159  TrueIdent.push_back(tmpint);
160  } // while
161  gotTrue = !TrueIdent.empty();
162  } else if (starts(line, "!F")) {
163  // Read misidentified particle IDs
164  ss >> dummy;
165  while ((ss >> tmpint).good()) {
166  FalseIdent.push_back(tmpint);
167  } // while
168  gotFalse = !FalseIdent.empty();
169  } else if (starts(line, "!P")) {
170  // Read number of momentum bins
171  int pbin;
172  ss >> dummy >> pbin;
173  PMin.resize(pbin);
174  PMax.resize(pbin);
175  gotBins = !PMin.empty();
176  } else if (starts(line, "1") || starts(line, "2") || starts(line, "3")) {
177  // Read the probabilities for this momentum bin/true ID/false ID
178  if (!(gotTrue && gotFalse && gotBins)) {
179  std::cerr << "Error in ParticleID: " <<
180  "P matrix input file has bad or missing format lines.\n";
181  return;
182  } // if
183  int table, pbin, pid;
184  double pmin, pmax, p1, p2, p3;
185  ss >> table >> pbin >> pmin >> pmax >> pid >> p1 >> p2 >> p3;
186  if ((unsigned)pbin > PMin.size()) {
187  std::cerr << "Error in ParticleID: " <<
188  "Out of bounds momentum bin listing.\n";
189  return;
190  } // if
191  pbin -= 1; // Go from [1, N] to [0, N) for vector index range
192  PMin.at(pbin) = pmin;
193  PMax.at(pbin) = pmax;
194  pid = InListOfFalse(pid);
195  if ((unsigned)pid > FalseIdent.size()) {
196  std::cerr << "Error in ParticleID: " <<
197  "P matrix has bad particle listing.\n";
198  return;
199  } // if
200  if (PMatrix.empty()) {
201  SetPMatrixSize();
202  } // if
203  // Set identification probabilities
204  if (1 == table) {
205  PMatrix.at(pbin).at(0).at(pid) = p1;
206  PMatrix.at(pbin).at(1).at(pid) = p2;
207  PMatrix.at(pbin).at(2).at(pid) = p3;
208  } // if
209  } // if
210  } // while
212 }
213 
215  ParticleMCS& prtOut) {
216  double momentum(0.);
217  if (bUseMC) {
218  momentum = prt.GetP();
219  } else {
220  momentum = prtOut.p;
221  } // if
222  const int pid = prt.Id();
223  if (InListOfTrue(pid) != -1 && Accept.Is(prt)) {
224  for (unsigned i(0); i < PMin.size(); i++) {
225  if (momentum > PMin.at(i) && momentum < PMax.at(i)) {
226  // Generated ID is always positive.
227  // Keep same sign as input PID i.e. no error in charge sign
228  if (pid > 0) {
229  prtOut.id = Wild(i, pid);
230  } else {
231  prtOut.id = -Wild(i, pid);
232  } // if
233  } // if
234  } // for
235  } // if
236 }
237 
238 void ParticleID::Print(Option_t* /* option */) const {
239  std::cout << "ParticleID using " << PMatPath << std::endl;
240 }
241 
242 } // namespace Smear
Int_t id
PDG particle code.
Definition: ParticleMCS.h:172
virtual Double_t GetP() const =0
virtual ~ParticleID()
Definition: ParticleID.cxx:32
int Wild(int pbin, int trueID)
Definition: ParticleID.cxx:76
void Smear(const erhic::VirtualParticle &, ParticleMCS &)
Definition: ParticleID.cxx:214
Double32_t p
Total momentum of particle.
Definition: ParticleMCS.h:178
bool Is(const erhic::VirtualParticle &prt) const
Definition: Acceptance.cxx:46
virtual void Print(Option_t *="") const
Definition: ParticleID.cxx:238
virtual Pid Id() const =0
void SetupProbabilityArray()
Definition: ParticleID.cxx:60
Abstract base class for a general particle.
virtual void Clear(Option_t *="")
Definition: ParticleID.cxx:117
void ReadP(TString filename)
Definition: ParticleID.cxx:126