ROOT logo
// $Id$
// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/

/// \ingroup evemacros
/// \file kine_tracks.C
/// \brief Import tracks from kinematics-tree / particle-stack.
///
/// Preliminary/minimal solution.
///
/// \author Matevz Tadel & Alja Mrak-Tadel: 2006, 2007 

#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TParticle.h>
#include <TParticlePDG.h>
#include <TEveManager.h>
#include <TEveTrackPropagator.h>

#include <AliMagF.h>
#include <AliStack.h>
#include <AliRunLoader.h>
#include <AliEveEventManager.h>
#include <AliEveMagField.h>
#include <AliEveTrack.h>
#include <AliEveKineTools.h>
#endif

// Use magnetic-field as retrieved from GRP.
Bool_t g_kine_tracks_true_field = kTRUE;

// Use Runge-Kutta track stepper.
Bool_t g_kine_tracks_rk_stepper = kFALSE;

//==============================================================================

void kine_track_propagator_setup(TEveTrackPropagator* trkProp);

TEveTrackList*
kine_tracks(Double_t min_pt  = 0,     Double_t min_p   = 0,
	    Bool_t   pdg_col = kTRUE, Bool_t   recurse = kTRUE,
	    Bool_t   use_track_refs = kTRUE);

void kine_daughters(AliEveTrack* parent,  AliStack* stack,
		    Double_t     min_pt,  Double_t  min_p,
		    Bool_t       pdg_col, Bool_t    recurse);

void    set_track_color(AliEveTrack* t, Bool_t pdg_col);
Color_t get_pdg_color(Int_t pdg);

TEveElement*
kine_track(Int_t  label,
	   Bool_t import_mother = kTRUE, Bool_t import_daughters = kTRUE,
	   Bool_t pdg_col       = kTRUE, Bool_t recurse          = kTRUE,
           TEveElement* cont = 0);

void kine_hide_neutrals(TEveElement* el=0, Int_t level=0);

//==============================================================================

void kine_track_propagator_setup(TEveTrackPropagator* trkProp)
{
  AliMagF* fld = AliEveEventManager::AssertMagField();

  if (g_kine_tracks_true_field)
  {
    trkProp->SetMagFieldObj(new AliEveMagField(fld));
  }
  else
  {
    trkProp->SetMagField(-0.1*fld->SolenoidField());
  }
  if (g_kine_tracks_rk_stepper)
  {
    trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
  }
}

//==============================================================================

TEveTrackList*
kine_tracks(Double_t min_pt,  Double_t min_p,
	    Bool_t   pdg_col, Bool_t   recurse,
	    Bool_t   use_track_refs)
{
  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
  rl->LoadKinematics();
  AliStack* stack = rl->Stack();
  if (!stack)
  {
    Error("kine_tracks", "can not get kinematics.");
    return 0;
  }

  gEve->DisableRedraw();

  TEveTrackList* cont = new TEveTrackList("Kine Tracks");
  cont->SetMainColor(3);
  TEveTrackPropagator* trkProp = cont->GetPropagator();

  kine_track_propagator_setup(trkProp);

  gEve->AddElement(cont);
  Int_t count = 0;
  Int_t Np = stack->GetNprimary();
  for (Int_t i = 0; i < Np; ++i)
  {
    TParticle* p = stack->Particle(i);
    if (p->GetStatusCode() <= 1)
    {
      if (p->Pt() < min_pt && p->P() < min_p) continue;

      ++count;
      AliEveTrack* track = new AliEveTrack(p, i, trkProp);

      //PH The line below is replaced waiting for a fix in Root
      //PH which permits to use variable siza arguments in CINT
      //PH on some platforms (alphalinuxgcc, solariscc5, etc.)
      //PH    track->SetName(Form("%s [%d]", p->GetName(), i));
      char form[1000];
      sprintf(form,"%s [%d]", p->GetName(), i);
      track->SetName(form);
      track->SetStdTitle();
      Int_t ml = p->GetMother(0);
      if (ml != -1)
      {
        track->SetTitle(Form("%s\nMother label=%d\nMother Pdg=%d",
                             track->GetElementTitle(),
                             ml, stack->Particle(ml)->GetPdgCode()));
      }
      set_track_color(track, pdg_col);

      gEve->AddElement(track, cont);

      if (recurse)
	kine_daughters(track, stack, min_pt, min_p, pdg_col, recurse);
    }
  }

  // set path marks
  AliEveKineTools kt;
  kt.SetDaughterPathMarks(cont, stack, recurse);
  if (use_track_refs && rl->LoadTrackRefs() == 0)
  {
    kt.SetTrackReferences(cont, rl->TreeTR(), recurse);
    trkProp->SetEditPathMarks(kTRUE);
  }
  kt.SortPathMarks(cont, recurse);

  //PH  const Text_t* tooltip = Form("min pT=%.2lf, min P=%.2lf), N=%d", min_pt, min_p, count);
  char tooltip[1000];
  sprintf(tooltip,"min pT=%.2lf, min P=%.2lf), N=%d", min_pt, min_p, count);
  cont->SetTitle(tooltip); // Not broadcasted automatically ...

  cont->MakeTracks(recurse);
  gEve->EnableRedraw();
  gEve->Redraw3D();

  return cont;
}

void kine_daughters(AliEveTrack* parent,  AliStack* stack,
		    Double_t     min_pt,  Double_t  min_p,
		    Bool_t       pdg_col, Bool_t    recurse)
{
  TParticle *p = stack->Particle(parent->GetLabel());
  if (p->GetNDaughters() > 0)
  {
    TEveTrackPropagator* rs = parent->GetPropagator();
    for (int d=p->GetFirstDaughter(); d>0 && d<=p->GetLastDaughter(); ++d)
    {
      TParticle* dp = stack->Particle(d);
      if (dp->Pt() < min_pt && dp->P() < min_p) continue;

      AliEveTrack* dtrack = new AliEveTrack(dp, d, rs);
      char form[1000];
      sprintf(form,"%s [%d]", dp->GetName(), d);
      dtrack->SetName(form);
      dtrack->SetStdTitle();
      set_track_color(dtrack, pdg_col);

      gEve->AddElement(dtrack, parent);

      if (recurse)
	kine_daughters(dtrack, stack, min_pt, min_p, pdg_col, recurse);
    }
  }
}

//==============================================================================

void set_track_color(AliEveTrack* t, Bool_t pdg_col)
{
  if (pdg_col)
    t->SetMainColor(get_pdg_color(t->GetPdg()));
  else
    t->SetMainColor(30);
}

Color_t get_pdg_color(Int_t pdg)
{
  // PDG color indices
  static const Color_t DefCol   = 30;
  static const Color_t ECol     = 5;
  static const Color_t MuCol    = 6;
  static const Color_t GammaCol = 7;
  static const Color_t MesCol1  = 3;
  static const Color_t MesCol2  = 38;
  static const Color_t BarCol   = 10;

  Int_t pdga  = TMath::Abs(pdg);
  Color_t col = DefCol;

  // elementary  particles
  if (pdga < 100) {
    switch (pdga) {
      case 11:
	col = ECol; break;
      case 12:
	col = MuCol; break;
      case 22:
	col = GammaCol; break;
    }
  }
  // mesons and barions
  else if (pdga < 100000) {
    Int_t i  = pdga;
    // Int_t i0 = i%10;  // Not used at the moment.
    i /= 10;
    Int_t i1 = i%10; i /= 10;
    Int_t i2 = i%10; i /= 10;
    Int_t i3 = i%10; i /= 10;
    Int_t i4 = i%10;
    //printf("pdg(%d) quark indices (%d,%d,%d,%d,%d) \n",pdg, i4,i3,i2, i1, i0);
    // meson
    if ((i3 == 0) && ( i4 < 2)){
      col = MesCol1; // quarks: i1,i2 (spin = i0)
      if(i1 == 3 || i2 == 3)
	col = MesCol2;
    } // barion
    else if ( i2 >= i1 && i3 >= i2 ) {
      col = BarCol; // quarks: i1,i2, i3 (spin = i0))
    }
  }

  return col;
}

//==============================================================================

TEveElement*
kine_track(Int_t  label,
	   Bool_t import_mother, Bool_t import_daughters,
	   Bool_t pdg_col,       Bool_t recurse,
           TEveElement* cont)
{
  // Create mother and daughters tracks with given label.
  // mother     -> particle with label
  // daughters  -> daughters of label

  if (label < 0) {
    Warning("kine_track", "label not set.");
    return 0;
  }

  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
  rl->LoadKinematics();
  AliStack* stack = rl->Stack();
  if (!stack)
  {
     Warning("kine_track", "can not get kinematics.");
    return 0;
  }
  if (label >= stack->GetNtrack())
  {
    Warning("kine_track", "label out of range.");
    return 0;
  }

  TParticle* p = stack->Particle(label);

  if (import_mother || (import_daughters && p->GetNDaughters()))
  {
    TEveTrackPropagator* rs = 0;

    if (cont == 0)
    {
      TEveTrackList* tlist = new TEveTrackList
	(Form("Kinematics of %d %d", label, p->GetNDaughters()));
      cont = tlist;

      TEveTrackPropagator* trkProp = tlist->GetPropagator();

      kine_track_propagator_setup(trkProp);

      char tooltip[1000];
      sprintf(tooltip,"Ndaughters=%d", p->GetNDaughters());
      tlist->SetTitle(tooltip);
      trkProp->SetMaxOrbs(2);
      trkProp->SetEditPathMarks(kTRUE);

      gEve->AddElement(cont);
      rs = tlist->GetPropagator();
    }
    else
    {
      // check if container is TEveTrackList or AliEveTrack (has rnr-style)
      AliEveTrack* t = dynamic_cast<AliEveTrack*>(cont);
      if (t) {
	rs = t->GetPropagator();
      } else {
        TEveTrackList* l = dynamic_cast<TEveTrackList*>(cont);
        if (l)
	  rs = l->GetPropagator();
        else
	  Error("kine_tracks.C", "TrackRenderStyle not set.");
      }
    }

    if (import_mother)
    {
      AliEveTrack* track = new AliEveTrack(p, label, rs);
      char form[1000];
      sprintf(form,"%s [%d]", p->GetName(), label);
      track->SetName(form);
      track->SetStdTitle();
      set_track_color(track, pdg_col);

      track->MakeTrack();
      gEve->AddElement(track, cont);
      cont = track;
    }

    if (import_daughters && p->GetNDaughters())
    {
      for (int d=p->GetFirstDaughter(); d>0 && d<=p->GetLastDaughter(); ++d)
      {
	TParticle* dp = stack->Particle(d);
	AliEveTrack* track = new AliEveTrack(dp, d, rs);
	char form[1000];
	sprintf(form,"%s [%d]", dp->GetName(), d);
	track->SetName(form);
	track->SetStdTitle();
	set_track_color(track, pdg_col);

        track->MakeTrack();
	gEve->AddElement(track, cont);

	if (recurse)
	  kine_daughters(track, stack, 0, 0, pdg_col, recurse);
      }
    }
  }

  gEve->Redraw3D();
  return cont;
}

//==============================================================================

void kine_hide_neutrals(TEveElement* el, Int_t level)
{
  if (el == 0)
  {
    el = gEve->GetCurrentEvent()->FindChild("Kine Tracks");
    if (!el)
      return;
  }

  TEveTrack* t = dynamic_cast<TEveTrack*>(el);
  if (t && t->GetCharge() == 0)
    t->SetRnrSelf(kFALSE);

  for (TEveElement::List_i i = el->BeginChildren(); i != el->EndChildren(); ++i)
  {
    kine_hide_neutrals(*i, level + 1);
  }

  if (level == 0)
    gEve->Redraw3D();
}
 kine_tracks.C:1
 kine_tracks.C:2
 kine_tracks.C:3
 kine_tracks.C:4
 kine_tracks.C:5
 kine_tracks.C:6
 kine_tracks.C:7
 kine_tracks.C:8
 kine_tracks.C:9
 kine_tracks.C:10
 kine_tracks.C:11
 kine_tracks.C:12
 kine_tracks.C:13
 kine_tracks.C:14
 kine_tracks.C:15
 kine_tracks.C:16
 kine_tracks.C:17
 kine_tracks.C:18
 kine_tracks.C:19
 kine_tracks.C:20
 kine_tracks.C:21
 kine_tracks.C:22
 kine_tracks.C:23
 kine_tracks.C:24
 kine_tracks.C:25
 kine_tracks.C:26
 kine_tracks.C:27
 kine_tracks.C:28
 kine_tracks.C:29
 kine_tracks.C:30
 kine_tracks.C:31
 kine_tracks.C:32
 kine_tracks.C:33
 kine_tracks.C:34
 kine_tracks.C:35
 kine_tracks.C:36
 kine_tracks.C:37
 kine_tracks.C:38
 kine_tracks.C:39
 kine_tracks.C:40
 kine_tracks.C:41
 kine_tracks.C:42
 kine_tracks.C:43
 kine_tracks.C:44
 kine_tracks.C:45
 kine_tracks.C:46
 kine_tracks.C:47
 kine_tracks.C:48
 kine_tracks.C:49
 kine_tracks.C:50
 kine_tracks.C:51
 kine_tracks.C:52
 kine_tracks.C:53
 kine_tracks.C:54
 kine_tracks.C:55
 kine_tracks.C:56
 kine_tracks.C:57
 kine_tracks.C:58
 kine_tracks.C:59
 kine_tracks.C:60
 kine_tracks.C:61
 kine_tracks.C:62
 kine_tracks.C:63
 kine_tracks.C:64
 kine_tracks.C:65
 kine_tracks.C:66
 kine_tracks.C:67
 kine_tracks.C:68
 kine_tracks.C:69
 kine_tracks.C:70
 kine_tracks.C:71
 kine_tracks.C:72
 kine_tracks.C:73
 kine_tracks.C:74
 kine_tracks.C:75
 kine_tracks.C:76
 kine_tracks.C:77
 kine_tracks.C:78
 kine_tracks.C:79
 kine_tracks.C:80
 kine_tracks.C:81
 kine_tracks.C:82
 kine_tracks.C:83
 kine_tracks.C:84
 kine_tracks.C:85
 kine_tracks.C:86
 kine_tracks.C:87
 kine_tracks.C:88
 kine_tracks.C:89
 kine_tracks.C:90
 kine_tracks.C:91
 kine_tracks.C:92
 kine_tracks.C:93
 kine_tracks.C:94
 kine_tracks.C:95
 kine_tracks.C:96
 kine_tracks.C:97
 kine_tracks.C:98
 kine_tracks.C:99
 kine_tracks.C:100
 kine_tracks.C:101
 kine_tracks.C:102
 kine_tracks.C:103
 kine_tracks.C:104
 kine_tracks.C:105
 kine_tracks.C:106
 kine_tracks.C:107
 kine_tracks.C:108
 kine_tracks.C:109
 kine_tracks.C:110
 kine_tracks.C:111
 kine_tracks.C:112
 kine_tracks.C:113
 kine_tracks.C:114
 kine_tracks.C:115
 kine_tracks.C:116
 kine_tracks.C:117
 kine_tracks.C:118
 kine_tracks.C:119
 kine_tracks.C:120
 kine_tracks.C:121
 kine_tracks.C:122
 kine_tracks.C:123
 kine_tracks.C:124
 kine_tracks.C:125
 kine_tracks.C:126
 kine_tracks.C:127
 kine_tracks.C:128
 kine_tracks.C:129
 kine_tracks.C:130
 kine_tracks.C:131
 kine_tracks.C:132
 kine_tracks.C:133
 kine_tracks.C:134
 kine_tracks.C:135
 kine_tracks.C:136
 kine_tracks.C:137
 kine_tracks.C:138
 kine_tracks.C:139
 kine_tracks.C:140
 kine_tracks.C:141
 kine_tracks.C:142
 kine_tracks.C:143
 kine_tracks.C:144
 kine_tracks.C:145
 kine_tracks.C:146
 kine_tracks.C:147
 kine_tracks.C:148
 kine_tracks.C:149
 kine_tracks.C:150
 kine_tracks.C:151
 kine_tracks.C:152
 kine_tracks.C:153
 kine_tracks.C:154
 kine_tracks.C:155
 kine_tracks.C:156
 kine_tracks.C:157
 kine_tracks.C:158
 kine_tracks.C:159
 kine_tracks.C:160
 kine_tracks.C:161
 kine_tracks.C:162
 kine_tracks.C:163
 kine_tracks.C:164
 kine_tracks.C:165
 kine_tracks.C:166
 kine_tracks.C:167
 kine_tracks.C:168
 kine_tracks.C:169
 kine_tracks.C:170
 kine_tracks.C:171
 kine_tracks.C:172
 kine_tracks.C:173
 kine_tracks.C:174
 kine_tracks.C:175
 kine_tracks.C:176
 kine_tracks.C:177
 kine_tracks.C:178
 kine_tracks.C:179
 kine_tracks.C:180
 kine_tracks.C:181
 kine_tracks.C:182
 kine_tracks.C:183
 kine_tracks.C:184
 kine_tracks.C:185
 kine_tracks.C:186
 kine_tracks.C:187
 kine_tracks.C:188
 kine_tracks.C:189
 kine_tracks.C:190
 kine_tracks.C:191
 kine_tracks.C:192
 kine_tracks.C:193
 kine_tracks.C:194
 kine_tracks.C:195
 kine_tracks.C:196
 kine_tracks.C:197
 kine_tracks.C:198
 kine_tracks.C:199
 kine_tracks.C:200
 kine_tracks.C:201
 kine_tracks.C:202
 kine_tracks.C:203
 kine_tracks.C:204
 kine_tracks.C:205
 kine_tracks.C:206
 kine_tracks.C:207
 kine_tracks.C:208
 kine_tracks.C:209
 kine_tracks.C:210
 kine_tracks.C:211
 kine_tracks.C:212
 kine_tracks.C:213
 kine_tracks.C:214
 kine_tracks.C:215
 kine_tracks.C:216
 kine_tracks.C:217
 kine_tracks.C:218
 kine_tracks.C:219
 kine_tracks.C:220
 kine_tracks.C:221
 kine_tracks.C:222
 kine_tracks.C:223
 kine_tracks.C:224
 kine_tracks.C:225
 kine_tracks.C:226
 kine_tracks.C:227
 kine_tracks.C:228
 kine_tracks.C:229
 kine_tracks.C:230
 kine_tracks.C:231
 kine_tracks.C:232
 kine_tracks.C:233
 kine_tracks.C:234
 kine_tracks.C:235
 kine_tracks.C:236
 kine_tracks.C:237
 kine_tracks.C:238
 kine_tracks.C:239
 kine_tracks.C:240
 kine_tracks.C:241
 kine_tracks.C:242
 kine_tracks.C:243
 kine_tracks.C:244
 kine_tracks.C:245
 kine_tracks.C:246
 kine_tracks.C:247
 kine_tracks.C:248
 kine_tracks.C:249
 kine_tracks.C:250
 kine_tracks.C:251
 kine_tracks.C:252
 kine_tracks.C:253
 kine_tracks.C:254
 kine_tracks.C:255
 kine_tracks.C:256
 kine_tracks.C:257
 kine_tracks.C:258
 kine_tracks.C:259
 kine_tracks.C:260
 kine_tracks.C:261
 kine_tracks.C:262
 kine_tracks.C:263
 kine_tracks.C:264
 kine_tracks.C:265
 kine_tracks.C:266
 kine_tracks.C:267
 kine_tracks.C:268
 kine_tracks.C:269
 kine_tracks.C:270
 kine_tracks.C:271
 kine_tracks.C:272
 kine_tracks.C:273
 kine_tracks.C:274
 kine_tracks.C:275
 kine_tracks.C:276
 kine_tracks.C:277
 kine_tracks.C:278
 kine_tracks.C:279
 kine_tracks.C:280
 kine_tracks.C:281
 kine_tracks.C:282
 kine_tracks.C:283
 kine_tracks.C:284
 kine_tracks.C:285
 kine_tracks.C:286
 kine_tracks.C:287
 kine_tracks.C:288
 kine_tracks.C:289
 kine_tracks.C:290
 kine_tracks.C:291
 kine_tracks.C:292
 kine_tracks.C:293
 kine_tracks.C:294
 kine_tracks.C:295
 kine_tracks.C:296
 kine_tracks.C:297
 kine_tracks.C:298
 kine_tracks.C:299
 kine_tracks.C:300
 kine_tracks.C:301
 kine_tracks.C:302
 kine_tracks.C:303
 kine_tracks.C:304
 kine_tracks.C:305
 kine_tracks.C:306
 kine_tracks.C:307
 kine_tracks.C:308
 kine_tracks.C:309
 kine_tracks.C:310
 kine_tracks.C:311
 kine_tracks.C:312
 kine_tracks.C:313
 kine_tracks.C:314
 kine_tracks.C:315
 kine_tracks.C:316
 kine_tracks.C:317
 kine_tracks.C:318
 kine_tracks.C:319
 kine_tracks.C:320
 kine_tracks.C:321
 kine_tracks.C:322
 kine_tracks.C:323
 kine_tracks.C:324
 kine_tracks.C:325
 kine_tracks.C:326
 kine_tracks.C:327
 kine_tracks.C:328
 kine_tracks.C:329
 kine_tracks.C:330
 kine_tracks.C:331
 kine_tracks.C:332
 kine_tracks.C:333
 kine_tracks.C:334
 kine_tracks.C:335
 kine_tracks.C:336
 kine_tracks.C:337
 kine_tracks.C:338
 kine_tracks.C:339
 kine_tracks.C:340
 kine_tracks.C:341
 kine_tracks.C:342
 kine_tracks.C:343
 kine_tracks.C:344
 kine_tracks.C:345
 kine_tracks.C:346
 kine_tracks.C:347
 kine_tracks.C:348
 kine_tracks.C:349
 kine_tracks.C:350
 kine_tracks.C:351
 kine_tracks.C:352
 kine_tracks.C:353
 kine_tracks.C:354
 kine_tracks.C:355
 kine_tracks.C:356
 kine_tracks.C:357
 kine_tracks.C:358
 kine_tracks.C:359
 kine_tracks.C:360
 kine_tracks.C:361
 kine_tracks.C:362
 kine_tracks.C:363
 kine_tracks.C:364
 kine_tracks.C:365
 kine_tracks.C:366
 kine_tracks.C:367
 kine_tracks.C:368
 kine_tracks.C:369
 kine_tracks.C:370
 kine_tracks.C:371
 kine_tracks.C:372
 kine_tracks.C:373
 kine_tracks.C:374
 kine_tracks.C:375
 kine_tracks.C:376
 kine_tracks.C:377
 kine_tracks.C:378
 kine_tracks.C:379
 kine_tracks.C:380
 kine_tracks.C:381
 kine_tracks.C:382
 kine_tracks.C:383
 kine_tracks.C:384
 kine_tracks.C:385
 kine_tracks.C:386