]>
Commit | Line | Data |
---|---|---|
5a5a1232 | 1 | #ifndef REVE_MCHelixLine_H |
2 | #define REVE_MCHelixLine_H | |
3 | ||
4 | #include <Reve/Track.h> | |
32e219c2 | 5 | #include <cassert> |
5a5a1232 | 6 | #include <vector> |
7 | ||
8 | namespace Reve { | |
9 | ||
bbfaa1c4 | 10 | struct MCVertex |
11 | { | |
12 | Float_t x,y,z,t; | |
32e219c2 | 13 | |
14 | MCVertex() : x(0), y(0), z(0), t(0) {} | |
15 | MCVertex(Float_t _x, Float_t _y, Float_t _z, Float_t _t=0) : | |
16 | x(_x), y(_y), z(_z), t(_t) {} | |
17 | ||
18 | Float_t Mag() const { return TMath::Sqrt(x*x+y*y+z*z);} | |
19 | Float_t Mag2() const { return x*x+y*y+z*z;} | |
20 | ||
21 | Float_t Perp() const { return TMath::Sqrt(x*x+y*y);} | |
22 | Float_t Perp2() const { return x*x+y*y;} | |
23 | Float_t R() const { return Perp(); } | |
24 | ||
25 | MCVertex operator + (const MCVertex & b) | |
26 | { return MCVertex(x + b.x, y + b.y, z + b.z, t + b.t); } | |
27 | ||
28 | MCVertex operator - (const MCVertex & b) | |
29 | { return MCVertex(x - b.x, y - b.y, z - b.z, t - b.t); } | |
30 | ||
31 | MCVertex operator * (Float_t a) | |
32 | { return MCVertex(a*x, a*y, a*z, a*t); } | |
33 | ||
34 | MCVertex& operator +=(const MCVertex & b) | |
35 | { x += b.x; y += b.y; z += b.z; t += b.t; return *this; } | |
bbfaa1c4 | 36 | }; |
5a5a1232 | 37 | |
38 | ||
bbfaa1c4 | 39 | struct MCStruct |
40 | { | |
41 | MCStruct(const MCStruct&); // Not implemented | |
42 | MCStruct& operator=(const MCStruct&); // Not implemented | |
43 | ||
44 | TrackRnrStyle* fRnrMod; | |
45 | std::vector<MCVertex>* fPoints; | |
46 | MCVertex fV; | |
47 | Float_t fVelocity; // size of particle velocity | |
5a5a1232 | 48 | |
bbfaa1c4 | 49 | MCStruct(TrackRnrStyle* rs, MCVertex* v0 , Float_t vel, std::vector<MCVertex>* tpv) : |
50 | fRnrMod (rs), | |
51 | fPoints (tpv), | |
52 | fV (*v0), | |
53 | fVelocity (vel) | |
b97c26da | 54 | { |
bbfaa1c4 | 55 | fPoints->push_back(fV); |
56 | } | |
57 | virtual ~MCStruct() {} | |
58 | }; | |
5a5a1232 | 59 | |
bbfaa1c4 | 60 | /**************************************************************************/ |
61 | // HELIX | |
62 | /**************************************************************************/ | |
5a5a1232 | 63 | |
bbfaa1c4 | 64 | struct MCHelix : public MCStruct |
65 | { | |
66 | // constant | |
67 | Float_t fA; // contains charge and magnetic field data | |
5a5a1232 | 68 | |
bbfaa1c4 | 69 | //parameters dependend pT and pZ size, set in init function |
70 | Float_t fLam; // momentum ratio pT/pZ | |
71 | Float_t fR; // a/pT | |
72 | Float_t fPhiStep; // step size in xy projection, dependent of RnrMode and momentum | |
73 | Float_t fTimeStep; | |
74 | ||
75 | Int_t fN; // step number in helix; | |
76 | Int_t NMax; // max number of points in helix | |
77 | Float_t x_off, y_off; // offset for fitting daughters | |
78 | Float_t sin, cos; | |
79 | Bool_t crosR; | |
5a5a1232 | 80 | |
bbfaa1c4 | 81 | MCHelix(TrackRnrStyle* rs, MCVertex* v0, Float_t vel, |
82 | std::vector<MCVertex>* tpv, Float_t a) : | |
83 | MCStruct(rs, v0 , vel, tpv), | |
84 | fA (a), | |
85 | fLam (0), fR (0), fPhiStep (0), fTimeStep (0), | |
86 | fN (0), NMax (0), | |
87 | x_off(0), y_off(0), | |
88 | sin (0), cos (0), crosR (0) | |
89 | {} | |
5a5a1232 | 90 | |
bbfaa1c4 | 91 | void Init(Float_t pT, Float_t pZ) |
92 | { | |
32e219c2 | 93 | fN = 0; |
bbfaa1c4 | 94 | crosR = false; |
32e219c2 | 95 | x_off = 0; |
96 | y_off = 0; | |
97 | fLam = pZ/pT; | |
98 | fR = pT/fA; | |
5a5a1232 | 99 | |
32e219c2 | 100 | fPhiStep = fRnrMod->fMinAng * TMath::DegToRad(); |
101 | if (fRnrMod->fDelta < TMath::Abs(fR)) | |
102 | { | |
bbfaa1c4 | 103 | Float_t ang = 2*TMath::ACos(1 - fRnrMod->fDelta/TMath::Abs(fR)); |
104 | if (ang < fPhiStep) fPhiStep = ang; | |
5a5a1232 | 105 | } |
32e219c2 | 106 | if (fA < 0) fPhiStep = -fPhiStep; |
5a5a1232 | 107 | |
bbfaa1c4 | 108 | // printf("MCHelix::init (%f/%f) labda %f time step %e phi step %f \n", pT, pZ,fLam, fTimeStep,fPhiStep); |
109 | fTimeStep = TMath::Abs(fR*fPhiStep)*TMath::Sqrt(1+fLam*fLam)/fVelocity; | |
110 | fTimeStep *= 0.01; //cm->m | |
111 | ||
112 | sin = TMath::Sin(fPhiStep); | |
113 | cos = TMath::Cos(fPhiStep); | |
114 | } | |
115 | ||
116 | void SetBounds() | |
117 | { | |
118 | // check steps for max orbits | |
119 | NMax = Int_t(fRnrMod->fMaxOrbs*TMath::TwoPi()/TMath::Abs(fPhiStep)); | |
120 | // check steps for Z boundaries | |
121 | Float_t nz; | |
122 | if(fLam > 0) { | |
123 | nz = (fRnrMod->fMaxZ - fV.z)/(fLam*TMath::Abs(fR*fPhiStep)); | |
124 | } else { | |
125 | nz = (-fRnrMod->fMaxZ - fV.z)/(fLam*TMath::Abs(fR*fPhiStep)); | |
126 | } | |
127 | // printf("steps in helix line %d nz %f vz %f\n", NMax, nz, fV.z); | |
32e219c2 | 128 | if (nz < NMax) NMax = Int_t(nz + 1); |
5a5a1232 | 129 | |
bbfaa1c4 | 130 | // check steps if circles intersect |
32e219c2 | 131 | if(TMath::Sqrt(fV.x*fV.x+fV.y*fV.y) < fRnrMod->fMaxR + TMath::Abs(fR)) |
132 | { | |
bbfaa1c4 | 133 | crosR = true; |
5a5a1232 | 134 | } |
bbfaa1c4 | 135 | // printf("end steps in helix line %d \n", NMax); |
136 | } | |
5a5a1232 | 137 | |
138 | ||
bbfaa1c4 | 139 | void Step(Float_t &px, Float_t &py, Float_t &/*pz*/) |
140 | { | |
141 | fV.t += fTimeStep; | |
142 | fV.x += (px*sin - py*(1 - cos))/fA + x_off; | |
143 | fV.y += (py*sin + px*(1 - cos))/fA + y_off; | |
144 | fV.z += fLam*TMath::Abs(fR*fPhiStep); | |
145 | fPoints->push_back(fV); | |
32e219c2 | 146 | Float_t px_t = px*cos - py*sin; |
147 | Float_t py_t = py*cos + px*sin; | |
bbfaa1c4 | 148 | px = px_t; |
149 | py = py_t; | |
b855ed81 | 150 | ++fN; |
bbfaa1c4 | 151 | } |
5a5a1232 | 152 | |
153 | ||
bbfaa1c4 | 154 | Bool_t LoopToVertex(Float_t &px, Float_t &py, Float_t &pz, |
f3e27855 | 155 | Float_t ex, Float_t ey, Float_t ez) |
bbfaa1c4 | 156 | { |
157 | Float_t p0x = px, p0y = py; | |
158 | Float_t zs = fLam*TMath::Abs(fR*fPhiStep); | |
32e219c2 | 159 | Float_t maxrsq = fRnrMod->fMaxR * fRnrMod->fMaxR; |
bbfaa1c4 | 160 | Float_t fnsteps = (ez - fV.z)/zs; |
161 | Int_t nsteps = Int_t((ez - fV.z)/zs); | |
162 | Float_t sinf = TMath::Sin(fnsteps*fPhiStep); | |
163 | Float_t cosf = TMath::Cos(fnsteps*fPhiStep); | |
5a5a1232 | 164 | |
bbfaa1c4 | 165 | { |
b855ed81 | 166 | if (nsteps > 0) |
167 | { | |
bbfaa1c4 | 168 | Float_t xf = fV.x + (px*sinf - py*(1 - cosf))/fA; |
169 | Float_t yf = fV.y + (py*sinf + px*(1 - cosf))/fA; | |
170 | x_off = (ex - xf)/fnsteps; | |
171 | y_off = (ey - yf)/fnsteps; | |
172 | Float_t xforw, yforw, zforw; | |
b855ed81 | 173 | for (Int_t l=0; l<nsteps; l++) |
174 | { | |
bbfaa1c4 | 175 | xforw = fV.x + (px*sin - py*(1 - cos))/fA + x_off; |
176 | yforw = fV.y + (py*sin + px*(1 - cos))/fA + y_off; | |
177 | zforw = fV.z + fLam*TMath::Abs(fR*fPhiStep); | |
32e219c2 | 178 | if (xforw*xforw+yforw*yforw > maxrsq || |
179 | TMath::Abs(zforw) > fRnrMod->fMaxZ) | |
180 | { | |
bbfaa1c4 | 181 | return false; |
182 | } | |
32e219c2 | 183 | Step(px, py, pz); |
b855ed81 | 184 | if (fN > NMax) |
185 | break; | |
bbfaa1c4 | 186 | } |
5a5a1232 | 187 | |
5a5a1232 | 188 | } |
bbfaa1c4 | 189 | // set time to the end point |
190 | fV.t += TMath::Sqrt((fV.x-ex)*(fV.x-ex)+(fV.y-ey)*(fV.y-ey) +(fV.z-ez)*(fV.z-ez))/fVelocity; | |
191 | fV.x = ex; fV.y = ey; fV.z = ez; | |
192 | fPoints->push_back(fV); | |
193 | } | |
5a5a1232 | 194 | |
bbfaa1c4 | 195 | { // fix momentum in the remaining part |
32e219c2 | 196 | Float_t cosr = TMath::Cos((fnsteps-nsteps)*fPhiStep); |
197 | Float_t sinr = TMath::Sin((fnsteps-nsteps)*fPhiStep); | |
198 | Float_t px_t = px*cosr - py*sinr; | |
199 | Float_t py_t = py*cosr + px*sinr; | |
bbfaa1c4 | 200 | px = px_t; |
201 | py = py_t; | |
202 | } | |
203 | { // calculate direction of faked px,py | |
204 | Float_t pxf = (p0x*cosf - p0y*sinf)/TMath::Abs(fA) + x_off/fPhiStep; | |
205 | Float_t pyf = (p0y*cosf + p0x*sinf)/TMath::Abs(fA) + y_off/fPhiStep; | |
32e219c2 | 206 | Float_t fac = TMath::Sqrt((p0x*p0x + p0y*p0y) / (pxf*pxf + pyf*pyf)); |
bbfaa1c4 | 207 | px = fac*pxf; |
208 | py = fac*pyf; | |
5a5a1232 | 209 | } |
bbfaa1c4 | 210 | return true; |
211 | } | |
5a5a1232 | 212 | |
bbfaa1c4 | 213 | Bool_t LoopToBounds(Float_t &px, Float_t &py, Float_t &pz) |
214 | { | |
215 | // printf("MC helix loop_to_bounds\n"); | |
216 | SetBounds(); | |
b855ed81 | 217 | if (NMax > 0) |
218 | { | |
32e219c2 | 219 | // printf("NMax MC helix loop_to_bounds\n"); |
220 | MCVertex forw; | |
221 | Float_t maxrsq = fRnrMod->fMaxR * fRnrMod->fMaxR; | |
b855ed81 | 222 | while (fN < NMax) |
223 | { | |
32e219c2 | 224 | forw.x = fV.x + (px*sin - py*(1 - cos))/fA + x_off; |
225 | forw.y = fV.y + (py*sin + px*(1 - cos))/fA + y_off; | |
226 | forw.z = fV.z + fLam*TMath::Abs(fR*fPhiStep); | |
227 | forw.t = fV.t + fTimeStep; | |
5a5a1232 | 228 | |
32e219c2 | 229 | if (crosR && forw.Perp2() > maxrsq) |
230 | { | |
231 | Float_t t = (fRnrMod->fMaxR - fV.R()) / (forw.R() - fV.R()); | |
232 | assert(t >= 0 && t <= 1); | |
233 | fPoints->push_back(fV + (forw-fV)*t); | |
bbfaa1c4 | 234 | return false; |
235 | } | |
32e219c2 | 236 | if (TMath::Abs(forw.z) > fRnrMod->fMaxZ) |
237 | { | |
238 | Float_t t = (fRnrMod->fMaxZ - TMath::Abs(fV.z)) / TMath::Abs((forw.z - fV.z)); | |
239 | assert(t >= 0 && t <= 1); | |
240 | fPoints->push_back(fV + (forw-fV)*t); | |
241 | return false; | |
242 | } | |
243 | ||
244 | Step(px, py, pz); | |
5a5a1232 | 245 | } |
bbfaa1c4 | 246 | return true; |
5a5a1232 | 247 | } |
bbfaa1c4 | 248 | return false; |
249 | } | |
250 | }; | |
5a5a1232 | 251 | |
bbfaa1c4 | 252 | /**************************************************************************/ |
253 | // LINE | |
254 | /**************************************************************************/ | |
5a5a1232 | 255 | |
bbfaa1c4 | 256 | struct MCLine : public MCStruct |
257 | { | |
258 | MCLine(TrackRnrStyle* rs, MCVertex* v0 ,Float_t vel, std::vector<MCVertex>* tpv): | |
259 | MCStruct(rs, v0 , vel, tpv) | |
260 | {} | |
5a5a1232 | 261 | |
bbfaa1c4 | 262 | Bool_t InBounds(Float_t ex, Float_t ey, Float_t ez) |
263 | { | |
264 | if(TMath::Abs(ez) > fRnrMod->fMaxZ || | |
265 | ex*ex + ey*ey > fRnrMod->fMaxR*fRnrMod->fMaxR) | |
266 | return false; | |
267 | else | |
268 | return true; | |
269 | } | |
5a5a1232 | 270 | |
bbfaa1c4 | 271 | void GotoVertex(Float_t x1, Float_t y1, Float_t z1) |
272 | { | |
bbfaa1c4 | 273 | fV.t += TMath::Sqrt((fV.x-x1)*(fV.x-x1)+(fV.y-y1)*(fV.y-y1)+(fV.z-z1)*(fV.z-z1))/fVelocity; |
274 | fV.x=x1; fV.y=y1; fV.z=z1; | |
275 | fPoints->push_back(fV); | |
276 | } | |
5a5a1232 | 277 | |
278 | ||
bbfaa1c4 | 279 | void GotoBounds( Float_t px, Float_t py, Float_t pz) |
280 | { | |
281 | Float_t tZ = 0,Tb = 0; | |
282 | // time where particle intersect +/- fMaxZ | |
283 | if (pz > 0) { | |
284 | tZ = (fRnrMod->fMaxZ - fV.z)/pz; | |
285 | } | |
286 | else if (pz < 0 ) { | |
287 | tZ = (-1)*(fRnrMod->fMaxZ + fV.z)/pz; | |
288 | } | |
289 | // time where particle intersects cylinder | |
290 | Float_t tR=0; | |
291 | Double_t a = px*px + py*py; | |
292 | Double_t b = 2*(fV.x*px + fV.y*py); | |
293 | Double_t c = fV.x*fV.x + fV.y*fV.y - fRnrMod->fMaxR*fRnrMod->fMaxR; | |
294 | Double_t D = b*b - 4*a*c; | |
295 | if(D >= 0) { | |
296 | Double_t D_sqrt=TMath::Sqrt(D); | |
297 | tR = ( -b - D_sqrt )/(2*a); | |
298 | if( tR < 0) { | |
299 | tR = ( -b + D_sqrt )/(2*a); | |
5a5a1232 | 300 | } |
301 | ||
bbfaa1c4 | 302 | // compare the two times |
303 | Tb = tR < tZ ? tR : tZ; | |
304 | } else { | |
305 | Tb = tZ; | |
5a5a1232 | 306 | } |
bbfaa1c4 | 307 | |
308 | GotoVertex(fV.x+px*Tb, fV.y+py*Tb, fV.z+ pz*Tb); | |
309 | } | |
310 | }; // struct Line | |
5a5a1232 | 311 | |
312 | ||
313 | } // namespace Reve | |
314 | ||
315 | #endif |