ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ECCEhpDIRCFastPIDMap.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ECCEhpDIRCFastPIDMap.cc
1 // $Id: $
2 
11 #include "ECCEhpDIRCFastPIDMap.h"
12 
13 #include <TF1.h>
14 #include <TFile.h>
15 #include <TH2F.h>
16 #include <TMath.h>
17 #include <TRandom.h>
18 #include <TVector3.h>
19 
20 #include <cassert>
21 #include <cmath>
22 
24  int barid = 0;
25 
26  fMass[0] = 0.000511;
27  fMass[1] = 0.105658;
28  fMass[2] = 0.139570;
29  fMass[3] = 0.49368;
30  fMass[4] = 0.938272;
31 
32  // multiple scattering for 17 mm thick radiator at 30 deg
33  fMs_mom = new TF1("", "expo(0)+expo(2)+expo(4)");
34  fMs_mom->SetParameters(4.40541e+00, -5.52436e+00, 2.35058e+00, -1.02703e+00,
35  9.55032e-01, -1.48500e-01);
36  // fMs_mom->SetParameters(9.39815e-01, -1.48243e-01, 4.69733e+00,
37  // -4.33960e+00, 2.19745e+00,
38  // -9.68617e-01);
39 
40  fMs_thickness = new TF1("", "pol1");
41 
42  if (barid == 1)
43  fMs_thickness->SetParameters(3.5, 0.0214286); // 10 mm bar
44  else
45  fMs_thickness->SetParameters(4.5, 0.0357143); // 17 mm bar
46 
47  TF1 *fMs_thickness_17 = new TF1("", "pol1");
48  fMs_thickness_17->SetParameters(4.5, 0.0357143); // 17 mm bar
49  fMs_thickness_max = fMs_thickness_17->Eval(70);
50 }
51 
53 
56  const double momentum,
57  const double theta_rad) const {
58  assert(fTrrMap);
59 
60  // preprocessing
61  double theta = theta_rad * TMath::RadToDeg();
62  truth_pid = abs(truth_pid);
63  // track_err - error assosiated with track direction [mrad]
64  double track_err = 0.326;
65  double p = momentum;
66 
68 
69  // copy from DrcPidFast::
70  // pdg - Particle Data Group code of the particle
71  // mom - 3-momentum of the particle [GeV/c]
72  // track_err - error assosiated with track direction [mrad]
73  // DrcPidInfo GetInfo(int pdg, TVector3 mom, double track_err = 0);
74 
75  const int max = 5;
77  int pid = get_pid(truth_pid);
78 
79  if (pid == 0) {
80  return ll_map;
81  }
82 
83  // set default values
84  for (int i = 0; i < max; i++) {
85  info.probability[i] = 0.25;
86  info.sigma[i] = 100;
87  }
88  info.cangle = 0;
89  info.cctr = 0;
90 
91  // check range
92  // if (theta < 19.99 || theta > 160.01){
93  // std::cout<<"theta out of [20,160] deg range: "<<theta<<std::endl;
94  // }
95 
96  double ms_mom_err = fMs_mom->Eval(p); // vector deviation after radiator
97 
98  double alpha = (theta < 90) ? 90 - theta : theta - 90;
99  double ms_thick_frac = fMs_thickness->Eval(alpha) / fMs_thickness_max;
100 
101  // 0.31 for averaging direction vector over the radiator thickness
102  double ms_err = 0.31 * ms_mom_err * ms_thick_frac;
103 
104  // ctr map is for theta = [25,153] and p = [0,10] GeV/c
105  if (theta < 25)
106  theta = 25;
107  if (theta > 153)
108  theta = 153;
109  if (p > 10)
110  p = 10;
111 
112  int bin = fTrrMap->FindBin(theta, p);
113  double ctr = fTrrMap->GetBinContent(bin); // Cherenkov track resolution [mrad]
114  double cctr = sqrt(ctr * ctr + track_err * track_err + ms_err * ms_err) *
115  0.001; // combined Cherenkov track resolution[rad]
116 
117  // 1.46907 - fused silica
118  double true_cangle =
119  acos(sqrt(p * p + fMass[pid] * fMass[pid]) / p / 1.46907);
120  true_cangle += gRandom->Gaus(0, cctr);
121 
122  // return default values if momentum below Cherenkov threshold (true_cangle is
123  // NaN)
124  if (isnan(true_cangle))
125  return ll_map;
126 
127  double cangle, sum = 0, fsum = 0;
128  double delta[max] = {0}; //, probability[max] = {0};
129 
130  for (int i = 0; i < max; i++) {
131  cangle = acos(sqrt(p * p + fMass[i] * fMass[i]) / p / 1.46907);
132  if (isnan(cangle)) {
133  ll_map[get_PIDCandidate(i)] =
134  -100; // set non-firing particle candidate to low probability
135  continue;
136  }
137  delta[i] = fabs(cangle - true_cangle);
138  sum += delta[i];
139  info.sigma[i] = (cangle - true_cangle) / cctr;
140  if (i == pid)
141  info.cangle = cangle;
142 
143  ll_map[get_PIDCandidate(i)] = -0.5 * info.sigma[i] * info.sigma[i];
144  }
145  // normalization
146  for (int i = 0; i < max; i++) {
147  if (delta[i] > 0)
148  info.probability[i] = sum / delta[i];
149  fsum += info.probability[i];
150  }
151  for (int i = 0; i < max; i++)
152  info.probability[i] /= fsum;
153  info.cctr = cctr;
154 
155  return ll_map;
156 }
157 
158 void ECCEhpDIRCFastPIDMap::ReadMap(const std::string &name) {
159  TFile *file = TFile::Open(name.c_str());
160  assert(file);
161  // fTrrMap = new TH2F();
162  file->GetObject("htrr", fTrrMap);
163  assert(fTrrMap);
164 }
165 
167  int pid = 0;
168  if (pdg == 11)
169  pid = 0; // e
170  if (pdg == 13)
171  pid = 1; // mu
172  if (pdg == 211)
173  pid = 2; // pi
174  if (pdg == 321)
175  pid = 3; // K
176  if (pdg == 2212)
177  pid = 4; // p
178  return pid;
179 }
180 
183  if (pid == 0)
185  if (pid == 1)
186  id = EICPIDDefs::MuonCandiate; // mu
187  if (pid == 2)
188  id = EICPIDDefs::PionCandiate; // pi
189  if (pid == 3)
190  id = EICPIDDefs::KaonCandiate; // K
191  if (pid == 4)
192  id = EICPIDDefs::ProtonCandiate; // p
193  assert(id != EICPIDDefs::InvalidCandiate);
194 
195  return id;
196 }