1

I. Introduction

I.1. What is ROOT ? ROOT is a system for large-scale data analysis and data mining. It is being developed for the analysis of Particle Physics data, but can be equally well used in other fields where large amounts of data need to be processed. ROOT is not a computer program, but instead is a set of over 300 C++ classes and an interactive C++ interpreter. So one can use it as a framework, just using existing classes and libraries in his programs. Or, one can use the interactive part of the interpreter to execute tasks defined by the user on the command line or run macros, which are in fact made of C++ code. Once the user is satisfied with his macro, he can compile it (since it is nothing else than C++) with a little extra effort and run it much faster.

I.2. Objectives of this document This tutorial is intended for people who want to get their hands quickly on the framework, but its intention is to eventually become a user’s manual. So the first chapter will be an "interactive" one in the sense that the best way to read it is in front of a computer with a ROOT session opened. Next chapters are more for reference. People that will begin to work with ROOT will usually have a FORTRAN or C background. I will suppose that the user is a little bit familiar with C and I will introduce the basic C++ notions when needed. This is not intended to be a C++ guide, it’s too huge of a task, but ROOT is a good environment to learn C++ and it would be a pity not to use it that way! So I will try to be as simple as possible from the C++ point of view. Each example will be followed by the explanation of the underlying C++ concepts used, enough to understand the various commands. I will also introduce some ROOT related specific concepts after each example. All constructive suggestions are welcome and you can reach me: [email protected]. This document will evolve with the evolution of ROOT so don’t ask too much at the beginning. Rather tell me what is missing or what should be changed.

I.3. Installation of ROOT The installation and build of the ROOT software is described in "Installation of ROOT and ROOT"

I.4. How to find information ? The main source of information for ROOT is ROOT main site http://root/cern.ch. There is a lot of information online, but no (for the moment) users manual. In particular, one can find all the source code of ROOT organised in a very nice way, and a searchable archive of the mailing list devoted to ROOT, roottalk. If you have a question, there is a slight chance that somebody asked it before you ! For VEGA, the information can be found at the VEGA site

1 2

II. An interactive session

In this first chapter, we will concentrate on giving the reader a feeling of the possibilities of the framework. We will use standard ROOT examples. The user actions will be written in bold characters.

II.1. Basic intrinsic operations First of all, one needs to know how to exit from a program! The C interpreter has some raw commands that begin with a dot. These commands are used to do intrinsic operations, not related to any C/C++ code. The ones that you should know for the beginning are: .q quits the interactive session .x loads a macro and executes it

We will see other raw commands, as we need them, especially commands to debug scripts (step, step over, set breakpoint, etc...).

II.2. The interpreter CINT, graphical interaction through a few examples

II.2.1. First very simple example First, go to the $ROOTSYS/tutorials and start the ROOT interactive session: your_prompt$ root The prompt that you see is "root[0]". In fact, you launched the very small root executable, which is linked with the ROOT libraries. This program gives access via a command-line prompt to all available ROOT classes/globals/functions. By typing C/C++ statements at the prompt, you can create objects, call functions, execute scripts, etc. For example type:

root[0] 1+sqrt(9) (double)4.000000000000e+00

root[1] for (int i = 0; i<5; i++) printf("Hello %d\n", i) Hello 0 Hello 1 Hello 2 Hello 3 Hello 4 root[2] .q

2 3

As you can see, if you know C or C++, you can use ROOT. No new command line or scripting language to learn. Some comments may be made at this point. First, there is no need to put a semicolon at the end of a line. Well, you can put one if you want. This is only true for statements written on the command line. One assumes that the carriage return is enough to express the end of the line for the interpreter. This is part of the interpreter’s extensions to C++ that were made to allow an easy interaction, while not at the expense of breaking the compatibility with C/C++ language. The extensions will be seen in the chapter "The use of CINT and it’s characteristics / Extensions to C+ +" Some of the extensions don’t work anymore inside a macro. For example, you have to put a semicolon at the end of each line in a macro.

II.2.2. Graphical output example Let’s try something more interesting. Again, start ROOT :

your_prompt$ root

root[0] TF1 f1("func1", "sin(x)/x", 0, 10) root[1] f1.Draw()

you should see something like this :

II.2.3. Classes, methods and constructors We can stop for a second (well, a few seconds...) and explain what we have done. A more thorough introduction to C++ is given in “ IV – more on C++ (for the interested reader)” paragraph. In ROOT and C++, we introduce the notion of object, which is just a C structure with some internal functions (called “methods”) associated to it. The line TF1 f1("func1", "sin(x)/x", 0, 10) created an object named f1 of the

3 4

type TF1 which is a one-dimensional function. The type of an object is also called a class. In fact, the line above builds an object by giving it a set of parameters. This is one example of a function associated to a class. It is a special one since it builds an object. It is called a constructor. To interact with an object in ROOT, the usual syntax is : object.action(parameters) This is the usual way of doing in C++. The dot can be replaced by -> if object is a pointer. But since the interpreter always know the type (class) of an object, if you put a dot instead, it will be automatically replaced when necessary. So now, we understand the two lines that allowed us to Draw our function. f1.Draw() means “call the method Draw associated with the object f1 of class TF1”. We will see the advantages of using objects and classes very soon. One point : the ROOT framework was designed as an object oriented framework. This doesn’t mean that a user cannot call plain functions. For example all the FrameLib standard functions are available in the VEGA framework.

II.2.4. ROOT related specifics We didn’t yet explain everything about the constructor of f1 : TF1 f1("func1", "sin(x)/x", 0, 10) "sin(x)/x" is the function that we want to define, 0 and 10 the limits but what is "func1”? It’s the name that we give to the object f1. Most objects in ROOT have a name. That way, there are lists of objects maintained by ROOT and it’s easy to find an object by its name, especially if it is in a database. We will see why it is so when we see the notion of inheritance.

II.2.5. Graphical output example: User interaction If you quit the framework, try to draw again the function "sin(x)/x". Now, we can look at some interactive capabilities. Every graphics drawn in a window (which is called a Canvas) is in fact a graphical object in the sense that you can grab it, resize it, change some characteristics with a mouse click. And all the changes that you do are not done on a graphical copy of the object but on the object itself. For example, for people using version 2.20 and above of ROOT, try to click somewhere on the x axis and drag along this axis. You have a very simple zoom. When the cursor is on any object, you have access to selected methods by pressing the right mouse button and obtaining a context menu showing some available methods for this object. If you try this on the function itself, you obtain this kind of behavior:

You can try for example to select the SetRange method and put -10, 10 in the dialog box fields.

4 5

This is equivalent to executing the member function f1.SetRange(-10,10) from the command line prompt, followed by f1.Draw(). There are other things you may want to try. For example select the "DrawPanel" item of the popup menu. You will see a panel like this one :

Try to resize the bottom slider and click Draw. You can zoom your graph. If you click on "lego2" and "Draw", you see a 2D representation of your graph :

You can rotate interactively this 2D plot. Of course, it is possible to plot real 2D functions or graphs, not only a disguised 1D. There are numerous ways to change the graphical options/colors/fonts with the various methods available in the popup. Here are a few examples:

5 6

Line Text Fill attrib attributes attrib utes utes

Once the picture suits your wishes, you may want to see what are the lines of code you should put in a macro to obtain the same result. To do that, choose the "Save as canvas.C" option in the "Files" menu. This will generate a macro that you can look into to see how to set the various options. Notice that you can also save in postscript or gif format the picture. One other interesting possibility is to save in native root format your canvas. This will enable you to open it again and to change whatever you like, since all the objects associated to the canvas (histograms, graphs, etc...) are saved at the same time.

II.2.6. Second example : Building a multi-pad canvas Let’s now try to build a canvas (i.e. a window) with several Pads. The pads are sub-windows that can contain other Pads or graphical objects. root[0] can = new TCanvas("can","Test canvas",1) root[1] can.Divide(2,2) Once again, we called the constructor of a class, this time the class TCanvas. The difference with the previous constructor call is that we want to build an object with a pointer to it. In C, we would have used malloc() or calloc(). Here, we use the operator new, which is the equivalent in C++. Instead of free() we will use delete. Usually, one has to declare a variable before using it. Since there cannot be any ambiguity in the line above, one doesn’t need to declare a variable “can”. In case such a statement in a macro is intended to be compiled, one would obviously have to declare the variable as a TCanvas* before using it. Next, we call the method Divide() of the TCanvas class (that is TCanvcas::Divide()) which divides the canvas into 4 zones and sets up a Pad in each of them. Now, if we do root[2] can.cd(1) root[3] f1.Draw() the function f1 will be drawn in the first Pad. All subsequent actions, draw an arrow for example, will be done on that Pad. To change the working Pad, there are three ways:  Click on the middle button of the mouse on an object, for example a Pad. This sets this pad as the 6 7

active one  Use the method cd() of TCanvas (that is TCanvas::cd()) by telling the number of the pad, as was done in the example above: root[2] can.cd(3) Pads are numbered from left to right and from top to bottom.  Each new pad created by the TCanvas::Divide method has a name which is the name of the canvas followed by _1, _2, etc... for example to cd() to the third pad, you should do : root[2] can_3.cd() The third pad will set itself as the selected pad since you call the TPad::cd() method for the object can_3. This remark just to show the state of mind people have when they "think" in C++

II.2.7. Inheritance and data encapsulation

II.2.7.1. II-1-7-1 Inheritance There is an obvious question that could be asked : what is the relation between a canvas and a pad ? Isn’t it almost the same thing? Yes it is. In fact, a canvas is a pad that spans through an entire window. This is nothing else than the notion of inheritance. The TPad class is the parent of the TCanvas class. So what? The most interesting thing is that you can reuse the code written in the parent class. For example, cd() is a method that TCanvas inherits from it’s parent, TPad.

II.2.7.2. II-1-7-2 Method overriding The method overriding is explained in paragraph IV. Basically, when a class Child derives from another class Parent, it can reuse the methods defined in Parent, but if one method of Parent is not well adapted to Child, one can redefine (override) it. For example Draw() in some Child class may be different from Draw() in the Parent class. There is no ambiguity since you always specify the object : childobject.Draw() or parentobject.Draw().

II.2.8. ROOT related specifics For what concerns inheritance, most objects in ROOT derive from a base class called TObject. This class contains everything that is shared by all the classes in ROOT. Especially, it handles  the object I/O, so one can send any object to a file without writing the corresponding code,  comparing two objects, enabling searches, sorts, etc…  graphics hit detection  notification between objects, so they can talk to each other… to name the most important ones.

II.3. An example of a macro Let's try now to see how we can write a simple macro. As we've said, this is just C/C++ code. Open the editor of your choice and look at the macro named vfill_histo.C. As a matter of convention, all macros are suffixed by .C. The source code has a .cxx or .cc suffix. vfill_histo.C is the following code :

{ 7 8

// Create and fill a histogram with random #'s from a Gaussian distribution. // See http://root.cern.ch/root/HowtoHistogram.html for a brief description // of how to use histograms in ROOT.

gROOT->Reset();

// TH1F is the equivalent of HBOOK1 // The fill data are 32 bit float points and weights are 64 bit fp.

printf("Creating Histogram...\n");

TH1F *h1 = new TH1F("h1","1-D Gaussians",100,-8,8);

printf("done.\n");

//The ROOT/CINT extensions to C++. The declaration of h1 may be //omitted when "new" is used. So h1 = new TH1F(...) will correctly //create an object of class "TH1F".

gRandom->SetSeed();

// Raw C types are typedefed. Float_t xgauss;

printf("Filling Histogram...\n");

for (Int_t i=0; i < 10000; i++) { xgauss = gRandom->Gaus(3,0.5); h1->Fill(xgauss,0.2); h1->Fill(xgauss-6); }

printf(" done.\n");

}

We can try to give detailed explanations of some of the lines above. gROOT->Reset();

This statement resets the interpreter environment, it is almost always used at the beginning of a macro but not if you want to preserve some variables that a precedent macro defined. gROOT is a global variable. We will see some more details about globals in ROOT in a few moments. gROOT is an object of the class TROOT, which represents your session. It contains, among other things, lists of named objects created during the session, such as histograms. This enables access to those objects by their name.

TH1F *h1 = new TH1F("h1","1-D Gaussians",100,-8,8);

Here, we create a histogram by invoking one of its constructors. Walking through this statement, we have :  TH1F : this is one of the histogram classes. All ROOT classes begin with a T (see Coding

8 9

Conventions). The H is for histogram, 1 for 1-D and F for using one float per channel.  *h1 is the name of the pointer to this object  new TH1F(…) invokes the constructor for this object with several parameters :  "h1" is the name of the histogram. In ROOT, as we have seen, most high level objects are named. Typically, one makes the name of the object the same as the pointer to which it refers.  "1-D Gaussians" is the title of the histogram. It will be displayed by default when the histogram is drawn.  100, -8, 8 are the number of bins nbins, xlow and xup. For PAW users : you don't have to worry about the type of xlow and xup, integers will be converted to floats. gRandom->SetSeed();

Another global. gRandom is the current object of the class TRandom of standard random generators. You probably already noticed that all globals begin with a "g" followed by a capital letter. This is also in the Coding Conventions paragraph. The SetSeed() method of TRandom chooses a random seed, here the default one. The class TRandom doesn't try to be overly ambitious. The important methods are :  SetSeed(iseed) : sets the seed of the random number generator. If no number is given, 65536 is used.  Gaus(mean, sigma) : return a random number distributed following a gaussian with mean and sigma.  Rannor(a,b) : returns two random numbers following a gaussian with mean=0 and sigma=1.  Rndm() : returns a uniformly distributed random number in the interval [0,1]

Float_t xgauss;

To avoid machine dependence of raw C types (double, float, and especially int, etc...), the basic types have been typedefed. So, instead of float, we use Float_t = 4 byte float. You can look at "Machine independent types in ROOT". for (Int_t i=0; i < 10000; i++) { xgauss = gRandom->Gaus(3,0.5); h1->Fill(xgauss,0.2); h1->Fill(xgauss-6); }

This seems to be a standard for loop in C in which you generate a random variable (gaussian) and you fill a histogram with this value. For somebody not used to C++ something is strange : the Fill() method used to fill the histogram is used twice but not with the same number of arguments. This is perfectly common in C++, and it is called method overloading. We will see more about this in the next chapter. 9 10

Now, to execute your macro type : root[5] .x vfill_histo.C Creating Histogram... done Filling Histogram... done

Now you have in your memory (the computer one, not yours...) a histogram with which you can play. For example type root[6] h1->Draw() root[7] h1->Dump()

As will be seen in the chapter "Writing macros", one can write a named macro and give arguments to a macro. You also probably noticed that there is no includes in the macro. In fact, all the standard C includes are already done in the environment, as well as ROOT specific ones. If you want to use C++ (cin, cout for example), you should include the C++ headers. For example : root[8] #include

you can do this also at the beginning of a macro, or in a logon file called rootlogon.C which is a macro always executed automatically when one launches ROOT. This file has to be put in your working directory.

II.3.1. C++ notions used: method overloading We've just seen, in the example above, that a method can have different forms, with different arguments. If we look at an excerpt of the header file defining the class TH1F : public: virtual void Fill(Axis_t x); virtual void Fill(Axis_t x, Stat_t w); virtual void Fill(Axis_t x, Axis_t y, Stat_t w); virtual void Fill(Axis_t x, Axis_t y, Axis_t z, Stat_t w);

You see that the Fill method is defined four times with different arguments. How does the compiler know what method to call ? For the compiler to be able to make the difference, the arguments must be different enough. There is no ambiguity in the Fill methods above since the number of parameters is different for each method. If someone had made the following statement : public: virtual void Fill(Axis_t x); virtual void Fill(Axis_t x, Stat_t w=1);

10 11

where in the second declaration, one of the arguments has a default value (this is permitted in C+ +), then the compiler doesn't know which method to call if someone uses

h1->Fill(23)

Should the compiler use the form Fill(Axis_t x); where x=23 or the form Fill(Axis_t x, Stat_t w=1); where x=23 and one uses the default value w=1 ? In that case, the compiler sends an error message. So one must be careful, when writing his methods not to come in such situations. Easier said than done.

II.4. How to compile a macro ? Sometimes (in fact quite often) a script may become so big or be so processing-hungry that one would like to have it compiled and not interpreted. There is included into ROOT what is called a script compiler, that allows to compile very easily the scripts you are going to produce. It starts by calling the C++ compiler that was used to build ROOT and builds a shared library. This shared library is then loaded and the function defined in the script is executed.

II.4.1. Preparation of the script So that seems nice, what is the deal ? It’s only that you have to prepare a little bit your script. But it is quite simple. You have to 1) Do not use extensions to C/C++ provided by the CINT interpreter. That means for example that while in the interpreter you do not need to declare variables whose type is known from the context, this is mandatory if you want to be able to compile. Since the compiler is not supposed to know the context of the interpreter. An example. In the interpreter, you can use statements like :

c1 = new TCanvas("c1", "Test",1);

where you do not declare the variable c1, you should do instead :

TCanvas* c1 = new TCanvas("c1", "Test",1);

More generally, use very standard C/C++ and declare all your variables

2) You should add the includes you use at the beginning of the file. Once again, this is for the real compiler that will do the work. Usually, the headers to be added are composed of the name of the classes used followed by the .h suffix. In case of included C code, the most commonly used are "FrameL.h" for all the Framelib calls, and the standard headers of the Virgo standard signal library. 3) In case you want to execute immediately (i.e. use the command “.x”) the first function of the script you compile, you have to name the function in your script with the same name as the file it is contained in. For example the file my_test.C should begin with my_test() { your code…. }

11 12

The tutorial script called tobedefined.C has been prepared this way, check it.

II.4.2. Compiling the script What remains to be done is to compile the script. If we want to execute the script called tobedefined.C, we just have to do (once in the vegatutorial directory) : root[9] .x tobedefined.C++ notice the ++ at the end of the command. This tells the interpreter to compile tobedefined.C, build a shared library called tobedefined.so, load this shared lib and execute tobedefined(). The resulting library tobedefined.so stays here and you can reuse it, that is reload it at a later time, with root[10] .L tobedefined.so furthermore, the tobedefined() function is available in the interpreter and may be used in some other script ! All this also works with loading the script after compiling : root[9] .L tobedefined.C++ is a valid statement. This will build the library and load it as before. It will just not execute any function.

12 13

III. More on C++ (for the interested reader)

This paragraph is intended to introduce the reader to some useful insights into C++, to allow some use of the most advanced features found in ROOT. It is in no case a full course in C++.

III.1. C++ notions used: classes, methods and constructors You can try to use CINT to test the given examples. Before that, exit the previous ROOT session, go to the directory "$VEGA/vegatutorial", launch ROOT and load into the environment the tutorial macro vtutorial.C : root[0] .L vtutorial.C The raw command .L loads a macro into the interpreter environment. You can then use all the functions/classes/objects defined inside it. C++ extends C with the notion of class. If you’re used to structures in C, a class is a struct, that is a group of variables that are related, which is extended with functions and routines specific to this structure (class). What is the interest? Consider a struct that is defined this way:

struct Line { float x1; float y1; float x2; float y2; }

This structure is defined in vtutorial.C so you don’t have to define it yourself. It represents a line to be drawn in a graphical window. (x1,y1) are the coordinates of the first point, (x2,y2) the coordinates of the second point. In standard C, if you want to effectively draw such a line, you first have to define a structure and initialize the points (you can try this):

Line firstline; firstline.x1 = 0.2; firstline.y1 = 0.2; firstline.x2 = 0.8; firstline.y2 = 0.9;

This defines a line going from the point (0.2,0.2) to the point (0.8,0.9). To draw this line, you will have to write a function, say LineDraw(Line l) and call it with your object as argument :

LineDraw(firstline);

In C++, we would not do that. We would instead define a class like this:

class TLine { 13 14

int x1; int y1; int x2; int y2;

TLine(int x1, int y1, int x2, int y2); void Draw(); }

where we added two functions, that we will call methods or member functions, to the TLine class. The first method is used for initializing the line objects we would build. It is called a constructor. The second one is the Draw method itself. So, to build and draw a line, we have to do:

TLine l(0.2,0.2,0.8,0.9); l.Draw();

The first line builds the object l by calling its constructor. The second line calls the Draw() method of this object. You don’t need to pass any parameters to this method since it applies to the object l and knows what are the coordinates of the line. These are internal variables x1, y1, x2, y2 that were initialized by the constructor.

III.2. C++ notions used: inheritance and data encapsulation

III.2.1. Inheritance There is an obvious question that could be asked : what is the relation between a canvas and a pad ? Isn’t it almost the same thing? Yes it is. In fact, a canvas is a pad that spans through an entire window. This is nothing else than the notion of inheritance. The TPad class is the parent of the TCanvas class. So what? The most interesting thing is that you can reuse the code written in the parent class. For example, cd() is a method that TCanvas inherits from it’s parent, TPad. Let’s try another example. We’ve defined a TLine class that contains everything necessary to draw a line. If we want to draw an arrow, is it so different from drawing a line? We just have to draw a triangle at one end. It would be very inefficient to define the class TArrow from scratch. Fortunately, inheritance allows a class to be defined from an existing class. We would write something like :

class TArrow : public TLine { int ArrowHeadSize;

void Draw(); void SetArrowSize(int arrowsize); }

The keyword "public" will be explained later. The class TArrow now contains everything that the class TLine does, and a couple of things more, the size of the arrowhead and a function that can change it. The Draw method of TArrow will draw the head and call the draw method of TLine. We just have to write the code for drawing the head!

III.2.2. Method overriding Giving the same name to a method (remember : method = member function of a class) in the child 14 15

class (TArrow) as in the parent (TLine) doesn't give any problem. This is called overriding a method. Draw in TArrow overrides Draw in TLine. There is no possible ambiguity since, when one calls the Draw() method, this applies to an object which type is known. Suppose we have an object l of type TLine and an object a of type TArrow. When you want to draw the line, you do :

l.Draw()

so Draw() from TLine is called. If you do

a.Draw()

Draw() from TArrow is called and the arrow a is drawn.

III.2.3. Public and private : data encapsulation We have seen previously the keyword "public". This keyword means that every name declared public is seen by the outside world. This is opposed to "private" which means only the class where the name was declared private can see this name. For example, suppose we declare in TArrow the variable ArrowHeadSize private as in :

private : int ArrowHeadSize;

. Then, only the methods (=member functions) of TArrow will be able to access this variable. Nobody else will see it. Even the classes that we could derive from TArrow will not see it. On the other hand, if we declare the method Draw() as public, everybody will be able to see it and use it. You see that the character public or private doesn't depend of the type of argument. It can be a data member, a member function, or even a class. For example, in the case of TArrow, the base class TLine is declared as public : class TArrow : public TLine {

This means that all methods of TArrow will be able to access all methods of TLine, but this will be also true for anybody in the outside world. Of course, this is true provided that TLine accepts the outside world to see it's methods/data members. If something is declared private in TLine, nobody will see it, not even TArrow members, even if TLine is declared as a public base class. What if TLine is declared "private" instead of "public"? Well, it will behave like any other name declared private in TArrow : only the data members and methods of TArrow will be able to access TLine, it's methods and data members, nobody else.

This may seem a little bit confusing and the reader should read a good C++ book if he/she wants more details. Especially since besides public and private, a member can be protected… But this is another story. Usually, one puts private the methods that the class uses internally, like some utilities classes, and that the programmer doesn’t want to be seen in the outside world. With "good" C++ practice (which we suppose is used in ROOT...), all data members of a class are 15 16

also set private. This is called data encapsulation and is one of the strongest advantages of Object Oriented Programming (OOP). By doing that, nobody can see the data members of a class, except the class itself. So, from the outside world, if one wants to access those data members, one should use so called "getters" and "setters" methods, which are special methods used only to get or set the data members. The advantage is that if the programmer wants to modify the inner workings of his class, he can do so without changing what the user sees. The user doesn’t even have to know that something has changed (for the better, hopefully). An example. In our TArrow class, we would have set the data member ArrowHeadSize private. The setter method is SetArrowSize(), we don’t need a getter method :

class TArrow : public TLine { private : int ArrowHeadSize;

public : void Draw(); void SetArrowSize(int arrowsize); }

If one wants to define an arrow, he does :

TArrow* myarrow = new TArrow(1,5,89,124);

this will call the constructor of TArrow, but also the constructor of TLine, which is the parent class of TArrow, automatically. Then, we want to set the size of the head :

myarrow->SetArrowSize(10);

and draw it :

myarrow->Draw();

III.3. C++ notions used: operators new and delete Why is it so interesting to use new and delete instead of malloc and free ? First, the operator new knows the size of the object it has to initialize. You don’t need to play with it. Second, and the most important, new calls the specified constructor of the class the object belongs to. No need to do special initialization, that is you have to think about it when you write your classes constructor. But new also calls the constructor of all the objects that your class contains. For example, the class TPad contains a list of all objects in the pad. This list is itself an object of the class TList and there is a call to the constructor of this list in the constructor of TPad. We will see that new calls also automatically the constructor of the parent class (see the inheritance paragraph). When you begin to use new, don’t use malloc anymore. Better said, try to avoid mixing new and malloc. There is a risk to use free() instead of delete to release a memory that was allocated by new. This is guaranteed to crash!

16 17

IV. Graphics and interaction with the user

Graphical capabilities of ROOT go from simple 2D objects (lines, polygons, arrows...) to various plots, histograms and even 3D graphical capabilities. In this chapter, we are going to focus on generalities about graphics and simple objects. Plots and histograms will be treated elsewhere, as well as 3D.

IV.1. Drawing objects In ROOT, most objects derive from a base class TObject. This class has a virtual method Draw() so all objects are supposed to be able to be "drawn". The basic whiteboard on which an object is drawn is called a Canvas (defined by the class TCanvas). If a few of them are defined, there is only one active at a time. One draws an object in the active canvas by using the statement object.Draw() This instructs the object "object" to draw itself. If no canvas is opened, a default one (named "c1") is drawn,. As an example, one may try the following commands : root[0] a = new TLine(0.1,0.1,0.6,0.6) root[1] a->Draw() The first statement defines a line (class TLine of course) and the second one draws it. A default canvas is drawn since there was no opened one.

IV.2. Interacting with graphical objects When an object is drawn, one can interact with it. For example the line drawn in the previous paragraph may be moved or transformed. One very important characteristic of ROOT is that transforming an object on the screen will also transform it in memory. One actually interacts with the real object, not with a copy of it on the screen. You can try for instance to look at the starting X coordinate of the line ; root[2] a->GetX1() (double)1.000000000e-1 This is of course what you defined when you created the line above. Now move it interactively by clicking with the left mouse button in the line's middle and try to do again root[3] a->GetX1() This is not the same result as before. As said, interacting with an object on the screen changed this object in memory.

IV.2.1. Moving, resizing and modifying objects

IV.2.1.1. Interactively with the left mouse button As was just seen, interacting with an object, that is moving or resizing it, is done with the left

17 18 mouse button. The cursor changes it's shape to indicate what may be done :

Point the object or one part of it :

Rotate :

Resize (exists also for the other directions) :

Enlarge (used for text) :

Move :

Here are some examples of Moving :

Resizing :

Rotating :

18 19

IV.2.1.2. By C++ statements How would one move an object in a script ? Since there is a so tight correspondance between what is seen on the screen and the object in memory, changing this object changes it on the screen. For example, try to do : root[4] a->SetX1(0.9) This should change one of the coordinates of our line. Nothing happens on the screen ?

IV.2.1.3. Updating the canvas This is normal. Imagine the waste of processing power if the canvas was redrawn each time one of the elements in it changes. One has to inform the canvas that something has changed. Since we didn't create it explicitly the canvas that was created is a default one. It's name is also the default, that is "c1". A redraw will be triggered by : 1) Issueing root[5] c1->Modified() Try it. 2) Just try to touch the window, resize it for example. 3) The end of the execution of a script. So if you just want to see the result of your script, you don't have to bother with manually updating the canvas. But if you want to see some intermediate results, you will have to issue c1->Modified() in the script.

IV.2.2. Selecting objects

IV.2.2.1. Interactively with the middle mouse button Objects in a canvas, as well as in a pad, as we will see below, are stacked on top of each other in the order they were drawn. Some objects may become "active" objects, which means they come above the others. To do it interactively, one has to use the middle button of the mouse. In case of canvases or pads (which are sub-canvases). The border becomes highlighted when selected.

IV.2.2.2. By C++ statements Often one wants to draw successively in different canvases or pads. By default, the objects are drawn in the active canvas. To activate a canvas in a script, one should use the "cd()" method of the canvas or the pad. root[6] c1->cd() This is a standard name for a selection method. See for example root files class TFile.

IV.2.3. Popup menus : the right button

IV.2.3.1. Using popups We have at our disposal one more mouse button. It would be a pitty not to use it. In ROOT, this is used to pop some menus up. Each popup menu corresponds to the object that is pointed to by the cursor. The script "hsimple.C" outputs a histogram. If one wants to see all the objects present in the canvas, one may click over a big number of objects :

Try to do this ! More seriously, this picture shows that drawing a simple histogram involves as 19 20 many as 7 objects. (we didn't show one of the axis). The user will be asked for numerical values or strings if needed to complete a command.

IV.2.3.2. Structure of the popup menus The curious reader will have probably noticed that each entry in the popup corresponds to a method of the class of the object involved. Look for example to the menu named "TAxis::xaxis". Obviously xaxis is the name of the object and TAxis it's class. If we look at the list of TAxis methods, for example in http://www.root.ch/root/html/TAxis.html, we see methods like "SetTimeDisplay" or "UnZoom" which appear in the popup. There are several blocks in the popup, separated by lines. The top one corresponds to methods of the class, the subsequent ones to methods of the parent class. The last ones are methods of parent classes in case of multiple inheritance, as for example "SetLineAttributes" in the case of "TPaveText::title". A TPaveText inherits from TAttLine, which defines the method SetLineAttributes().

IV.2.3.3. Generating popups from your code If the reader is even more curious, he/she may have noticed that some header files defining ROOT classes contain comments of the type // *MENU*. This is how popup menus are generated from header files, without any other intervention from the programmer. This is easily understandable. Since the CINT interpreter knows what are the classes and which are the methods of a particular class, one can use this to generate automatically and on the fly the popup menus from the type of object one is clicking on. If you click on an axis, ROOT will ask the interpreter what are the methods of the TAxis class and which ones are set for being displayed in a popup. Now, how does the interpreter know this ? Remember, when you build a class that you want to use in the ROOT environment, you use the rootcint utility which builds the so called stub functions and the dictionnary. These functions and the dictionnary are giving the whole system a knowledge of the classes present. The rootcint utility parses all the header files to do it's job. One can use, and is using, this parsing to put some additional information. And the only places left are the comments, since all the rest is C/C++ code, with no freedom left. So, you have a class that contains a Draw() method, that will display itself and you would like a popup to appear when on clicks on the image of an object of this class. The recipe is fairly simple : 1) The class have to contain the ClassDef/ClassImp macros 2) For each method you want to appear in the popup, put a comment after the declaration containing *MENU* or *TOGGLE* depending on the behaviour you expect. One usually uses Set methods (setters). Example : class MyClass : public TObject { private : int fV1; // first variable double fV2; // second variable public : 20 21

int GetV1() {return fV1;} double GetV2() {return fV2;} void SetV1(int x1) { fV1 = x1;} // *MENU* void SetV2(double d2) { fV2 = d2;} // *MENU* void SetBoth(int x1, double d2) {fV1 = x1; fV2 = d2;} }

3) You can specify what arguments are going to be used and what data member of the class should be changed. For example : *ARGS={x1=>fV1} This statement is in the comment field, after the *MENU*. If there are more than one argument, these arguments are separated by commas : void SetXXX(Int_t x1, Float_t y2); // *MENU* *ARGS={x1=>fX1, y2=>fY2} where fX1 qnd fY2 are data fields in the same class. If this arguments statement is present, the dialog window that appears after selecting this SetXXX field will contain the values present at that moment in the variables. This is normal since we indicate to the system whhich argument corresponds to which data member of the class. The *TOGGLE* declaration instead of *MENU* is used if one wants to toggle a boolean data field from 1 to 0 or 0 to 1. In that case, it is safe to call the data field "fXXX" where XXX is the name of the setter (SetXXX, replace XXX by what you want).

IV.2.4. Executing events when a cursor passes on top of an object This paragraph is more for reference for a class designer. When a class is designed, it is often desirable to include drawing methods for it. We will have a more extensive discussion about this, but drawing an object in a canvas or a pad consists in "attaching" the object to that pad. When one uses "object.Draw()", the object is NOT painted at this moment. It is only attached to the active pad or canvas. Another method should be provided for the object to be painted, the Paint() method. This is all explained in the next paragraph. As well as Draw() and Paint(), there are other methods that may be provided by the designer of the class. When the mouse is moved or a button pressed/released, the TCanvas function named HandleInput() scans the list of objects in all it's pads and for each object calls some standard methods to make the object react to the event (mouse movement, click or whatever). The first one is DistanceToPrimitive(px,py). This function computes a "distance" to an object from the mouse position at the pixel position (px,py, see definition at the end of this paragraph) and returns this distance in pixel units. The selected object will be the one with the shortest computed distance. To see how this works, select the "Event Status" item in the canvas "Options" menu. ROOT will display one status line showing the picked object. If the picked object is, for example, an histogram, the status line indicates the name of the histogram, the position x,y in histogram coordinates, the channel number and the channel content. It's nice for the canvas to know what is the closest object from the mouse, but it's even nicer to be able to make this object react. The second standard method to be provided is 21 22

ExecuteEvent(). This method actually does the event reaction. It's prototype is : void ExecuteEvent(Int_t event, Int_t px, Int_t py); where px and py are the coordinates at which the event occured, except if the event is a key press, in which case px contains the key code. "event" is the event that occurs and is one of the following (defined in Buttons.h): kNoEvent, kButton1Down, kButton2Down, kButton3Down, kButton1Up, kButton2Up, kButton3Up, kButton1Motion, kButton2Motion, kButton3Motion, kButton1Locate, kButton2Locate, kButton3Locate, kButton1Double, kButton2Double, kButton3Double, kKeyDown, kKeyUp, kKeyPress, kMouseMotion, kMouseEnter, kMouseLeave. We hope the names are self-axplanatory. Designing an ExecuteEvent method is not very easy, except if one wants very basic treatment. We will not go into that and let the reader refer to the sources of classes like TLine or TBox. Go and look at their ExecuteEvent method ! But we can nevertheless give some reference to the various actions that may be performed. For example, one often wants to change the shape of the cursor when passing on top of an object. This is done via gPad->SetCursor(cursor) where cursor is the type of cursor. It may be : kBottomLeft, kBottomRight, kTopLeft, kTopRight, kBottomSide, kLeftSide, kTopSide, kRightSide, kMove, kCross, kArrowHor, kArrowVer, kHand, kRotate, kPointer, kArrowRight, kCaret, kWatch. They are defined in TVirtualX.h and again we hope the names are self-explanatory. If not, try them by designing a small class. It may derive from something already known like TLine. Note that the ExecuteEvent() functions may in turn, invoke other objects such functions in case an object is drawn using other objects. You can also exploit at best the virtues of inheritance. See for example how the class TArrow (derived from TLine) use or redefine the picking functions in it's base class. The last comment is that mouse position is always given in pixel units in all these standard functions. px=0 and py=0 corresponds to the top-left corner of the canvas. Here, we have followed the standard convention in windowing systems. Note that user coordinates in a canvas (pad) have the origin at the bottom-left corner of the canvas (pad). This is all explained in the paragraph "Coordinate system of a pad".

IV.3. Canvas, pads and all that : graphical containers We have talked a lot about canvases, which may be seen as windows. More generally, a graphical entity that contains graphical objects is called a Pad. A Canvas is a special kind of Pad. So, from now on, when we say something about pads, this also applies to canvases.

IV.3.1. Canvas and Pads

IV.3.1.1. Pads "contain" other objects A pad (class TPad) is a graphical container in the sense it contains other graphical objects like

22 23 histograms, arrows,.... It may contain other pads (subpads) as well. More technically, each pad has a linked list of pointers to the objects it holds. Drawing an object is nothing more than adding it's pointer to this list. Look for example to the code of TH1::Draw(). This is merely ten lines. The last statement is AppendPad(). This calls a method of TObject that just adds the pointer of the object, here a histogram, to the list of attached objects of the current pad. Since this is a TObject method, every object may be "drawn", which means attached to a pad. We can illustrate this by the following figure. The image :

corresponds to this structure :

When is the painting done then ? The answer is : when needed. Every object that derives from TObject has a Paint() method. It may be empty, but for graphical objects, this routine contains all the instructions to effectively paint it in the active pad. Since a Pad has the list of objects it owns, it will call successively the Paint() method of each object, thus re-painting the whole pad on the screen. If the object is a subpad, it's Paint() method will call the Paint() method of objects attached, thus recursively calling Paint() for all the objects.

IV.3.1.2. The global "gPad" When an object is drawn, it is always in the so called active pad. For every day use, it is comfortable to be able to access the active pad, whatever it is. For that purpose, there is a global pointer, called "gPad" that is always pointing to the active pad. If you want to change the fill color of the active pad to blue but you don't know it's name, just do root[6] gPad->SetFillColor(38) To get the list of colors, go to the paragraph "Color and color palettes" or if you have an opened canvas, click in the "View" menu, selecting the "Colors" entry. gPad is probably the most used global variable in ROOT.

IV.3.1.3. Finding and accessing an object in a pad Now that we have a pointer to the active pad (gPad) and that we know this pad contains some objects, it is sometimes interesting to access one of those objects. The method GetPrimitive() of TPad, i.e. TPad::GetPrimitive(const char* name) does exactly this. Since most of 23 24

the objects that a pad contains derive from TObject, they have a name. The following statement : root[6] obj = gPad->GetPrimitive("myobjectname") (class TObject*)0x1063cba8 will return a pointer to the object "myobjectname" and put that pointer into the variable "obj". As you see, the type of returned pointer is (TObject*). Even if your object is something more complicated as a histogram TH1F, this is normal. A function cannot return more than one type. So the one chosen was the lowest common denominator to all possible classes, the class from which everything derives, TObject. How to get the right pointer then ? Simply do a cast of the function output, that is transform this output (pointer) into the right type. For example if the object is a TPaveLabel : root[6] obj = (TPaveLabel*)(gPad->GetPrimitive("myobjectname")) (class TPaveLabel*)0x1063cba8 This works for all objects deriving from TObject. But a question remains. An object has a name if it derives from TNamed, not from TObject. For example an arrow (TArrow) doesn't have a name. In that case, the "name" is the name of the class. To know the name of an object, just click with the right button on it. The name appears at the top of the popup menu.

IV.3.1.4. Hiding an object in a pad Hiding an object in a pad can be made by removing it from the list of objects owned by that pad. This list is accessible by the GetListOfPrimitives() method of TPad. This method returns a pointer to a TList.. Suppose we get the pointer to the object we want to hide, call it "obj" (see paragraph above). We get the pointer to the list : root[6] li = gPad->GetListOfPrimitives() Then remove the object from this list : root[6] li->Remove(obj) The object will disappear from the pad as soon as it is updated (try to resize it). If one wants to make the object reappear : root[6] obj->Draw() Caution, this will not work with composed objects, for example many histograms drawn on the same plot (with the option "same"). There are other ways ! Try to use the method described here for simple objects (lines, labels, ...).

IV.3.2. Coordinate system of a pad

IV.3.2.1. Definition of the various coordinates systems There are three coordinate systems that may be used :  The least commonly used is the pixel coordinate system that we already saw, used by functions such as DistanceToPrimitive() and ExecuteEvent(). It is used mainly for cursor position, which is always given in pixel units. If (px,py) is the cursor position, px=0 and py=0 corresponds to the top-left corner of the pad. Here, we have followed the standard convention in windowing systems.  Much more commonly used is the NDC (Normalized Coordinate System). These coordinates are independent of the size of the window or a particular user system. The coordinates are in the range [0,1]. The coordinates (0,0) correspond to the bottom-left corner of the pad. Several internal Root functions use 24 25 this system (3D primitives, Postscript, log scale mapping to lin scale). The user will want to use this system if the user coordinates are not known a priori.  The most commonly used system is the user coordinate system. Most Pad user callable functions are working in this system. All graphics primitives have parameters defined in terms of user coordinates. The three systems are described by the following picture :

IV.3.2.2. Setting globally the coordinates system By default, when an empty pad is drawn the, the user coordinates are set to [0,1] and are equivalent to NDC. If one draws a high level graphical object (histogram, function,...) the user coordinates are set to the histogram ones. So when you set a point, it will be in the histogram coordinates, for instance. For a newly created blank pad, one may use TPad::Range to set the user coordinate system. This function is defined as : void Range(float x1, float y1, float x2, float y2) x1, x2 are the limits coordinates of the pad in x, y1, y2 the same in y. So : root[6] gPad->Range(-100,100,-100,100) will set the active pad to have both coordinates to go from -100 to +100, the center of the pad being in this case (0,0).

IV.3.2.3. Using NDC for a particular object Most of the time, one is in the user coordinate system. Sometimes, one wants to use NDC despite this fact. There are two ways to achieve this. One may set the NDC for one particular object or one may convert NDC to user coordinates. Most graphical objects do have a way to be drawn in NDC. For instance a line (TLine) may be drawn in NDC by using DrawLineNDC(). A latex formula or a text may use TText::SetNDC() to be drawn in NDC coordinates.

IV.3.2.4. Converting between coordinates systems There are a few utility function in TPad to convert from one system of coordinates to another. In the following table, a point is defined by : (px,py) in pixel coordinates; (ux,uy) in user coordinates; (ndcx,ndcy) in NDC coordinates Converts from ... to ... methods of TPad returns PixeltoX(px) float Pixel to PixeltoY(py) float User PixeltoXY(px,py, &ux, changes ux,uy &uy) XtoPixel(ux) i n User to YtoPixel(uy) t Pixel XYtoPixel(ux,uy,&px,&py i ) n t changes px,py NDC to UtoPixel(ndcx) i 25 26

Pixel VtoPixel(ndcy) n t i n t

Frames... TFrame

IV.3.3. Dividing a pad into subpads Dividing a pad into subpads in order for instance to draw a few histograms, may be done in two ways. The first is to build pad objects and to draw them into a parent pad, which may be a canvas. The second is to automatically divide a pad into nxm subpads.

IV.3.3.1. Manual divide The simplest way to divide a pad is to build subpads in it. However this forces the user to explicitely indicate the size and position of those subpads. Suppose we want to build a subpad in the active pad (pointed by gPad). First, we build it, using one of pads constructor: root[6] subpad1 = new TPad("subpad1","The first subpad", 0.1,0.1,0.5,0.5) (All this is on one line, of course). One gives the coordinates of the lower left point (0.1,0.1) and of the upper right one (0.5,0.5). These coordinates are in NDC. This means that they are independent of the user coordinates system, in particular if you have already drawn for example a histogram in the mother pad. The only thing left to be done is to draw the pad : root[6] subpad1->Draw() Well, this is almost true since, if you want other pads, you have to redo this procedure as many times as necessary.

IV.3.3.2. Automatic divide The manual way of dividing a pad into subpads is sometimes very tedious. There is a way to automatically generate nxm subpads inside a given pad. If "pad1" is a pad then : root[6] pad1->Divide(3,2) will divide the pad into 3 columns of 2 subpads :

26 27

The generated subpads get names pad1_i where i is 1 to nxm. In our case pad1_1, pad1_2... pad1_6 :

The names pad1_1 etc.. corresponds to new variables in CINT, so you may use them as soon as the pad->Divide() was executed. But in a compiled program, one has to access these objects. Remember that a pad contains other objects and that these objects may themselves be pads. So we can use the GetPrimitive() method of TPad : TPad* pad1_1 = (TPad*)(pad1->GetPrimitive("pad1_1"))

One question remains. In case one does an automatic divide, how can he set the default margins between pads ? This is done by adding two parameters to Divide(), which are the margins in x and y : root[6] pad1->Divide(3,2,0.1,0.1) The margins are here set to 10% of the parent pad width.

IV.3.4. Making a pad transparent As we will see in the paragraph "Fill attributes", a fill style (type of hatching) may be set for a pad. This is done with root[6] pad1->SetFillStyle(istyle) where istyle is a style number, defined in "Fill attributes". There is a special set of styles that allows to handle various levels of transparency. These are styles number 4000 to 4100, 4000 being fully transparent and 4100 fully opaque. So, suppose you have an existing canvas with several pads. You create a new pad (transparent) covering for example the entire canvas. Then you draw you primitives in this pad. The same can be achieved with the graphics editor.

example: root [0] .x tutorials/h1draw.C root [1] TPad *newpad=new TPad("newpad","a transparent pad",0,0,1,1); 27 28

root [2] newpad.SetFillStyle(4000); root [3] newpad.Draw(); root [4] newpad.cd(); root [5] // create some primitives, etc

IV.3.5. Log scale is a pad attribute ! Yes ! log scale is not an axis attribute only, since it influences the way objects are drawn in a pad. So it is a pad attribute. If you have a pad with a histogram, a right-click on the pad, outside of the histograms frame will convince you. The SetLogx(), SetLogy() and SetLogz() methods are there. As you see, TPad defines Log scale for the two directions x and y plus z if you want to draw a 3D representation of some function or histogram. The way to set logscale in the x direction for the active pad is : root [5] gPad->SetLogx(1) and to unset log in the z direction : root [5] gPad->SetLogz(0)

IV.3.6. Needs to be updated when finished drawing

IV.3.7. Scrollable canvas

IV.4. Graphical objects In this paragraph, we describe the various simple 2D graphical objects defined in ROOT. Usually, one defines these objects with their constructor and draws them with their Draw() method. So the examples will be very brief. Most graphical objects have line and fill attributes (color, width,…) that will be described in “Graphical objects attributes”. If the user wants more information, the class names are given and he may refer to the online developer documentation. This is especially true for functions and methods that set and get internal values of the objects described here.

IV.4.1. Lines, arrows, and geometrical objects

IV.4.1.1. Line : class TLine The simplest graphical object is a line. It is implemented in the TLine class. The constructor is : TLine(Coord_t x1, Coord_t y1, Coord_t x2, Coord_t y2) where x1, y1, x2, y2 are the coordinates of the first and second point. This constructor may be used as in : root [0] l = new TLine(0.2,0.2,0.8,0.3) root [1] l->Draw()

IV.4.1.2. Arrows : class TArrow Different arrow formats as explained in the picture below are provided :

28 29

Once an arrow is drawn on the screen: - One can click on one of the edges and move this edge. - One can click on any other arrow part to move the entire arrow. The constructor is : TArrow(Coord_t x1, Coord_t y1,Coord_t x2, Coord_t y2, Float_t arrowsize, Option_t *option) It defines an arrow between points x1,y1 and x2,y2. The arrowsize is in percentage of the pad height. The options are the following :

- option = ">"

- option = "<"

- option = "|>"

- option = "<|"

- option = "<>"

- option = "<|>" arrow defined by a triangle If the fill color defined if FillColor == 0, draw open triangle else draw full triangle with fill color. If "ar" is an arrow object, fill color is set with ar->SetFillColor(icolor), where icolor is the color defined in “Color and color palettes”. The opening angle between the two sides of the arrow is 60 degrees. It can be changed with ar- >SetAngle(angle), where angle is expressed in degrees.

29 30

IV.4.1.3. Polyline : class TPolyLine A polyline is a set of joint segments. It is defined by a set of N points in a 2D space. It’s constructor is TPolyLine(Int_t n, Float_t* x, Float_t* y, Option_t* option) Where n is the number of points, x and y arrays of n elements corresponding to the coordinates of these points. TPolyLine can be used by itself but is also a base class for other objects, such as curly arcs.

IV.4.1.4. Circles, Ellipses : class TEllipse Ellipse is a general ellipse that can be truncated and rotated. An ellipse is defined by its center (x1,y1) and two radius r1 and r2. A minimum and maximum angle may be specified (phimin, phimax). The picture below illustrates different types of ellipses :

The Ellipse may be rotated with an angle theta. The attributes of the outline line and of the fill area are described in “Graphical objects attributes”

The constructor of a TEllipse object is : TEllipse(Float_t x1, Float_t y1,Float_t r1,Float_t r2,Float_t phimin,Float_t phimax,Float_t theta) An ellipse may be created with a statement like root [0] e = new TEllipse(0.2,0.2,0.8,0.3) root [1] e->Draw()

IV.4.1.5. Squares : classes TBox and TWbox A square is defined by the class TBox since it is a base class for many different higher level graphical primitives. A box is defined by - it’s bottom-left coordinates x1,y1 - it’s top right coordinates x2,y2 The constructor being 30 31

TBox(Coord_t x1, Coord_t y1, Coord_t x2, Coord_t y2) It may be used as in : root [0] b = new TBox(0.2,0.2,0.8,0.3) root [1] b->Draw()

A TWbox is a square (TBox) with a border size and a border mode :

The attributes of the outline line and of the fill area are described in “Graphical objects attributes”

IV.4.1.6. One point, or marker : class TMarker A marker is a point with a fancy shape ! The possible markers are the following:

One marker is build via the constructor : TMarker(Coord_t x, Coord_t y, Int_t marker) x and y are the coordinates of the marker and marker is the type, shown above. Suppose ma is a valid marker. One can set the size of the marker with ma->SetMarkerSize(size), where size is the desired size. The available sizes are :

Sizes smaller than 1 may be specified.

IV.4.1.7. Set of points : class TPolyMarker A PolyMarker is defined by an array on N points in a 2-D space. At each point x[i], y[i] a marker is drawn. The list of marker types is shown in the previous paragraph. 31 32

The marker attributes are managed by the class TAttMarker and are described in “Graphical objects attributes” The constructor for a PolyMarker is : TPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option) Where x and y are arrays of coordinates for the n points that form the polymarker.

IV.4.1.8. Curly and wavy lines for Feynman diagrams This is a peculiarity of particle physics, but we do need sometimes to draw Feynman diagrams. Our friends working in banking can skip this part ! A set of classes implements curly or wavy polylines typically used to draw Feynman diagrams. Amplitudes and wavelengths may be specified in the constructors, via commands or interactively from popup menus. These classes are TCurlyLine and TCurlyArc. These classes make use of TPolyLine by inheritance, ExecuteEvent methods are highly inspired from the methods used in TPolyLine and TArc. The picture below has been generated by the tutorial feynman.C :

The constructors are : TCurlyLine(Float_t x1, Float_t y1, Float_t x2, Float_t y2, Float_t wavelength, Float_t amplitude) With starting point (x1, y1), end point (x2,y2). The wavelength and amplitude are given in percent of the pad height For TCurlyArc, the constructor is : TCurlyArc(Float_t x1, Float_t y1, Float_t rad, Float_t phimin, Float_t phimax, Float_t wavelength, Float_t amplitude) The center is (x1, y1) and the radius rad. The wavelength and amplitude are given in percent of the line length, phimin and phimax, which are the starting and ending angle of the arc, are given in degrees. Refer to the tutorial feynman.C for a more extensive example.

IV.4.2. Text, labels and paves

IV.4.3. Text and Latex mathematical expressions Text can be embedded in PaveLabels or titles of graphs or many other objects but it can live a life of it’s own. All text displayed in ROOT graphics is an object of class TText. Most of the time, for a physicist, it will be a TLatex expression (which derives from TText)

32 33

TLatex has been conceived to draw mathematical formulae or equations. It’s syntax is very similar to the Latex one in mathematical mode.

IV.4.3.1. Subscripts and Superscripts Subscripts and superscripts are made with the _ and ^ commands. These commands can be combined to make complicated subscript and superscript expressions. You may choose how to display subscripts and superscripts using the 2 functions SetIndiceSize(Float_t) and SetLimitIndiceSize(Int_t). Examples of what can be obtained using subscripts and superscripts : The expression gives The expression gives The expression gives

x^{2y} 2 y x^{y^{2}} y2 x^{y}_{1} y x x x1

x_{2y} x^{y_{1}} y1 x_{1}^{y} y x2 y x x1

IV.4.3.2. Fractions Fractions denoted by the / symbol are made in the obvious way. The #frac command is used for large fractions in displayed formula; it has two arguments: the numerator and the denominator. An example : y  z / 2 x  y 2 1 is obtained by the expression x=#frac{y+z/2}{y^{2}+1}

IV.4.3.3. Roots The #sqrt command produces the square root of its argument; it has an optional first argument for other roots. Example : #sqrt{10} #sqrt[3]{10}

IV.4.3.4. Mathematical Symbols TLatex can make dozens of special mathematical symbols. A few of them, such as + and > , are produced by typing the corresponding keyboard character. Others are obtained with the commands in the following table :

#Box draw a square

33 34

IV.4.3.5. Delimiters You can produce 3 kinds of proportional delimiters. #[]{....} or "a la" Latex #left[.....#right] : big square brackets #{}{....} or #left{.....#right} : big curly brackets #||{....} or #left|.....#right| : big absolute value symbol #(){....} or #left(.....#right) : big parenthesis

IV.4.3.6. Greek Letters The command to produce a lowercase Greek letter is obtained by adding a # to the name of the letter. For an uppercase Greek letter, just capitalize the first letter of the command name. #alpha #beta #gamma #delta #epsilon #zeta #eta #theta #iota #kappa #lambda #mu #nu #xi #omicron #pi #varpi #rho #sigma #tau #upsilon #phi #varphi #chi #psi #omega #Gamma #Delta #Theta #Lambda #Xi #Pi #Sigma #Upsilon #Phi #Psi #Omega

IV.4.3.7. Putting One Thing Above Another Symbols in a formula are sometimes placed one above another. TLatex provides special commands for doing this. (which ones ?)

IV.4.3.8. Accents, arrows and bars #hat{a} = hat #check = inversed hat #acute = acute #grave = agrave #dot = derivative #ddot = double derivative furthermore, a is obtained with #bar{a}  a is obtained with #vec{a}

IV.4.3.9. Changing Style in Math Mode You can change the font and the text color at any moment using : #font[font-number]{...} and #color[color-number]{...}

IV.4.3.10. Example1 The following macro (tutorials/latex.C) { gROOT->Reset(); TCanvas c1("c1","Latex",600,700); TLatex l; l.SetTextAlign(12); l.SetTextSize(0.04);

34 35

l.DrawLatex(0.1,0.8,"1) C(x) = d #sqrt{#frac{2}{#lambdaD}} #int^{x}_{0}cos(#frac{#pi}{2}t^{2})dt"); l.DrawLatex(0.1,0.6,"2) C(x) = d #sqrt{#frac{2}{#lambdaD}} #int^{x}cos(#frac{#pi}{2}t^{2})dt"); l.DrawLatex(0.1,0.4,"3) R = |A|^{2} = #frac{1}{2}(#[]{#frac{1} {2}+C(V)}^{2}+#[]{#frac{1}{2}+S(V)}^{2})"); l.DrawLatex(0.1,0.2,"4) F(t) = #sum_{i=-#infty}^{#infty}A(i)cos#[] {#frac{i}{t+i}}"); } produces the following picture:

IV.4.3.11. Example2 The following macro (tutorials/latex2.C): { gROOT->Reset(); TCanvas c1("c1","Latex",600,700); TLatex l; l.SetTextAlign(23); l.SetTextSize(0.1); l.DrawLatex(0.5,0.95,"e^{+}e^{-}#rightarrowZ^{0}#rightarrowI#bar{I}, q#bar{q}"); l.DrawLatex(0.5,0.75,"|#vec{a}#bullet#vec{b}|=#Sigmaa^{i}_{jk} +b^{bj}_{i}"); l.DrawLatex(0.5,0.5,"i(#partial_{#mu}#bar{#psi}#gamma^{#mu} +m#bar{#psi}=0#Leftrightarrow(#Box+m^{2})#psi=0"); l.DrawLatex(0.5,0.3,"L_{em}=eJ^{#mu}_{em}A_{#mu} , 35 36

J^{#mu}_{em}=#bar{I}#gamma_{#mu}I , M^{j}_{i}=#SigmaA_{#alpha}#tau^{#alphaj}_{i}"); } produces the following picture :

IV.4.3.12. Example3 The following macro (tutorials/latex3.C): { gROOT->Reset(); TCanvas c1("c1"); TPaveText pt(.1,.5,.9,.9); pt.AddText("#frac{2s}{#pi#alpha^{2}} #frac{d#sigma}{dcos#theta} (e^{+}e^{-} #rightarrow f#bar{f} ) = "); pt.AddText("#left| #frac{1}{1 - #Delta#alpha} #right|^{2} (1+cos^{2}#theta"); pt.AddText("+ 4 Re #left{ #frac{2}{1 - #Delta#alpha} #chi(s) #[] {#hat{g}_{#nu}^{e}#hat{g}_{#nu}^{f} (1 + cos^{2}#theta) + 2 #hat{g}_{a}^{e}#hat{g}_{a}^{f} cos#theta) } #right}"); pt.SetLabel("Born equation"); pt.Draw(); } produces the following picture :

36 37

IV.4.4. Axis

IV.4.5. Sliders

IV.4.6. 3D graphical objects Need TView sometimes Axis in 3D ?

IV.4.6.1. Helix : class THelix Helix is, hmmm, well, a helix. It has 3 different constructors. If a particle with charge q passes through a point (x,y,z) with momentum (px,py,pz) with magnetic field B along an axis (nx,ny,nz), this helix can be constructed like THelix p(x0,y0,z0, px,py,pz, q*B, nx,ny,nz); (nx,ny,nz) defaults to (0,0,1). A helix in its own frame can be defined with initial position (x0,y0,z0) and "velocity" (vx0,vy0,vz0), both 3-vectors, and an angular frequency w. The parametric equation of the helix is x = x0 - vt / w * sin(-w * t + phi0) y = y0 + vt / w * cos(-w * t + phi0) z = z0 + vz * t The 'normal constructor' has 6 parameters,

Example: THelix pl1(xyz0, v0, w, range, rtype, axis); where: - xyz0 : array of initial position - v0 : array of initial velocity - w : angular frequency - range : helix range - rtype : kHelixZ specifies allowed drawing range in helix Z direction, i.e., along B field., 37 38

kLabZ specifies drawing range in lab frame. kHelixX, kHelixY, kLabX, kLabY, kUnchanged ... etc can also be specified - axis : helix axis

A Third constructor uses several default values:

Example: c1 = new TCanvas("c1"); TView *view = new TView(1); view->SetRange(-1,-1,-1,1,1,1); THelix *helix = new THelix(0.0, 0.0, 0.0, 1.0, 0.0, 0.3, 10.0); helix->Draw();

will initializes a helix with its axis in Z direction (rtype=kHelixZ). range[0] = 0 and range[1] = 1 Comments/suggestions/etc on this class should be sent to the author: [email protected] (Ping Yeh)

IV.5. Graphical objects attributes

IV.5.1. Text attributes When a class contains text or derives from a text class, it has to deal with this text attributes like font, size, etc… This is done by inheriting the class also from the TAttText class (secondary inheritance), which defines text attributes. TLatex and TText do so.

IV.5.1.1. Setting text attributes interactively When clicking on an object containing text, one of the last items in the popup is "SetTextAttributes". Selecting it makes the following window appear :

This canvas allows you to set : 38 39

The text alignment Font Color Size

IV.5.1.2. Setting text alignment Text alignment may also be set by a method call. What is said here applies to all objects deriving from TAttText, and there are many. We will take an example that may be transposed to other types. Suppose "la" is a TLatex object. The alignment is set with : root[0] la->SetTextAlign(align) where align is a short describing the alignment : align = 10*HorizontalAlign + VerticalAlign For Horizontal alignment the following convention applies: 1=left adjusted, 2=centered, 3=rigth adjusted For Vertical alignment the following convention applies: 1=bottom adjusted, 2=centered, 3=top adjusted For example align = 11 = left adjusted and bottom adjusted align = 32 = right adjusted and vertically centered

IV.5.1.3. Setting text color Text color may also be set by a method call. What is said here applies to all objects deriving from TAttText, and there are many. We will take an example that may be transposed to other types. Suppose "la" is a TLatex object. The text color is set with : root[0] la->SetTextColor(color) where color is a color number. The colors are described in "Color and color palettes"

IV.5.1.4. Setting text font Text font may also be set by a method call. What is said here applies to all objects deriving from TAttText, and there are many. We will take an example that may be transposed to other types. Suppose "la" is a TLatex object. The text font is set with : root[0] la->SetTextFont(font) where font is the text font code. font = 10*fontID + precision Font IDs must be between 1 and 14 (see below) precision = 1 fast hardware fonts (steps in the size) 39 40

precision = 2 scalable and rotatable hardware fonts Example : font = 62 is the font with ID 6 and precision 2 The available fonts are : Font ID X11 True Type name is italic "boldness" 1 times-medium-i-normal "Times New Roman" 1 4 2 times-bold-r-normal "Times New Roman" 0 7 3 times-bold-i-normal "Times New Roman" 1 7 4 helvetica-medium-r-normal "Arial" 0 4 5 helvetica-medium-o-normal "Arial" 1 4 6 helvetica-bold-r-normal "Arial" 0 7 7 helvetica-bold-o-normal "Arial" 1 7 8 courier-medium-r-normal "Courier New" 0 4 9 courier-medium-o-normal "Courier New" 1 4 10 courier-bold-r-normal "Courier New" 0 7 11 courier-bold-o-normal "Courier New" 1 7 12 symbol-medium-r-normal "Symbol" 0 6 13 times-medium-r-normal "Times New Roman" 0 4 14 "Wingdings" 0 4 Here is an example of what is obtained :

with the following macro : { textc = new TCanvas("textc","Example of text",1); for (int i=1;i<15;i++) { cid = new char[8]; sprintf(cid,"ID %d :",i); cid[7] = 0; 40 41

lid = new TLatex(0.1,1-(double)i/15,cid); lid->SetTextFont(62); lid.Draw(); l = new TLatex(0.2,1-(double)i/15,"The quick brown fox is not here anymore"); l->SetTextFont(i*10+2); l.Draw(); } }

IV.5.1.5. Setting text size Text size may be set by a method call. What is said here applies to all objects deriving from TAttText, and there are many. We will take an example that may be transposed to other types. Suppose "la" is a TLatex object. The text size is set with : root[0] la->SetTextSize(size) where size is the text size expressed in percentage of the current pad height The text size in pixels (say charheight) will be: charheight = textsize*canvas_height if current pad is horizontal. charheight = textsize*canvas_width if current pad is vertical.

IV.5.1.6. Setting text angle Text angle may be set by a method call. What is said here applies to all objects deriving from TAttText, and there are many. We will take an example that may be transposed to other types. Suppose "la" is a TLatex object. The text angle is set with : root[0] la->SetTextAngle(angle) where angle is the text angle with respect to horizontal, expressed in degrees IV.5.2. Line attributes All classes manipulating lines have to deal with line attributes. This is done by using secondary inheritance of the class TAttLine.

IV.5.2.1. Setting line attributes interactively When clicking on an object being a line or having some line attributes, one of the last items in the popup is "SetLineAttributes". Selecting it makes the following window appear :

This canvas allows you to set :

41 42

The line color Style Width

IV.5.2.2. Setting line color Line color may be set by a method call. What is said here applies to all objects deriving from TAttLine, and there are many (histograms, plots,…) . We will take an example that may be transposed to other types. Suppose "li" is a TLine object. The line color is set with : root[0] li->SetLineColor(color) where color is a color number. The colors are described in "Color and color palettes"

IV.5.2.3. Setting line style Line style may be set by a method call. What is said here applies to all objects deriving from TAttLine, and there are many (histograms, plots,…). We will take an example that may be transposed to other types. Suppose "li" is a TLine object. The line style is set with : root[0] li->SetLineStyle(style) where style is one of : 1=solid, 2=dash, 3=dash-dot, 4=dot-dot.

IV.5.2.4. Setting line width Line width may be set by a method call. What is said here applies to all objects deriving from TAttLine, and there are many (histograms, plots,…). We will take an example that may be transposed to other types. Suppose "li" is a TLine object. The line width is set with : root[0] li->SetLineWidth(width) where width is the width expressed in pixel units

IV.5.3. Fill attributes Almost all graphics classes have a fill area somewhere. These classes have to deal with fill attributes. This is done by using secondary inheritance of the class TAttFill.

IV.5.3.1. Setting line attributes interactively When clicking on an object having a fill area, one of the last items in the popup is "SetFillAttributes". Selecting it makes the following window appear :

42 43

This canvas allows you to set :

The fill color Style

IV.5.3.2. Setting fill color Fill color may be set by a method call. What is said here applies to all objects deriving from TAttFill, and there are many (histograms, plots,…) . We will take an example that may be transposed to other types. Suppose "h" is a TH1F (1 dim histogram) object. The histogram fill color is set with : root[0] h->SetFillColor(color) where color is a color number. The colors are described in "Color and color palettes"

IV.5.3.3. Setting fill style Fill style may be set by a method call. What is said here applies to all objects deriving from TAttFill, and there are many (histograms, plots,…). We will take an example that may be transposed to other types. Suppose "h" is a TH1F (1 dim histogram) object. The histogram fill style is set with : root[0] h->SetFillStyle(style) where the convention for style is : 0 : hollow 1001 : solid 2001 : hatch style 3000 + pattern number : patterns 4000 to 4100 : transparency, 4000 = fully transparent, 4100 = fully opaque. The various patterns are represented here :

43 44

IV.5.4. Color and color palettes

IV.6. Histograms, graphs and functions as graphical objects

IV.6.1. Legends TLegend

IV.7. Style management

IV.8. Saving in postscript, and in other formats

44