ATLAS Offline Software
Loading...
Searching...
No Matches
PixeldEdxData.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "TMath.h"
7#include <cmath>
8#include <algorithm>
9
10void PixeldEdxData::setPar(const int i, const double param) {
11 m_par[i].push_back(param);
12}
13
14void PixeldEdxData::setPosNeg(const bool posneg) {
15 m_posneg = posneg;
16}
17
18void PixeldEdxData::setFunctionType(const std::string &fun) {
19 m_fun = fun;
20}
21
22void PixeldEdxData::setBetheBlochType(const std::string &bb) {
23 m_bb = bb;
24}
25
26void PixeldEdxData::setMinimumdEdxForMass(const double mindedxMass) {
27 m_mindedxformass = mindedxMass;
28}
29
30double PixeldEdxData::dEdxPdf(const double dedx,const double signedP,const double mass, const std::array<double,9> &par, const int offset) const {
31 const auto p = std::abs(signedP);
32
33 double x0 = getdEdx(p,mass,par);
34
35 double pLG[4]={1,1,1,1};
36
37 if (m_fun=="AG") {
38 x0 = std::log(x0) - 9.4;
39 pLG[1] = x0;
40 pLG[0] = par[offset]+par[offset+2];
41 pLG[3] = par[offset+1]+par[offset+3];
42 return asymGaus(dedx, pLG[1], pLG[0], pLG[3]);
43 }
44 else if (m_fun=="CB") {
45 x0 = std::log(x0) - 9.4;
46 pLG[0] = x0;
47 pLG[1] = par[offset];
48 pLG[2] = par[offset+1];
49 pLG[3] = par[offset+2];
50 return crystalBall(dedx, pLG[0], pLG[1], pLG[2], pLG[3]);
51 }
52 return 0;
53}
54
55double PixeldEdxData::fdEdxZero(const double x, const std::array<double,9> & par) const {
56 return getdEdx(par[6],x,par)-par[5];
57}
58
59double PixeldEdxData::getPar(const int i, const int j) const {
60 auto itr = m_par.find(i);
61 if (itr!=m_par.end()) {
62 const std::vector<double> &param = itr->second;
63 if (j<(int)param.size()) {
64 return param[j];
65 }
66 }
67 return 0;
68}
69
70std::array<double,3>
71PixeldEdxData::getP(const double dedxArg, const double signedP, const int nGoodPixels) const {
72 std::array<double,3> vhypo{-2,-2,-2};
73 if (nGoodPixels<=0) { return vhypo; }
74 const auto & par = getFirstNPar(signedP,nGoodPixels,9);
75 const auto p = std::fabs(signedP);
76
77 const auto dedx = std::log(dedxArg)-9.4;
78
79 double pk = dEdxPdf(dedx,p,m_kMass ,par,5);
80 double pp = dEdxPdf(dedx,p,m_pMass ,par,5);
81 double ppi = dEdxPdf(dedx,p,m_piMass,par,5);
82
83 if (ppi+pk+pp>=0) {
84 vhypo = {ppi, pk,pp};
85 }
86 else {
87 vhypo ={-1,-1,-1};
88 }
89 return vhypo;
90}
91
92std::array<double,9>
93PixeldEdxData::getFirstNPar(const double p, const int nGoodPixels, const int npar) const {
94 std::array<double,9> par{};
95 auto setNGoodPixels{nGoodPixels};
96 if (setNGoodPixels>5) { setNGoodPixels=5; }
97 if (p<0 && m_posneg) { setNGoodPixels += 5; }
98 for (int i=0;i<npar;i++){
99 par[i] = getPar(setNGoodPixels-1,i);
100 }
101 return par;
102}
103
104double PixeldEdxData::getMass(const double dedx, const double signedP, const int nGoodPixels) const {
105
106 if (dedx<m_mindedxformass) { return m_piMass; }
107
108 if (nGoodPixels<=0) { return -2; }
109 auto par = getFirstNPar(signedP,nGoodPixels,5);
110
111 const auto p = std::abs(signedP);
112
113 par[5] = dedx;
114 par[6] = p;
115
116 double xmin=0;
117 double xmax=14000;
118
119 double xmed = (xmin+xmax)*0.5;
120 double prec=1e-6;
121
122 if (dedx<15000){ return m_piMass; }
123
124 do {
125 if (fdEdxZero(xmed,par)==0) { return xmed; }
126 if (fdEdxZero(xmed,par)*fdEdxZero(xmax,par)>0) { xmax=xmed; }
127 else { xmin=xmed; }
128 xmed=(xmin+xmax)*0.5;
129 } while (std::abs(xmax-xmin)>prec);
130 return xmed;
131}
132
133double PixeldEdxData::getdEdx(const double signedP, const double mass, const int nGoodPixels) const {
134 if (nGoodPixels<=0) { return -2; }
135 const auto & par = getFirstNPar(signedP,nGoodPixels,5);
136 const auto p = std::abs(signedP);
137 if (m_bb=="3p") { return dEdx_3p(p,mass,par); }
138 else if (m_bb=="5p") { return dEdx_5p(p,mass,par); }
139 else if (m_bb=="5p_aleph") { return dEdx_5p_aleph(p,mass,par); }
140 return 0;
141}
142
143double PixeldEdxData::getdEdx(const double signedP, const double mass, const std::array<double,9> & par) const {
144 const auto p = std::abs(signedP);
145 if (m_bb=="3p") { return dEdx_3p(p,mass,par); }
146 else if (m_bb=="5p") { return dEdx_5p(p,mass,par); }
147 else if (m_bb=="5p_aleph") { return dEdx_5p_aleph(p,mass,par); }
148 return 0;
149}
150
151// Crystal Ball distribution
152double PixeldEdxData::crystalBall(const double x,const double x0,const double sig,const double alp,const double n) {
153 double A = std::pow(n/std::abs(alp),n)*std::exp(-std::pow(std::abs(alp),2)*0.5);
154 double B = n/std::abs(alp)-std::abs(alp);
155 double pull = (x-x0)/sig;
156 double N = sig*(n/alp*(1/(n-1))*std::exp(-alp*alp*0.5)+std::sqrt(M_PI_2)*(1+std::erf(alp*M_SQRT1_2)));
157 if (pull<alp){
158 return std::exp(-pull*pull*0.5)/N;
159 }
160 return A*std::pow(B+pull,-n)/N;
161}
162
163// Asymetric Gaussian distribution
164double PixeldEdxData::asymGaus(const double x,const double x0,const double sig,const double asym) {
165 double sigp = sig*asym;
166 double sigm = sig/asym;
167 double fun;
168 if (x>x0) { fun = TMath::Gaus(x,x0,sigp,false); }
169 else { fun = TMath::Gaus(x,x0,sigm,false); }
170 return fun/(std::sqrt(2*M_PI)*((sigp*0.5) + (sigm*0.5)));
171}
172
173// Moyal distribution
174double PixeldEdxData::moyal(const double x,const double Ep,const double R) {
175 double lambda = (x-Ep)/R;
176 return std::sqrt(std::exp(-lambda-std::exp(-lambda))*M_1_PI*0.5);
177}
178
179double PixeldEdxData::dEdx_5p_BG_aleph(const double xbg, const std::array<double,9>& pp) {
180 double gamma = std::sqrt(xbg*xbg+1.);
181 double beta = std::sqrt(1.-1./(gamma*gamma));
182 return pp[0]/std::pow(beta,pp[3])*(pp[1]-std::pow(beta,pp[3])-std::log(pp[2]+1./std::pow(beta*gamma,pp[4])));
183}
184
185double PixeldEdxData::dEdx_5p_aleph(const double p,const double mass, const std::array<double,9>& pp) {
186 double bg = p/mass;
187 return dEdx_5p_BG_aleph(bg,pp);
188}
189
190double PixeldEdxData::dEdx_5p_BG(const double xbg, const std::array<double,9>& pp) {
191 double gamma = std::sqrt(xbg*xbg+1);
192 double beta = std::sqrt(1.-1./(gamma*gamma));
193 double fdedx = pp[0]/std::pow(beta,pp[2])*std::log(1+std::pow(std::abs(pp[1])*beta*gamma,pp[4]))-pp[3];
194 return fdedx;
195}
196
197double PixeldEdxData::dEdx_5p(const double p,const double mass, const std::array<double,9>& pp) {
198 double bg = p/mass;
199 return dEdx_5p_BG(bg,pp);
200}
201
202double PixeldEdxData::dEdx_BG(const double xbg, const std::array<double,9>& pp) {
203 double gamma = std::sqrt(xbg*xbg+1);
204 double beta = std::sqrt(1-1/(gamma*gamma));
205 double beta2 = beta*beta;
206 double gamma2 = gamma*gamma;
207 double fdedx = (pp[0]/std::pow(beta2,pp[2]))*(std::log(std::abs(pp[1])*beta2*gamma2))-pp[0];
208 return fdedx;
209}
210
211double PixeldEdxData::dEdx_def(const double p,const double mass, const std::array<double,9>& pp) {
212 double bg = p/mass;
213 return dEdx_BG(bg,pp);
214}
215
216double PixeldEdxData::dEdx_3p(const double p,const double mass, const std::array<double,9>& pp) {
217 double bg = p/mass;
218 return dEdx_BG(bg,pp);
219}
220
221std::vector<float>
222PixeldEdxData::getLikelihoods(const double dedx2, const double p2, const int nGoodPixels) const {
223 double dedx=dedx2;
224 double p=p2*0.001;
225 std::vector<float> vecResult(3,-1);
226 if (nGoodPixels>0){
227 const auto & array { getP(dedx,p,nGoodPixels)};
228 std::copy(array.begin(), array.end(),vecResult.begin());
229 }
230 return vecResult;
231}
232
#define M_PI
Store pixel dEdx data in PixeldEdxData.
#define x
double m_mindedxformass
static double crystalBall(const double x, const double x0, const double sig, const double alp, const double n)
double getdEdx(const double p, const double mass, const int nGoodPixels) const
std::vector< float > getLikelihoods(const double dedx2, const double p2, const int nGoodPixels) const
static double dEdx_5p_BG(const double xbg, const std::array< double, 9 > &pp)
static double dEdx_BG(const double xbg, const std::array< double, 9 > &pp)
std::string m_fun
static constexpr double m_kMass
double getMass(const double dedx, const double signedP, const int nGoodPixels) const
void setMinimumdEdxForMass(const double mindedxMass)
void setBetheBlochType(const std::string &bb)
std::string m_bb
void setFunctionType(const std::string &fun)
static double dEdx_5p_aleph(const double p, double mass, const std::array< double, 9 > &pp)
static double dEdx_5p(const double p, const double mass, const std::array< double, 9 > &pp)
double getPar(const int i, const int j) const
double dEdxPdf(const double dedx, const double signedP, const double mass, const std::array< double, 9 > &par, const int offset) const
static double dEdx_def(const double p, const double mass, const std::array< double, 9 > &pp)
static constexpr double m_piMass
std::unordered_map< uint32_t, std::vector< double > > m_par
std::array< double, 9 > getFirstNPar(const double p, const int nGoodPixels, const int np) const
static double asymGaus(const double x, const double x0, const double sig, const double asym)
void setPar(const int i, const double param)
static double dEdx_5p_BG_aleph(const double xbg, const std::array< double, 9 > &pp)
static constexpr double m_pMass
double fdEdxZero(const double x, const std::array< double, 9 > &par) const
void setPosNeg(const bool posneg)
std::array< double, 3 > getP(const double dedxArg, const double signedP, const int nGoodPixels) const
static double moyal(const double x, const double Ep, const double R)
static double dEdx_3p(const double p, const double mass, const std::array< double, 9 > &pp)
double xmax
Definition listroot.cxx:61
double xmin
Definition listroot.cxx:60
hold the test vectors and ease the comparison