Draw charged tracks as straight lines when magnetic field is near zero.
[u/mrichter/AliRoot.git] / EVE / Reve / Track.cxx
1 // $Header$
2
3 #include "Track.h"
4 #include "MCHelixLine.hi"
5
6 #include <TPolyLine3D.h>
7 #include <TPolyMarker3D.h>
8 #include <TColor.h>
9
10 // Updates
11 #include <Reve/RGTopFrame.h>
12 #include <TCanvas.h>
13
14 #include <vector>
15
16 using namespace Reve;
17
18 //______________________________________________________________________
19 // Track
20 //
21
22 ClassImp(Reve::Track)
23
24 Track::Track()
25 {
26   fRnrStyle = 0;
27 }
28
29 Track::Track(Reve::MCTrack* t, TrackRnrStyle* rs)
30 {
31   fRnrStyle = rs;
32
33   fName = t->GetName();
34   fLineColor = fRnrStyle->GetColor();
35   fMainColorPtr = &fLineColor;
36
37   fV.Set(t->Vx(), t->Vy(), t->Vz());
38   fP.Set(t->Px(), t->Py(), t->Pz());
39   fBeta   = t->P()/t->Energy();
40
41   TParticlePDG* pdgp = t->GetPDG();
42   if(pdgp == 0) {
43     t->ResetPdgCode(); pdgp = t->GetPDG();
44   }
45
46   fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3);
47   fLabel  = t->label;
48 }
49
50 Track::Track(Reve::RecTrack* t, TrackRnrStyle* rs)
51 {
52   fRnrStyle = rs;
53   fName = t->GetName();
54   fLineColor = fRnrStyle->GetColor();
55   fMainColorPtr = &fLineColor;
56
57   fV = t->V;
58   fP = t->P;
59   fBeta   = t->beta;
60   fCharge = t->sign;
61   fLabel  = t->label; 
62 }
63
64 Track::~Track()
65 {}
66
67 void Track::Reset(Int_t n_points)
68 {
69   delete [] TPolyLine3D::fP; TPolyLine3D::fP = 0;
70   fN = n_points;
71   if(fN) TPolyLine3D::fP = new Float_t [3*fN];
72   memset(TPolyLine3D::fP, 0, 3*fN*sizeof(Float_t));
73   fLastPoint = -1;
74 }
75
76 /**************************************************************************/
77
78 void Track::MakeTrack()
79 {
80   
81   TrackRnrStyle& RS((fRnrStyle != 0) ? *fRnrStyle : TrackRnrStyle::fgDefStyle);
82
83   Float_t px = fP.x, py = fP.y, pz = fP.z;  
84
85   MCVertex  mc_v0;
86   mc_v0.x = fV.x;
87   mc_v0.y = fV.y; 
88   mc_v0.z = fV.z; 
89   mc_v0.t = 0;
90
91   std::vector<MCVertex> track_points;
92   Bool_t decay = kFALSE;
93
94   if ((TMath::Abs(fV.z) > RS.fMaxZ) || (fV.x*fV.x + fV.y*fV.y > RS.fMaxR*RS.fMaxR)) 
95     goto make_polyline;
96   
97   if (fCharge != 0 && TMath::Abs(RS.fMagField) > 1e-5) {
98
99     // Charged particle in magnetic field
100
101     Float_t a = RS.fgkB2C * RS.fMagField * fCharge;
102    
103     MCHelix helix(fRnrStyle, &mc_v0, TMath::C()*fBeta, &track_points, a); //m->cm
104     helix.Init(TMath::Sqrt(px*px+py*py), pz);
105    
106     if(!fPathMarks.empty()){
107       for(std::vector<Reve::PathMark*>::iterator i=fPathMarks.begin(); i!=fPathMarks.end(); ++i) {
108         Reve::PathMark* pm = *i;
109         
110         if(RS.fFitDaughters &&  pm->type == Reve::PathMark::Daughter){
111           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
112              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
113             goto helix_bounds;
114
115           //printf("%s fit daughter  \n", fName.Data()); 
116           helix.LoopToVertex(fP.x, fP.y, fP.z, pm->V.x, pm->V.y, pm->V.z);
117           fP.x -=  pm->P.x;
118           fP.y -=  pm->P.y;
119           fP.z -=  pm->P.z;
120         }
121         if(RS.fFitDecay &&  pm->type == Reve::PathMark::Decay){
122           
123           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
124              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
125             goto helix_bounds;
126           helix.LoopToVertex(fP.x, fP.y, fP.z, pm->V.x, pm->V.y, pm->V.z);
127           decay = true;
128           break;
129         }
130       }
131     }
132   helix_bounds:
133     //go to bounds
134     if(!decay || RS.fFitDecay == kFALSE){
135       helix.LoopToBounds(px,py,pz);
136       // printf("%s loop to bounds  \n",fName.Data() );
137     }
138
139   } else {
140
141     // Neutral particle or no field
142
143     MCLine line(fRnrStyle, &mc_v0, TMath::C()*fBeta, &track_points);
144    
145     if(!fPathMarks.empty()){
146       for(std::vector<Reve::PathMark*>::iterator i=fPathMarks.begin(); i!=fPathMarks.end(); ++i) {
147         Reve::PathMark* pm = *i;
148
149         if(RS.fFitDaughters &&  pm->type == Reve::PathMark::Daughter){
150           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
151              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
152             goto line_bounds;
153           line.GotoVertex(pm->V.x, pm->V.y, pm->V.z);
154           fP.x -=  pm->P.x;
155           fP.y -=  pm->P.y;
156           fP.z -=  pm->P.z;
157         }
158
159         if(RS.fFitDecay &&  pm->type == Reve::PathMark::Decay){
160           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
161              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
162             goto line_bounds;
163           line.GotoVertex(pm->V.x, pm->V.y, pm->V.z);
164           decay = true;
165           break;
166         }
167       }
168     }
169
170   line_bounds:
171     if(!decay || RS.fFitDecay == kFALSE)
172       line.GotoBounds(px,py,pz);
173
174   }
175 make_polyline:
176   Reset(track_points.size());
177   for(std::vector<MCVertex>::iterator i=track_points.begin(); i!=track_points.end(); ++i)
178     SetNextPoint(i->x, i->y, i->z);
179 }
180
181 /**************************************************************************/
182
183 void Track::ImportHits()
184 {
185   Reve::LoadMacro("hits_from_label.C");
186   gROOT->ProcessLine(Form("hits_from_label(%d);", fLabel));
187 }
188
189 void Track::ImportClusters()
190 {
191   Reve::LoadMacro("clusters_from_label.C");
192   gROOT->ProcessLine(Form("clusters_from_label(%d);", fLabel));
193 }
194
195
196 /**************************************************************************/
197 /**************************************************************************/
198
199 //______________________________________________________________________
200 // TrackRnrStyle
201 //
202
203 ClassImp(Reve::TrackRnrStyle)
204
205 Float_t       TrackRnrStyle::fgDefMagField = 5;
206 const Float_t TrackRnrStyle::fgkB2C        = 0.299792458e-3;
207 TrackRnrStyle TrackRnrStyle::fgDefStyle;
208
209 void TrackRnrStyle::Init()
210 {
211   fMagField = fgDefMagField;
212
213   fMaxR  = 350;
214   fMaxZ  = 450;
215
216   fMaxOrbs = 0.5;
217   fMinAng  = 45;
218
219   fFitDaughters = kTRUE;
220   fFitDecay     = kTRUE;
221
222   fDelta  = 0.1; //calculate step size depending on helix radius
223 }
224
225 /**************************************************************************/
226 /**************************************************************************/
227
228 //______________________________________________________________________
229 // TrackList
230 //
231
232 ClassImp(Reve::TrackList)
233
234 void TrackList::Init()
235 {
236   fMarkerStyle = 6;
237   fMarkerColor = 5;
238   // fMarker->SetMarkerSize(0.05);
239
240   fRnrMarkers = kTRUE;
241   fRnrTracks  = kTRUE;
242
243   mRnrStyle = new TrackRnrStyle;
244   SetMainColorPtr(&mRnrStyle->fColor);
245 }
246
247 TrackList::TrackList(Int_t n_tracks) :
248   TPolyMarker3D(n_tracks),
249   RenderElementListBase()
250 {
251   Init();
252 }
253
254 TrackList::TrackList(const Text_t* name, Int_t n_tracks) :
255   TPolyMarker3D(n_tracks),
256   RenderElementListBase()
257 {
258   Init();
259   SetName(name);
260 }
261
262 void TrackList::Reset(Int_t n_tracks)
263 {
264   delete [] fP; fP = 0;
265   fN = n_tracks;
266   if(fN) fP = new Float_t [3*fN];
267   memset(fP, 0, 3*fN*sizeof(Float_t));
268   fLastPoint = -1;
269 }
270
271 /**************************************************************************/
272
273 void TrackList::Paint(Option_t* option)
274 {
275   if(fRnrElement) {
276     if(fRnrMarkers) {
277       TPolyMarker3D::Paint(option);
278     }
279     if(fRnrTracks) {
280       for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
281         if((*i)->GetRnrElement())
282           (*i)->GetObject()->Paint(option);
283       }
284     }
285   }
286 }
287
288 /**************************************************************************/
289
290 void TrackList::AddElement(RenderElement* el)
291 {
292   static const Exc_t eH("TrackList::AddElement ");
293   if (dynamic_cast<Track*>(el)  == 0)
294     throw(eH + "new element not a Track.");
295   RenderElementListBase::AddElement(el);
296 }
297
298 /**************************************************************************/
299
300 void TrackList::SetRnrMarkers(Bool_t rnr)
301 {
302   fRnrMarkers = rnr;
303   gReve->Redraw3D();
304 }
305
306 void TrackList::SetRnrTracks(Bool_t rnr)
307 {
308
309   fRnrTracks = rnr;
310   gReve->Redraw3D();
311 }
312
313 /**************************************************************************/
314
315 void TrackList::MakeTracks()
316 {
317   for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
318     ((Track*)(*i))->MakeTrack();
319   }
320   gReve->Redraw3D();
321 }
322
323
324 void TrackList::MakeMarkers()
325 {
326   Reset(fList.size());
327   for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
328     Track& t = *((Track*)(*i));
329     if(t.GetN() > 0)
330       SetNextPoint(t.fV.x, t.fV.y, t.fV.z);
331   }
332   gReve->Redraw3D();
333 }
334
335 /**************************************************************************/
336 /*************************************************************************/
337
338 void TrackList::SetMaxR(Float_t x)
339 {
340   mRnrStyle->fMaxR = x;
341   MakeTracks();
342   MakeMarkers();
343 }
344
345 void TrackList::SetMaxZ(Float_t x)
346 {
347   mRnrStyle->fMaxZ = x;
348   MakeTracks();
349   MakeMarkers();
350 }
351
352 void TrackList::SetMaxOrbs(Float_t x)
353 {
354   mRnrStyle->fMaxOrbs = x;
355   MakeTracks();
356 }
357
358 void TrackList::SetMinAng(Float_t x)
359 {
360   mRnrStyle->fMinAng = x;
361   MakeTracks();
362 }
363
364 void TrackList::SetDelta(Float_t x)
365 {
366   mRnrStyle->fDelta = x;
367   MakeTracks();
368 }
369
370 void TrackList::SetFitDaughters(Bool_t x)
371 {
372   mRnrStyle->fFitDaughters = x;
373   MakeTracks();
374 }
375
376 void TrackList::SetFitDecay(Bool_t x)
377 {
378   mRnrStyle->fFitDecay = x;
379   MakeTracks();
380 }
381
382 /**************************************************************************/
383 /**************************************************************************/
384
385 void TrackList::SelectByPt(Float_t min_pt, Float_t max_pt)
386 {
387   Float_t minptsq = min_pt*min_pt;
388   Float_t maxptsq = max_pt*max_pt;
389   Float_t ptsq;
390
391   for(lpRE_i i=fList.begin(); i!=fList.end(); ++i) {
392     ptsq = ((Track*)(*i))->fP.Perp2();
393     (*i)->SetRnrElement(ptsq >= minptsq && ptsq <= maxptsq);
394   }
395 }
396
397 /**************************************************************************/
398
399 #include <TGFrame.h>
400 #include <TGDoubleSlider.h>
401 #include <TGXYLayout.h>
402
403 void TrackList::MakePtScrollbar()
404 {
405   TGMainFrame* mf = new TGMainFrame(gClient->GetRoot(), 320, 60);
406
407   TGDoubleHSlider* hs = new TGDoubleHSlider(mf);
408   hs->SetRange(0.2, 10);
409   hs->SetPosition(0.2, 10);
410   hs->Resize(300, 25);
411   mf->AddFrame(hs, new TGLayoutHints(kLHintsCenterX, 10, 10, 10, 10));
412
413   hs->Connect("PositionChanged()", "Reve::TrackList",
414               this, "HandlePtScrollEvent()");
415
416   mf->SetWindowName("Pt Selector");
417   mf->MapSubwindows();
418   mf->Resize(mf->GetDefaultSize()); // this is used here to init layout algorithm
419   mf->MapWindow();
420 }
421
422 void TrackList::HandlePtScrollEvent()
423 {
424   TGDoubleHSlider* hs = (TGDoubleHSlider*)gTQSender;
425
426   Float_t min = hs->GetMinPosition(), max = hs->GetMaxPosition();
427   printf("hslidor min=%f max=%f\n", min, max);
428   SelectByPt(min, max);
429 }