ROOT logo

From $ROOTSYS/tutorials/tree/tree2a.C

#include "TROOT.h"
#include "TFile.h"
#include "TTree.h"
#include "TBrowser.h"
#include "TH2.h"
#include "TMath.h"
#include "TRandom.h"
#include "TCanvas.h"

//+ This example is the same as tree2.C, but uses a class instead of a C-struct.
// In this example, we are mapping a class to one of the Geant3
// common blocks /gctrak/. In the real life, this common will be filled
// by Geant3 at each step and only the Tree Fill function should be called.
// The example emulates the Geant3 step routines.
//
// to run the example, do:
// .x tree2a.C+ to execute with native compiler
//
//  Note that this example cannot be run under CINT (ie .x tree2a.c)
//  because an interpreted class cannot derive from a compiled class.
//
//  Author: Rene Brun

const Int_t MAXMEC = 30;

class Gctrak : public TObject {
public:
  Float_t  vect[7]; 
  Float_t  getot; 
  Float_t  gekin; 
  Float_t  vout[7];   //! not persistent
  Int_t    nmec; 
  Int_t   *lmec;      //[nmec]
  Int_t   *namec;     //[nmec]
  Int_t    nstep;     //! not persistent
  Int_t    pid; 
  Float_t  destep; 
  Float_t  destel;    //! not persistent
  Float_t  safety;    //! not persistent
  Float_t  sleng;     //! not persistent
  Float_t  step;      //! not persistent
  Float_t  snext;     //! not persistent
  Float_t  sfield;    //! not persistent 
  Float_t  tofg;      //! not persistent
  Float_t  gekrat;    //! not persistent 
  Float_t  upwght;    //! not persistent 
  
  Gctrak() {lmec=0; namec=0;}
  
  ClassDef(Gctrak,1)
}; 


void helixStep(Float_t step, Float_t *vect, Float_t *vout)
{
  // extrapolate track in constant field
   Float_t field = 20;      //magnetic field in kilogauss
   enum Evect {kX,kY,kZ,kPX,kPY,kPZ,kPP};
   vout[kPP] = vect[kPP];
   Float_t h4    = field*2.99792e-4;
   Float_t rho   = -h4/vect[kPP];
   Float_t tet   = rho*step;
   Float_t tsint = tet*tet/6;
   Float_t sintt = 1 - tsint;
   Float_t sint  = tet*sintt;
   Float_t cos1t = tet/2;
   Float_t f1 = step*sintt;
   Float_t f2 = step*cos1t;
   Float_t f3 = step*tsint*vect[kPZ];
   Float_t f4 = -tet*cos1t;
   Float_t f5 = sint;
   Float_t f6 = tet*cos1t*vect[kPZ];
   vout[kX]   = vect[kX]  + (f1*vect[kPX] - f2*vect[kPY]);
   vout[kY]   = vect[kY]  + (f1*vect[kPY] + f2*vect[kPX]);
   vout[kZ]   = vect[kZ]  + (f1*vect[kPZ] + f3);
   vout[kPX]  = vect[kPX] + (f4*vect[kPX] - f5*vect[kPY]);
   vout[kPY]  = vect[kPY] + (f4*vect[kPY] + f5*vect[kPX]);
   vout[kPZ]  = vect[kPZ] + (f4*vect[kPZ] + f6);   
}

void tree2aw()
{
   //create a Tree file tree2.root
   
   //create the file, the Tree and a few branches with 
   //a subset of gctrak
   TFile f("tree2.root","recreate");
   TTree t2("t2","a Tree with data from a fake Geant3");
   Gctrak *gstep = new Gctrak;
   t2.Branch("track",&gstep,8000,1);
   
   //Initialize particle parameters at first point
   Float_t px,py,pz,p,charge=0;
   Float_t vout[7];
   Float_t mass  = 0.137;
   Bool_t newParticle = kTRUE;
   gstep->lmec    = new Int_t[MAXMEC];
   gstep->namec   = new Int_t[MAXMEC];
   gstep->step    = 0.1;
   gstep->destep  = 0;
   gstep->nmec    = 0;
   gstep->pid     = 0;
      
   //transport particles 
   for (Int_t i=0;i<10000;i++) {
      //generate a new particle if necessary
      if (newParticle) {
         px = gRandom->Gaus(0,.02);
         py = gRandom->Gaus(0,.02);
         pz = gRandom->Gaus(0,.02);
         p  = TMath::Sqrt(px*px+py*py+pz*pz);
         charge = 1; if (gRandom->Rndm() < 0.5) charge = -1;
         gstep->pid    += 1;
         gstep->vect[0] = 0;
         gstep->vect[1] = 0;
         gstep->vect[2] = 0;
         gstep->vect[3] = px/p;
         gstep->vect[4] = py/p;
         gstep->vect[5] = pz/p;
         gstep->vect[6] = p*charge;
         gstep->getot   = TMath::Sqrt(p*p + mass*mass);
         gstep->gekin   = gstep->getot - mass;
         newParticle = kFALSE;
      }
      
      // fill the Tree with current step parameters
      t2.Fill();
      
      //transport particle in magnetic field
      helixStep(gstep->step, gstep->vect, vout); //make one step
      
      //apply energy loss
      gstep->destep = gstep->step*gRandom->Gaus(0.0002,0.00001);
      gstep->gekin -= gstep->destep;
      gstep->getot   = gstep->gekin + mass;
      gstep->vect[6] = charge*TMath::Sqrt(gstep->getot*gstep->getot - mass*mass);
      gstep->vect[0] = vout[0];
      gstep->vect[1] = vout[1];
      gstep->vect[2] = vout[2];
      gstep->vect[3] = vout[3];
      gstep->vect[4] = vout[4];
      gstep->vect[5] = vout[5];
      gstep->nmec    = (Int_t)(5*gRandom->Rndm());
      for (Int_t l=0;l<gstep->nmec;l++) {
         gstep->lmec[l] = l;
         gstep->namec[l] = l+100;
      }
      if (gstep->gekin < 0.001)            newParticle = kTRUE;
      if (TMath::Abs(gstep->vect[2]) > 30) newParticle = kTRUE;
   }
  
   //save the Tree header. The file will be automatically closed
   //when going out of the function scope
   t2.Write();
}

void tree2ar()
{
   //read the Tree generated by tree2w and fill one histogram
   //we are only interested by the destep branch.
     
   //note that we use "new" to create the TFile and TTree objects !
   //because we want to keep these objects alive when we leave 
   //this function.
   TFile *f = new TFile("tree2.root");
   TTree *t2 = (TTree*)f->Get("t2");
   Gctrak *gstep = 0;
   t2->SetBranchAddress("track",&gstep);
   TBranch *b_destep = t2->GetBranch("destep");
   
   //create one histogram
   TH1F *hdestep   = new TH1F("hdestep","destep in Mev",100,1e-5,3e-5);
   
   //read only the destep branch for all entries
   Long64_t nentries = t2->GetEntries();
   for (Long64_t i=0;i<nentries;i++) {
      b_destep->GetEntry(i); 
      hdestep->Fill(gstep->destep);
   }
  
   //we do not close the file. 
   //We want to keep the generated histograms
   //We fill a 3-d scatter plot with the particle step coordinates
   TCanvas *c1 = new TCanvas("c1","c1",600,800);
   c1->SetFillColor(42);
   c1->Divide(1,2);
   c1->cd(1);
   hdestep->SetFillColor(45);
   hdestep->Fit("gaus");
   c1->cd(2);
   gPad->SetFillColor(37);
   t2->SetMarkerColor(kRed);
   t2->Draw("vect[0]:vect[1]:vect[2]");
   if (gROOT->IsBatch()) return;
   
   // invoke the x3d viewer
   gPad->GetViewer3D("x3d");
}   

void tree2a() {
   tree2aw();
   tree2ar();
}
 tree2a.C:1
 tree2a.C:2
 tree2a.C:3
 tree2a.C:4
 tree2a.C:5
 tree2a.C:6
 tree2a.C:7
 tree2a.C:8
 tree2a.C:9
 tree2a.C:10
 tree2a.C:11
 tree2a.C:12
 tree2a.C:13
 tree2a.C:14
 tree2a.C:15
 tree2a.C:16
 tree2a.C:17
 tree2a.C:18
 tree2a.C:19
 tree2a.C:20
 tree2a.C:21
 tree2a.C:22
 tree2a.C:23
 tree2a.C:24
 tree2a.C:25
 tree2a.C:26
 tree2a.C:27
 tree2a.C:28
 tree2a.C:29
 tree2a.C:30
 tree2a.C:31
 tree2a.C:32
 tree2a.C:33
 tree2a.C:34
 tree2a.C:35
 tree2a.C:36
 tree2a.C:37
 tree2a.C:38
 tree2a.C:39
 tree2a.C:40
 tree2a.C:41
 tree2a.C:42
 tree2a.C:43
 tree2a.C:44
 tree2a.C:45
 tree2a.C:46
 tree2a.C:47
 tree2a.C:48
 tree2a.C:49
 tree2a.C:50
 tree2a.C:51
 tree2a.C:52
 tree2a.C:53
 tree2a.C:54
 tree2a.C:55
 tree2a.C:56
 tree2a.C:57
 tree2a.C:58
 tree2a.C:59
 tree2a.C:60
 tree2a.C:61
 tree2a.C:62
 tree2a.C:63
 tree2a.C:64
 tree2a.C:65
 tree2a.C:66
 tree2a.C:67
 tree2a.C:68
 tree2a.C:69
 tree2a.C:70
 tree2a.C:71
 tree2a.C:72
 tree2a.C:73
 tree2a.C:74
 tree2a.C:75
 tree2a.C:76
 tree2a.C:77
 tree2a.C:78
 tree2a.C:79
 tree2a.C:80
 tree2a.C:81
 tree2a.C:82
 tree2a.C:83
 tree2a.C:84
 tree2a.C:85
 tree2a.C:86
 tree2a.C:87
 tree2a.C:88
 tree2a.C:89
 tree2a.C:90
 tree2a.C:91
 tree2a.C:92
 tree2a.C:93
 tree2a.C:94
 tree2a.C:95
 tree2a.C:96
 tree2a.C:97
 tree2a.C:98
 tree2a.C:99
 tree2a.C:100
 tree2a.C:101
 tree2a.C:102
 tree2a.C:103
 tree2a.C:104
 tree2a.C:105
 tree2a.C:106
 tree2a.C:107
 tree2a.C:108
 tree2a.C:109
 tree2a.C:110
 tree2a.C:111
 tree2a.C:112
 tree2a.C:113
 tree2a.C:114
 tree2a.C:115
 tree2a.C:116
 tree2a.C:117
 tree2a.C:118
 tree2a.C:119
 tree2a.C:120
 tree2a.C:121
 tree2a.C:122
 tree2a.C:123
 tree2a.C:124
 tree2a.C:125
 tree2a.C:126
 tree2a.C:127
 tree2a.C:128
 tree2a.C:129
 tree2a.C:130
 tree2a.C:131
 tree2a.C:132
 tree2a.C:133
 tree2a.C:134
 tree2a.C:135
 tree2a.C:136
 tree2a.C:137
 tree2a.C:138
 tree2a.C:139
 tree2a.C:140
 tree2a.C:141
 tree2a.C:142
 tree2a.C:143
 tree2a.C:144
 tree2a.C:145
 tree2a.C:146
 tree2a.C:147
 tree2a.C:148
 tree2a.C:149
 tree2a.C:150
 tree2a.C:151
 tree2a.C:152
 tree2a.C:153
 tree2a.C:154
 tree2a.C:155
 tree2a.C:156
 tree2a.C:157
 tree2a.C:158
 tree2a.C:159
 tree2a.C:160
 tree2a.C:161
 tree2a.C:162
 tree2a.C:163
 tree2a.C:164
 tree2a.C:165
 tree2a.C:166
 tree2a.C:167
 tree2a.C:168
 tree2a.C:169
 tree2a.C:170
 tree2a.C:171
 tree2a.C:172
 tree2a.C:173
 tree2a.C:174
 tree2a.C:175
 tree2a.C:176
 tree2a.C:177
 tree2a.C:178
 tree2a.C:179
 tree2a.C:180
 tree2a.C:181
 tree2a.C:182
 tree2a.C:183
 tree2a.C:184
 tree2a.C:185
 tree2a.C:186
 tree2a.C:187
 tree2a.C:188
 tree2a.C:189
 tree2a.C:190
 tree2a.C:191
 tree2a.C:192
 tree2a.C:193
 tree2a.C:194
 tree2a.C:195
 tree2a.C:196
 tree2a.C:197
 tree2a.C:198
 tree2a.C:199
 tree2a.C:200
 tree2a.C:201
 tree2a.C:202
 tree2a.C:203
 tree2a.C:204