EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParticleID.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ParticleID.cxx
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 
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 
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 
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 
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.GetP();
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.SetId (Wild(i, pid) );
230  } else {
231  prtOut.SetId( -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