Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveTrack.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include <ROOT/REveTrack.hxx>
14 #include <ROOT/REvePointSet.hxx>
15 #include <ROOT/REveManager.hxx>
17 
18 #include "TParticle.h"
19 #include "TPolyLine3D.h"
20 #include "TMarker.h"
21 #include "TPolyMarker3D.h"
22 #include "TColor.h"
23 #include "TParticlePDG.h"
24 #include "TClass.h"
25 #include "Riostream.h"
26 
27 #include <vector>
28 #include <algorithm>
29 #include <functional>
30 
31 #include "json.hpp"
32 
33 
34 using namespace ROOT::Experimental;
35 namespace REX = ROOT::Experimental;
36 
37 /** \class REveTrack
38 \ingroup REve
39 Visual representation of a track.
40 
41 If member fDpDs is set, the momentum is reduced on all path-marks that do
42 not fix the momentum according to the distance travelled from the previous
43 pathmark.
44 */
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 /// Default constructor.
48 
49 REveTrack::REveTrack() :
50  REveLine(),
51 
52  fV(),
53  fP(),
54  fPEnd(),
55  fBeta(0),
56  fDpDs(0),
57  fPdg(0),
58  fCharge(0),
59  fLabel(kMinInt),
60  fIndex(kMinInt),
61  fStatus(0),
62  fLockPoints(kFALSE),
63  fPathMarks(),
64  fLastPMIdx(0),
65  fPropagator(nullptr)
66 {
67 }
68 
69 ////////////////////////////////////////////////////////////////////////////////
70 /// Constructor from TParticle.
71 
72 REveTrack::REveTrack(TParticle *t, Int_t label, REveTrackPropagator *prop):
73  REveLine(),
74 
75  fV(t->Vx(), t->Vy(), t->Vz()),
76  fP(t->Px(), t->Py(), t->Pz()),
77  fPEnd(),
78  fBeta(t->P()/t->Energy()),
79  fDpDs(0),
80  fPdg(0),
81  fCharge(0),
82  fLabel(label),
83  fIndex(kMinInt),
84  fStatus(t->GetStatusCode()),
85  fLockPoints(kFALSE),
86  fPathMarks(),
87  fLastPMIdx(0),
88  fPropagator(nullptr)
89 {
90  SetPropagator(prop);
91  SetMainColorPtr(&fLineColor);
92 
93  TParticlePDG *pdgp = t->GetPDG();
94  if (pdgp) {
95  fPdg = pdgp->PdgCode();
96  fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3);
97  }
98 
99  SetName(t->GetName());
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 
104 REveTrack::REveTrack(REveMCTrack* t, REveTrackPropagator* prop):
105  REveLine(),
106 
107  fV(t->Vx(), t->Vy(), t->Vz()),
108  fP(t->Px(), t->Py(), t->Pz()),
109  fPEnd(),
110  fBeta(t->P()/t->Energy()),
111  fDpDs(0),
112  fPdg(0),
113  fCharge(0),
114  fLabel(t->fLabel),
115  fIndex(t->fIndex),
116  fStatus(t->GetStatusCode()),
117  fLockPoints(kFALSE),
118  fPathMarks(),
119  fLastPMIdx(0),
120  fPropagator(0)
121 {
122  // Constructor from REveUtil Monte Carlo track.
123 
124  SetPropagator(prop);
125  fMainColorPtr = &fLineColor;
126 
127  TParticlePDG* pdgp = t->GetPDG();
128  if (pdgp) {
129  fCharge = (Int_t) TMath::Nint(pdgp->Charge()/3);
130  }
131 
132  SetName(t->GetName());
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// Constructor from REveRecTrack<double> reconstructed track.
137 
138 REveTrack::REveTrack(REveRecTrackD* t, REveTrackPropagator* prop) :
139  REveLine(),
140 
141  fV(t->fV),
142  fP(t->fP),
143  fPEnd(),
144  fBeta(t->fBeta),
145  fDpDs(0),
146  fPdg(0),
147  fCharge(t->fSign),
148  fLabel(t->fLabel),
149  fIndex(t->fIndex),
150  fStatus(t->fStatus),
151  fLockPoints(kFALSE),
152  fPathMarks(),
153  fLastPMIdx(0),
154  fPropagator(0)
155 {
156  SetPropagator(prop);
157  fMainColorPtr = &fLineColor;
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Constructor from REveRecTrack<float> reconstructed track.
162 /// It is recommended to use constructor with REveRecTrack<double> since
163 /// REveTrackPropagator operates with double type.
164 
165 REveTrack::REveTrack(REveRecTrack* t, REveTrackPropagator* prop) :
166  REveLine(),
167 
168  fV(t->fV),
169  fP(t->fP),
170  fPEnd(),
171  fBeta(t->fBeta),
172  fDpDs(0),
173  fPdg(0),
174  fCharge(t->fSign),
175  fLabel(t->fLabel),
176  fIndex(t->fIndex),
177  fStatus(t->fStatus),
178  fLockPoints(kFALSE),
179  fPathMarks(),
180  fLastPMIdx(0),
181  fPropagator(0)
182 {
183  SetPropagator(prop);
184  fMainColorPtr = &fLineColor;
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 /// Copy constructor. Track parameters are copied but the
189 /// extrapolation is not performed so you should still call
190 /// MakeTrack() to do that.
191 /// If points of 't' are locked, they are cloned.
192 
193 REveTrack::REveTrack(const REveTrack& t) :
194  REveLine(t),
195  fV(t.fV),
196  fP(t.fP),
197  fPEnd(),
198  fBeta(t.fBeta),
199  fDpDs(t.fDpDs),
200  fPdg(t.fPdg),
201  fCharge(t.fCharge),
202  fLabel(t.fLabel),
203  fIndex(t.fIndex),
204  fStatus(t.fStatus),
205  fLockPoints(t.fLockPoints),
206  fPathMarks(),
207  fLastPMIdx(t.fLastPMIdx),
208  fPropagator(nullptr)
209 {
210  if (fLockPoints)
211  ClonePoints(t);
212 
213  SetPathMarks(t);
214  SetPropagator (t.fPropagator);
215 
216  CopyVizParams(&t);
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Destructor.
221 
222 REveTrack::~REveTrack()
223 {
224  SetPropagator(nullptr);
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Compute the bounding box of the track.
229 
230 void REveTrack::ComputeBBox()
231 {
232  if (fSize > 0 || ! fPathMarks.empty())
233  {
234  BBoxInit();
235  Int_t n = fSize;
236  Float_t *p = & fPoints[0].fX;
237  for (Int_t i = 0; i < n; ++i, p += 3)
238  {
239  BBoxCheckPoint(p);
240  }
241  for (const auto &pm: fPathMarks)
242  {
243  BBoxCheckPoint(pm.fV.fX, pm.fV.fY, pm.fV.fZ);
244  }
245  }
246  else
247  {
248  BBoxZero();
249  }
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Set standard track title based on most data-member values.
254 
255 void REveTrack::SetStdTitle()
256 {
257  TString idx(fIndex == kMinInt ? "<undef>" : Form("%d", fIndex));
258  TString lbl(fLabel == kMinInt ? "<undef>" : Form("%d", fLabel));
259  SetTitle(Form("Index=%s, Label=%s\nChg=%d, Pdg=%d\n"
260  "pT=%.3f, pZ=%.3f\nV=(%.3f, %.3f, %.3f)",
261  idx.Data(), lbl.Data(), fCharge, fPdg,
262  fP.Perp(), fP.fZ, fV.fX, fV.fY, fV.fZ));
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Copy track parameters from t. Track-propagator is set, too.
267 /// PathMarks are cleared - you can copy them via SetPathMarks(t).
268 /// If track 't' is locked, you should probably clone its points
269 /// over - use REvePointSet::ClonePoints(t);
270 
271 void REveTrack::SetTrackParams(const REveTrack& t)
272 {
273  fV = t.fV;
274  fP = t.fP;
275  fBeta = t.fBeta;
276  fPdg = t.fPdg;
277  fCharge = t.fCharge;
278  fLabel = t.fLabel;
279  fIndex = t.fIndex;
280 
281  fPathMarks.clear();
282  SetPropagator(t.fPropagator);
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Copy path-marks from t.
287 
288 void REveTrack::SetPathMarks(const REveTrack& t)
289 {
290  std::copy(t.RefPathMarks().begin(), t.RefPathMarks().end(),
291  std::back_insert_iterator<vPathMark_t>(fPathMarks));
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Set track's propagator.
296 /// Reference counts of old and new propagator are updated.
297 
298 void REveTrack::SetPropagator(REveTrackPropagator *prop)
299 {
300  if (fPropagator == prop) return;
301  if (fPropagator) fPropagator->DecRefCount(this);
302  fPropagator = prop;
303  if (fPropagator) fPropagator->IncRefCount(this);
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Set line and marker attributes from REveTrackList.
308 
309 void REveTrack::SetAttLineAttMarker(REveTrackList* tl)
310 {
311  SetRnrLine(tl->GetRnrLine());
312  SetLineColor(tl->GetLineColor());
313  SetLineStyle(tl->GetLineStyle());
314  SetLineWidth(tl->GetLineWidth());
315 
316  SetRnrPoints(tl->GetRnrPoints());
317  SetMarkerColor(tl->GetMarkerColor());
318  SetMarkerStyle(tl->GetMarkerStyle());
319  SetMarkerSize(tl->GetMarkerSize());
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Calculate track representation based on track data and current
324 /// settings of the propagator.
325 /// If recurse is true, descend into children.
326 
327 void REveTrack::MakeTrack(Bool_t recurse)
328 {
329  if (!fLockPoints)
330  {
331  Reset(0);
332  fLastPMIdx = 0;
333 
334  REveTrackPropagator& rTP((fPropagator != nullptr) ? *fPropagator : REveTrackPropagator::fgDefault);
335 
336  const Double_t maxRsq = rTP.GetMaxR() * rTP.GetMaxR();
337  const Double_t maxZ = rTP.GetMaxZ();
338 
339  if ( ! REveTrackPropagator::IsOutsideBounds(fV, maxRsq, maxZ))
340  {
341  REveVectorD currP = fP;
342  Bool_t decay = kFALSE;
343  rTP.InitTrack(fV, fCharge);
344  for (auto pm = fPathMarks.begin(); pm != fPathMarks.end(); ++pm, ++fLastPMIdx)
345  {
346  Int_t start_point = rTP.GetCurrentPoint();
347 
348  if (rTP.GetFitReferences() && pm->fType == REvePathMarkD::kReference)
349  {
350  if (REveTrackPropagator::IsOutsideBounds(pm->fV, maxRsq, maxZ))
351  break;
352  if (rTP.GoToVertex(pm->fV, currP))
353  {
354  currP.fX = pm->fP.fX; currP.fY = pm->fP.fY; currP.fZ = pm->fP.fZ;
355  }
356  else
357  {
358  break;
359  }
360  }
361  else if (rTP.GetFitDaughters() && pm->fType == REvePathMarkD::kDaughter)
362  {
363  if (REveTrackPropagator::IsOutsideBounds(pm->fV, maxRsq, maxZ))
364  break;
365  if (rTP.GoToVertex(pm->fV, currP))
366  {
367  currP.fX -= pm->fP.fX; currP.fY -= pm->fP.fY; currP.fZ -= pm->fP.fZ;
368  if (fDpDs != 0)
369  {
370  Double_t dp = fDpDs * rTP.GetTrackLength(start_point);
371  Double_t p = currP.Mag();
372  if (p > dp) currP *= 1.0 - dp / p;
373  }
374  }
375  else
376  {
377  break;
378  }
379  }
380  else if (rTP.GetFitDecay() && pm->fType == REvePathMarkD::kDecay)
381  {
382  if (REveTrackPropagator::IsOutsideBounds(pm->fV, maxRsq, maxZ))
383  break;
384  rTP.GoToVertex(pm->fV, currP);
385  decay = kTRUE;
386  ++fLastPMIdx;
387  break;
388  }
389  else if (rTP.GetFitCluster2Ds() && pm->fType == REvePathMarkD::kCluster2D)
390  {
391  REveVectorD itsect;
392  if (rTP.IntersectPlane(currP, pm->fV, pm->fP, itsect))
393  {
394  REveVectorD delta = itsect - pm->fV;
395  REveVectorD vtopass = pm->fV + pm->fE*(pm->fE.Dot(delta));
396  if (REveTrackPropagator::IsOutsideBounds(vtopass, maxRsq, maxZ))
397  break;
398  if ( ! rTP.GoToVertex(vtopass, currP))
399  break;
400 
401  if (fDpDs != 0)
402  {
403  Double_t dp = fDpDs * rTP.GetTrackLength(start_point);
404  Double_t p = currP.Mag();
405  if (p > dp) currP *= 1.0 - dp / p;
406  }
407  }
408  else
409  {
410  Warning("REveTrack::MakeTrack", "Failed to intersect plane for Cluster2D. Ignoring path-mark.");
411  }
412  }
413  else if (rTP.GetFitLineSegments() && pm->fType == REvePathMarkD::kLineSegment)
414  {
415  if (REveTrackPropagator::IsOutsideBounds(pm->fV, maxRsq, maxZ))
416  break;
417 
418  if (rTP.GoToLineSegment(pm->fV, pm->fE, currP))
419  {
420  if (fDpDs != 0)
421  {
422  Double_t dp = fDpDs * rTP.GetTrackLength(start_point);
423  Double_t p = currP.Mag();
424  if (p > dp) currP *= 1.0 - dp / p;
425  }
426  }
427  else
428  {
429  break;
430  }
431  }
432  else
433  {
434  if (REveTrackPropagator::IsOutsideBounds(pm->fV, maxRsq, maxZ))
435  break;
436  }
437  } // loop path-marks
438 
439  if (!decay)
440  {
441  // printf("%s loop to bounds \n",fName.Data() );
442  rTP.GoToBounds(currP);
443  }
444  fPEnd = currP;
445  // make_polyline:
446  rTP.FillPointSet(this);
447  rTP.ResetTrack();
448  }
449  }
450 
451  if (recurse)
452  {
453  for (auto &c: fChildren) {
454  REveTrack* t = dynamic_cast<REveTrack *>(c);
455  if (t) t->MakeTrack(recurse);
456  }
457  }
458 }
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 /// Copy visualization parameters from element el.
462 
463 void REveTrack::CopyVizParams(const REveElement* el)
464 {
465  // No local parameters.
466 
467  // const REveTrack* t = dynamic_cast<const REveTrack*>(el);
468  // if (t)
469  // {}
470 
471  REveLine::CopyVizParams(el);
472 }
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 /// Write visualization parameters.
476 
477 void REveTrack::WriteVizParams(std::ostream& out, const TString& var)
478 {
479  REveLine::WriteVizParams(out, var);
480 
481  // TString t = " " + var + "->";
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// Virtual from REveProjectable, return REveTrackProjected class.
486 
487 TClass* REveTrack::ProjectedClass(const REveProjection*) const
488 {
489  return TClass::GetClass<REveTrackProjected>();
490 }
491 
492 namespace
493 {
494  struct Cmp_pathmark_t
495  {
496  bool operator()(REvePathMarkD const & a, REvePathMarkD const & b)
497  { return a.fTime < b.fTime; }
498  };
499 }
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 /// Sort registered pat-marks by time.
503 
504 void REveTrack::SortPathMarksByTime()
505 {
506  std::sort(fPathMarks.begin(), fPathMarks.end(), Cmp_pathmark_t());
507 }
508 
509 ////////////////////////////////////////////////////////////////////////////////
510 /// Print registered path-marks.
511 
512 void REveTrack::PrintPathMarks()
513 {
514  static const REveException eh("REveTrack::PrintPathMarks ");
515 
516  printf("REveTrack '%s', number of path marks %d, label %d\n",
517  GetCName(), (Int_t)fPathMarks.size(), fLabel);
518 
519  for (auto &pm: fPathMarks)
520  {
521  printf(" %-9s p: %8f %8f %8f Vertex: %8e %8e %8e %g Extra:%8f %8f %8f\n",
522  pm.TypeName(),
523  pm.fP.fX, pm.fP.fY, pm.fP.fZ,
524  pm.fV.fX, pm.fV.fY, pm.fV.fZ,
525  pm.fE.fX, pm.fE.fY, pm.fE.fZ,
526  pm.fTime);
527  }
528 }
529 
530 ////////////////////////////////////////////////////////////////////////////////
531 /// Fill core part of JSON representation.
532 
533 Int_t REveTrack::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
534 {
535  // TODO: missing streaming of fitting points
536  return REveLine::WriteCoreJson(j, rnr_offset);
537 }
538 
539 ////////////////////////////////////////////////////////////////////////////////
540 /// Crates 3D point array for rendering.
541 
542 void REveTrack::BuildRenderData()
543 {
544  // TODO: missing streaming o fitting points
545  REveLine::BuildRenderData();
546 }
547 
548 ////////////////////////////////////////////////////////////////////////////////
549 /// Emits "SecSelected(REveTrack*)" signal.
550 
551 void REveTrack::SecSelected(REveTrack* /*track*/)
552 {
553  // Emit("SecSelected(REveTrack*)", (Long_t)track);
554 }
555 
556 
557 //==============================================================================
558 //==============================================================================
559 
560 /** \class REveTrackList
561 \ingroup REve
562 A list of tracks supporting change of common attributes and
563 selection based on track parameters.
564 */
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Constructor. If track-propagator argument is 0, a new default
568 /// one is created.
569 
570 REveTrackList::REveTrackList(REveTrackPropagator* prop) :
571  REveElement(),
572  TAttMarker(1, 20, 1),
573  TAttLine(1,1,1),
574 
575  fPropagator(0),
576  fRecurse(kTRUE),
577  fRnrLine(kTRUE),
578  fRnrPoints(kFALSE),
579 
580  fMinPt (0), fMaxPt (0), fLimPt (0),
581  fMinP (0), fMaxP (0), fLimP (0)
582 {
583 
584  fChildClass = TClass::GetClass<REveTrack>(); // override member from base REveElementList
585 
586  fMainColorPtr = &fLineColor;
587 
588  if (!prop) prop = new REveTrackPropagator;
589  SetPropagator(prop);
590 }
591 
592 ////////////////////////////////////////////////////////////////////////////////
593 /// Constructor. If track-propagator argument is 0, a new default
594 /// one is created.
595 
596 REveTrackList::REveTrackList(const std::string& name, REveTrackPropagator* prop) :
597  REveElement(name),
598  TAttMarker(1, 20, 1),
599  TAttLine(1,1,1),
600 
601  fPropagator(0),
602  fRecurse(kTRUE),
603  fRnrLine(kTRUE),
604  fRnrPoints(kFALSE),
605 
606  fMinPt (0), fMaxPt (0), fLimPt (0),
607  fMinP (0), fMaxP (0), fLimP (0)
608 {
609  fChildClass = TClass::GetClass<REveTrack>(); // override member from base REveElementList
610 
611  fMainColorPtr = &fLineColor;
612 
613  if (!prop) prop = new REveTrackPropagator;
614  SetPropagator(prop);
615 }
616 
617 ////////////////////////////////////////////////////////////////////////////////
618 /// Destructor.
619 
620 REveTrackList::~REveTrackList()
621 {
622  SetPropagator(0);
623 }
624 
625 ////////////////////////////////////////////////////////////////////////////////
626 /// Set default propagator for tracks.
627 /// This is not enforced onto the tracks themselves but this is the
628 /// propagator that is shown in the GUI.
629 
630 void REveTrackList::SetPropagator(REveTrackPropagator* prop)
631 {
632  if (fPropagator == prop) return;
633  if (fPropagator) fPropagator->DecRefCount();
634  fPropagator = prop;
635  if (fPropagator) fPropagator->IncRefCount();
636 }
637 
638 ////////////////////////////////////////////////////////////////////////////////
639 /// Regenerate the visual representations of tracks.
640 /// The momentum limits are rescanned during the same traversal.
641 
642 void REveTrackList::MakeTracks(Bool_t recurse)
643 {
644  fLimPt = fLimP = 0;
645 
646  for (auto &c: fChildren) {
647  REveTrack* track = dynamic_cast<REveTrack*>(c);
648  if (track) {
649  track->MakeTrack(recurse);
650 
651  fLimPt = TMath::Max(fLimPt, track->fP.Perp());
652  fLimP = TMath::Max(fLimP, track->fP.Mag());
653  }
654  if (recurse)
655  FindMomentumLimits(c, recurse);
656  }
657 
658  fLimPt = RoundMomentumLimit(fLimPt);
659  fLimP = RoundMomentumLimit(fLimP);
660 
661  SanitizeMinMaxCuts();
662 }
663 
664 ////////////////////////////////////////////////////////////////////////////////
665 /// Loop over children and find highest pT and p of contained EveTracks.
666 /// These are stored in members fLimPt and fLimP.
667 
668 void REveTrackList::FindMomentumLimits(Bool_t recurse)
669 {
670  fLimPt = fLimP = 0;
671 
672  if (HasChildren())
673  {
674  for (auto &c: RefChildren())
675  {
676  REveTrack* track = dynamic_cast<REveTrack *>(c);
677  if (track)
678  {
679  fLimPt = TMath::Max(fLimPt, track->fP.Perp());
680  fLimP = TMath::Max(fLimP, track->fP.Mag());
681  }
682  if (recurse)
683  FindMomentumLimits(c, recurse);
684  }
685 
686  fLimPt = RoundMomentumLimit(fLimPt);
687  fLimP = RoundMomentumLimit(fLimP);
688  }
689 
690  SanitizeMinMaxCuts();
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Loop over track elements of argument el and find highest pT and p.
695 /// These are stored in members fLimPt and fLimP.
696 
697 void REveTrackList::FindMomentumLimits(REveElement *el, Bool_t recurse)
698 {
699  for (auto &c: el->RefChildren()) {
700  auto track = dynamic_cast<REveTrack *>(c);
701  if (track) {
702  fLimPt = TMath::Max(fLimPt, track->fP.Perp());
703  fLimP = TMath::Max(fLimP, track->fP.Mag());
704  }
705  if (recurse)
706  FindMomentumLimits(c, recurse);
707  }
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Round the momentum limit up to a nice value.
712 
713 Double_t REveTrackList::RoundMomentumLimit(Double_t x)
714 {
715  using namespace TMath;
716 
717  if (x < 1e-3) return 1e-3;
718 
719  Double_t fac = Power(10, 1 - Floor(Log10(x)));
720  return Ceil(fac*x) / fac;
721 }
722 
723 ////////////////////////////////////////////////////////////////////////////////
724 /// Set Min/Max cuts so that they are within detected limits.
725 
726 void REveTrackList::SanitizeMinMaxCuts()
727 {
728  fMinPt = TMath::Min(fMinPt, fLimPt);
729  fMaxPt = (fMaxPt == 0) ? fLimPt : TMath::Min(fMaxPt, fLimPt);
730  fMinP = TMath::Min(fMinP, fLimP);
731  fMaxP = (fMaxP == 0) ? fLimP : TMath::Min(fMaxP, fLimP);
732 }
733 
734 ////////////////////////////////////////////////////////////////////////////////
735 /// Set rendering of track as line for the list and the elements.
736 
737 void REveTrackList::SetRnrLine(Bool_t rnr)
738 {
739  for (auto &c: RefChildren()) {
740  auto track = (REveTrack *)(c);
741  if (track->GetRnrLine() == fRnrLine)
742  track->SetRnrLine(rnr);
743  if (fRecurse)
744  SetRnrLine(rnr, c);
745  }
746  fRnrLine = rnr;
747 }
748 
749 ////////////////////////////////////////////////////////////////////////////////
750 /// Set rendering of track as line for children of el.
751 
752 void REveTrackList::SetRnrLine(Bool_t rnr, REveElement* el)
753 {
754  for (auto &c: el->RefChildren()) {
755  auto track = dynamic_cast<REveTrack *>(c);
756  if (track && (track->GetRnrLine() == fRnrLine))
757  track->SetRnrLine(rnr);
758  if (fRecurse)
759  SetRnrLine(rnr, c);
760  }
761 }
762 
763 ////////////////////////////////////////////////////////////////////////////////
764 /// Set rendering of track as points for the list and the elements.
765 
766 void REveTrackList::SetRnrPoints(Bool_t rnr)
767 {
768  for (auto &c: RefChildren()) {
769  auto track = (REveTrack *)(c);
770  if (track->GetRnrPoints() == fRnrPoints)
771  track->SetRnrPoints(rnr);
772  if (fRecurse)
773  SetRnrPoints(rnr, c);
774  }
775  fRnrPoints = rnr;
776 }
777 
778 ////////////////////////////////////////////////////////////////////////////////
779 /// Set rendering of track as points for children of el.
780 
781 void REveTrackList::SetRnrPoints(Bool_t rnr, REveElement* el)
782 {
783  for (auto &c: el->RefChildren()) {
784  auto track = dynamic_cast<REveTrack *>(c);
785  if (track)
786  if (track->GetRnrPoints() == fRnrPoints)
787  track->SetRnrPoints(rnr);
788  if (fRecurse)
789  SetRnrPoints(rnr, c);
790  }
791 }
792 
793 ////////////////////////////////////////////////////////////////////////////////
794 /// Set main (line) color for the list and the elements.
795 
796 void REveTrackList::SetMainColor(Color_t col)
797 {
798  for (auto &c: RefChildren()) {
799  auto track = (REveTrack *)(c);
800  if (track->GetLineColor() == fLineColor)
801  track->SetLineColor(col);
802  if (fRecurse)
803  SetLineColor(col, c);
804  }
805  REveElement::SetMainColor(col);
806 }
807 
808 ////////////////////////////////////////////////////////////////////////////////
809 /// Set line color for children of el.
810 
811 void REveTrackList::SetLineColor(Color_t col, REveElement* el)
812 {
813  for (auto &c: el->RefChildren()) {
814  auto track = dynamic_cast<REveTrack *>(c);
815  if (track && track->GetLineColor() == fLineColor)
816  track->SetLineColor(col);
817  if (fRecurse)
818  SetLineColor(col, c);
819  }
820 }
821 
822 ////////////////////////////////////////////////////////////////////////////////
823 /// Set line width for the list and the elements.
824 
825 void REveTrackList::SetLineWidth(Width_t width)
826 {
827  for (auto &c: RefChildren()) {
828  auto track = (REveTrack *)(c);
829  if (track->GetLineWidth() == fLineWidth)
830  track->SetLineWidth(width);
831  if (fRecurse)
832  SetLineWidth(width, c);
833  }
834  fLineWidth = width;
835 }
836 
837 ////////////////////////////////////////////////////////////////////////////////
838 /// Set line width for children of el.
839 
840 void REveTrackList::SetLineWidth(Width_t width, REveElement* el)
841 {
842  for (auto &c: el->RefChildren()) {
843  auto track = dynamic_cast<REveTrack *>(c);
844  if (track && track->GetLineWidth() == fLineWidth)
845  track->SetLineWidth(width);
846  if (fRecurse)
847  SetLineWidth(width, c);
848  }
849 }
850 
851 ////////////////////////////////////////////////////////////////////////////////
852 /// Set line style for the list and the elements.
853 
854 void REveTrackList::SetLineStyle(Style_t style)
855 {
856  for (auto &c: RefChildren()) {
857  auto track = (REveTrack *)(c);
858  if (track->GetLineStyle() == fLineStyle)
859  track->SetLineStyle(style);
860  if (fRecurse)
861  SetLineStyle(style, c);
862  }
863  fLineStyle = style;
864 }
865 
866 ////////////////////////////////////////////////////////////////////////////////
867 /// Set line style for children of el.
868 
869 void REveTrackList::SetLineStyle(Style_t style, REveElement* el)
870 {
871  for (auto &c: el->RefChildren()) {
872  auto track = dynamic_cast<REveTrack *>(c);
873  if (track && track->GetLineStyle() == fLineStyle)
874  track->SetLineStyle(style);
875  if (fRecurse)
876  SetLineStyle(style, c);
877  }
878 }
879 
880 ////////////////////////////////////////////////////////////////////////////////
881 /// Set marker style for the list and the elements.
882 
883 void REveTrackList::SetMarkerStyle(Style_t style)
884 {
885  for (auto &c: RefChildren()) {
886  auto track = (REveTrack *)(c);
887  if (track->GetMarkerStyle() == fMarkerStyle)
888  track->SetMarkerStyle(style);
889  if (fRecurse)
890  SetMarkerStyle(style, c);
891  }
892  fMarkerStyle = style;
893 }
894 
895 ////////////////////////////////////////////////////////////////////////////////
896 /// Set marker style for children of el.
897 
898 void REveTrackList::SetMarkerStyle(Style_t style, REveElement* el)
899 {
900  for (auto &c: el->RefChildren()) {
901  auto track = dynamic_cast<REveTrack *>(c);
902  if (track && track->GetMarkerStyle() == fMarkerStyle)
903  track->SetMarkerStyle(style);
904  if (fRecurse)
905  SetMarkerStyle(style, c);
906  }
907 }
908 
909 ////////////////////////////////////////////////////////////////////////////////
910 /// Set marker color for the list and the elements.
911 
912 void REveTrackList::SetMarkerColor(Color_t col)
913 {
914  for (auto &c: RefChildren()) {
915  auto track = (REveTrack *)(c);
916  if (track->GetMarkerColor() == fMarkerColor)
917  track->SetMarkerColor(col);
918  if (fRecurse)
919  SetMarkerColor(col, c);
920  }
921  fMarkerColor = col;
922 }
923 
924 ////////////////////////////////////////////////////////////////////////////////
925 /// Set marker color for children of el.
926 
927 void REveTrackList::SetMarkerColor(Color_t col, REveElement* el)
928 {
929  for (auto &c: el->RefChildren()) {
930  auto track = dynamic_cast<REveTrack *>(c);
931  if (track && track->GetMarkerColor() == fMarkerColor)
932  track->SetMarkerColor(col);
933  if (fRecurse)
934  SetMarkerColor(col, c);
935  }
936 }
937 
938 ////////////////////////////////////////////////////////////////////////////////
939 /// Set marker size for the list and the elements.
940 
941 void REveTrackList::SetMarkerSize(Size_t size)
942 {
943  for (auto &c: RefChildren()) {
944  auto track = (REveTrack *)(c);
945  if (track->GetMarkerSize() == fMarkerSize)
946  track->SetMarkerSize(size);
947  if (fRecurse)
948  SetMarkerSize(size, c);
949  }
950  fMarkerSize = size;
951 }
952 
953 ////////////////////////////////////////////////////////////////////////////////
954 /// Set marker size for children of el.
955 
956 void REveTrackList::SetMarkerSize(Size_t size, REveElement* el)
957 {
958  for (auto &c: el->RefChildren()) {
959  auto track = dynamic_cast<REveTrack*>(c);
960  if (track && track->GetMarkerSize() == fMarkerSize)
961  track->SetMarkerSize(size);
962  if (fRecurse)
963  SetMarkerSize(size, c);
964  }
965 }
966 
967 ////////////////////////////////////////////////////////////////////////////////
968 /// Select visibility of tracks by transverse momentum.
969 /// If data-member fRecurse is set, the selection is applied
970 /// recursively to all children.
971 
972 void REveTrackList::SelectByPt(Double_t min_pt, Double_t max_pt)
973 {
974  fMinPt = min_pt;
975  fMaxPt = max_pt;
976 
977  const Double_t minptsq = min_pt*min_pt;
978  const Double_t maxptsq = max_pt*max_pt;
979 
980  for (auto &c: RefChildren()) {
981  const Double_t ptsq = ((REveTrack*)c)->fP.Perp2();
982  Bool_t on = ptsq >= minptsq && ptsq <= maxptsq;
983  c->SetRnrState(on);
984  if (on && fRecurse)
985  SelectByPt(min_pt, max_pt, c);
986  }
987 }
988 
989 ////////////////////////////////////////////////////////////////////////////////
990 /// Select visibility of el's children tracks by transverse momentum.
991 
992 void REveTrackList::SelectByPt(Double_t min_pt, Double_t max_pt, REveElement *el)
993 {
994  const Double_t minptsq = min_pt*min_pt;
995  const Double_t maxptsq = max_pt*max_pt;
996 
997  for (auto &c: el->RefChildren()) {
998  auto track = (REveTrack *)(c);
999  if (track) {
1000  const Double_t ptsq = track->fP.Perp2();
1001  Bool_t on = ptsq >= minptsq && ptsq <= maxptsq;
1002  track->SetRnrState(on);
1003  if (on && fRecurse)
1004  SelectByPt(min_pt, max_pt, c);
1005  }
1006  }
1007 }
1008 
1009 ////////////////////////////////////////////////////////////////////////////////
1010 /// Select visibility of tracks by momentum.
1011 /// If data-member fRecurse is set, the selection is applied
1012 /// recursively to all children.
1013 
1014 void REveTrackList::SelectByP(Double_t min_p, Double_t max_p)
1015 {
1016  fMinP = min_p;
1017  fMaxP = max_p;
1018 
1019  const Double_t minpsq = min_p*min_p;
1020  const Double_t maxpsq = max_p*max_p;
1021 
1022  for (auto &c: RefChildren()) {
1023  const Double_t psq = ((REveTrack*)c)->fP.Mag2();
1024  Bool_t on = psq >= minpsq && psq <= maxpsq;
1025  c->SetRnrState(psq >= minpsq && psq <= maxpsq);
1026  if (on && fRecurse)
1027  SelectByP(min_p, max_p, c);
1028  }
1029 }
1030 
1031 ////////////////////////////////////////////////////////////////////////////////
1032 /// Select visibility of el's children tracks by momentum.
1033 
1034 void REveTrackList::SelectByP(Double_t min_p, Double_t max_p, REveElement* el)
1035 {
1036  const Double_t minpsq = min_p*min_p;
1037  const Double_t maxpsq = max_p*max_p;
1038 
1039  for (auto &c: el->RefChildren()) {
1040  auto track = (REveTrack *)(c);
1041  if (track) {
1042  const Double_t psq = ((REveTrack*)c)->fP.Mag2();
1043  Bool_t on = psq >= minpsq && psq <= maxpsq;
1044  track->SetRnrState(on);
1045  if (on && fRecurse)
1046  SelectByP(min_p, max_p, c);
1047  }
1048  }
1049 }
1050 
1051 ////////////////////////////////////////////////////////////////////////////////
1052 /// Find track by label, select it and display it in the editor.
1053 
1054 REveTrack *REveTrackList::FindTrackByLabel(Int_t label)
1055 {
1056  for (auto &c: fChildren) {
1057  if (((REveTrack*)c)->GetLabel() == label)
1058  {
1059  // TGListTree *lt = REX::gEve->GetLTEFrame()->GetListTree();
1060  // TGListTreeItem *mlti = lt->GetSelected();
1061  // if (mlti->GetUserData() != this)
1062  // mlti = FindListTreeItem(lt);
1063  // TGListTreeItem *tlti = (*i)->FindListTreeItem(lt, mlti);
1064  // lt->HighlightItem(tlti);
1065  // lt->SetSelected(tlti);
1066  // REX::gEve->EditElement(*i);
1067  return (REveTrack*) c;
1068  }
1069  }
1070  return nullptr;
1071 }
1072 
1073 ////////////////////////////////////////////////////////////////////////////////
1074 /// Find track by index, select it and display it in the editor.
1075 
1076 REveTrack* REveTrackList::FindTrackByIndex(Int_t index)
1077 {
1078  for (auto &c: fChildren) {
1079  if (((REveTrack *)c)->GetIndex() == index) {
1080  // TGListTree *lt = REX::gEve->GetLTEFrame()->GetListTree();
1081  // TGListTreeItem *mlti = lt->GetSelected();
1082  // if (mlti->GetUserData() != this)
1083  // mlti = FindListTreeItem(lt);
1084  // TGListTreeItem *tlti = (*i)->FindListTreeItem(lt, mlti);
1085  // lt->HighlightItem(tlti);
1086  // lt->SetSelected(tlti);
1087  // REX::gEve->EditElement(*i);
1088  return (REveTrack *) c;
1089  }
1090  }
1091  return nullptr;
1092 }
1093 
1094 ////////////////////////////////////////////////////////////////////////////////
1095 /// Copy visualization parameters from element el.
1096 
1097 void REveTrackList::CopyVizParams(const REveElement* el)
1098 {
1099  const REveTrackList* m = dynamic_cast<const REveTrackList*>(el);
1100  if (m)
1101  {
1102  TAttMarker::operator=(*m);
1103  TAttLine::operator=(*m);
1104  fRecurse = m->fRecurse;
1105  fRnrLine = m->fRnrLine;
1106  fRnrPoints = m->fRnrPoints;
1107  fMinPt = m->fMinPt;
1108  fMaxPt = m->fMaxPt;
1109  fLimPt = m->fLimPt;
1110  fMinP = m->fMinP;
1111  fMaxP = m->fMaxP;
1112  fLimP = m->fLimP;
1113  }
1114 
1115  REveElement::CopyVizParams(el);
1116 }
1117 
1118 ////////////////////////////////////////////////////////////////////////////////
1119 /// Write visualization parameters.
1120 
1121 void REveTrackList::WriteVizParams(std::ostream& out, const TString& var)
1122 {
1123  REveElement::WriteVizParams(out, var);
1124 
1125  TString t = " " + var + "->";
1126  TAttMarker::SaveMarkerAttributes(out, var);
1127  TAttLine ::SaveLineAttributes (out, var);
1128  out << t << "SetRecurse(" << ToString(fRecurse) << ");\n";
1129  out << t << "SetRnrLine(" << ToString(fRnrLine) << ");\n";
1130  out << t << "SetRnrPoints(" << ToString(fRnrPoints) << ");\n";
1131  // These setters are not available -- need proper AND/OR mode.
1132  // out << t << "SetMinPt(" << fMinPt << ");\n";
1133  // out << t << "SetMaxPt(" << fMaxPt << ");\n";
1134  // out << t << "SetLimPt(" << fLimPt << ");\n";
1135  // out << t << "SetMinP(" << fMinP << ");\n";
1136  // out << t << "SetMaxP(" << fMaxP << ");\n";
1137  // out << t << "SetLimP(" << fLimP << ");\n";
1138 }
1139 
1140 ////////////////////////////////////////////////////////////////////////////////
1141 /// Virtual from REveProjectable, returns REveTrackListProjected class.
1142 
1143 TClass* REveTrackList::ProjectedClass(const REveProjection*) const
1144 {
1145  return TClass::GetClass<REveTrackListProjected>();
1146 }