# Presentation: 249798

## ROOT 102

- ROOT is an object oriented HEP analysis framework

## ROOT contacts at Fermi

- Philippe Canal , x2545	pcanal@fnal.gov
- Peter Malzacher, x6510	malzache@fnal.gov
- Suzanne Panacek, x8334	spanacek@fnal.gov

## What We Will Cover Today

- Macros
- Fitting
- I/O
- Analysis
- CINT
- Command line
- Debugging
- Environment

## Class Schedule

- _Session 1: Functions and Fitting_
- Function Objects (TF1)
- Fitting
- _Session 2: Building ROOT Trees_
- Files, Trees, and Branches
- 5 Steps to build a TTree
- Exercise #1
- _Break_

**Notes:**
This class is organized to give the student some hands-on experience with ROOT. There are four exercise sessions where you  can practice the subjects covered in the session.

We ask you to return promptly from the exercise and make a switch from the hands-on mode to the lecture-mode. 

## Class Schedule

- _Session 3: Putting Trees to Work_
- Using Trees in Analysis
- Exercise #2_ _
- _Session 4: More about CINT _
- Environment settings
- CINT debugging
- Exercise #3
- _Session 5: For real Experts_
- How to add your own root classes
- Script compiler

## Session1: Functions and Fitting

- Function Objects (TF1)
- Three constructors for TF1
- User Defined Functions
- Fitting
- Fit()
- Fitting with a user defined function
- Fitting subranges and combining functions
- Demonstration of background and signal function

## Function Objects (TF1)

- Built in function objects
- see this link for a full list of built in functions
- _[http://root.cern.ch/root/html/TFormula.html#TFormula:TFormula](http://root.cern.ch/root/html/TFormula.html#TFormula:TFormula)_
- use the Fit Panel
- Creating your own function objects
- TF1, TF2, TF3
- Three Signatures for the TF1 constructor

**Notes:**
A TF1 object is a one dimensional function defined between a lower and upper limit.
 In addition to TF1, ROOT provides a TF2 and a TF3.  TF2 is a 2 dimensional function with parameters, and TF3 is a 3 dimensional function with parameters

## TF1 Constructors

- 1. A C++ like expression using x with a fixed set of operators and functions defined in TFormula
- TF1 *f1 = new TF1("f1",**"sin(x)/x"**,0,10);
- f1->Draw();
- TF1 *f2 = new TF1("f2","**f1 * 2**",0,10);

## TF1 Constructors (cont.)

- 2. Same as the previous TF1  with Parameters
- Call the constructor with parameter indices
- TF1 *f1 = new TF1
- ("f1","**[0]**** ***x*sin( **[1]**** ***x)",-3,3);
- Set the parameters explicitly
- f1->SetParameter(0,10);f1->SetParameter(1,5);f1->Draw();

## TF1 Constructors (cont.)

- 3. Use a defined function
- Define a function**Double_t MyFunction(Double_t *x, Double_t *par)**{ 	Float_t  xx 	=	x[0];	Double_t val	= 		TMath::Abs(par[0]*sin(par[1]*xx)/xx); 	return val;}
- TF1 constructor TF1 *f1 = new TF1("f1",**MyFunction**,0,10,**2**);
- NOTE: The **2** is the number of parameters in MyFunction.
- Set the parametersf1->SetParameters(2,1);

## Fitting

- To fit a histogram:
- 	<Histogram>->Fit("<FunctionName>");
- 	TF1 *f1 = new TF1
- ("**f1**","[0]** ***x*sin([1]*x)",-3,3);
- f1->SetParameters(10,5);aHistogram->Fit("**f1**");

## Fitting

*Example: fitting a histogram with user defined function.*
- Step 1. Define the function:
**Double_t MyFunction (Double_t *x, Double_t *par)**
- {
- 	Double_t arg= 0;
- 	if (par[2]) arg = (x[0] - par[1])/par[2];
- 	Double_t fitval =
- 		par[0] * TMath::Exp(-0.5*arg*arg);
- 	return fitval;
- }

**Notes:**

To fit a histogram with a user define function:
Step 1:
Create a new macro and define the function to use in the fit. 
{
   Double_t MyFunction (Double_t *x, Double_t *par)
   {
      Double_t arg= 0;	
      if (par[2]) arg = (x[0] - par[1])/par[2];	
      Double_t fitval = 
	par[0]*TMath::Exp(-0.5*arg*arg);
      return fitval;
   }
}

## Fitting (cont.)

- Step 2. TF1 constructorTF1 *aFunction = 		new TF1("**MyGaus**", **MyFunction**, -5,5,**3**);
- Step 3. Set initial value of the parametersaFunction->SetParameters(**5000, ****	****	****h->GetMean(),****	****	****h->GetRMS());**
- Step 4. Fit and draw the histogramh->Fit("**MyGaus**");

**Notes:**
Step 2: Call the constructor for TF1 with the name of the function, the lower and upper limits and the number of parameters.
   TF1 *aFunction = 
      new TF1("MyGaus", MyFunction, -5,5,3);
Step 3**:
Set the parameters: p1 = 5000, p2 = mean of the histogram, p3 = the RMS of the histogram
  aFunction->SetParameters(5000, 		h->GetMean(),		h->GetRMS
Step 4: 
Fit the histogram with the predefined function.
   h->fit("MyGaus");
** we assume you have a histogram h to use.

## Fitting Subranges

- Define the range in the TF1 constructor.
- TF1 *g1 = new TF1("**g1**", "gaus", **85,95**);
- Use "R" option in the Fit() method.h->Fit**("g1", "R");**

**Notes:**
Fitting a subrange:
Step 1:
create a function for the fit and give it a subrange in the constructor
   TF1 *g1 = new TF1("g1", "gaus", 85,98);

Step 2:
fit and draw the histogram and use the range specified in the function constructor. 
	h->Fit("g1","R");

Fitting multiple functions 
Step 1:
create one more function, this time we use the gaussian function provided by ROOT. Give it a subrange:   	TF1   *gaus1 = new TF1("g1","gaus",1,3);   
Step 2:Call the Fit method . Use the "R" option to use the range specified by the function constructor. Use the "+" option to add this new function to the list of functions. By default the previous function is deleted.
	aHisto->Fit("g1","R+");

## Combining Functions

- Add two functions with "+" operator.
- Assign the parameters for each contributing function.

## Combining Functions

- y(E) = a1 + a2E + a3E2    +   AP  ( / 2 )/( (E-)2 + (/2)2) 			background			lorenzianPeak
- 	par[0] = a1			par[0] = AP
- 	par[1] = a2			par[1] = 
- 	par[2] = a3			par[2] = 
- fitFunction = background (x, par ) + lorenzianPeak (x, &par[3])
- 	par[0] = a1
- 	par[1] = a2
- 	par[2] = a3
- 	par[3] = Ap
- 	par[4] = 
- 	par[5] = 

## Fitting Demo

- Look at
- FittingDemo.C
- fitf.C
- Run FittingDemo.C
- More info on fitting:
- _[http://root.cern.ch/root/html/examples/fit1.C.html](http://root.cern.ch/root/html/examples/fit1.C.html)_
- _[http://root.cern.ch/root/html/examples/myfit.C.html](http://root.cern.ch/root/html/examples/myfit.C.html)_
- _[http://root.cern.ch/root/html/examples/backsig.C.html](http://root.cern.ch/root/html/examples/backsig.C.html)_

**Notes:**
See FittingDemo.C and fitf.C

FittingDemo.C is an unamed macro. The concept of named and unamed macros is covered in ROOT 101. A named macro has a function that has the same name as the file and is executed when CINT parses the .X command. All variables in the function are local and not accessible on the command line. An unamed macro is a set of commands enclosed in curly brackets. It can or can not have functions. All commands inside the curly brackets are executed, and the variables are global and available on the command line.

## Session1: Functions and Fitting Summary

- Functions Objects (TF1)
- Three constructors for TF1
- User Defined Functions
- Fitting
- Fit()
- Fitting with a user defined function
- Fitting subranges and combining functions
- Demonstration of background and signal function

## Session 2: Building ROOT Trees

- Overview of
- ROOT Files
- Trees
- Branches
- 5 Steps to build a TTree
- DemonstrationBuilding a tree with an object.
- Exercise #1

## ROOT Files (TFile)

- When a ROOT file is opened it becomes the _current directory_.
- Histograms and trees are _automatically saved_ in the file.
- When the file is closed the _histogram and tree objects _associated with the file_ are deleted_.
- _Any object_ derived from TObject can be written to a ROOT file. It has to be added explicitly.

**Notes:**
Some points to remember about the TFile class:
The constructor of the TFile opens the file for reading or writing.
When a file is opened in ROOT, it becomes the current directory. The global variable gDirectory reflects this.  To change directory to a different file use the cd() method for the target file.  
New histograms and trees are automatically written to the current file. 
Any object derived from TObject can be written to the file, however they have to be added explicitly by calling file->Append(), or object->Write().
When the file is closed or the file object deleted, the histograms and trees in the file are no longer available in the ROOT session. The histogram and tree objects and  are deleted along with the file object.

## ROOT Trees (TTree)

- Storing _large number_ of entries.
- _Hierarchy_ of branches and leaves.
- Reading _selective_ branches
- Use TTree::_AutoSave()_ to save the tree.

**Notes:**
The TTree class is designed for storing large number of events. It minimizes the space overhead per entry to about 4 bytes. If each entry were added individually it would require about 60 bytes of control data. 
 The constructor allows the specification of a buffer size that is flushed to disk when it is full.
 A tree can also be split across several files .
The TTree class consists of a hierarchy of branches and leaves which allows a flexible organization of data
 a tree may have one or many branches and  a branch may have one or many leaves
 branches are independent and  maybe written to different files
 The TTree class allows selective branches to be read for optimized I/O. Each branch can be read independently of any other branch.
A TTree is flushed to disk every time the buffer is full (see buffer size in the Branch method). However, if no call to Write() is made the header information for the tree is not written disk which means you can not retrieve data from it. 
To automatically write the tree to the file use the AutoSave() method of TTree. The AutoSave() method writes the file every fAutoSave bytes.

## ROOT Branches (TBranch)

- _Independent _of each other
- Can be written to _different files_
- _Three kinds_ of branches:
- simple structure or list of variables
- any object (TObject)
- a TClonesArray

## Five Steps to Build a Tree

- _	__	__Steps:_
- 		1. Create a TFile
- 		2. Create a TTree
- 		3. Add TBranch to the TTree
- 		4. Fill the tree
- 		5. Write the file

## Step 1: Create a TFile Object

- The TFile constructor
- file name (i.e. " AFile.root ")
- option: _NEW, CREATE, RECREATE,_ _UPDATE,_ _or READ_
- file title, shown in the root browser
- compression level 0-9, defaults to 1.

- TFile *hfile = new
-    TFile("AFile.root","RECREATE","Example");

**Notes:**
Step 1: Create a macro (BuildTree.C). First load the shared library libEvent.so that contains the class definition of Event and Track. These are the objects we want to write to the tree. Then create a TFile object. 
{
// load the shared library with the class definition
// for event.
 gROOT->LoadMacro("$ROOTSYS/test/libEvent.so"); 

// create a TFile object, using RECREATE to overwrite // if it exists 	
TFile *hfile = new TFile("AFile.root", "RECREATE", 
               "An Example ROOT file");
}

## Step 2: Create a TTree Object

- A tree is a list of branches.
- The TTree Constructor:
- Tree Name (e.g. "T")
- Tree Title
- Maximum total size of buffers kept in memory  (defaults to 64 MB)

- TTree *tree = new TTree("T","A ROOT tree");

**Notes:**
Maxvirtualsize is by default 64Mbytes. It means: Keeps as many buffers in memory until the sum of all buffers is greater than 64 Megabyte. 
Step 2
create a TTree object with the name T and the default buffer size of 64 MB
TTree *tree = new TTree("T","A ROOT tree");

## Step 3: Adding Branches with an Object

- Branch name
- Class name
- Object (descendant of TObject)
- Buffer size (default = 32,000)
- Split level (default = 1)

- Event *event = new  Event();
- tree->Branch
-   ("EventBranch","Event",&event,64000,1);

**Notes:**
Step 3
create a branch object for the event object:
Event *event = new  Event(); tree->Branch       ("EventBranch","Event",&event,64000,1);

## Splitting a Branch

- Setting the split level (default = 1)

- Split level = 0

- Split level = 1

- Example:
- tree->Branch("EvBr","Event",&ev,64000,0);

**Notes:**
Setting the split level
If split level=1 (default), this branch will automatically be split into sub-branches, with one sub-branch for each data member of the object itself.  Splitting is recursive so that there is a branch for each of the data members of the objects contained in the top object. The parent class is also split.
If the split level = 0, the branch is not split and the entire object is written on one branch. 
Making one single branch and one single buffer can be the right choice when one wants to process only a subset of all entries in the tree.
Making several branches is particularly interesting in the data analysis phase, when one wants to histogram some attributes of an object (entry) without reading all the attributes.

## Adding Branches with a List of Variables

- Branch name
- Address: the address of the first item of a structure.
- Leaflist: all variable names and types

- Example
- TBranch *b = tree->Branch ("Ev_Branch",&event,
- 	"ntrack/I:nseg:nvtex:flag/i:temp/F");

**Notes:**
The variable name and the variable type are separated by a slash (/). If no type is given, the type of the variable is assumed to be the same as the previous variable. If the first variable does not have a type, it is assumed of type F by default. 
The list of currently supported types is given below: 
- C : a character string terminated by the 0 character- B : an 8 bit signed integer - b : an 8 bit unsigned integer - S : a 16 bit signed integer - s : a 16 bit unsigned integer - I : a 32 bit signed integer - i : a 32 bit unsigned integer - F : a 32 bit floating point - D : a 64 bit floating point
The leaflist with names of variables is NOT used to pick variables out of the structure, but is only used later by root as names for the elements that were saved on the branch. The type info is used for a byte count to decide how much to save. The variables actually written out are simply the block of bytes starting at the starting address, and they may or may not match up with the leaflist depending on whether or not the programmer is being careful. 
A branch created with a structure is probably the closest to a branch that represents a block in an ntuple.

## Adding Branches with a TClonesArray

- Branch name
- Clones array
- Buffer size
- Split level (default = 1)

- Example:
- tree->Branch( "Track_B",&Track,64000,1);

**Notes:**
This Branch method takes as input an array of objects of the same class (I.e. tracks, hits). When the split level is set to 1 (and by default) it creates one branch for each of the members of the class.
Using a ClonesArray in the Branch method will optimize the I/O for the root file. Since ROOT knows a clones array contains objects of the same class, it will reuse the memory space to read and write the object from the tree. This optimization uses much fewer calls to "new" and can make a large difference in execution time. 
TClonesArray
The TClonesArray is a direct access list of objects of the same class. For example, if the TClonesArray is an array of TTrack objects, this function will create one sub-branch for each data member of the object TTrack.

## Step 4: Fill the Tree 

- Create a for loop
- Create Event objects.
- Call the Fill method for the tree.
- 		tree->Fill()

**Notes:**
The Fill method will loop on all defined branches and fetch the information from the variables associated with the branch and copy it to the branch.
Step 4
write a for loop to assigns values to create events and fill the tree with them.
for (ev = 0; ev < 200; ev++) {
   Float_t  sigmat, sigmas;
   gRandom->Rannor(sigmat,sigmas);
   Int_t ntrack = Int_t (600 +600*sigmat/120.);
   Float_t random = gRandom->Rndm(1); 
   event -> SetHeader(ev, 200, 960312, random);
   event -> SetNseg(Int_t (10*600+20*sigmas));
   event -> SetNvertex(1); 
   event -> SetFlag(UInt_t (random+0.5));
   event -> SetTemperature(random+20.);
   for (Int_t t = 0; t < ntrack; t++)
      event->AddTrack(random); 
   tree->Fill();   //fill the tree
   event->GetTracks()->Clear();
}

## Step 5: Write the File

- The TFile::Write()
- Writes Histograms and Trees
- Write is needed to write file header
- hfile->Write();

**Notes:**

Step 5
write the file.
	hfile->Write();

When is what written to disk?
File Header: when calling the file->Write() or file->Close() method.File Content: when calling the file->Write() or file->Close() method.Objects on file (like Histograms): with File Content or when calling theobj->Write() method.Trees: same as other objects or when the number of bytes that have been generated since the previous AutoSave is greater than fAutoSave (use SetAutoSave) (this includes, tree, branch and leaf meta data).Leaf data: every time the buffer is full (size given in the TTree::Branch call)or the tree is written.

## Demonstration: 5 steps to build a Tree

- BuildTreeDemo.C
- create "AFile.root"
- 2nd Type of Branch, crated with a class name and split.
- .X BuildTreeDemo.C
- One tree called "T"
- One branch for eachdata member of Event.
- recursive split (see Track)

**Notes:**
As an example, look at BuildTreeDemo.C. This is a macro containing the 5 steps discussed earlier. 

Now execute the BuildTreeDemo.C

root [0] .X BuildTree.C
root [1] TBrowser B

You can see there is a tree called "T", and one branch for each data member of the object we used to create the branch. You can also see the recursive nature of the split. Each data member of Track is also in a branch.

## Session 2: Building ROOT Trees Summary

- Overview of
- ROOT Files
- Trees
- Branches
- 5 Steps to build a TTree
- Demonstrationbuilding a tree with an object

## Exercises #1

- Write a macro (ABCWrite.C) that creates a tree from the floating numbers in the ASCII file ABC.txt. The tree should contain 2 branches. The first branch has three variables (a,b,c). The second branch has one variable p=sqrt(a*a + b*b + c*c). Write the tree to a file called ABC.root.
- ABC.txt can be found at:_[_x000b_](http://www-pat.fnal.gov/root/102/ABC.txt)__[www-pat.fnal.gov/root/102/ABC.](http://www-pat.fnal.gov/root/102/ABC.txt)__[txt](http://www-pat.fnal.gov/root/102/ABC.txt)_

## Session 3: Putting Trees to Work

- Using Trees in Analysis
- From the command line
- Using MakeClass
- Using Chains
- Exercise #2_ _

## Using Trees in Analysis

- The TTree::Draw()
- _Parameters:_
- 1. expressions for x,y,z

- myTree->Draw("**ntrack**");
- myTree->Draw("**sqrt(ntrack): ntrack**");

**Notes:**
Steps by Step:
To draw views of a tree from the command line:
1. Open the root file if it is not already open :
TFile *p = new TFile("AFile.root","READ");
2. Create a canvas with 4 divisions and activate the first sub-pad
TCanvas *myCanvas = new TCanvas
	("myCanvas","My Canvas", 0,0,600,400);
myCanvas->Divide(2,2);
myCanvas->cd(1);
3. Draw the first histogram using the TTree::Draw method with just the name of a variable.
T->Draw("ntrack");
4. Change the active pad and use the TTree::Draw method to plot two variables.
myCanvas->cd(2);
T->Draw("sqrt(ntrack): ntrack");

## Using Trees in Analysis (cont.)

- The TTree::Draw()
-  _Parameters:_
- 2. selection
- 3. draw option
- 4. number of entries

- myTree->Draw("sqrt(ntrack): ntrack",	"**temp > 20.8**");myTree ->Draw("sqrt(ntrack): ntrack",
- 	"temp >20.8","**surf2**");

**Notes:**
Steps by Step continued:
5. Change the active pad and add a selection parameter to TTree::Draw 
myCanvas->cd(3); 
T->Draw("sqrt(ntrack): ntrack","temp > 20.8");
6. Change the active pad and add a draw option
myCanvas->cd(4); 
T->Draw("sqrt(ntrack): ntrack",
		"temp >20.8","surf2");

## Using Trees in Analysis (cont.)

- If the Branch was created with an object and was not split we can still use the Draw() method.
- myTree->Draw("**event.GetNtrack()**");
- 				event 	  = branch name
- 				GetNtrack()  = a method of the 					   	   object on the branch.

## Histograms and Lists 

- The TTree::Draw() parameters continued:
- - saving the histogram
- 		myTree ->Draw(" ntrack **>> myHisto**");	myHisto->Draw();
- 	 - saving an event list 	myTree ->Draw("**>> myList**","ntrack>0");	myList->Print("all")
- - using an event list	myTree ->**SetEventList**(myList);	myTree ->Draw("ntrack");

**Notes:**
Saving the histogram:
- By default ROOT creates a histogram called htemp.
- By default the histogram is reset. Use a "+"  to append the data to the histogram:
	T->Draw("ntrack >>+ myHisto") 
Saving an event list:
T->Draw(">> myList", " ntrack");
myList->Print("all")
When the first argument is preceded by ">>" ROOT knows that this command is not intended to draw anything, but to save the entries in a list with the name given in the first argument.

Using the event list:
TEventList *elist = (TEventList*)gDirectory->Get("myList");
T->SetEventList(elist);
T->Draw("ntrack");

## Information about the TTree Contents

- After executing the Draw command, we can get information about the TTree:
- GetSelectedRows()
- Returns the number of entries accepted by the selection expression.
- GetV1(), GetV2(), GetV3()
- returns a pointer to the float array of the first, second, or third variable (x,y,z)
- GetW()

**Notes:**
After executing the Draw command, we can get information about the TTree:
- GetSelectedRows ()    returns the number of entries accepted by the selection expression. In case where no selection was specified, it returns the number of entries processed. 
- GetV1()   returns a pointer to the float array of the first variable
- GetV2()   returns a pointer to the float array of second variable 
- GetV3()   returns a pointer to the float array of third variable
- GetW()  returns a pointer to the float array of Weights where weight equal the result of the selection expression.
To get the fPx array from the tree and loop through the entries from the command line:
T->Draw("ntrack","temp>20.8")
Float_t *a
a = T->GetV1()
int i = 0;
{
 for (Int_t i =0; i < T->GetSelectedRows() ; i+10)
      cout << a[i] << endl;
}

## Introducing MakeClass

- Draw() is powerful and quick.
- What if  you would like to plot the masses of all oppositely charged pairs of tracks?  You need a loop over all events, find all pairs of tracks, and calculate the required quantities.
- ROOT provides MakeClass to do this.

## Using MakeClass

*Scenario:  We would like to do selective plotting. For simplicity we choose to plot only the first 100 tracks of each entry*.
*We have a ROOT file with a tree with one branch  which has leaves of type "Event". The designer has made the class definition* *available in the shared library libEvent.so and given you the header file Event.h.*

**Notes:**
The data designer makes a shared library available to you, which defines the classes needed. In this case the classes are Event, EventHeader, and Track. The designer also gives you the Event.h file for you to be able to see the definition of the classes.

Open the root file:             EventOB.root
View it in the ROOT Object Browser. You can see that there is only one leaf in the tree (T) and that leaf is called event. If you double click on it nothing happens.

## Event.h

- Event has
- a TClonesArray of Tracks
- GetNtrack() method
- much more ...
- Track has
- a GetPx() method
- much more ...

## Using MakeClass()

- 1. Load the shared library
- 		root [0].L libEvent.so
- 2. Load the root file
- 		root [1] TFile *f = new TFile
- 						("EventOB.root");
- 3. Call MakeClass	root [2] T->MakeClass("MyClass");
- 	- creates MyClass.C and MyClass.h- where does T come from?

**Notes:**
To plot only selective entries, we need to loop over all entries in the tree and be able to select the ones we want. ROOT provides a utility that creates a skeleton class to do this: MakeClass() 

Step 1: Load the shared library to define the Event and Track classes
    root [0] .L libEvent.so

Step 2: Load the root file
   root [1] TFile *f = new TFile("EventOB.root");

Step 3: Call MakeClass
   root [2] T->MakeClass("MyClass");
This creates 2 files MyTree.h and MyTree.C.

Where does "T" come from? This is the CINT naming feature in action. CINT looks for an object that was created with the name "T" and creates a variable with the same name and class (more on this is session 4). In this example, the root file EventOB.root has a tree in it that is called T. Do a f->ls() and you will see T.  This does not work in a compiled program.

## Using MakeClass()

- _MyClass.h and MyClass.C_
- MyClass.h
- contains the class definition of "MyClass"
- MyTree.C
- contains the class implementation of "MyClass"

**Notes:**

Look at MyClass.h and MyClass.C
Note that it declared the leave type Event *event.

## Loading and Using MyClass.C

- Load the macro and create a MyClass object:
- root [0].L libEvent.so
- root [1].L MyClass.C
- root [2] MyClass *m = new MyClass ();

**Notes:**
To load the macro and create an instance of MyClass:
Step 1  Load the shared library that contains the class definition for Event.
root [0].L libEvent.so
Step 2  Load the macro MyClass.C. This will automatically open the file.
root [1].L MyClass.C
Step 3  Create an instance of MyClass
root [2] MyClass *m = new MyClass();

## GetEntry()

- MyClass::GetEntry()
- root [3] **m->GetEntry(1);**
- root [4] m->event->GetNtrack()
- (Int_t)**597**
- root [5] **m->GetEntry(2);**
- root [6] m->event->GetNtrack()
- (Int_t)**606**

**Notes:**
Load the MyClass.C and execute GetEntry
root [0] .L libEvent.so
root [1] .L MyClass.C
root [2] MyClass *m = new MyClass()
root [3] m->GetEntry(1)    
(Int_t)48018
root [4] m->event->GetNtrack()
(Int_t)597
     root [5] m->GetEntry(2);      
     root [6] m->event->GetNtrack()
     (Int_t)606
Note: the reason you see a response after m->GetEntry(1) and you see nothing after m->GetEntry(2); is the use of the semicolon. If the semicolon is omitted, CINT will print the output of the method. In this case it is the bytes read. To convince your self try:
root [0] 3+4
(int)7
root [1] 3+4;
root [2]

## Loop()

- MyClass::Loop()
- root [6] **m->Loop();**
- Bytes read: 48492
- Bytes read: 48413
- Bytes read: 48255
- Bytes read: 48413
- Bytes read: 48255
- Bytes read: 48176
- ...

**Notes:**
Add this line to the Loop() to have some output:
cout << " Bytes read: " << nb << endl;
Load the MyClass.C and execute Loop()
     root [0] .L libEvent.so
root [1] .L MyClass.C
root [2] MyClass *m = new MyClass();
root [3] m->Loop(); 
...   
            Bytes read: 48492
     Bytes read: 48413
     Bytes read: 48255
     Bytes read: 48413
     Bytes read: 48255
     Bytes read: 48176

## Expanding Loop()

- _Modifying MyClass::Loop() _
- 	 1. Create a Track object
**	****	**Track *track     = 0;
- 2. Create two histograms
- TH1F *myHisto = new TH1F(
- 		"myHisto","fPx",100,-5,5);
- TH1F *smallHisto = new TH1F(
- 		"small","fPx 100",100,-5,5);

## Expanding Loop() (cont.)

- 3. In Event loop, get the event branch
- b_event->GetEntry(i);
- 4. And get the number of tracks
- n_Tracks = event->GetNtrack();
- 6. Add track loop
- for (Int_t j = 0; j < n_Tracks; j++){
- 	track = (Track*) event->GetTracks()->At(j);

## Expanding Loop() (cont.)

- . Fill the first histogram with Px
- myHisto->Fill(track->GetPx());
- 8. Add an if statement for the first 100 tracks
- if (j < 100){
- smallHisto->Fill(track->GetPx());
- }
- 9. Outside of the Event loop, draw the histograms
- myHisto->Draw();
- smallHisto->Draw("Same");

## Expanding Loop() (cont.)

- .L libEvent.so
- .L MyClass.C
- MyClass *m = new MyClass();
- m->Loop()

## Chains

- Scenario:
*Perform an analysis using multiple ROOT files. All files are of the same structure and have the same tree.*

**Notes:**
When the input is to be found in several files containing the same tree, we can use TChain to access the data on the tree in all the files.  

## Chains (cont.)

- TChain::Add()
- root [3] TChain chain("T");
- root [4] chain.Add("Event.root")
- root [5] chain.Draw("fTracks.fPx")
- root [6] myCanvas->cd(2);
- root [7] chain.Add("Event50.root")
- root [8] chain.Draw("fTracks.fPx")

**Notes:**
This example builds a chain with 2 root files that contain the tree "T".
Step 1:  Create a chain and call the Add method:
root [0] TCanvas *myCanvas = new TCanvas (
	"myCanvas","My Canvas", 0,0,600,400);
root [1] myCanvas->Divide(2,1);
root [2] myCanvas->cd(1);
root [3] TChain chain("T");
root [4] chain.Add("Event.root")
root [5] chain.Draw("fTracks.fPx")
root [6] myCanvas->cd(2);
root [7] chain.Add("Event50.root")
root [8] chain.Draw("fTracks.fPx")

## Chains (cont.)

- TChain::GetListOf...
- To see the files that are chained
- 		chain.GetListOfFiles()->Print()
- List the branches and leaves of the chain.
- 		chain.GetListOfBranches()->Print()
- 		chain.GetListOfLeaves()->Print()
- TChain::Merge()
- To merge the files in a chain and write them to a new file :
- 		chain.Merge("all.root")

**Notes:**
Step 2:  To see the files that are chained:
root [9] chain.GetListOfFiles()->Print()
Step 3:  List the branches and leaves of the chain.
root [10] chain.GetListOfBranches()->Print() root [11] chain.GetListOfLeaves()->Print()
Step 4:  To merge the files in a chain and write them to a new file :
root [12] chain.Merge("all.root")

## Demo: Changing "MyClass" to use a Chain	

- 1.  Changing MyClassChain.h
- Change TTree to TChain
- Use Add() to add the files to the chain
- 2. Changing MyClassChain.C
- TTree to TChain

**Notes:**
Step 1: Change the header file from using a tree to using a chain. Carefully change all occurrences of TTree to TChain. Add the files to the chain in the constructor:
	...
	chain->Add("EventOB.root");	chain->Add("EventOB50.root");	chain->Add("EventOB40.root");
	...	

Step 2: Change the source file to use TChain:
...
if (fChain == 0) return;
...
Int_t nentries = Int_t(fChain->GetEntries());

## Demo: Changing "MyClass"

- 3. Load and executeMyClassChain.C

**Notes:**
Step 3: To execute the new MyClass::Loop()
root [0] .L libEvent.so            
root [1] .L MyClassChain.C         
root [2] MyClass *m = new MyClass()
root [3] m.Loop()                  

## Session 3 SummaryPutting Trees to Work

- Using Trees in Analysis
- From the command line using TTree::Draw()
- Using MakeClass and Loop()
- Using Chains

## Exercise #2

- Use MakeClass on the ABC.root file and call the class "ABC". Modify the loop to draw a histogram of the last 100 entries of p.

## Session 4: More about CINT

- Coding Conventions
- Global Variables
- Environment Settings
- CINT
- Debugging
- Stepping
- Setting breakpoints
- Inspecting

## Coding Conventions

- Based on Taligent
- Classes		 begin with T 		TTree, TBrowser
- Non-class types 	 end with _t 		Int_t
- Data members	 begin with f		fTree
- Member functions begin with a capital Loop()
- Constants 		 begin with k 		kInitialSize, kRed
- Static variables 	 begin with g 		gEnv
- Static data members                              begin with fg           fgTokenClient

## Coding Conventions (cont.)

- Enumeration types 		begin with E 			EColorLevel
- Locals and parameters 		begin with a lower case	nbytes
- Getters and setters 			begin with Get, Set, or Is (boolean)			SetLast(), GetFirst(), IsDone()

## TObject: The Mother of all Root objects

- Defines protocol and default behavior for all objects in ROOT.
- I/O
- Inspection
- Printing
- Drawing
- TObjects can be stored in collection classes.

**Notes:**
The TObject class provides the default behavior and protocol for all objects in the ROOT system. It provides a standard protocol for object I/O, error handling, sorting, inspection, printing, and drawing. Every object which inherits from TObject can be stored in the ROOT collection classes. 
I/O examples: 
Write(): Writes this object to the current directory gDirectory.
Inspection: 
Inspect(): draws a canvas with the current state of the object. It displays the value of each member.
Printing
Print():  Prints the name of the class, the name of the variable and the title of the variable. It must be overridden to print the what is relative to the subclass. For example TEnv overrides Print() to print the .rootrc file.
Inheritance Tree:
DrawClass(): draws a canvas with the inheritance tree for the class.
Drawing:
The Draw() method does nothing by default. It has to be overwritten by the subclass to have any action.

## gROOT

- gROOT->Reset();
- gROOT->GetListOf< list type >();
- gROOT->LoadMacro();
- gROOT->Time();
- gROOT->ProcessLine()

**Notes:**
gROOT->Reset() clears the global scope. When clearing the global scope the destructors of objects are called. Objects created on the heap (via new) are not deleted. For example:
root [0] .L libEvent.so
root [1] TFile f ("Event.root");
root [2] TFile *f1 = new TFile("EventOB.root");
root [3] gROOT->GetListOfFiles()->Print()
TFile: name=/home/Event.root, title=, option=READ
TFile: name=/home/EventOB.root, title=, option=READ
root [4] gROOT->Reset();  
root [5] gROOT->GetListOfFiles()->Print()
TFile: name=/home/EventOB.root, title=, option=READ
The call to Reset() will call the destructors for f, but will not call the destructor for f1. It will however delete the variables f and f1, but the root file EventOB.root still exists.
gROOT->GetListOf< list type >() returns a pointer to a TSeqCollection of the specified list. The available lists to get are: Browsables, Browsers, Canvases, Classes, Colors, Files, Functions, and Geometries. 
gROOT->LoadMacro() loads a macro in the interpreter's memory. Equivalent to the command line command ".L filename".
gROOT->Time(1) Print the real and CPU time it takes for each command. Once turned on, even if in a macro, it needs to be turned off with the command gROOT->Time(0)
gROOT->ProcessLine() processes a single command line, either a C++ statement or an interpreter command starting with a ".". This can be used to execute a CINT statement in a macro.

## gROOT->FindObject(<Name>)

- smallHisto is the _Variable Name_
- small is the _Object Name_.
- TH1F ***smallHisto **= new TH1F
- 			("**small**","fPx 100",100,-5,5);
- gROOT->FindObject("**smallHisto**")
- 			(class TObject*)**0x0** // null pointer
- gROOT->FindObject("**small**")
- 			(class TObject*)**0x104c7528**
- FindObject needs the _Object Name_.

**Notes:**
gROOT->FindObject(<name>) attempts to find the object with the <name>. This is the name given in the constructor of the object. For example an object created with this constructor:
TH1F *smallH= new TH1F("small","fPx 100",100,-5,5);
will be found by gROOT->FindObject("small"). The object will not be found if the variable name is used. In this example gROOT->FindObject("smallH") will return a null pointer.  The search path for FindObject is
-  List of files-  List of memory mapped files-  List of functions-  List of geometries-  List of canvases -  List of styles -  List of specials - List of materials in current geometry-  List of shapes in current geometry-  List of matrices in current geometry-  List of Nodes in current geometry-  Current Directory in memory-  Current Directory on file 

## gROOT->FindObject() cont.

- FindObject returns a pointer to TObject.
- Need to cast it to call class methods.
- This generates an error:
- gROOT->FindObject("small")->GetBinContent(2)
- This is OK:
- gROOT->FindObject("small")->ClassName()
- TH1F* histo=(TH1F*) gROOT->FindObject("small")
- histo->GetBinContent(2)

**Notes:**
gROOT->FindObject(<name>) returns a pointer to TObject. You will need to cast it first to be useful.
For example: this creates an error.
 gROOT->FindObject("small")->GetBinContent(2)
You must first cast the TObject pointer to a TH1 * to be able to call TH1 methods:
((TH1*) gROOT->FindObject("small"))->GetBinContent(2)
or
TH1F* histo=(TH1F*) gROOT->FindObject("small");histo->GetBinContent(2)
If there are two objects with the same name, you should check the class name of the returned TObject pointer.
root [2] gROOT->FindObject("small")->ClassName()
(Text_t* 0x1052d03c)"TH1F"

## gROOT->FindObject() cont.

- Due to CINT magic this is also OK:
- 	TH1F *smallHisto = new TH1F
- 			("**small**","fPx 100",100,-5,5);
- 	**small**->GetBinContent(2);
- CINT implicitly executes a FindObject("small")
- Casts it to the correct class
- Creates a variable called "small" of the correct class
- 		**Warning: This will not work in compiled code!**

**Notes:**
CINT automatically executes a FindObject is the Object name is used:
small->GetBinContent(2);
This also creates a variable of type TH1F. It is an extension of CINT that will not work in regular C++ code.

## Global Variables (cont.)

- gRandom
- gRandom->Gaus(1,2)
- You can replace the random generator with your own:delete gRandom;gRandom = new **TRandom2**(0); //seed=0
- gFile
- gFile->GetName()
- gDirectory
- gDirectory->GetName()
- gSystem
- gSystem->HostName()

**Notes:**
gRandom: is a basic Random number generator (periodicity 10**8). Setting the seed to 0 implies that the seed will be generated from the time. Any other value will be used as a constant.
The following basic Random distributions  are provided:    Gaus(mean,sigma)    Rndm()   Landau(mean,sigma)   Poisson(mean)   Binomial(ntot,prob)
You can customize your root session by replacing the random number generator. You can delete gRandom and recreate it with your own constructor of your own class.
gFile: is a pointer to the current file. 
gDirectory: is a pointer to the current directory. 
gSystem: contains operating system information for the current root session.

## Environment Settings

- Find the current settings
- gEnv->Print()
- .rootrc
- looks first in current directory
- second in ~ ($HOME)
- third in $ROOTSYS

**Notes:**
.rootrc file 
ROOT looks for the environment setting in the .rootrc file. It first checks if there is one locally ./.rootcr then in the users home directory: $HOME/.rootrc, and finally in the ROOT directory: $ROOTSYS/.rootrc.

## Environment Settings (cont.)

- _The .rootrc file:_
- The Macro Path
- Unix.*.Root.MacroPath:.:$(HOME)/myRootMacros
- Options in rootrc
- Root.ShowPath: false
- History File
- $HOME/.root_hist
- Automatically Executing Macros
- rootlogon.C
- rootlogoff.C
- rootalias.C

**Notes:**
The Dynamic Path is the path used by the loader to find shared libraries. 
The Macro Path is the path used by the loader to look for root macros when the .X or .L commands are used. 
Root.ShowPath:  trueShows on the command line the path of the object that is used.
Four files can be specified:
Rint.Load: 	rootalias.C  
Rint.Logon:  	rootlogon.C
Rint.Logoff:	rootlogoff.C
Rint.History:	$(HOME)/.root_hist
For example we would like to automatically execute the macro Browser.C. It loads libEvent.so, starts a browser, opens a file, and draws one histogram 
{
gROOT->ProcessLine(".L libEvent.so");
TBrowser * b = new TBrowser();
TFile *  f = new TFile("Event.root");
T->Draw("fTracks.fPx");
}
Make this your logon macro by editing the .rootrc file:
Rint.Logon:             Browser.C

## Command Line Options

- > root -/?
- Usage: root [-l] [-b] [-n] [-q] [file1.C ... fileN.C]
- Options:
-   -b : run in batch mode without graphics
-   -n : do not execute logon and logoff macros as specified in .rootrc
-   -q : exit after processing command line macro files
-   -l : do not show splash screen

## CINT Commands

- [expression] 	evaluates the expression
- root[3] 3*4
- (int)12
- .files  		show loaded source files
- .class [name] 	show class definition
- .g 			prints all objects in the root session
- .ls 			ls on current directory
- .pwd		list the current directory, canvas, 				and style.

**Notes:**
[expression]Almost any  expression can be given. You can inputdeclaration, loops, etc... Exceptions are function definitions,class definition with member function definitions, etc...
.files will show all loaded files including .h files.
.class  .class <ClassName> prints all methods and members of the class.  .class without any arguments will print a list of all classes in order that they were created.
.gwill show a list of objects in the order that they were created.
.ls
shows the contents of the current directory
.pwd
shows the current directory, current style, and current canvas (if there is one)

## Demo on CINT Commands

- .class
- root [0] .L libEvent.so
- root [1] .class Event
- .g
- root [2] .g...
- 0x104c7560 Event e , size=56
-   0x0        private: Int_t fNtrack
-   0x0        private: Int_t fNseg
-   0x0        private: Int_t fNvertex
-   ...

## CINT Extensions to C++

- 1. Declaration can be omitted
-  f = new TFile("Event.root")
- 2. "." notation rather than "->"   f.ls()
- 3. Search  for an object
-  TH1F *smallHisto = new TH1F
- 		("small","fPx 100",100,-5,5);
- 	small->Draw();
**	****	****Warning: These will not work in compiled code!**

**Notes:**
1. The declaration can be omitted when ‘new’ is used:
f = new TFile("Event.root")
2. Can use the simple "." notation rather than "->"
f.ls()
3. In case CINT can not find an object being referenced it will ask ROOT to search for an object with an identical name in the search path defined by TROOT.FindObject(). In addition to a FindObject, CINT will cast it to the class and allocate the variable with the same name:

WARNING: These extensions will not compile with a regular C++ compiler.

## CINT Types

## CINT Multi-line Command

- Start with "{"
- For example:

- root [9] {
- end with '}'> Int_t j = 0;
- end with '}'> for (Int_t i = 0; i < 3; i++)
- end with '}'> {
- end with '}'> j= j + i;
- end with '}'> cout <<"i = " <<i<<", j = " <<j<<endl;
- end with '}'> }
- end with '}'> }
- i = 0, j = 0
- i = 1, j = 1
- i = 2, j = 3

## Debugging: Stepping

- .s           set the step mode to step into              function
- .S           set the step mode to go over              function or loop
- .e           continue to end of the function
- .c           continue to next breakpoint
- .c 45      continue to line 45
- .p <var> print the value of var

**Notes:**
Root> .s
.s turns on the step mode execution.

S
.S sets the step mode to stepping over the function or loop 

e
.e executes the function and steps over it. 

.c 45
.c 45 continues to line 45. This will also change the mode to "continue"

.p prints the value of the variable.

## Debugging: Breakpoints

- .trace MyClass       	prints the executing                               	code to window
- .deltrace MyClass	 removes the trace
- .break MyClass      	breaks at each                               	method of MyClass
- .delbreak MyClass 	removes the break
- .b 34                       	sets a break point at                               	line 34
- .db 34                     	removes the break                               	point at line 34

**Notes:**
.trace MyClass 
Prints the code it is executing without stopping. This is helpful to find the line number to set a break point
.deltrace MyClass
Deactivates the trace command
.break MyClassPuts a breakpoint at the beginning of each method of MyClass.
.delbreak MyClassRemoves the breakpoints at the beginning of each method of MyClass.
.b 34 
Puts a breakpoint at line 34 of the currently executing macro.
.db 34
Removes the breakpoint at line 34. Hitting return will execute to the end of the function.
.D
changes the display mode

## Debugging: Inspecting

- DrawClass()        Draws the                         inheritance tree
- Inspect()              Draw the current                        contents of an object
- Dump()                Lists the current                         contents of an object
- gDebug = 1	    Prints debugging
-                             information

## Demonstration: CINT commands

- DrawClass() and Dump():
- root [0] .L libEvent.so
- root [1] Event e
- root [2] e->DrawClass()
- root [2] e->Dump()
- FindObject():
- root [3] f = TFile("AFile.root")
- root [4] .ls
- root [5] gROOT->FindObject("T")
- root [6] T

## Summary of Session 4: More about CINT

- Coding Conventions
- Global Variables
- Environment Settings
- CINT
- Debugging
- Stepping
- Setting breakpoints
- Inspecting

## Exercise #3

- Download Ex3.C Ex3.h and Ex3.root from the website:
- _[http://pat-www/root/102/Files.htm](http://pat-www/root/102/Files.htm)_
- Use the CINT debugger to step through the Loop() method of the Ex3.C macro. Find the values of nentries, and the value of "p" when "i = 122".

## Session 5: For the real Expert

- Adding your own class
- Script compiler

## Adding your own class to ROOT

- _Step 1:_
- define your classes.
- _Step 2:_
**ClassDef**(*ClassName,ClassVersionID*)
**ClassImp**(*ClassName*)

## ClassDef and ClassImp

- ClassDef and ClassImp are needed for
- 1. RTTI (run time type identification) :
- 	root[0] .class <Class Name>
- 	prints the members and functions of the class
- 	root[0] <object>->ClassName()
- 	returns the name of object's class
- 2. I/O
- Streamer method needed for writing to ROOT files and Trees.

**Notes:**
You can add a class without using the ClassDef and ClassImp macros, however you will be limited. Specifically the RTTI (run time type identification) and object I/O features of ROOT will not be available to you for these classes. 
The ShowMembers() and Streamer() method, as well as the  >> operator overloads  are implemented only if you use ClassDef and ClassImp.

## rootcint

- _Step 3:_
- create a LinkDef.h file.
- _Step 4:_
- call rootcint in the Makefile to create a CINT dictionary.
- EventDict.cxx Event.h EventLinkDef.h
- $(ROOTSYS)/bin/**rootcint** -f EventDict.cxx -c Event.h EventLinkDef.h
- _For more information:_ _[http://root.cern.ch/root/RootCintMan.html](http://root.cern.ch/root/RootCintMan.html)_
- $ROOTSYS/test/Makefile, Event.cxx, and Event.h

## The Script Compiler

- A ROOT enhancement developed at Fermi (by Philippe Canal)
- Advantages :
-  syntax checking
-  speed of execution
-  full C++ feature set
- Disadvantages:
- load each C++ shared library once the
- shared library (.so) is temporary

**Notes:**
The Script Compiler allows the user to use an external compiler to create a shared library from a C++ macro.
Advantages of the Script Compiler are:
 syntax checking is more thorough than CINT and with better error messages
 speed of execution is better because it is compiled rather than interpreted.
 able to use full C++ beyond the limitation of CINT. For example full template support and STL.
Disadvantages:
 can only load each C++ shared library once per root session, this also means that you can not use the .U command to unload the shared library.
the shared library (.so) is temporary, it will disappear after quitting the root session 

## Demonstration of the Script Compiler

- .L ScriptCompilerDemo.C++
- or gSystem->CompileMacro("ScriptCompilerDemo.C");
- root [0] gROOT->Time()
- root [1] .L ScriptCompilerDemo.C++
- root [2] .files
- root [3] Demo()
- Compare performance with CINT
- root [0] gROOT->Time()
- root [1] .L ScriptCompilerDemo.C
- root [3] Demo()

**Notes:**
To use the script compiler :
root [0] gROOT->Time() 
root [1] .L ScriptCompilerDemo.C++
	Real time 0:0:5, CP time 0.030
root [2] .files
  ... 
  4 fp=0x   0 lines=0   file="/home/ghi/spanacek/root102/./ScriptCompilerDemo.so" 
root [3] Demo()
	Real time 0:0:0, CP time 0.280

Compare the script compiled macro performance with the CINT interpreted macro.
Exit and reenter root.
root [0] gROOT->Time()
root [1].L ScriptCompilerDemo.C
	Real time 0:0:0, CP time 0.000
root [2] Demo()
	Real time 0:0:5, CP time 4.820

## Adding Your Class With the Script Compiler

- Step 1: Write the class definition in a separate file.
- Step 2: Add the ClassDef and ClassImp macro calls to the class definition.
- Step 3: Load the class with the script compiler. In another script:	gSystem->CompileMacro("ABCClass.C");or from the command line:	root[0] .L ABCClass.C++
- For an example see ABCWriteClass.C and ABCClass.C

## Wrap up

- Questions ?
- Feedback Forms
- More information:
- www-pat.fnal.gov/root/102
- http://root.cern.ch
- roottalk@root.cern.ch
- about-root@fnal.gov
- http://ods.fnal.gov/ods/root-eval