Project
Loading...
Searching...
No Matches
GPUTRDRecoParam.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef O2_GPU_TRD_RECOPARAM_H
17#define O2_GPU_TRD_RECOPARAM_H
18
19#include "GPUCommonDef.h"
20#include "GPUCommonRtypes.h"
21#include "GPUCommonArray.h"
22#include "GPUCommonMath.h"
23
24namespace o2
25{
26namespace gpu
27{
28struct GPUSettingsRec;
29
31{
32 public:
33 GPUTRDRecoParam() = default;
35 ~GPUTRDRecoParam() = default;
36
38 void init(float bz, const GPUSettingsRec* rec = nullptr);
39
40#if !defined(GPUCA_GPUCODE_DEVICE)
42 GPUd() void recalcTrkltCov(const float tilt, const float snp, const float rowSize, std::array<float, 3>& cov, const float pull = 0., const int occupancy = 0) const
43 {
44 recalcTrkltCov(tilt, snp, rowSize, cov.data(), pull, occupancy);
45 }
46#endif
47 GPUd() void recalcTrkltCov(const float tilt, const float snp, const float rowSize, float* cov, const float pull = 0., const int occupancy = 0) const;
48
49 GPUd() float getRPhiRes(float snp, float pull = 0.f, int occupancy = 0) const;
50 GPUd() float getDyRes(float snp, int occupancy = 0) const { return mDyA2 + mDyC2 * (snp - mLorentzAngle) * (snp - mLorentzAngle) + mOccDyA * occupancy; } // a^2 + c^2 * (snp - b)^2
51 GPUd() float convertAngleToDy(float snp) const { return 3.f * snp / CAMath::Sqrt(1 - snp * snp); } // when calibrated, sin(phi) = (dy / xDrift) / sqrt(1+(dy/xDrift)^2) works well
52 GPUd() double getDyLikelihood(float snp, float slope, int occupancy = 0) const;
53 GPUd() double getZLikelihood(float deltaZ, float padLength, float sigmaZtrk) const;
54 GPUd() float getCorrYDy(float snp) const { return CAMath::Sqrt(mCorrYDyA + mCorrYDyC * (snp - mLorentzAngle) * (snp - mLorentzAngle)); }
55 GPUd() float getPileUpProbTracklet(int nBC, bool withChargeInfo, bool Q0 = true, bool Q1 = true) const;
56 GPUd() float getPileUpProbTrack(int nBC, std::array<int, 6> Q0, std::array<int, 6> Q1) const;
57
59 GPUd() float getZCorrCoeffNRC() const { return mZCorrCoefNRC; }
60
62 GPUd() int getPileUpRangeBefore() const { return mPileUpRangeBefore; }
63 GPUd() int getPileUpRangeAfter() const { return mPileUpRangeAfter; }
64
65 private:
66 // tracklet error parameterization depends on the magnetic field
67 float mLorentzAngle{0.f};
68 // rphi
69 float mRPhiA{1.f};
70 float mRPhiATgp{1.f};
71 float mRPhiC2{0.f};
72 // angle
73 float mDyA2{6e-3f};
74 float mDyC2{0.3f};
75 // variation in y when dy variates by one sigma (= cov / sigma_dy = corr * sigma_y) for tracklet (valid within ~[-0.6,0.6] of dy_trklt-dy_trk)
76 float mCorrYDyA{9e-4f};
77 float mCorrYDyC{1.5e-2f};
78 // error parametrization vs angular pull (pol2)
79 float mPullA{2.8e-3f};
80 float mPullB{0.040f};
81 // error parametrization of y position vs occupancy defined as ntracklets within chamber (prop to sqrt(occupancy))
82 float mOccA{3.3e-4f};
83 // error parametrization for dy vs occupancy defined as ntracklets within chamber (prop to sqrt(occupancy))
84 float mOccDyA{2.5e-4f};
85 // slope likelihood parametrization with Gaussian core and left and right exponential tails
86 float mDyExpA{1.78f};
87 float mDyExpC{-1.65f};
88 float mDyExpNormA{1.96e-3f};
89 float mDyExpNormC{0.21f};
90
91 float mZCorrCoefNRC{1.4f};
92
93 // pile-up prob parametrization, depending on charges
94 // default parametrization, all tracklets
95 int mPileUpRangeBefore{-130};
96 int mPileUpMaxProb{0};
97 int mPileUpRangeAfter{70};
98 // tracklets with Q0!=0 and Q1!=0
99 int mPileUpRangeBefore11{-130};
100 int mPileUpMaxProb11{0};
101 int mPileUpRangeAfter11{30};
102 // tracklets with Q0=0 and Q1!=0
103 int mPileUpRangeBefore01{-80};
104 int mPileUpMaxProb01{30};
105 int mPileUpRangeAfter01{70};
106 // tracklets with Q0!=0 and Q1=0
107 int mPileUpRangeBefore10{-130};
108 int mPileUpMaxProb10{-60};
109 int mPileUpRangeAfter10{30};
110 // tracklets with Q0=0 and Q1=0
111 int mPileUpRangeBefore00{-10};
112 int mPileUpMaxProb00{22};
113 int mPileUpRangeAfter00{40};
114
115 ClassDefNV(GPUTRDRecoParam, 4);
116};
117
125GPUdi() float GPUTRDRecoParam::getRPhiRes(float snp, float pull, int occupancy) const
126{
127 // flat uncertainty + radial-alignment uncertainty depending on tan(phi)
128 float tgp = (CAMath::Abs(snp) < 0.99999f) ? CAMath::Abs(snp) / CAMath::Sqrt(1 - snp * snp) : 1e6;
129 float resIdeal = mRPhiA + mRPhiATgp * tgp;
130 if (pull > 10) {
131 // parametrization does not really work well for such large pull values
132 pull = 10.f;
133 }
134 float resPull = mPullA * pull * pull + mPullB * pull; // parametrization as pol2 summed in quadrature
135 float resOccupancy = mOccA * occupancy; // parametrization as sqrt() summed in quadrature
136 return (resIdeal * resIdeal + mRPhiC2 * (snp - mLorentzAngle) * (snp - mLorentzAngle) + resPull * resPull + resOccupancy);
137}
138
139GPUdi() double GPUTRDRecoParam::getDyLikelihood(float snp, float slope, int occupancy) const
140{
141 // Gaussian + left exponential + right exponential
142 double likelihood = CAMath::Exp(-0.5f * (slope - GPUTRDRecoParam::convertAngleToDy(snp)) * (slope - GPUTRDRecoParam::convertAngleToDy(snp)) / GPUTRDRecoParam::getDyRes(snp, occupancy));
143
144 // Normalization for the exponential is parametrized with respect to the Gaussian, it is smaller at lorentz angle
145 double expNorm = CAMath::Sqrt(mDyExpNormA + mDyExpNormC * (snp - mLorentzAngle) * (snp - mLorentzAngle));
146 if (slope < convertAngleToDy(snp)) {
147 // left tail in this case, larger tail for large positive snp
148 likelihood += expNorm * CAMath::Exp((mDyExpA + mDyExpC * (snp - mLorentzAngle)) * (slope - GPUTRDRecoParam::convertAngleToDy(snp)));
149 } else {
150 // right tail, larger tail for large negative snp
151 likelihood += expNorm * CAMath::Exp(-(mDyExpA - mDyExpC * (snp - mLorentzAngle)) * (slope - GPUTRDRecoParam::convertAngleToDy(snp)));
152 }
153
154 // Normalized such that likelihood is 1 when track angle and tracklet slope agree, and always lower than 1 otherwise (such that -log(likelihood) is always positive)
155 likelihood /= (1.f + expNorm);
156 return likelihood;
157}
158
159GPUdi() double GPUTRDRecoParam::getZLikelihood(float deltaZ, float padLength, float sigmaZtrk) const
160{
161 // logistic function as approximation of convolution between uniform tracklet Z and gaussian track, depends on sqrt(3)/pi times the track resolution
162 // normalized so that maximum is 1
163 double lmax = 1.f / (1.f + CAMath::Exp(-0.5f * padLength / 0.5513f / sigmaZtrk)) - 1.f / (1.f + CAMath::Exp(0.5f * padLength / 0.5513f / sigmaZtrk));
164 return 1.f / lmax / (1.f + CAMath::Exp((deltaZ - 0.5f * padLength) / 0.5513f / sigmaZtrk)) - 1.f / lmax / (1.f + CAMath::Exp((deltaZ + 0.5f * padLength) / 0.5513f / sigmaZtrk));
165}
166
167GPUdi() float GPUTRDRecoParam::getPileUpProbTracklet(int nBC, bool withChargeInfo, bool Q0, bool Q1) const
168{
169 // get the probability that the tracklet with charges Q0 and Q1 belongs to a given BC, with a (signed) distance nBC from the TRD-triggered BC
170 // parametrization depends on whether charges are 0 (bool is false) or not (bool is true)
171
172 float prob = 0.;
173
174 int maxBC = mPileUpRangeAfter;
175 int minBC = mPileUpRangeBefore;
176 int maxProbBC = mPileUpMaxProb;
177 if (nBC <= mPileUpRangeBefore || nBC >= mPileUpRangeAfter) {
178 return prob;
179 }
180
181 if (withChargeInfo) {
182 if (Q0 && Q1) {
183 maxBC = mPileUpRangeAfter11;
184 minBC = mPileUpRangeBefore11;
185 maxProbBC = mPileUpMaxProb11;
186 }
187 if (!Q0 && Q1) {
188 maxBC = mPileUpRangeAfter01;
189 minBC = mPileUpRangeBefore01;
190 maxProbBC = mPileUpMaxProb01;
191 }
192 if (Q0 && !Q1) {
193 maxBC = mPileUpRangeAfter10;
194 minBC = mPileUpRangeBefore10;
195 maxProbBC = mPileUpMaxProb10;
196
197 // if Q1 = 0, there is a second maximum at nBC=0, probably due to tracklets with low energy loss in the drift/TR regions
198 // so we enlarge the probability around there
199 if (nBC > maxProbBC && nBC <= 0) {
200 prob += 2. / (maxBC - minBC) / (0 - maxProbBC) * (nBC - maxProbBC);
201 }
202 if (nBC > 0 && nBC < maxBC) {
203 prob += 2. / (maxBC - minBC) / (0 - maxBC) * (nBC - maxBC);
204 }
205 }
206 if (!Q0 && !Q1) {
207 maxBC = mPileUpRangeAfter00;
208 minBC = mPileUpRangeBefore00;
209 maxProbBC = mPileUpMaxProb00;
210 }
211 }
212
213 // prob is 0 if the BC is too far, maximal for a given nBC, and with two linear functions in between. The maximum is chosen so that the integral is 1.
214 if (nBC <= minBC || nBC >= maxBC) {
215 return 0.;
216 }
217 float maxProb = 2. / (maxBC - minBC);
218 if (nBC > minBC && nBC <= maxProbBC) {
219 prob += maxProb / (maxProbBC - minBC) * (nBC - minBC);
220 } else {
221 prob += maxProb / (maxProbBC - maxBC) * (nBC - maxBC);
222 }
223 return prob;
224}
225
226GPUdi() float GPUTRDRecoParam::getPileUpProbTrack(int nBC, std::array<int, 6> Q0, std::array<int, 6> Q1) const
227{
228 // get the probability that the track belongs to a given BC, with a (signed) distance nBC from the TRD-triggered BC
229 // it depends on the individual probabilities for every of its tracklets.
230 //
231 // If P(BC|L0,L1,...) is the probability that the track belongs to a given BC, given the information on the tracklet charges in L0,L1, ...
232 // P(BC|L0,L1,...) proportional to P(BC)*P(L0,L1,...|BC), prop to P(BC)*P(L0|BC)*P(L1|BC)*... since for a given track and BC, charge in different layers are independent
233 // prop to P(BC) * P(BC|L0)/P(BC) * P(BC|L1)/P(BC) * ...
234 //
235 // P(BC) is the probability with no charge information: we start from this probability, and each tracklet adds new information on pileup probability
236
237 // basic probability, if we had no info on the charges
238 float probNoInfo = GPUTRDRecoParam::getPileUpProbTracklet(nBC, false);
239
240 float probTrack = probNoInfo;
241 if (probNoInfo < 1e-6f)
242 return 0.;
243
244 // For each tracklet, we add the info on its charge
245 for (int i = 0; i < 6; i++) {
246 // negative charge values if the tracklet is not present
247 if (Q0[i] < 0 || Q1[i] < 0)
248 continue;
249 float probTracklet = GPUTRDRecoParam::getPileUpProbTracklet(nBC, true, (Q0[i] != 0), (Q1[i] != 0));
250 probTrack *= probTracklet / probNoInfo;
251 }
252
253 return probTrack;
254}
255
256} // namespace gpu
257} // namespace o2
258
259#endif // O2_GPU_TRD_RECOPARAM_H
int32_t i
uint16_t slope
Definition RawData.h:1
void init(float bz, const GPUSettingsRec *rec=nullptr)
Load parameterization for given magnetic field.
const float const float std::array< float, 3 > & cov
GPUd() int getPileUpRangeAfter() const
const float const float rowSize
float float sigmaZtrk const
GPUd() void recalcTrkltCov(const float tilt
Recalculate tracklet covariance based on phi angle of related track.
GPUTRDRecoParam(const GPUTRDRecoParam &)=default
const float const float std::array< float, 3 > const float pull
const float const float std::array< float, 3 > const float const int occupancy
GPUd() int getPileUpRangeBefore() const
Get BC intervals for pile-up.
GPUd() float getPileUpProbTracklet(int nBC
GLenum array
Definition glcorearb.h:4274
GLdouble f
Definition glcorearb.h:310
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GPUdi() o2
Definition TrackTRD.h:39
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
GPUReconstruction * rec