Change track-start marker style.
[u/mrichter/AliRoot.git] / EVE / Reve / Track.cxx
1 // $Header$
2
3 #include "Track.h"
4 #include "MCHelixLine.hi"
5 #include "PointSet.h"
6
7 #include <TPolyLine3D.h>
8 #include <TPolyMarker3D.h>
9 #include <TColor.h>
10
11 // Updates
12 #include <Reve/RGTopFrame.h>
13 #include <TCanvas.h>
14
15 #include <vector>
16
17 using namespace Reve;
18
19 //______________________________________________________________________
20 // Track
21 //
22
23 ClassImp(Reve::Track)
24
25 Track::Track() :
26   Line(),
27
28   fV(),
29   fP(),
30   fBeta(0),
31   fCharge(0),
32   fLabel(-1),
33   fIndex(-1),
34   fPathMarks(),
35
36   fRnrStyle(0)
37 {}
38
39 Track::Track(TParticle* t, Int_t label, TrackRnrStyle* rs):
40   Line(),
41
42   fV(t->Vx(), t->Vy(), t->Vz()),
43   fP(t->Px(), t->Py(), t->Pz()),
44   fBeta(t->P()/t->Energy()),
45   fCharge(0),
46   fLabel(label),
47   fIndex(-1),
48   fPathMarks(),
49
50   fRnrStyle(rs)
51 {
52   fLineColor = fRnrStyle->GetColor();
53   fMainColorPtr = &fLineColor;
54
55   TParticlePDG* pdgp = t->GetPDG();
56   if (pdgp)
57     fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3);
58
59   SetName(t->GetName());
60 }
61
62 Track::Track(Reve::MCTrack* t, TrackRnrStyle* rs):
63   Line(),
64
65   fV(t->Vx(), t->Vy(), t->Vz()),
66   fP(t->Px(), t->Py(), t->Pz()),
67   fBeta(t->P()/t->Energy()),
68   fCharge(0),
69   fLabel(t->label),
70   fIndex(t->index),
71   fPathMarks(),
72
73   fRnrStyle(rs)
74 {
75   fLineColor = fRnrStyle->GetColor();
76   fMainColorPtr = &fLineColor;
77
78   TParticlePDG* pdgp = t->GetPDG();
79   if(pdgp == 0) {
80     t->ResetPdgCode(); pdgp = t->GetPDG();
81   }
82   fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3);
83
84   SetName(t->GetName());
85 }
86
87 Track::Track(Reve::RecTrack* t, TrackRnrStyle* rs) :
88   Line(),
89
90   fV(t->V),
91   fP(t->P),
92   fBeta(t->beta),
93   fCharge(t->sign),
94   fLabel(t->label),
95   fIndex(t->index),
96   fPathMarks(),
97
98   fRnrStyle(rs)
99 {
100   fLineColor = fRnrStyle->GetColor();
101   fMainColorPtr = &fLineColor;
102
103   SetName(t->GetName());
104 }
105
106 Track::~Track()
107 {
108   for (vpPathMark_i i=fPathMarks.begin(); i!=fPathMarks.end(); ++i)
109     delete *i;
110 }
111
112 /*
113 void Track::Reset(Int_t n_points)
114 {
115   delete [] TPolyLine3D::fP; TPolyLine3D::fP = 0;
116   fN = n_points;
117   if(fN) TPolyLine3D::fP = new Float_t [3*fN];
118   memset(TPolyLine3D::fP, 0, 3*fN*sizeof(Float_t));
119   fLastPoint = -1;
120 }
121 */
122
123  /**************************************************************************/
124
125 void Track::MakeTrack( Bool_t recurse)
126 {
127   TrackRnrStyle& RS((fRnrStyle != 0) ? *fRnrStyle : TrackRnrStyle::fgDefStyle);
128
129   Float_t px = fP.x, py = fP.y, pz = fP.z;  
130
131   MCVertex  mc_v0;
132   mc_v0.x = fV.x;
133   mc_v0.y = fV.y; 
134   mc_v0.z = fV.z; 
135   mc_v0.t = 0;
136
137   std::vector<MCVertex> track_points;
138   Bool_t decay = kFALSE;
139
140   if ((TMath::Abs(fV.z) > RS.fMaxZ) || (fV.x*fV.x + fV.y*fV.y > RS.fMaxR*RS.fMaxR)) 
141     goto make_polyline;
142   
143   if (fCharge != 0 && TMath::Abs(RS.fMagField) > 1e-5) {
144
145     // Charged particle in magnetic field
146
147     Float_t a = RS.fgkB2C * RS.fMagField * fCharge;
148    
149     MCHelix helix(fRnrStyle, &mc_v0, TMath::C()*fBeta, &track_points, a); //m->cm
150     helix.Init(TMath::Sqrt(px*px+py*py), pz);
151    
152     if(!fPathMarks.empty())
153     {
154       for(std::vector<Reve::PathMark*>::iterator i=fPathMarks.begin(); i!=fPathMarks.end(); ++i)
155       {
156         Reve::PathMark* pm = *i;
157         
158         if (RS.fFitReferences && pm->type == Reve::PathMark::Reference)
159         {
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 helix_bounds;
163
164           // printf("%s fit reference  \n", fName.Data()); 
165           helix.LoopToVertex(px, py, pz, pm->V.x, pm->V.y, pm->V.z);
166           px =  pm->P.x;
167           py =  pm->P.y;
168           pz =  pm->P.z;
169         }
170         else if(RS.fFitDaughters &&  pm->type == Reve::PathMark::Daughter)
171         {
172           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
173              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
174             goto helix_bounds;
175
176           // printf("%s fit daughter  \n", fName.Data()); 
177           helix.LoopToVertex(px, py, pz, pm->V.x, pm->V.y, pm->V.z);
178           px -=  pm->P.x;
179           py -=  pm->P.y;
180           pz -=  pm->P.z;
181         }
182         else if(RS.fFitDecay &&  pm->type == Reve::PathMark::Decay)
183         {
184           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
185              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
186             goto helix_bounds;
187           helix.LoopToVertex(px, py, pz, pm->V.x, pm->V.y, pm->V.z);
188           decay = true;
189           break;
190         }
191       }
192     }
193   helix_bounds:
194     // go to bounds
195     if(!decay || RS.fFitDecay == kFALSE){
196       helix.LoopToBounds(px,py,pz);
197       // printf("%s loop to bounds  \n",fName.Data() );
198     }
199
200   } else {
201
202     // Neutral particle or no field
203
204     MCLine line(fRnrStyle, &mc_v0, TMath::C()*fBeta, &track_points);
205    
206     if(!fPathMarks.empty()){
207       for(std::vector<Reve::PathMark*>::iterator i=fPathMarks.begin(); i!=fPathMarks.end(); ++i) {
208         Reve::PathMark* pm = *i;
209
210         if(RS.fFitDaughters &&  pm->type == Reve::PathMark::Daughter){
211           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
212              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
213             goto line_bounds;
214           line.GotoVertex(pm->V.x, pm->V.y, pm->V.z);
215           fP.x -=  pm->P.x;
216           fP.y -=  pm->P.y;
217           fP.z -=  pm->P.z;
218         }
219
220         if(RS.fFitDecay &&  pm->type == Reve::PathMark::Decay){
221           if(TMath::Abs(pm->V.z) > RS.fMaxZ 
222              || TMath::Sqrt(pm->V.x*pm->V.x + pm->V.y*pm->V.y) > RS.fMaxR )
223             goto line_bounds;
224           line.GotoVertex(pm->V.x, pm->V.y, pm->V.z);
225           decay = true;
226           break;
227         }
228       }
229     }
230
231   line_bounds:
232     if(!decay || RS.fFitDecay == kFALSE)
233       line.GotoBounds(px,py,pz);
234
235   }
236 make_polyline:
237   Reset(track_points.size());
238   for(std::vector<MCVertex>::iterator i=track_points.begin(); i!=track_points.end(); ++i)
239     SetNextPoint(i->x, i->y, i->z);
240
241   if(recurse) {
242     Track* t;
243     for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
244       t = dynamic_cast<Track*>(*i);
245       if(t)t->MakeTrack(recurse); 
246     }
247   }
248 }
249
250 /**************************************************************************/
251
252 void Track::ImportHits()
253 {
254   Reve::LoadMacro("hits_from_label.C");
255   gROOT->ProcessLine(Form("hits_from_label(%d, (Reve::RenderElement*)%p);", 
256                           fLabel, this));
257 }
258
259 void Track::ImportClusters()
260 {
261   Reve::LoadMacro("clusters_from_label.C");
262   gROOT->ProcessLine(Form("clusters_from_label(%d, (Reve::RenderElement*)%p);", 
263                           fLabel, this));
264 }
265
266 void Track::ImportClustersFromIndex()
267 {
268   static const Exc_t eH("Track::ImportClustersFromIndex ");
269
270   if (fIndex < 0)
271     throw(eH + "index not set.");
272
273   Reve::LoadMacro("clusters_from_index.C");
274   gROOT->ProcessLine(Form("clusters_from_index(%d, (Reve::RenderElement*)%p);", 
275                           fIndex, this));
276 }
277
278 /**************************************************************************/
279
280 void Track::ImportKine()
281 {
282   static const Exc_t eH("Track::ImportKine ");
283
284   if (fLabel < 0)
285     throw(eH + "label not set.");
286
287   Reve::LoadMacro("kine_tracks.C");
288   gROOT->ProcessLine(Form("kine_track(%d, kFALSE, kTRUE, (Reve::RenderElement*)%p);", 
289                           fLabel, this));
290
291 }
292
293 void Track::ImportKineWithArgs(Bool_t importMother, Bool_t importDaugters)
294 {
295   static const Exc_t eH("Track::ImportKineWithArgs ");
296
297   if (fLabel < 0)
298     throw(eH + "label not set.");
299
300   Reve::LoadMacro("kine_tracks.C");
301   gROOT->ProcessLine(Form("kine_track(%d, %d, %d, (Reve::RenderElement*)%p);", 
302                            fLabel, importMother, importDaugters, this));
303
304 }
305
306 /**************************************************************************/
307
308 void Track::PrintKineStack()
309 {
310   Reve::LoadMacro("print_kine_from_label.C");
311   gROOT->ProcessLine(Form("print_kine_from_label(%d);", fLabel));
312 }
313
314
315 void Track::PrintPathMarks()
316 {
317   static const Exc_t eH("Track::PrintPathMarks ");
318
319   if (fLabel < 0)
320     throw(eH + "label not set.");
321
322   printf("Number of path marks %d label %d\n",
323          fPathMarks.size(), fLabel);
324
325   PathMark* pm;
326   for(vpPathMark_i i=fPathMarks.begin(); i!=fPathMarks.end(); i++) 
327   {
328     pm = *i;
329     printf("Reve::PathMark: %-9s  p: %8f %8f %8f Vertex: %8e %8e %8e %g \n",
330            pm->type_name(),
331            pm->P.x,  pm->P.y, pm->P.z,
332            pm->V.x,  pm->V.y, pm->V.z,
333            pm->time);
334   }
335 }
336
337 /**************************************************************************/
338
339 void Track::CtrlClicked(Reve::Track* track)
340 {
341   Emit("CtrlClicked(Reve::Track*)", (Long_t)track);
342 }
343
344
345 /**************************************************************************/
346 /**************************************************************************/
347
348 //______________________________________________________________________
349 // TrackRnrStyle
350 //
351
352 ClassImp(Reve::TrackRnrStyle)
353
354 Float_t       TrackRnrStyle::fgDefMagField = 5;
355 const Float_t TrackRnrStyle::fgkB2C        = 0.299792458e-3;
356 TrackRnrStyle TrackRnrStyle::fgDefStyle;
357
358 TrackRnrStyle::TrackRnrStyle() :
359   TObject(),
360
361   fColor(1),
362   fWidth(1),
363   fMagField(fgDefMagField),
364
365   fMaxR  (350),
366   fMaxZ  (450),
367
368   fMaxOrbs (0.5),
369   fMinAng  (45),
370   fDelta   (0.1),
371
372   fMinPt   (0.1),
373   fMaxPt   (10),
374
375   fFitDaughters  (kTRUE),
376   fFitReferences (kTRUE),
377   fFitDecay      (kTRUE),
378
379   fRnrDaughters  (kTRUE),
380   fRnrReferences (kTRUE),
381   fRnrDecay      (kTRUE)
382 {}
383 /**************************************************************************/
384 /**************************************************************************/
385
386 //______________________________________________________________________
387 // TrackList
388 //
389
390 ClassImp(Reve::TrackList)
391
392 void TrackList::Init()
393 {
394   fMarkerStyle = 4;
395   fMarkerColor = 4;
396   fMarkerSize  = 0.4;
397
398   if (fRnrStyle== 0) fRnrStyle = new TrackRnrStyle;
399   SetMainColorPtr(&fRnrStyle->fColor);
400 }
401
402 TrackList::TrackList(Int_t n_tracks, TrackRnrStyle* rs) :
403   RenderElement(),
404   TPolyMarker3D(n_tracks),
405
406   fTitle(),
407
408   fRnrStyle      (rs),
409   fRnrTracks     (kTRUE),
410   fEditPathMarks (kFALSE)
411 {
412   Init();
413 }
414
415 TrackList::TrackList(const Text_t* name, Int_t n_tracks, TrackRnrStyle* rs) :
416   RenderElement(),
417   TPolyMarker3D(n_tracks),
418   
419   fTitle(),
420
421   fRnrStyle   (rs),
422   fRnrTracks  (kTRUE)
423 {
424   Init();
425   SetName(name);
426 }
427
428 void TrackList::Reset(Int_t n_tracks)
429 {
430   delete [] fP; fP = 0;
431   fN = n_tracks;
432   if(fN) fP = new Float_t [3*fN];
433   memset(fP, 0, 3*fN*sizeof(Float_t));
434   fLastPoint = -1;
435 }
436
437 /**************************************************************************/
438
439 void TrackList::Paint(Option_t* option)
440 {
441   if(fRnrSelf) {
442     if(fRnrMarkers) {
443       TPolyMarker3D::Paint(option);
444     }
445     if(fRnrTracks && fRnrChildren) {
446       for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
447         if((*i)->GetRnrSelf())
448           (*i)->GetObject()->Paint(option);
449       }
450     }
451   }
452 }
453
454 /**************************************************************************/
455
456 void TrackList::AddElement(RenderElement* el)
457 {
458   static const Exc_t eH("TrackList::AddElement ");
459   if (dynamic_cast<Track*>(el)  == 0)
460     throw(eH + "new element not a Track.");
461   RenderElement::AddElement(el);
462 }
463
464 /**************************************************************************/
465
466 void TrackList::MakeTracks()
467 {
468   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
469     ((Track*)(*i))->MakeTrack();
470   }
471   gReve->Redraw3D();
472 }
473
474
475 void TrackList::MakeMarkers()
476 {
477   Reset(fChildren.size());
478   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
479     Track& t = *((Track*)(*i));
480     if(t.GetN() > 0)
481       SetNextPoint(t.fV.x, t.fV.y, t.fV.z);
482   }
483   gReve->Redraw3D();
484 }
485
486 /**************************************************************************/
487 /*************************************************************************/
488
489 void TrackList::SetWidth(Width_t w)
490 {
491   Width_t oldw = fRnrStyle->fWidth;
492   fRnrStyle->fWidth = w;
493   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
494     Track& t = *((Track*)(*i));
495     if (t.GetLineWidth() == oldw)
496       t.SetLineWidth(w);
497   }
498 }
499
500 void TrackList::SetMaxR(Float_t x)
501 {
502   fRnrStyle->fMaxR = x;
503   MakeTracks();
504   MakeMarkers();
505 }
506
507 void TrackList::SetMaxZ(Float_t x)
508 {
509   fRnrStyle->fMaxZ = x;
510   MakeTracks();
511   MakeMarkers();
512 }
513
514 void TrackList::SetMaxOrbs(Float_t x)
515 {
516   fRnrStyle->fMaxOrbs = x;
517   MakeTracks();
518 }
519
520 void TrackList::SetMinAng(Float_t x)
521 {
522   fRnrStyle->fMinAng = x;
523   MakeTracks();
524 }
525
526 void TrackList::SetDelta(Float_t x)
527 {
528   fRnrStyle->fDelta = x;
529   MakeTracks();
530 }
531
532 void TrackList::SetFitDaughters(Bool_t x)
533 {
534   fRnrStyle->fFitDaughters = x;
535   MakeTracks();
536 }
537
538 void TrackList::SetFitReferences(Bool_t x)
539 {
540   fRnrStyle->fFitReferences = x;
541   MakeTracks();
542 }
543
544 void TrackList::SetFitDecay(Bool_t x)
545 {
546   fRnrStyle->fFitDecay = x;
547   MakeTracks();
548 }
549
550 void TrackList::SetRnrDecay(Bool_t rnr)
551 {
552   fRnrStyle->fRnrDecay = rnr;
553   MakeTracks();
554 }
555
556 void TrackList::SetRnrDaughters(Bool_t rnr)
557 {
558   fRnrStyle->fRnrDaughters = rnr;
559   MakeTracks();
560 }
561
562 void TrackList::SetRnrReferences(Bool_t rnr)
563 {
564   fRnrStyle->fRnrReferences = rnr;
565   MakeTracks();
566 }
567  
568 void TrackList::SetRnrMarkers(Bool_t rnr)
569 {
570   fRnrMarkers = rnr;
571   gReve->Redraw3D();
572 }
573
574 void TrackList::SetRnrTracks(Bool_t rnr)
575 {
576
577   fRnrTracks = rnr;
578   gReve->Redraw3D();
579 }
580
581 /**************************************************************************/
582 /**************************************************************************/
583
584 void TrackList::SelectByPt(Float_t min_pt, Float_t max_pt)
585 {
586   fRnrStyle->fMinPt = min_pt;
587   fRnrStyle->fMaxPt = max_pt;
588
589   Float_t minptsq = min_pt*min_pt;
590   Float_t maxptsq = max_pt*max_pt;
591   Float_t ptsq;
592
593   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
594     ptsq = ((Track*)(*i))->fP.Perp2();
595     (*i)->SetRnrSelf(ptsq >= minptsq && ptsq <= maxptsq);
596   }
597 }
598
599 /**************************************************************************/
600
601 void TrackList::ImportHits()
602 {
603   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
604     ((Track*)(*i))->ImportHits();
605   }
606 }
607
608 void TrackList::ImportClusters()
609 {
610   for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
611     ((Track*)(*i))->ImportClusters();
612   }
613 }
614
615 /**************************************************************************/
616 /**************************************************************************/
617 /**************************************************************************/
618
619 #include "RGEditor.h"
620
621 //______________________________________________________________________
622 // TrackCounter
623 //
624
625 ClassImp(TrackCounter)
626
627 TrackCounter* TrackCounter::fgInstance = 0;
628
629 TrackCounter::TrackCounter(const Text_t* name, const Text_t* title) :
630   RenderElement(),
631   TNamed(name, title),
632
633   fBadLineStyle (6),
634   fClickAction  (CA_ToggleTrack),
635   fAllTracks    (0),
636   fGoodTracks   (0),
637   fTrackLists   ()
638 {
639   if (fgInstance == 0) fgInstance = this;
640   TQObject::Connect("Reve::Track", "CtrlClicked(Reve::Track*)",
641                     "Reve::TrackCounter", this, "DoTrackAction(Reve::Track*)");
642 }
643
644 TrackCounter::~TrackCounter()
645 {
646   TQObject::Disconnect("Reve::Track", "DoTrackAction(Reve::Track*)");
647   if (fgInstance == this) fgInstance = 0;
648 }
649
650 /**************************************************************************/
651
652 void TrackCounter::Reset()
653 {
654   printf("TrackCounter::Reset()\n");
655   fAllTracks  = 0;
656   fGoodTracks = 0;
657   TIter next(&fTrackLists);
658   TrackList* tlist;
659   while ((tlist = dynamic_cast<TrackList*>(next())))
660     tlist->RemoveParent(this);
661   fTrackLists.Clear();
662 }
663
664 void TrackCounter::RegisterTracks(TrackList* tlist, Bool_t goodTracks)
665 {
666   // printf("TrackCounter::RegisterTracks '%s', %s\n",
667   //   tlist->GetObject()->GetName(), goodTracks ? "good" : "bad");
668
669   tlist->AddParent(this);
670   fTrackLists.Add(tlist);
671
672   List_i i = tlist->BeginChildren();
673   while (i != tlist->EndChildren())
674   {
675     Track* t = dynamic_cast<Track*>(*i);
676     if (t != 0)
677     {
678       if (goodTracks)
679       {
680         ++fGoodTracks;
681       } else {
682         t->SetLineStyle(fBadLineStyle);
683       }
684       ++fAllTracks;
685     }
686     ++i;
687   }
688 }
689
690 void TrackCounter::DoTrackAction(Track* track)
691 {
692   // !!!! No check done if ok.
693   // !!!! Should also override RemoveElementLocal
694   // !!!! But then ... should also sotre local information if track is ok.
695
696   switch (fClickAction)
697   {
698
699     case CA_PrintTrackInfo:
700     {
701       printf("Track '%s'\n", track->GetObject()->GetName());
702       Vector &v = track->fV, &p = track->fP;
703       printf("  Vx=%f, Vy=%f, Vz=%f; Pt=%f, Pz=%f, phi=%f)\n",
704              v.x, v.y, v.z, p.Perp(), p.z, TMath::RadToDeg()*p.Phi());
705       printf("  <other information should be printed ... full AliESDtrack>\n");
706       break;
707     }
708
709     case CA_ToggleTrack:
710     {
711       if (track->GetLineStyle() == 1)
712       {
713         track->SetLineStyle(fBadLineStyle);
714         --fGoodTracks;
715       } else {
716         track->SetLineStyle(1);
717         ++fGoodTracks;
718       }
719       gReve->Redraw3D();
720
721       printf("TrackCounter::CountTrack All=%d, Good=%d, Bad=%d\n",
722              fAllTracks, fGoodTracks, fAllTracks-fGoodTracks);
723
724       if (gReve->GetEditor()->GetModel() == GetObject())
725         gReve->EditRenderElement(this);
726
727       break;
728     }
729
730   } // end switch fClickAction
731 }
732
733 /**************************************************************************/
734
735 void TrackCounter::OutputEventTracks(FILE* out)
736 {
737   if (out == 0)
738   {
739     out = stdout;
740     fprintf(out, "TrackCounter::FinalizeEvent()\n");
741   }
742
743   fprintf(out, "Event = %d  Ntracks = %d\n", fEventId, fGoodTracks);
744
745   TIter tlists(&fTrackLists);
746   TrackList* tlist;
747   Int_t cnt = 0;
748   while ((tlist = (TrackList*) tlists()) != 0)
749   {
750     List_i i = tlist->BeginChildren();
751     while (i != tlist->EndChildren())
752     {
753       Track* t = dynamic_cast<Track*>(*i);
754       if (t != 0 && t->GetLineStyle() == 1)
755       {
756         ++cnt;
757         fprintf(out, " %2d: chg=%+2d  pt=%8.5f  eta=%+8.5f\n",
758                cnt, t->fCharge, t->fP.Perp(), t->fP.Eta());
759       }
760       ++i;
761     }
762   }
763 }