Project
Loading...
Searching...
No Matches
DiffAndTimeStructEstimator.cxx
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
14#include "TRDBase/Geometry.h"
15#include <cmath>
16
17namespace o2::trd
18{
19
20using namespace garfield;
21using namespace constants;
22
23//_____________________________________________________________________________
24bool DiffusionAndTimeStructEstimator::sampleTimeStruct(float vdrift)
25{
26 //
27 // Samples the timing structure of a drift cell
28 // Drift Time data calculated with Garfield (by C.Lippmann)
29 //
30
31 bool retVal = true;
32
33 // Nothing to do
34 if (std::abs(mTimeLastVdrift - vdrift) < 1.e-3) {
35 return retVal;
36 }
37 mTimeLastVdrift = vdrift;
38
39 // Drift time maps are saved for some drift velocity values (in drift region):
40 constexpr float fVDsmp[8] = {1.032, 1.158, 1.299, 1.450, 1.610, 1.783, 1.959, 2.134};
41
42 if (vdrift < fVDsmp[0]) {
43 LOG(debug) << "TRD: Drift Velocity too small " << vdrift << " < " << fVDsmp[0];
44 vdrift = fVDsmp[0];
45 retVal = false;
46 } else if (vdrift > fVDsmp[7]) {
47 LOG(debug) << "TRD: Drift Velocity too large " << vdrift << " > " << fVDsmp[7];
48 vdrift = fVDsmp[7];
49 retVal = false;
50 }
51 if (vdrift > fVDsmp[6]) {
52 mVDlo = fVDsmp[6];
53 mVDhi = fVDsmp[7];
54 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
55 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
56 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time2100[ctrt][ctrz];
57 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time2200[ctrt][ctrz];
58 }
59 }
60 } else if (vdrift > fVDsmp[5]) {
61 mVDlo = fVDsmp[5];
62 mVDhi = fVDsmp[6];
63 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
64 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
65 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time2000[ctrt][ctrz];
66 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time2100[ctrt][ctrz];
67 }
68 }
69 } else if (vdrift > fVDsmp[4]) {
70 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
71 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
72 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time1900[ctrt][ctrz];
73 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time2000[ctrt][ctrz];
74 }
75 }
76 mVDlo = fVDsmp[4];
77 mVDhi = fVDsmp[5];
78 } else if (vdrift > fVDsmp[3]) {
79 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
80 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
81 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time1800[ctrt][ctrz];
82 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time1900[ctrt][ctrz];
83 }
84 }
85 mVDlo = fVDsmp[3];
86 mVDhi = fVDsmp[4];
87 } else if (vdrift > fVDsmp[2]) {
88 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
89 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
90 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time1700[ctrt][ctrz];
91 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time1800[ctrt][ctrz];
92 }
93 }
94 mVDlo = fVDsmp[2];
95 mVDhi = fVDsmp[3];
96 } else if (vdrift > fVDsmp[1]) {
97 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
98 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
99 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time1600[ctrt][ctrz];
100 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time1700[ctrt][ctrz];
101 }
102 }
103 mVDlo = fVDsmp[1];
104 mVDhi = fVDsmp[2];
105 } else if (vdrift > (fVDsmp[0] - 1.0e-5)) {
106 for (int ctrt = 0; ctrt < TIMEBINSGARFIELD; ctrt++) {
107 for (int ctrz = 0; ctrz < ZBINSGARFIELD; ctrz++) {
108 mTimeStruct1[ctrt + ctrz * TIMEBINSGARFIELD] = Time1500[ctrt][ctrz];
109 mTimeStruct2[ctrt + ctrz * TIMEBINSGARFIELD] = Time1600[ctrt][ctrz];
110 }
111 }
112 mVDlo = fVDsmp[0];
113 mVDhi = fVDsmp[1];
114 }
115 mInvBinWidth = 1. / (mVDhi - mVDlo);
116 return retVal;
117}
118
119//_____________________________________________________________________________
120float DiffusionAndTimeStructEstimator::timeStruct(float vdrift, float dist, float z, bool* errFlag)
121{
122 //
123 // Applies the time structure of the drift cells (by C.Lippmann).
124 // The drift time of electrons to the anode wires depends on the
125 // distance to the wire (z) and on the position in the drift region.
126 //
127 // input :
128 // dist = radial distance from (cathode) pad plane [cm]
129 // z = distance from anode wire (parallel to cathode planes) [cm]
130 //
131 // output :
132 // tdrift = the drift time of an electron at the given position
133 //
134 // We interpolate between the drift time values at the two drift
135 // velocities fVDlo and fVDhi, being smaller and larger than
136 // fDriftVelocity. We use the two stored drift time maps fTimeStruct1
137 // and fTimeStruct2, calculated for the two mentioned drift velocities.
138 //
139
140 if (!sampleTimeStruct(vdrift)) {
141 *errFlag = true;
142 }
143
144 // Indices:
145 int r1 = (int)(10 * dist);
146 if (r1 < 0) {
147 r1 = 0;
148 }
149 if (r1 > 37) {
150 r1 = 37;
151 }
152 int r2 = r1 + 1;
153 if (r2 > 37) {
154 r2 = 37;
155 }
156 const int kz1 = ((int)(100 * z / 2.5));
157 const int kz2 = kz1 + 1;
158
159 if ((r1 < 0) || (r1 > 37) || (kz1 < 0) || (kz1 > 10)) {
160 LOG(warn) << Form("TRD: Time struct indices out of range: dist=%.2f, z=%.2f, r1=%d, kz1=%d", dist, z, r1, kz1);
161 }
162
163 const float ky111 = mTimeStruct1[r1 + 38 * kz1];
164 const float ky221 = ((r2 <= 37) && (kz2 <= 10)) ? mTimeStruct1[r2 + 38 * kz2] : mTimeStruct1[37 + 38 * 10];
165 const float ky121 = (kz2 <= 10) ? mTimeStruct1[r1 + 38 * kz2] : mTimeStruct1[r1 + 38 * 10];
166 const float ky211 = mTimeStruct1[r2 + 38 * kz1];
167
168 const float ky112 = mTimeStruct2[r1 + 38 * kz1];
169 const float ky222 = ((r2 <= 37) && (kz2 <= 10)) ? mTimeStruct2[r2 + 38 * kz2] : mTimeStruct2[37 + 38 * 10];
170 const float ky122 = (kz2 <= 10) ? mTimeStruct2[r1 + 38 * kz2] : mTimeStruct2[r1 + 38 * 10];
171 const float ky212 = mTimeStruct2[r2 + 38 * kz1];
172
173 // Interpolation in dist-directions, lower drift time map
174 const float ky11 = (ky211 - ky111) * 10 * dist + ky111 - (ky211 - ky111) * r1;
175 const float ky21 = (ky221 - ky121) * 10 * dist + ky121 - (ky221 - ky121) * r1;
176
177 // Interpolation in dist-direction, larger drift time map
178 const float ky12 = (ky212 - ky112) * 10 * dist + ky112 - (ky212 - ky112) * r1;
179 const float ky22 = (ky222 - ky122) * 10 * dist + ky122 - (ky222 - ky122) * r1;
180
181 // Dist now is the drift distance to the anode wires (negative if electrons are
182 // between anode wire plane and cathode pad plane)
183 dist -= Geometry::amThick() * 0.5;
184
185 // Interpolation in z-directions, lower drift time map
186 const bool condition = ((std::abs(dist) > 0.005) || (z > 0.005));
187 const float ktdrift1 =
188 condition ? (ky21 - ky11) * 100 * z / 2.5 + ky11 - (ky21 - ky11) * kz1 : 0.0;
189 // Interpolation in z-directions, larger drift time map
190 const float ktdrift2 =
191 condition ? (ky22 - ky12) * 100 * z / 2.5 + ky12 - (ky22 - ky12) * kz1 : 0.0;
192
193 // Interpolation between the values at fVDlo and fVDhi
194 const float a = (ktdrift2 - ktdrift1) * mInvBinWidth; // 1./(mVDhi - mVDlo);
195 const float b = ktdrift2 - a * mVDhi;
196 const float t = a * vdrift + b;
197
198 return t;
199}
200
201//_____________________________________________________________________________
202bool DiffusionAndTimeStructEstimator::getDiffCoeff(float& dl, float& dt, float vdrift)
203{
204 //
205 // Calculates the diffusion coefficients in longitudinal <dl> and
206 // transverse <dt> direction for a given drift velocity <vdrift>
207 //
208
209 // Nothing to do
210 if (std::abs(mDiffLastVdrift - vdrift) < 0.001) {
211 dl = mDiffusionL;
212 dt = mDiffusionT;
213 return true;
214 }
215 mDiffLastVdrift = vdrift;
216
217 if (mGasMixture == SimParam::GasMixture::Xenon) {
218 //
219 // Vd and B-field dependent diffusion and Lorentz angle
220 //
221
222 // kNb = kNb = kNb
223 constexpr int kNb = 5;
224
225 // If looking at compatibility with AliRoot:
226 // ibL and ibT are calculated the same way so, just define ib = ibL = ibT
227 int ib = ((int)(10 * (mBz - 0.15)));
228 ib = std::max(0, ib);
229 ib = std::min(kNb - 1, ib);
230
231 // DiffusionT
232 constexpr float p0T[kNb] = {0.009550, 0.009599, 0.009674, 0.009757, 0.009850};
233 constexpr float p1T[kNb] = {0.006667, 0.006539, 0.006359, 0.006153, 0.005925};
234 constexpr float p2T[kNb] = {-0.000853, -0.000798, -0.000721, -0.000635, -0.000541};
235 constexpr float p3T[kNb] = {0.000131, 0.000122, 0.000111, 0.000098, 0.000085};
236 // DiffusionL
237 constexpr float p0L[kNb] = {0.007440, 0.007493, 0.007513, 0.007672, 0.007831};
238 constexpr float p1L[kNb] = {0.019252, 0.018912, 0.018636, 0.018012, 0.017343};
239 constexpr float p2L[kNb] = {-0.005042, -0.004926, -0.004867, -0.004650, -0.004424};
240 constexpr float p3L[kNb] = {0.000195, 0.000189, 0.000195, 0.000182, 0.000169};
241
242 const float v2 = vdrift * vdrift;
243 const float v3 = v2 * vdrift;
244 mDiffusionL = p0L[ib] + p1L[ib] * vdrift + p2L[ib] * v2 + p3L[ib] * v3;
245 mDiffusionT = p0T[ib] + p1T[ib] * vdrift + p2T[ib] * v2 + p3T[ib] * v3;
246
247 dl = mDiffusionL;
248 dt = mDiffusionT;
249 return true;
250 } else if (mGasMixture == SimParam::GasMixture::Argon) {
251 //
252 // Diffusion constants and Lorentz angle only for B = 0.5T
253 //
254 mDiffusionL = 0.0182;
255 mDiffusionT = 0.0159;
256 dl = mDiffusionL;
257 dt = mDiffusionT;
258 return true;
259 } else {
260 return false;
261 }
262}
263
264} // namespace o2::trd
int32_t retVal
std::ostringstream debug
bool getDiffCoeff(float &dl, float &dt, float vdrift)
determines the diffusion coefficients as a function of drift velocity
float timeStruct(float vdrift, float xd, float z, bool *errFlag=nullptr)
determines drift time as function of drift velocity and coordinates
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat GLfloat v3
Definition glcorearb.h:814
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time1800
Definition Garfield.h:146
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time1600
Definition Garfield.h:66
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time1900
Definition Garfield.h:186
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time1500
Definition Garfield.h:26
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time1700
Definition Garfield.h:106
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time2200
Definition Garfield.h:306
constexpr int ZBINSGARFIELD
Definition Garfield.h:23
constexpr int TIMEBINSGARFIELD
Definition Garfield.h:22
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time2000
Definition Garfield.h:226
constexpr std::array< std::array< float, ZBINSGARFIELD >, TIMEBINSGARFIELD > Time2100
Definition Garfield.h:266
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"