From $ROOTSYS/tutorials/eve/track.C

// @(#)root/eve:$Id$
// Author: Alja Mrak-Tadel

// Demonstrates usage of TEveTrackPRopagator with different magnetic
// field configurations.
// Needs to be run in compiled mode.
// root
//   .L track.C+
//   track(3, kTRUE)
//
// void track(Int_t mode = 5, Bool_t isRungeKutta = kTRUE)
// Modes are
// 0 - B = 0, no difference btween signed and charge particles;
// 1 - constant B field (along z, but could have arbitrary direction);
// 2 - variable B field, sign change at  R = 200 cm;
// 3 - magnetic field with a zero-field region;
// 4 - CMS magnetic field - simple track;
// 5 - CMS magnetic field - track with different path-marks.
// 6 - Concpetual ILC detector, problematic track

#if defined(__CINT__) && !defined(__MAKECINT__)
{
   Info("track.C",
        "Has to be run in compiled mode, esp. if you want to pass parameters.");
   gSystem->CompileMacro("track.C");
   track();
}
#else

#include "TEveTrackPropagator.h"
#include "TEveTrack.h"
#include "TEveVSDStructs.h"
#include "TEveManager.h"
#include "TEveViewer.h"
#include "TSystem.h"
#include "TGLViewer.h"
#include "TMath.h"

#include "TEveViewer.h"
#include "TEvePointSet.h"

#include <iostream>

TEveTrackPropagator* g_prop = 0;

class GappedField : public TEveMagField
{
public:
   GappedField():TEveMagField(){}
   ~GappedField(){};
   using   TEveMagField::GetField;

   virtual TEveVectorD GetFieldD(Double_t /*x*/, Double_t /*y*/, Double_t z) const
   {
      if (TMath::Abs(z) < 300) return TEveVectorD(0, 0, -4);
      if (TMath::Abs(z) < 600) return TEveVectorD(0, 0, 0);
      return TEveVectorD(0, 0, 4);
   }
};

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

class CmsMagField: public TEveMagField
{
   bool m_magnetIsOn;
   bool m_reverse;
   bool m_simpleModel;

public:
   CmsMagField():
      m_magnetIsOn(true),
      m_reverse(false),
      m_simpleModel(true){}

   virtual ~CmsMagField(){}
   virtual Double_t   GetMaxFieldMagD() const { return m_magnetIsOn ? 3.8 : 0.0; }
   void               setMagnetState( bool state )
   {
      if (state != m_magnetIsOn)
      {
         if ( state )
            std::cout << "Magnet state is changed to ON" << std::endl;
         else
            std::cout << "Magnet state is changed to OFF" << std::endl;
      }
      m_magnetIsOn = state;
   }

   bool isMagnetOn() const               { return m_magnetIsOn;}
   void setReverseState(bool state)      { m_reverse = state; }
   bool isReverse() const                { return m_reverse;}
   void setSimpleModel(bool simpleModel) { m_simpleModel = simpleModel; }
   bool isSimpleModel() const            { return m_simpleModel;}

   using   TEveMagField::GetField;

   virtual TEveVectorD GetFieldD(Double_t x, Double_t y, Double_t z) const
   {
      double R = sqrt(x*x+y*y);
      double field = m_reverse?-GetMaxFieldMag():GetMaxFieldMag();
      //barrel
      if ( TMath::Abs(z)<724 )
      {
         //inside solenoid
         if ( R < 300) return TEveVectorD(0,0,field);
         // outside solinoid
         if ( m_simpleModel ||
              ( R>461.0 && R<490.5 ) ||
              ( R>534.5 && R<597.5 ) ||
              ( R>637.0 && R<700.0 ) )
            return TEveVectorD(0,0,-field/3.8*1.2);

      } else {
         // endcaps
         if (m_simpleModel)
         {
            if ( R < 50 ) return TEveVectorD(0,0,field);
            if ( z > 0 )
               return TEveVectorD(x/R*field/3.8*2.0, y/R*field/3.8*2.0, 0);
            else
               return TEveVectorD(-x/R*field/3.8*2.0, -y/R*field/3.8*2.0, 0);
         }
         // proper model
         if ( ( TMath::Abs(z)>724 && TMath::Abs(z)<786  ) ||
              ( TMath::Abs(z)>850 && TMath::Abs(z)<910  ) ||
              ( TMath::Abs(z)>975 && TMath::Abs(z)<1003 ) )
         {
            if ( z > 0 )
               return TEveVectorD(x/R*field/3.8*2.0, y/R*field/3.8*2.0, 0);
            else
               return TEveVectorD(-x/R*field/3.8*2.0, -y/R*field/3.8*2.0, 0);
         }
      }
      return TEveVectorD(0,0,0);
   }
};


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

//______________________________________________________________________________
TEveTrack* make_track(TEveTrackPropagator* prop, Int_t sign)
{
  // Make track with given propagator.
  // Add to math-marks to test fit.

  TEveRecTrackD *rc = new TEveRecTrackD();
  rc->fV.Set(0.028558, -0.000918, 3.691919);
  rc->fP.Set(0.767095, -2.400006, -0.313103);
  rc->fSign = sign;

  TEveTrack* track = new TEveTrack(rc, prop);
  track->SetName(Form("Charge %d", sign));
  // daughter 0
  TEvePathMarkD* pm1 = new TEvePathMarkD(TEvePathMarkD::kDaughter);
  pm1->fV.Set(1.479084, -4.370661, 3.119761);
  track->AddPathMark(*pm1);
  // daughter 1
  TEvePathMarkD* pm2 = new TEvePathMarkD(TEvePathMarkD::kDaughter);
  pm2->fV.Set(57.72345, -89.77011, -9.783746);
  track->AddPathMark(*pm2);

  return track;
}


void track(Int_t mode = 1, Bool_t isRungeKutta = kTRUE)
{
#if defined (__CINT__)
   Error("track.C", "Must be run in compiled mode!");
   return;
#endif

   gSystem->IgnoreSignal(kSigSegmentationViolation, true);
   TEveManager::Create();

   TEveTrackList *list = new TEveTrackList();
   TEveTrackPropagator* prop = g_prop = list->GetPropagator();
   prop->SetFitDaughters(kFALSE);
   prop->SetMaxZ(1000);

   if (isRungeKutta)
   {
      prop->SetStepper(TEveTrackPropagator::kRungeKutta);
      list->SetName("RK Propagator");
   }
   else
   {
      list->SetName("Heix Propagator");
   }

   TEveTrack *track = 0;
   switch (mode)
   {
      case 0:
      {
         // B = 0 no difference btween signed and charge particles
         prop->SetMagField(0.);
         list->SetElementName(Form("%s, zeroB", list->GetElementName()));
         track = make_track(prop, 1);
         break;
      }

      case 1:
      {
         // constant B field, const angle
         prop->SetMagFieldObj(new TEveMagFieldConst(0., 0., -3.8));
         list->SetElementName(Form("%s, constB", list->GetElementName()));
         track = make_track(prop, 1);
         break;
      }

      case 2:
      {
         // variable B field, sign change at  R = 200 cm
         prop->SetMagFieldObj(new TEveMagFieldDuo(200, -4.4, 2));
         list->SetElementName(Form("%s, duoB", list->GetElementName()));
         track = make_track(prop, 1);
         break;
      }

      case 3:
      {
         // gapped field
         prop->SetMagFieldObj(new GappedField());
         list->SetElementName(Form("%s, gappedB", list->GetElementName()));


         TEveRecTrackD *rc = new TEveRecTrackD();
         rc->fV.Set(0.028558, -0.000918, 3.691919);
         rc->fP.Set(0.767095, -0.400006, 2.313103);
         rc->fSign = 1;
         track = new TEveTrack(rc, prop);

         TEvePointSet* marker = new TEvePointSet(2);
         marker->SetElementName("B field break points");
         marker->SetPoint(0, 0., 0., 300.f);
         marker->SetPoint(1, 0., 0., 600.f);
         marker->SetMarkerColor(3);
         gEve->AddElement(marker);
         break;
      }

      case 4:
      {
         // Magnetic field of CMS I.
         CmsMagField* mf = new CmsMagField;
         mf->setReverseState(true);

         prop->SetMagFieldObj(mf);
         prop->SetMaxR(1000);
         prop->SetMaxZ(1000);
         prop->SetRnrDaughters(kTRUE);
         prop->SetRnrDecay(kTRUE);
         prop->RefPMAtt().SetMarkerStyle(4);
         list->SetElementName(Form("%s, CMS field", list->GetElementName()));


         TEveRecTrackD *rc = new TEveRecTrackD();
         rc->fV.Set(0.027667, 0.007919, 0.895964);
         rc->fP.Set(3.903134, 2.252232, -3.731366);
         rc->fSign = -1;
         track = new TEveTrack(rc, prop);

         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(3.576755e+00, 2.080579e+00, -2.507230e+00)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(8.440379e+01, 6.548286e+01, -8.788129e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.841321e+02, 3.915693e+02, -3.843072e+02)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.946167e+02, 4.793932e+02, -4.615060e+02)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDecay,
                  TEveVectorD(2.249656e+02, 5.835767e+02, -5.565275e+02)));

         track->SetRnrPoints(kTRUE);
         track->SetMarkerStyle(4);

         break;
      }

      case 5:
      {
         // Magnetic field of CMS I.
         CmsMagField* mf = new CmsMagField;
         mf->setReverseState(true);
         mf->setSimpleModel(false);

         prop->SetMagFieldObj(mf);
         prop->SetMaxR(1000);
         prop->SetMaxZ(1000);
         prop->SetRnrReferences(kTRUE);
         prop->SetRnrDaughters(kTRUE);
         prop->SetRnrDecay(kTRUE);
         prop->RefPMAtt().SetMarkerStyle(4);
         list->SetElementName(Form("%s, CMS field", list->GetElementName()));

         TEveRecTrackD *rc = new TEveRecTrackD();
         rc->fV.Set(-16.426592, 16.403185, -19.782692);
         rc->fP.Set(3.631100, 3.643450, 0.682254);
         rc->fSign = -1;
         track = new TEveTrack(rc, prop);

         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kReference,
                  TEveVectorD(-1.642659e+01, 1.640318e+01, -1.978269e+01),
                  TEveVectorD(3.631100, 3.643450, 0.682254)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kReference,
                  TEveVectorD(-1.859987e+00, 3.172243e+01, -1.697866e+01),
                  TEveVectorD(3.456056, 3.809894, 0.682254)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kReference,
                  TEveVectorD(4.847579e+01, 9.871711e+01, -5.835719e+00),
                  TEveVectorD(2.711614, 4.409945, 0.687656)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.342045e+02, 4.203950e+02, 3.846268e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.483827e+02, 5.124750e+02, 5.064311e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.674676e+02, 6.167731e+02, 6.517403e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDecay,
                  TEveVectorD(1.884976e+02, 7.202000e+02, 7.919290e+01)));

         track->SetRnrPoints(kTRUE);
         track->SetMarkerStyle(4);

         break;
      }

      case 6:
      {
         // Problematic track from Druid
         prop->SetMagFieldObj(new TEveMagFieldDuo(350, -3.5, 2.0));
         prop->SetMaxR(1000);
         prop->SetMaxZ(1000);
         prop->SetRnrReferences(kTRUE);
         prop->SetRnrDaughters(kTRUE);
         prop->SetRnrDecay(kTRUE);
         prop->RefPMAtt().SetMarkerStyle(4);
         list->SetElementName(Form("%s, Some ILC Detector field",
                                   list->GetElementName()));

         TEveRecTrackD *rc = new TEveRecTrackD();
         rc->fV.Set(57.1068, 31.2401, -7.07629);
         rc->fP.Set(4.82895, 2.35083, -0.611757);
         rc->fSign = 1;
         track = new TEveTrack(rc, prop);

         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(1.692235e+02, 7.047929e+01, -2.064785e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDaughter,
                  TEveVectorD(5.806180e+02, 6.990633e+01, -6.450000e+01)));
         track->AddPathMark(TEvePathMarkD(TEvePathMarkD::kDecay,
                  TEveVectorD(6.527213e+02, 1.473249e+02, -8.348498e+01)));

         track->SetRnrPoints(kTRUE);
         track->SetMarkerStyle(4);

         break;
      }
   };

   if (isRungeKutta)
      list->SetLineColor(kMagenta);
   else
      list->SetLineColor(kCyan);

   track->SetLineColor(list->GetLineColor());

   gEve->AddElement(list);
   list->AddElement(track);

   track->MakeTrack();

   TEveViewer *ev = gEve->GetDefaultViewer();
   TGLViewer  *gv = ev->GetGLViewer();
   gv->SetGuideState(TGLUtil::kAxesOrigin, kTRUE, kFALSE, 0);

   gEve->Redraw3D(kTRUE);
   gSystem->ProcessEvents();

   gv->CurrentCamera().RotateRad(-0.5, 1.4);
   gv->RequestDraw();
}

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