]>
Commit | Line | Data |
---|---|---|
c5555bc0 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // $Id$ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////// | |
19 | // Class AliHelix | |
20 | // Representation and extrapolation of AliTracks in a magnetic field. | |
21 | // | |
22 | // This class is meant to provide a means to display and extrapolate | |
23 | // AliTrack objects in the presence of a constant homogeneous magnetic field. | |
24 | // | |
b847fc3d | 25 | // For track/event displays the line width, colour etc... can be set using the |
26 | // standard facilities (see TAttLine). | |
27 | // By default the linewith is set to 2 and the colour set to -1 in the constructor. | |
28 | // The latter results in an automatic colour coding according to the track charge | |
29 | // with the convention positive=red neutral=green negative=blue. | |
30 | // | |
62e01f4c | 31 | // To indicate the track starting point, the memberfunction SetMarker() |
32 | // may be used. | |
33 | // By default no marker will be displayed. | |
34 | // | |
c5555bc0 | 35 | // Examples : |
36 | // ========== | |
37 | // | |
38 | // Display and extrapolation of individual tracks | |
39 | // ---------------------------------------------- | |
40 | // Float_t vec[3]; | |
41 | // AliPosition r1; | |
42 | // Ali3Vector p; | |
43 | // AliTrack t; | |
44 | // | |
45 | // vec[0]=0; | |
46 | // vec[1]=0; | |
47 | // vec[2]=0; | |
48 | // r1.SetVector(vec,"car"); | |
49 | // | |
50 | // vec[0]=1; | |
51 | // vec[1]=0; | |
52 | // vec[2]=0.3; | |
53 | // p.SetVector(vec,"car"); | |
54 | // | |
55 | // t.Set3Momentum(p); | |
56 | // t.SetBeginPoint(r1); | |
57 | // t.SetCharge(-1); | |
58 | // t.SetMass(0.139); | |
59 | // | |
60 | // // The magnetic field vector in Tesla | |
61 | // Ali3Vector b; | |
62 | // vec[0]=0; | |
63 | // vec[1]=0; | |
64 | // vec[2]=1; | |
65 | // b.SetVector(vec,"car"); | |
66 | // | |
67 | // AliHelix* helix=new AliHelix(); | |
68 | // helix->SetB(b); | |
69 | // helix->SetTofmax(1e-7); | |
70 | // | |
71 | // TCanvas* c1=new TCanvas("c1","c1"); | |
72 | // TView* view=new TView(1); | |
73 | // view->SetRange(-1000,-1000,-1000,1000,1000,1000); | |
74 | // view->ShowAxis(); | |
75 | // | |
76 | // // Track displays | |
77 | // Double_t range[2]={0,600}; | |
78 | // helix->Display(&t,range,3); | |
79 | // t.SetCharge(-t.GetCharge()); | |
80 | // helix->Display(&t); | |
81 | // | |
82 | // // Track extrapolation | |
83 | // Double_t pars[3]={550,0.001,3}; | |
84 | // AliPosition* rext=helix->Extrapolate(&t,pars); | |
85 | // if (rext) rext->Data(); | |
86 | // ====================================================================== | |
87 | // | |
88 | // Online display of events generated via AliCollider | |
89 | // -------------------------------------------------- | |
90 | // Int_t nevents=5; // Number of events to be generated | |
91 | // Int_t jrun=1; // The run number of this batch of generated events | |
92 | // | |
93 | // cout << " ***" << endl; | |
94 | // cout << " *** AliCollider run for " << nevents << " events." << endl; | |
95 | // cout << " ***" << endl; | |
96 | // | |
97 | // AliCollider* gen=new AliCollider(); | |
98 | // | |
99 | // gen->OpenFortranFile(6,"dump.log"); | |
100 | // | |
101 | // gen->SetVertexMode(2); | |
102 | // gen->SetResolution(1e-4); | |
103 | // | |
104 | // gen->SetRunNumber(jrun); | |
105 | // gen->SetPrintFreq(1); | |
106 | // | |
107 | // gen->SetSpectatorPmin(0.01); | |
108 | // | |
109 | // Int_t zp=1; | |
110 | // Int_t ap=1; | |
111 | // Int_t zt=2; | |
112 | // Int_t at=4; | |
113 | // | |
114 | // gen->Init("fixt",zp,ap,zt,at,158); | |
115 | // | |
116 | // AliHelix* helix=new AliHelix(); | |
117 | // Float_t vec[3]={0,2,0}; | |
118 | // Ali3Vector b; | |
119 | // b.SetVector(vec,"car"); | |
120 | // helix->SetB(b); | |
121 | // | |
122 | // helix->Refresh(-1); // Refresh display after each event | |
123 | // | |
124 | // TCanvas* c1=new TCanvas("c1","c1"); | |
125 | // TView* view=new TView(1); | |
126 | // view->SetRange(-200,-200,-200,200,200,200); | |
127 | // view->ShowAxis(); | |
128 | // | |
129 | // // Prepare random number sequence for this run | |
130 | // // to obtain the number of participants for each event | |
131 | // AliRandom rndm(abs(jrun)); | |
132 | // Float_t* rans=new Float_t[nevents]; | |
133 | // rndm.Uniform(rans,nevents,2,ap+at); | |
134 | // Int_t npart=0; | |
135 | // Int_t ntk=0; | |
136 | // for (Int_t i=0; i<nevents; i++) | |
137 | // { | |
138 | // npart=rans[i]; | |
139 | // gen->MakeEvent(npart); | |
140 | // AliEvent* evt=gen->GetEvent(); | |
141 | // if (evt) | |
142 | // { | |
143 | // helix->Display(evt); | |
144 | // c1->Update(); | |
145 | // gSystem->Sleep(5000); // Some delay to keep the display on screen | |
146 | // } | |
147 | // } | |
148 | // ====================================================================== | |
149 | // | |
150 | //--- Author: Nick van Eijndhoven 17-jun-2004 Utrecht University | |
151 | //- Modified: NvE $Date$ Utrecht University | |
152 | /////////////////////////////////////////////////////////////////////////// | |
153 | ||
b09247a2 | 154 | #include <cstdlib> |
c5555bc0 | 155 | #include "Riostream.h" |
695e17b3 | 156 | #include "TPolyMarker3D.h" |
157 | #include "AliPosition.h" | |
158 | #include "AliTrack.h" | |
159 | #include "AliEvent.h" | |
160 | #include "AliHelix.h" | |
c5555bc0 | 161 | |
162 | ClassImp(AliHelix) // Class implementation to enable ROOT I/O | |
163 | ||
164 | AliHelix::AliHelix() : THelix() | |
165 | { | |
166 | // Default constructor | |
167 | fRefresh=0; | |
168 | fCurves=0; | |
169 | fExt=0; | |
170 | fTofmax=1e-8; | |
62e01f4c | 171 | fMstyle=-1; |
172 | fMsize=0; | |
173 | fMcol=0; | |
174 | fEnduse=1; | |
b847fc3d | 175 | |
176 | fLineWidth=2; | |
177 | fLineColor=-1; | |
c5555bc0 | 178 | } |
179 | /////////////////////////////////////////////////////////////////////////// | |
695e17b3 | 180 | // AliHelix::~AliHelix() |
181 | // { | |
182 | // // Destructor to delete dynamically allocated memory. | |
183 | // if (fCurves) | |
184 | // { | |
185 | // delete fCurves; | |
186 | // fCurves=0; | |
187 | // } | |
188 | // if (fExt) | |
189 | // { | |
190 | // delete fExt; | |
191 | // fExt=0; | |
192 | // } | |
193 | // } | |
c5555bc0 | 194 | /////////////////////////////////////////////////////////////////////////// |
195 | AliHelix::AliHelix(const AliHelix& h) : THelix(h) | |
196 | { | |
197 | // Copy constructor | |
198 | fB=h.fB; | |
199 | fRefresh=h.fRefresh; | |
aa8231b0 | 200 | fTofmax=h.fTofmax; |
201 | fMstyle=h.fMstyle; | |
202 | fMsize=h.fMsize; | |
203 | fMcol=h.fMcol; | |
204 | fEnduse=h.fEnduse; | |
c5555bc0 | 205 | } |
206 | /////////////////////////////////////////////////////////////////////////// | |
207 | void AliHelix::SetB(Ali3Vector& b) | |
208 | { | |
209 | // Set the magnetic field vector in Tesla. | |
210 | fB=b; | |
211 | ||
212 | if (fB.GetNorm()>0) | |
213 | { | |
214 | Double_t axis[3]; | |
215 | fB.GetVector(axis,"car"); | |
216 | SetAxis(axis); | |
217 | } | |
218 | } | |
219 | /////////////////////////////////////////////////////////////////////////// | |
220 | Ali3Vector& AliHelix::GetB() | |
221 | { | |
222 | // Provide the magnetic field vector in Tesla. | |
223 | return fB; | |
224 | } | |
225 | /////////////////////////////////////////////////////////////////////////// | |
226 | void AliHelix::SetTofmax(Float_t tof) | |
227 | { | |
228 | // Set the maximum time of flight for straight tracks in seconds. | |
229 | // This maximum tof will be used for drawing etc... in case no begin | |
230 | // and endpoints can be determined from the track info. | |
231 | // Notes : | |
232 | // ------- | |
233 | // 1) In case the user specifies an explicit range, it will override | |
234 | // the maximum tof limit. | |
235 | // 2) By default the tofmax is set to 10 ns in the AliHelix constructor. | |
236 | fTofmax=tof; | |
237 | } | |
238 | /////////////////////////////////////////////////////////////////////////// | |
239 | Float_t AliHelix::GetTofmax() const | |
240 | { | |
241 | // Provide the maximum time of flight for straight tracks in seconds. | |
242 | return fTofmax; | |
243 | } | |
244 | /////////////////////////////////////////////////////////////////////////// | |
62e01f4c | 245 | void AliHelix::SetMarker(Int_t style,Float_t size,Int_t col) |
246 | { | |
247 | // Specify the marker (style, size and colour) to indicate the starting point | |
248 | // of a track in a display. | |
249 | // In case col<0 the marker will have the same color as the track itself. | |
250 | // | |
251 | // Defaults are style=8, size=0.2 and col=-1. | |
252 | ||
253 | fMstyle=style; | |
254 | fMsize=size; | |
255 | fMcol=col; | |
256 | } | |
257 | /////////////////////////////////////////////////////////////////////////// | |
258 | void AliHelix::UseEndPoint(Int_t mode) | |
259 | { | |
260 | // Select usage of track endpoint in drawing and extrapolation. | |
261 | // This allows correct event displays even for very long tracks. | |
262 | // | |
263 | // mode = 0 : Do not use the track endpoint | |
264 | // 1 : Use the track endpoint | |
265 | // | |
266 | // The default value is mode=1 (which is also set in the constructor). | |
267 | ||
268 | if (mode==0 || mode==1) fEnduse=mode; | |
269 | } | |
270 | /////////////////////////////////////////////////////////////////////////// | |
c5555bc0 | 271 | void AliHelix::MakeCurve(AliTrack* t,Double_t* range,Int_t iaxis,Double_t scale) |
272 | { | |
273 | // Make the helix curve for the specified AliTrack. | |
274 | // Detailed information of all the helix points can be obtained via the | |
275 | // GetN() and GetP() memberfunctions of TPolyLine3D. | |
276 | // In case one wants to display or extrapolate an AliTrack it is preferable | |
277 | // to use the Display() or Extrapolate() memberfunctions. | |
278 | // It is assumed that the track charge is stored in elementary units | |
25eefd00 | 279 | // (i.e. charge=1 for a proton). |
c5555bc0 | 280 | // The input argument "scale" specifies the unit scale for the various |
281 | // locations where scale=0.01 indicates unit scales in cm etc... | |
282 | // In case scale<=0, the unit scale for locations is determined from the | |
283 | // begin, reference or endpoint of the track. If neither of these | |
25eefd00 | 284 | // positions is present, all locations are assumed to be given in meter. |
c5555bc0 | 285 | // The lower and upper bounds for the range are specified by range[0] and |
286 | // range[1] and the argument "iaxis" indicates along which axis this range | |
287 | // is specified. | |
288 | // The range can be specified either in the LAB frame or in the Helix frame. | |
289 | // The latter is the frame in which the Z axis points in the B direction. | |
290 | // | |
291 | // The conventions for the "iaxis" argument are the following : | |
292 | // iaxis = 1 ==> X axis in the LAB frame | |
293 | // 2 ==> Y axis in the LAB frame | |
294 | // 3 ==> Z axis in the LAB frame | |
295 | // -1 ==> X axis in the Helix frame | |
296 | // -2 ==> Y axis in the Helix frame | |
297 | // -3 ==> Z axis in the Helix frame | |
298 | // | |
299 | // In case range=0 the begin/end/reference points of the AliTrack and the | |
300 | // maximum time of flight (see the SetTofmax() memberfunction) will be used | |
301 | // and an appropriate choice for the iaxis parameter will be made automatically | |
302 | // based on the track kinematics. | |
303 | // In case the reference point is not present, the begin or endpoint will be used | |
304 | // as reference point for the 3-momentum specification. If neither of these positions | |
305 | // is present, (0,0,0) will be taken as the reference point. | |
306 | // | |
307 | // The default values are range=0, iaxis=3 and scale=-1. | |
308 | ||
309 | SetPolyLine(0); // Reset the polyline data points | |
310 | ||
311 | if (!t || (range && !iaxis)) return; | |
312 | ||
25eefd00 | 313 | Double_t energy=t->GetEnergy(1); // Track energy in GeV |
c5555bc0 | 314 | Double_t betanorm=t->GetBeta(); |
315 | ||
316 | if (energy<=0 || betanorm<=0) return; | |
317 | ||
318 | AliPosition* rbeg=t->GetBeginPoint(); | |
62e01f4c | 319 | AliPosition* rend=0; |
320 | if (fEnduse) rend=t->GetEndPoint(); | |
c5555bc0 | 321 | AliPosition* rref=t->GetReferencePoint(); |
322 | ||
323 | // Magnetic field vector or default Z-direction | |
324 | Double_t bvec[3]={0,0,1}; | |
325 | if (fB.GetNorm()>0) fB.GetVector(bvec,"car"); | |
326 | ||
327 | // The unit scale for locations if not specified by the user | |
328 | if (scale<=0) | |
329 | { | |
25eefd00 | 330 | scale=1; // Set default to meter |
c5555bc0 | 331 | if (rbeg) |
332 | { | |
333 | scale=rbeg->GetUnitScale(); | |
334 | } | |
335 | else if (rend) | |
336 | { | |
337 | scale=rend->GetUnitScale(); | |
338 | } | |
339 | else if (rref) | |
340 | { | |
341 | scale=rref->GetUnitScale(); | |
342 | } | |
343 | } | |
344 | ||
345 | Double_t c=2.99792458e8/scale; // Lightspeed in the selected unit scale | |
346 | ||
347 | // The helix angular frequency | |
348 | Double_t w=9e7*(t->GetCharge()*fB.GetNorm())/energy; | |
349 | ||
350 | // The particle velocity in the LAB frame | |
351 | Ali3Vector beta=t->GetBetaVector(); | |
352 | Ali3Vector v=beta*c; | |
353 | Double_t vel[3]; | |
354 | v.GetVector(vel,"car"); | |
355 | ||
356 | // The particle velocity in the Helix frame | |
357 | Ali3Vector betaprim=beta.GetPrimed(fRotMat); | |
358 | v=v.GetPrimed(fRotMat); | |
359 | Double_t velprim[3]; | |
360 | v.GetVector(velprim,"car"); | |
361 | ||
362 | // Check compatibility of velocity and range specification. | |
363 | if (range) | |
364 | { | |
365 | Double_t betavec[3]; | |
366 | if (iaxis>0) beta.GetVector(betavec,"car"); | |
367 | if (iaxis<0) betaprim.GetVector(betavec,"car"); | |
7a086578 | 368 | if (fabs(betavec[abs(iaxis)-1])/betanorm<1e-10) return; |
c5555bc0 | 369 | } |
370 | ||
371 | // The LAB location in which the velocity of the particle is defined | |
372 | Double_t loc[3]={0,0,0}; | |
25eefd00 | 373 | Ali3Vector rx; |
374 | Double_t scalex=-1; | |
c5555bc0 | 375 | if (rref) |
376 | { | |
25eefd00 | 377 | rx=(Ali3Vector)(*rref); |
c5555bc0 | 378 | scalex=rref->GetUnitScale(); |
379 | } | |
380 | else if (rbeg) | |
381 | { | |
25eefd00 | 382 | rx=(Ali3Vector)(*rbeg); |
c5555bc0 | 383 | scalex=rbeg->GetUnitScale(); |
384 | } | |
385 | else if (rend) | |
386 | { | |
25eefd00 | 387 | rx=(Ali3Vector)(*rend); |
c5555bc0 | 388 | scalex=rend->GetUnitScale(); |
389 | } | |
390 | ||
25eefd00 | 391 | if (scalex>0 && (scalex/scale>1.1 || scale/scalex>1.1)) rx*=scalex/scale; |
392 | rx.GetVector(loc,"car"); | |
c5555bc0 | 393 | |
394 | // Initialisation of Helix kinematics | |
395 | SetHelix(loc,vel,w,0,kUnchanged,bvec); | |
396 | ||
397 | Int_t bend=0; | |
7a086578 | 398 | if (fabs(w)>0 && fabs(fVt)>0) bend=1; |
c5555bc0 | 399 | |
400 | // Flight time boundaries. | |
401 | // The time origin t=0 is chosen to indicate the position in which | |
402 | // the particle velocity was defined. | |
403 | // The total flight time is initialised to the (user specified) tofmax. | |
404 | Double_t tmin=0,tmax=0; | |
405 | Double_t tof=fTofmax; | |
406 | Double_t dum=0; | |
407 | ||
408 | // The trajectory begin and end points | |
409 | Double_t vec1[3]={0,0,0}; | |
410 | Double_t vec2[3]={0,0,0}; | |
411 | Ali3Vector r1; | |
412 | Ali3Vector r2; | |
25eefd00 | 413 | Double_t scale1=1; |
414 | Double_t scale2=1; | |
c5555bc0 | 415 | |
416 | if (!bend) | |
417 | { | |
418 | //////////////////////////////////////// | |
419 | // Treatment of straight trajectories // | |
420 | //////////////////////////////////////// | |
421 | Ali3Vector r; | |
422 | if (range) // Specified range allows for exact flight time boundaries | |
423 | { | |
424 | if (iaxis>0) | |
425 | { | |
426 | tmin=(range[0]-loc[iaxis-1])/vel[iaxis-1]; | |
427 | tmax=(range[1]-loc[iaxis-1])/vel[iaxis-1]; | |
428 | } | |
429 | else | |
430 | { | |
431 | loc[0]=fX0; | |
432 | loc[1]=fY0; | |
433 | loc[2]=fZ0; | |
7a086578 | 434 | tmin=(range[0]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1]; |
435 | tmax=(range[1]-loc[abs(iaxis)-1])/velprim[abs(iaxis)-1]; | |
c5555bc0 | 436 | } |
437 | if (tmax<tmin) | |
438 | { | |
439 | dum=tmin; | |
440 | tmin=tmax; | |
441 | tmax=dum; | |
442 | } | |
443 | // Make the 'curve' in the LAB frame and exit. | |
444 | // Use the parametrisation : r(t)=r0+t*v | |
445 | // using the range based flight time boundaries. | |
446 | // An additional point in the middle of the trajectory is | |
447 | // generated in view of accuracy in the case of extrapolations. | |
448 | tof=tmax-tmin; | |
449 | v=beta*c; | |
25eefd00 | 450 | r1=rx; |
c5555bc0 | 451 | r=v*tmin; |
452 | r1=r1+r; | |
453 | r1.GetVector(vec1,"car"); | |
454 | SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2])); | |
455 | r=v*(tof/2.); | |
456 | r2=r1+r; | |
457 | r2.GetVector(vec2,"car"); | |
458 | SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2])); | |
459 | r=v*tof; | |
460 | r2=r1+r; | |
461 | r2.GetVector(vec2,"car"); | |
462 | SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2])); | |
463 | } | |
464 | else // Automatic range determination | |
465 | { | |
466 | // Initially the point with Z=0 in the Helix frame is taken as a starting point. | |
467 | // In case this point can't be reached, the point in which the particle velocity | |
468 | // was defined is taken as the starting point. | |
469 | // The endpoint is initially obtained by applying the tofmax from the start point. | |
470 | tmin=0; | |
7a086578 | 471 | if (fabs(fVz)>0) tmin=-fZ0/fVz; |
c5555bc0 | 472 | v=beta*c; |
25eefd00 | 473 | r1=rx; |
c5555bc0 | 474 | r=v*tmin; |
475 | r1=r1+r; | |
476 | ||
477 | // Override the initial begin and endpoint settings by the track data | |
478 | if (rbeg) | |
479 | { | |
480 | r1=(Ali3Vector)(*rbeg); | |
481 | scale1=rbeg->GetUnitScale(); | |
482 | // All coordinates in the selected unit scale | |
483 | if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale; | |
484 | } | |
485 | ||
486 | r=v*fTofmax; | |
487 | r2=r1+r; | |
488 | if (rend) | |
489 | { | |
490 | r2=(Ali3Vector)(*rend); | |
491 | scale2=rend->GetUnitScale(); | |
492 | // All coordinates in the selected unit scale | |
493 | if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale; | |
494 | } | |
495 | ||
496 | r1.GetVector(vec1,"car"); | |
497 | r2.GetVector(vec2,"car"); | |
498 | ||
499 | // Make the 'curve' in the LAB frame and exit. | |
500 | SetNextPoint(float(vec1[0]),float(vec1[1]),float(vec1[2])); | |
501 | SetNextPoint(float(vec2[0]),float(vec2[1]),float(vec2[2])); | |
502 | } | |
503 | } | |
504 | else | |
505 | { | |
506 | ////////////////////////////////////// | |
507 | // Treatment of curved trajectories // | |
508 | ////////////////////////////////////// | |
509 | ||
510 | // Initialisation of the flight time boundaries. | |
511 | // Based on the constant motion of the particle along the Helix Z-axis, | |
512 | // the parametrisation z(t)=z0+fVz*t in the Helix frame is used. | |
513 | // If possible the point with Z=0 in the Helix frame is taken as a starting point. | |
514 | // In case this point can't be reached, the point in which the particle velocity | |
515 | // was defined is taken as the starting point. | |
516 | tmin=0; | |
7a086578 | 517 | if (fabs(fVz)>0) tmin=-fZ0/fVz; |
c5555bc0 | 518 | tmax=tmin+fTofmax; |
519 | ||
520 | if (tmax<tmin) | |
521 | { | |
522 | dum=tmin; | |
523 | tmin=tmax; | |
524 | tmax=dum; | |
525 | } | |
526 | ||
527 | // Determination of the range in the helix frame | |
528 | ||
529 | if (!range) // Automatic range determination | |
530 | { | |
25eefd00 | 531 | scale1=1; |
532 | scale2=1; | |
c5555bc0 | 533 | if (rbeg) |
534 | { | |
535 | r1=rbeg->GetPrimed(fRotMat); | |
536 | scale1=rbeg->GetUnitScale(); | |
537 | // All coordinates in the selected unit scale | |
538 | if (scale1/scale>1.1 || scale/scale1>1.1) r1*=scale1/scale; | |
539 | // Re-calculate the tmin for this new starting point | |
540 | r1.GetVector(vec1,"car"); | |
7a086578 | 541 | if (fabs(fVz)>0) tmin=(vec1[2]-fZ0)/fVz; |
c5555bc0 | 542 | tmax=tmin+fTofmax; |
543 | } | |
544 | if (rend) | |
545 | { | |
546 | r2=rend->GetPrimed(fRotMat); | |
547 | scale2=rend->GetUnitScale(); | |
548 | // All coordinates in the selected unit scale | |
549 | if (scale2/scale>1.1 || scale/scale2>1.1) r2*=scale2/scale; | |
550 | r2.GetVector(vec2,"car"); | |
7a086578 | 551 | if (fabs(fVz)>0) tmax=(vec2[2]-fZ0)/fVz; |
c5555bc0 | 552 | } |
553 | // Make the curve on basis of the flight time boundaries and exit | |
554 | if (tmax<tmin) | |
555 | { | |
556 | dum=tmin; | |
557 | tmin=tmax; | |
558 | tmax=dum; | |
559 | } | |
560 | SetRange(tmin,tmax,kHelixT); | |
561 | } | |
562 | else // User explicitly specified range | |
563 | { | |
7a086578 | 564 | vec1[abs(iaxis)-1]=range[0]; |
565 | vec2[abs(iaxis)-1]=range[1]; | |
c5555bc0 | 566 | r1.SetVector(vec1,"car"); |
567 | r2.SetVector(vec2,"car"); | |
568 | if (iaxis>0) // Range specified in LAB frame | |
569 | { | |
570 | r1=r1.GetPrimed(fRotMat); | |
571 | r1.GetVector(vec1,"car"); | |
572 | r2=r2.GetPrimed(fRotMat); | |
573 | r2.GetVector(vec2,"car"); | |
574 | } | |
575 | // Determination of the axis component with the | |
576 | // largest range difference | |
577 | Double_t dmax=0; | |
578 | Int_t imax=0; | |
579 | Double_t test=0; | |
580 | for (Int_t i=0; i<3; i++) | |
581 | { | |
7a086578 | 582 | test=fabs(vec1[i]-vec2[i]); |
c5555bc0 | 583 | if (test>dmax) |
584 | { | |
585 | dmax=test; | |
586 | imax=i; | |
587 | } | |
588 | } | |
589 | ||
590 | Double_t rmin=vec1[imax]; | |
591 | Double_t rmax=vec2[imax]; | |
592 | if (rmax<rmin) | |
593 | { | |
594 | dum=rmin; | |
595 | rmin=rmax; | |
596 | rmax=dum; | |
597 | } | |
598 | ||
599 | // The kinematic range boundaries in the helix frame | |
600 | Double_t xmin=fX0-fVt/fW; | |
601 | Double_t xmax=fX0+fVt/fW; | |
602 | Double_t ymin=fY0-fVt/fW; | |
603 | Double_t ymax=fY0+fVt/fW; | |
604 | ||
605 | if (xmax<xmin) | |
606 | { | |
607 | dum=xmin; | |
608 | xmin=xmax; | |
609 | xmax=dum; | |
610 | } | |
611 | if (ymax<ymin) | |
612 | { | |
613 | dum=ymin; | |
614 | ymin=ymax; | |
615 | ymax=dum; | |
616 | } | |
617 | ||
618 | // Set the range for the helix | |
619 | if (imax==2 && dmax>0) SetRange(rmin,rmax,kHelixZ); | |
620 | if (imax==1) | |
621 | { | |
622 | // Limit range to kinematic boundaries if needed | |
623 | if (rmin<=ymin) rmin=ymin+1e-6*dmax; | |
624 | if (rmax>=ymax) rmax=ymax-1e-6*dmax; | |
625 | if (rmin<rmax) SetRange(rmin,rmax,kHelixY); | |
626 | } | |
627 | if (imax==0) | |
628 | { | |
629 | // Limit range to kinematic boundaries if needed | |
630 | if (rmin<=xmin) rmin=xmin+1e-6*dmax; | |
631 | if (rmax>=xmax) rmax=xmax-1e-6*dmax; | |
632 | if (rmin<rmax) SetRange(rmin,rmax,kHelixX); | |
633 | } | |
634 | } | |
635 | } | |
636 | return; | |
637 | } | |
638 | /////////////////////////////////////////////////////////////////////////// | |
639 | void AliHelix::Display(AliTrack* t,Double_t* range,Int_t iaxis,Double_t scale) | |
640 | { | |
641 | // Display the helix curve of an AliTrack. | |
642 | // Various curves can be displayed together or individually; please refer to | |
643 | // the memberfunction Refresh() for further details. | |
644 | // It is assumed that the track charge is stored in elementary units | |
25eefd00 | 645 | // (i.e. charge=1 for a proton). |
c5555bc0 | 646 | // The input argument "scale" specifies the unit scale for the various |
647 | // locations where scale=0.01 indicates unit scales in cm etc... | |
648 | // In case scale<=0, the unit scale for locations is determined from the | |
649 | // begin, reference or endpoint of the track. If neither of these | |
25eefd00 | 650 | // positions is present, all locations are assumed to be given in meter. |
c5555bc0 | 651 | // The lower and upper bounds for the range are specified by range[0] and |
652 | // range[1] and the argument "iaxis" indicates along which axis this range | |
653 | // is specified. | |
654 | // The range can be specified either in the LAB frame or in the Helix frame. | |
655 | // The latter is the frame in which the Z axis points in the B direction. | |
656 | // | |
657 | // The conventions for the "iaxis" argument are the following : | |
658 | // iaxis = 1 ==> X axis in the LAB frame | |
659 | // 2 ==> Y axis in the LAB frame | |
660 | // 3 ==> Z axis in the LAB frame | |
661 | // -1 ==> X axis in the Helix frame | |
662 | // -2 ==> Y axis in the Helix frame | |
663 | // -3 ==> Z axis in the Helix frame | |
664 | // | |
665 | // In case range=0 the begin/end/reference points of the AliTrack and the | |
666 | // maximum time of flight (see the SetTofmax() memberfunction) will be used | |
667 | // and an appropriate choice for the iaxis parameter will be made automatically | |
668 | // based on the track kinematics. | |
669 | // In case the reference point is not present, the begin or endpoint will be used | |
670 | // as reference point for the 3-momentum specification. If neither of these positions | |
671 | // is present, (0,0,0) will be taken as the reference point. | |
672 | // | |
673 | // The default values are range=0, iaxis=3 and scale=-1. | |
674 | // | |
675 | // Note : | |
676 | // ------ | |
677 | // Before any display activity, a TCanvas and a TView have to be initiated | |
678 | // first by the user like for instance | |
679 | // | |
680 | // TCanvas* c1=new TCanvas("c1","c1"); | |
681 | // TView* view=new TView(1); | |
682 | // view->SetRange(-1000,-1000,-1000,1000,1000,1000); | |
683 | // view->ShowAxis(); | |
25eefd00 | 684 | // |
685 | // The user can also use the 3D viewing facilities from the TCanvas menu | |
686 | // to open an appropriate view. | |
c5555bc0 | 687 | |
688 | if (!t || (range && !iaxis)) return; | |
689 | ||
690 | MakeCurve(t,range,iaxis,scale); | |
691 | ||
692 | if (fRefresh>0) Refresh(fRefresh); | |
693 | ||
25eefd00 | 694 | Int_t np=GetLastPoint()+1; |
c5555bc0 | 695 | if (!np) return; |
696 | ||
697 | Float_t* points=GetP(); | |
698 | TPolyLine3D* curve=new TPolyLine3D(np,points); | |
699 | ||
b847fc3d | 700 | curve->SetLineWidth(fLineWidth); |
701 | if (fLineColor<0) | |
702 | { | |
703 | Float_t q=t->GetCharge(); | |
704 | curve->SetLineColor(kGreen); | |
705 | if (q>0) curve->SetLineColor(kRed); | |
706 | if (q<0) curve->SetLineColor(kBlue); | |
707 | } | |
708 | else | |
709 | { | |
710 | curve->SetLineColor(fLineColor); | |
711 | } | |
c5555bc0 | 712 | curve->Draw(); |
713 | ||
714 | if (!fCurves) | |
715 | { | |
716 | fCurves=new TObjArray(); | |
717 | fCurves->SetOwner(); | |
718 | } | |
719 | fCurves->Add(curve); | |
62e01f4c | 720 | |
721 | // Display the marker for the track starting point | |
722 | if (fMstyle>0) | |
723 | { | |
724 | TPolyMarker3D* m=new TPolyMarker3D(); | |
725 | m->SetPoint(0,points[0],points[1],points[2]); | |
726 | m->SetMarkerStyle(fMstyle); | |
727 | m->SetMarkerSize(fMsize); | |
728 | Int_t col=curve->GetLineColor(); | |
729 | if (fMcol>0) col=fMcol; | |
730 | m->SetMarkerColor(col); | |
731 | m->Draw(); | |
732 | fCurves->Add(m); | |
733 | } | |
c5555bc0 | 734 | } |
735 | /////////////////////////////////////////////////////////////////////////// | |
736 | void AliHelix::Refresh(Int_t mode) | |
737 | { | |
738 | // Refresh the display screen before showing the next curve. | |
739 | // | |
740 | // mode = 0 : refreshing fully under user control. | |
741 | // 1 : the display screen will be refreshed automatically | |
742 | // at each individual track display. | |
743 | // -1 : the display screen will be refreshed automatically | |
744 | // at each event display. | |
745 | // | |
746 | // The default is mode=0. | |
747 | ||
7a086578 | 748 | if (abs(mode)<2) fRefresh=mode; |
c5555bc0 | 749 | if (fCurves) fCurves->Delete(); |
750 | } | |
751 | /////////////////////////////////////////////////////////////////////////// | |
752 | void AliHelix::Display(AliEvent* evt,Double_t* range,Int_t iaxis,Double_t scale) | |
753 | { | |
754 | // Display the helix curves of all tracks of the specified event. | |
755 | // Various events can be displayed together or individually; please refer to | |
756 | // the memberfunction Refresh() for further details. | |
757 | // Please refer to the track display memberfunction for further details | |
758 | // on the input arguments. | |
759 | // | |
760 | // The default values are range=0, iaxis=3 and scale=-1. | |
761 | // | |
762 | // Note : | |
763 | // ------ | |
764 | // Before any display activity, a TCanvas and a TView have to be initiated | |
765 | // first by the user like for instance | |
766 | // | |
767 | // TCanvas* c1=new TCanvas("c1","c1"); | |
768 | // TView* view=new TView(1); | |
769 | // view->SetRange(-1000,-1000,-1000,1000,1000,1000); | |
770 | // view->ShowAxis(); | |
25eefd00 | 771 | // |
772 | // The user can also use the 3D viewing facilities from the TCanvas menu | |
773 | // to open an appropriate view. | |
c5555bc0 | 774 | |
775 | if (!evt) return; | |
776 | ||
777 | if (fRefresh<0) Refresh(fRefresh); | |
778 | ||
779 | Int_t ntk=evt->GetNtracks(); | |
780 | for (Int_t jtk=1; jtk<=ntk; jtk++) | |
781 | { | |
782 | AliTrack* tx=evt->GetTrack(jtk); | |
783 | if (tx) Display(tx,range,iaxis,scale); | |
784 | } | |
785 | } | |
786 | /////////////////////////////////////////////////////////////////////////// | |
aa8231b0 | 787 | void AliHelix::Display(TObjArray* arr,Double_t* range,Int_t iaxis,Double_t scale) |
788 | { | |
789 | // Display the helix curves of all tracks in the specified array. | |
790 | // A convenient way to obtain an array with selected tracks from e.g. an AliEvent | |
791 | // is to make use of its GetTracks() selection facility. | |
792 | // Various arrays can be displayed together or individually; please refer to | |
793 | // the memberfunction Refresh() for further details. | |
794 | // Please refer to the track display memberfunction for further details | |
795 | // on the input arguments. | |
796 | // | |
797 | // The default values are range=0, iaxis=3 and scale=-1. | |
798 | // | |
799 | // Note : | |
800 | // ------ | |
801 | // Before any display activity, a TCanvas and a TView have to be initiated | |
802 | // first by the user like for instance | |
803 | // | |
804 | // TCanvas* c1=new TCanvas("c1","c1"); | |
805 | // TView* view=new TView(1); | |
806 | // view->SetRange(-1000,-1000,-1000,1000,1000,1000); | |
807 | // view->ShowAxis(); | |
25eefd00 | 808 | // |
809 | // The user can also use the 3D viewing facilities from the TCanvas menu | |
810 | // to open an appropriate view. | |
aa8231b0 | 811 | |
812 | if (!arr) return; | |
813 | ||
814 | Int_t ntk=arr->GetEntries(); | |
815 | for (Int_t jtk=0; jtk<ntk; jtk++) | |
816 | { | |
817 | TObject* obj=arr->At(jtk); | |
818 | if (!obj) continue; | |
819 | if (!(obj->InheritsFrom("AliTrack"))) continue; | |
820 | AliTrack* tx=(AliTrack*)obj; | |
821 | Display(tx,range,iaxis,scale); | |
822 | } | |
823 | } | |
824 | /////////////////////////////////////////////////////////////////////////// | |
c5555bc0 | 825 | AliPosition* AliHelix::Extrapolate(AliTrack* t,Double_t* pars,Double_t scale) |
826 | { | |
827 | // Extrapolate an AliTrack according to the corresponding helix curve | |
828 | // and provide a pointer to the impact position w.r.t. a specified plane. | |
829 | // In case the track can never reach the specified plane, the returned | |
830 | // position pointer is zero. | |
831 | // Detailed information of all the helix points used in the extrapolation | |
832 | // can be obtained via the GetN() and GetP() memberfunctions of TPolyLine3D. | |
833 | // It is assumed that the track charge is stored in elementary units | |
25eefd00 | 834 | // (i.e. charge=1 for a proton). |
c5555bc0 | 835 | // The input argument "scale" specifies the unit scale for the various |
836 | // locations where scale=0.01 indicates unit scales in cm etc... | |
837 | // In case scale<=0, the unit scale for locations is determined from the | |
838 | // begin, reference or endpoint of the track. If neither of these | |
25eefd00 | 839 | // positions is present, all locations are assumed to be given in meter. |
c5555bc0 | 840 | // The extrapolation parameters for the impact plane and required accuracy |
841 | // are specified by pars[0], pars[1] and pars[2], respectively. | |
842 | // pars[0] = coordinate value of the plane for the impact point | |
843 | // pars[1] = required accuracy on the specified impact plane coordinate | |
844 | // pars[2] = the axis along which the value of par[0] is specified | |
845 | // | |
846 | // The parameters can be specified either w.r.t. the LAB frame or the Helix frame. | |
847 | // The latter is the frame in which the Z axis points in the B direction. | |
848 | // | |
849 | // The conventions for the par[2] argument are the following : | |
850 | // par[2] = 1 ==> X axis in the LAB frame | |
851 | // 2 ==> Y axis in the LAB frame | |
852 | // 3 ==> Z axis in the LAB frame | |
853 | // -1 ==> X axis in the Helix frame | |
854 | // -2 ==> Y axis in the Helix frame | |
855 | // -3 ==> Z axis in the Helix frame | |
856 | // | |
857 | // Example : | |
858 | // --------- | |
859 | // To obtain an extrapolation to the plane Z=0 in the LAB frame | |
860 | // with an accuracy of 0.001 cm the input arguments would be | |
861 | // pars[0]=0 pars[1]=0.001 pars[2]=3 scale=0.01 | |
862 | // | |
863 | // Note : The default value for the scale is -1. | |
864 | ||
865 | if (fExt) | |
866 | { | |
867 | delete fExt; | |
868 | fExt=0; | |
869 | } | |
870 | ||
871 | if (!t || !pars) return fExt; | |
872 | ||
873 | AliPosition* rbeg=t->GetBeginPoint(); | |
874 | AliPosition* rend=t->GetEndPoint(); | |
875 | AliPosition* rref=t->GetReferencePoint(); | |
876 | ||
877 | // The unit scale for locations if not specified by the user | |
878 | if (scale<=0) | |
879 | { | |
25eefd00 | 880 | scale=1; // Set default to meter |
c5555bc0 | 881 | if (rbeg) |
882 | { | |
883 | scale=rbeg->GetUnitScale(); | |
884 | } | |
885 | else if (rend) | |
886 | { | |
887 | scale=rend->GetUnitScale(); | |
888 | } | |
889 | else if (rref) | |
890 | { | |
891 | scale=rref->GetUnitScale(); | |
892 | } | |
893 | } | |
894 | ||
895 | Double_t range[2]; | |
7a086578 | 896 | range[0]=pars[0]-fabs(pars[1])/2.; |
897 | range[1]=pars[0]+fabs(pars[1])/2.; | |
c5555bc0 | 898 | |
899 | Int_t iaxis=int(pars[2]); | |
900 | ||
901 | MakeCurve(t,range,iaxis,scale); | |
902 | ||
25eefd00 | 903 | Int_t np=GetLastPoint()+1; |
c5555bc0 | 904 | if (!np) return fExt; |
905 | ||
906 | Float_t* points=GetP(); | |
907 | ||
908 | // First point of the curve around the impact | |
909 | Int_t ip=0; | |
910 | Float_t first[3]={points[3*ip],points[3*ip+1],points[3*ip+2]}; | |
911 | ||
912 | // Last point of the curve around the impact | |
25eefd00 | 913 | ip=GetLastPoint(); |
c5555bc0 | 914 | Float_t last[3]={points[3*ip],points[3*ip+1],points[3*ip+2]}; |
915 | ||
916 | // The accuracy on the impact point | |
917 | Float_t err[3]; | |
7a086578 | 918 | err[0]=fabs(first[0]-last[0]); |
919 | err[1]=fabs(first[1]-last[1]); | |
920 | err[2]=fabs(first[2]-last[2]); | |
c5555bc0 | 921 | |
922 | // Take the middle point as impact location | |
923 | ip=np/2; | |
924 | Float_t imp[3]={points[3*ip],points[3*ip+1],points[3*ip+2]}; | |
925 | ||
926 | fExt=new AliPosition(); | |
927 | fExt->SetUnitScale(scale); | |
928 | fExt->SetPosition(imp,"car"); | |
929 | fExt->SetPositionErrors(err,"car"); | |
930 | ||
931 | return fExt; | |
932 | } | |
933 | /////////////////////////////////////////////////////////////////////////// |