Draw expression varexp for specified entries.
Returns -1 in case of error or number of selected events in case of success.
varexp is an expression of the general form
- "e1" produces a 1-d histogram (TH1F) of expression "e1"
- "e1:e2" produces an unbinned 2-d scatter-plot (TGraph) of "e1" versus "e2"
- "e1:e2:e3" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
versus "e2" versus "e3"
- "e1:e2:e3:e4" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
versus "e2" versus "e3" and "e4" mapped on the color number.
(to create histograms in the 2, 3, and 4 dimesional case, see section "Saving
the result of Draw to an histogram")
Example:
varexp = x simplest case: draw a 1-Dim distribution of column named x
= sqrt(x) : draw distribution of sqrt(x)
= x*y/z
= y:sqrt(x) 2-Dim distribution of y versus sqrt(x)
= px:py:pz:2.5*E produces a 3-d scatter-plot of px vs py ps pz
and the color number of each marker will be 2.5*E.
If the color number is negative it is set to 0.
If the color number is greater than the current number of colors
it is set to the highest color number.
The default number of colors is 50.
see TStyle::SetPalette for setting a new color palette.
Note that the variables e1, e2 or e3 may contain a selection.
example, if e1= x*(y<0), the value histogrammed will be x if y<0
and will be 0 otherwise.
The expressions can use all the operations and build-in functions
supported by TFormula (See TFormula::Analyze), including free
standing function taking numerical arguments (TMath::Bessel).
In addition, you can call member functions taking numerical
arguments. For example:
- "TMath::BreitWigner(fPx,3,2)"
- "event.GetHistogram().GetXaxis().GetXmax()"
- "event.GetTrack(fMax).GetPx()
selection is an expression with a combination of the columns.
In a selection all the C++ operators are authorized.
The value corresponding to the selection expression is used as a weight
to fill the histogram.
If the expression includes only boolean operations, the result
is 0 or 1. If the result is 0, the histogram is not filled.
In general, the expression may be of the form:
value*(boolean expression)
if boolean expression is true, the histogram is filled with
a weight = value.
Examples:
selection1 = "x3.2"
selection2 = "(x+y)*(sqrt(z)>3.2)"
selection1 returns a weigth = 0 or 1
selection2 returns a weight = x+y if sqrt(z)>3.2
returns a weight = 0 otherwise.
option is the drawing option.
- See TH1::Draw for the list of all drawing options.
- If option COL is specified when varexp has three fields:
tree.Draw("e1:e2:e3","","col");
a 2D scatter is produced with e1 vs e2, and e3 is mapped on the color
table.
- If option contains the string "goff", no graphics is generated.
nentries is the number of entries to process (default is all)
first is the first entry to process (default is 0)
This function returns the number of selected entries. It returns -1
if an error occurs.
Drawing expressions using arrays and array elements
Let assumes, a leaf fMatrix, on the branch fEvent, which is a 3 by 3 array,
or a TClonesArray.
In a TTree::Draw expression you can now access fMatrix using the following
syntaxes:
String passed What is used for each entry of the tree
"fMatrix" the 9 elements of fMatrix
"fMatrix[][]" the 9 elements of fMatrix
"fMatrix[2][2]" only the elements fMatrix[2][2]
"fMatrix[1]" the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2]
"fMatrix[1][]" the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2]
"fMatrix[][0]" the 3 elements fMatrix[0][0], fMatrix[1][0] and fMatrix[2][0]
"fEvent.fMatrix...." same as "fMatrix..." (unless there is more than one leaf named fMatrix!).
In summary, if a specific index is not specified for a dimension, TTree::Draw
will loop through all the indices along this dimension. Leaving off the
last (right most) dimension of specifying then with the two characters '[]'
is equivalent. For variable size arrays (and TClonesArray) the range
of the first dimension is recalculated for each entry of the tree.
TTree::Draw also now properly handling operations involving 2 or more arrays.
Let assume a second matrix fResults[5][2], here are a sample of some
of the possible combinations, the number of elements they produce and
the loop used:
expression element(s) Loop
"fMatrix[2][1] - fResults[5][2]" one no loop
"fMatrix[2][] - fResults[5][2]" three on 2nd dim fMatrix
"fMatrix[2][] - fResults[5][]" two on both 2nd dimensions
"fMatrix[][2] - fResults[][1]" three on both 1st dimensions
"fMatrix[][2] - fResults[][]" six on both 1st and 2nd dimensions of
fResults
"fMatrix[][2] - fResults[3][]" two on 1st dim of fMatrix and 2nd of
fResults (at the same time)
"fMatrix[][] - fResults[][]" six on 1st dim then on 2nd dim
In summary, TTree::Draw loops through all un-specified dimensions. To
figure out the range of each loop, we match each unspecified dimension
from left to right (ignoring ALL dimensions for which an index has been
specified), in the equivalent loop matched dimensions use the same index
and are restricted to the smallest range (of only the matched dimensions).
When involving variable arrays, the range can of course be different
for each entry of the tree.
So the loop equivalent to "fMatrix[][2] - fResults[3][]" is:
for (Int_t i0; i < min(3,2); i++) {
use the value of (fMatrix[i0][2] - fMatrix[3][i0])
}
So the loop equivalent to "fMatrix[][2] - fResults[][]" is:
for (Int_t i0; i < min(3,5); i++) {
for (Int_t i1; i1 < 2; i1++) {
use the value of (fMatrix[i0][2] - fMatrix[i0][i1])
}
}
So the loop equivalent to "fMatrix[][] - fResults[][]" is:
for (Int_t i0; i < min(3,5); i++) {
for (Int_t i1; i1 < min(3,2); i1++) {
use the value of (fMatrix[i0][i1] - fMatrix[i0][i1])
}
}
Retrieving the result of Draw
By default the temporary histogram created is called "htemp", but only in
the one dimensional Draw("e1") it contains the TTree's data points. For
a two dimensional Draw, the data is filled into a TGraph which is named
"Graph". They can be retrieved by calling
TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // 1D
TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
For a three and four dimensional Draw the TPloyMarker3D is unnamed, and
cannot be retrieved.
gPad always contains a TH1 derived object called "htemp" which allows to
access the axes:
TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
TH2F *htemp = (TH2F*)gPad->GetPrimitive("htemp"); // empty, but has axes
TAxis *xaxis = htemp->GetXaxis();
Saving the result of Draw to an histogram
If varexp0 contains >>hnew (following the variable(s) name(s),
the new histogram created is called hnew and it is kept in the current
directory (and also the current pad). This works for all dimensions.
Example:
tree.Draw("sqrt(x)>>hsqrt","y>0")
will draw sqrt(x) and save the histogram as "hsqrt" in the current
directory. To retrieve it do:
TH1F *hsqrt = (TH1F*)gDirectory->Get("hsqrt");
The binning information is taken from the environment variables
Hist.Binning.?D.?
In addition, the name of the histogram can be followed by up to 9
numbers between '(' and ')', where the numbers describe the
following:
1 - bins in x-direction
2 - lower limit in x-direction
3 - upper limit in x-direction
4-6 same for y-direction
7-9 same for z-direction
When a new binning is used the new value will become the default.
Values can be skipped.
Example:
tree.Draw("sqrt(x)>>hsqrt(500,10,20)")
// plot sqrt(x) between 10 and 20 using 500 bins
tree.Draw("sqrt(x):sin(y)>>hsqrt(100,10,60,50,.1,.5)")
// plot sqrt(x) against sin(y)
// 100 bins in x-direction; lower limit on x-axis is 10; upper limit is 60
// 50 bins in y-direction; lower limit on y-axis is .1; upper limit is .5
By default, the specified histogram is reset.
To continue to append data to an existing histogram, use "+" in front
of the histogram name.
A '+' in front of the histogram name is ignored, when the name is followed by
binning information as described in the previous paragraph.
tree.Draw("sqrt(x)>>+hsqrt","y>0")
will not reset hsqrt, but will continue filling.
This works for 1-D, 2-D and 3-D histograms.
Accessing collection objects
TTree::Draw default's handling of collections is to assume that any
request on a collection pertain to it content. For example, if fTracks
is a collection of Track objects, the following:
tree->Draw("event.fTracks.fPx");
will plot the value of fPx for each Track objects inside the collection.
Also
tree->Draw("event.fTracks.size()");
would plot the result of the member function Track::size() for each
Track object inside the collection.
To access information about the collection itself, TTree::Draw support
the '@' notation. If a variable which points to a collection is prefixed
or postfixed with '@', the next part of the expression will pertain to
the collection object. For example:
tree->Draw("event.@fTracks.size()");
will plot the size of the collection refered to by fTracks (i.e the number
of Track objects).
Drawing 'objects'
When a class has a member function named AsDouble or AsString, requesting
to directly draw the object will imply a call to one of the 2 functions.
If both AsDouble and AsString are present, AsDouble will be used.
AsString can return either a char*, a std::string or a TString.s
For example, the following
tree->Draw("event.myTTimeStamp");
will draw the same histogram as
tree->Draw("event.myTTimeStamp.AsDouble()");
In addition, when the object is a type TString or std::string, TTree::Draw
will call respectively TString::Data and std::string::c_str()
If the object is a TBits, the histogram will contain the index of the bit
that are turned on.
Retrieving information about the tree itself.
You can refer to the tree (or chain) containing the data by using the
string 'This'.
You can then could any TTree methods. For example:
tree->Draw("This->GetReadEntry()");
will display the local entry numbers be read.
tree->Draw("This->GetUserInfo()->At(0)->GetName()");
will display the name of the first 'user info' object.
Special functions and variables
Entry$: A TTree::Draw formula can use the special variable Entry$
to access the entry number being read. For example to draw every
other entry use:
tree.Draw("myvar","Entry$%2==0");
Entry$ : return the current entry number (== TTree::GetReadEntry())
LocalEntry$ : return the current entry number in the current tree of a
chain (== GetTree()->GetReadEntry())
Entries$ : return the total number of entries (== TTree::GetEntries())
Length$ : return the total number of element of this formula for this
entry (==TTreeFormula::GetNdata())
Iteration$: return the current iteration over this formula for this
entry (i.e. varies from 0 to Length$).
Length$(formula): return the total number of element of the formula given as a
parameter.
Sum$(formula): return the sum of the value of the elements of the formula given
as a parameter. For example the mean for all the elements in
one entry can be calculated with:
Sum$(formula)/Length$(formula)
Min$(formula): return the minimun (within one TTree entry) of the value of the
elements of the formula given as a parameter.
Max$(formula): return the maximum (within one TTree entry) of the value of the
elements of the formula given as a parameter.
MinIf$(formula,condition)
MaxIf$(formula,condition): return the minimum (maximum) (within one TTree entry)
of the value of the elements of the formula given as a parameter
if they match the condition. If not element match the condition, the result is zero. To avoid the
the result is zero. To avoid the consequent peak a zero, use the
pattern:
tree->Draw("MinIf$(formula,condition)","condition");
which will avoid calculation MinIf$ for the entries that have no match
for the condition.
Alt$(primary,alternate) : return the value of "primary" if it is available
for the current iteration otherwise return the value of "alternate".
For example, with arr1[3] and arr2[2]
tree->Draw("arr1+Alt$(arr2,0)");
will draw arr1[0]+arr2[0] ; arr1[1]+arr2[1] and arr1[2]+0
Or with a variable size array arr3
tree->Draw("Alt$(arr3[0],0)+Alt$(arr3[1],0)+Alt$(arr3[2],0)");
will draw the sum arr3 for the index 0 to min(2,actual_size_of_arr3-1)
As a comparison
tree->Draw("arr3[0]+arr3[1]+arr3[2]");
will draw the sum arr3 for the index 0 to 2 only if the
actual_size_of_arr3 is greater or equal to 3.
Note that the array in 'primary' is flatened/linearilized thus using
Alt$ with multi-dimensional arrays of different dimensions in unlikely
to yield the expected results. To visualize a bit more what elements
would be matched by TTree::Draw, TTree::Scan can be used:
tree->Scan("arr1:Alt$(arr2,0)");
will print on one line the value of arr1 and (arr2,0) that will be
matched by
tree->Draw("arr1-Alt$(arr2,0)");
The ternary operator is not directly support in TTree::Draw however, to plot the
equivalent of 'var2<20 ? -99 : var1', you can use:
tree->Draw("(var2<20)*99+(var2>=20)*var1","");
Drawing a user function accessing the TTree data directly
If the formula contains a file name, TTree::MakeProxy will be used
to load and execute this file. In particular it will draw the
result of a function with the same name as the file. The function
will be executed in a context where the name of the branches can
be used as a C++ variable.
For example draw px using the file hsimple.root (generated by the
hsimple.C tutorial), we need a file named hsimple.cxx:
double hsimple() {
return px;
}
MakeProxy can then be used indirectly via the TTree::Draw interface
as follow:
new TFile("hsimple.root")
ntuple->Draw("hsimple.cxx");
A more complete example is available in the tutorials directory:
h1analysisProxy.cxx , h1analysProxy.h and h1analysisProxyCut.C
which reimplement the selector found in h1analysis.C
The main features of this facility are:
* on-demand loading of branches
* ability to use the 'branchname' as if it was a data member
* protection against array out-of-bound
* ability to use the branch data as object (when the user code is available)
See TTree::MakeProxy for more details.
Making a Profile histogram
In case of a 2-Dim expression, one can generate a TProfile histogram
instead of a TH2F histogram by specyfying option=prof or option=profs.
The option=prof is automatically selected in case of y:x>>pf
where pf is an existing TProfile histogram.
Making a parallel coordinates plot.
In case of a 2-Dim or more expression with the option=para, one can generate
a parallel coordinates plot. With that option, the number of dimensions is
arbitrary. Giving more than 4 variables without the option=para or
option=candle or option=goff will produce an error.
Making a candle sticks chart.
In case of a 2-Dim or more expression with the option=candle, one can generate
a candle sticks chart. With that option, the number of dimensions is
arbitrary. Giving more than 4 variables without the option=para or
option=candle or option=goff will produce an error.
Saving the result of Draw to a TEventList or a TEntryList
TTree::Draw can be used to fill a TEventList object (list of entry numbers)
instead of histogramming one variable.
If varexp0 has the form >>elist , a TEventList object named "elist"
is created in the current directory. elist will contain the list
of entry numbers satisfying the current selection.
If option "entrylist" is used, a TEntryList object is created
Example:
tree.Draw(">>yplus","y>0")
will create a TEventList object named "yplus" in the current directory.
In an interactive session, one can type (after TTree::Draw)
yplus.Print("all")
to print the list of entry numbers in the list.
tree.Draw(">>yplus", "y>0", "entrylist")
will create a TEntryList object names "yplus" in the current directory
By default, the specified entry list is reset.
To continue to append data to an existing list, use "+" in front
of the list name;
tree.Draw(">>+yplus","y>0")
will not reset yplus, but will enter the selected entries at the end
of the existing list.
Using a TEventList or a TEntryList as Input
Once a TEventList or a TEntryList object has been generated, it can be used as input
for TTree::Draw. Use TTree::SetEventList or TTree::SetEntryList to set the
current event list
Example1:
TEventList *elist = (TEventList*)gDirectory->Get("yplus");
tree->SetEventList(elist);
tree->Draw("py");
Example2:
TEntryList *elist = (TEntryList*)gDirectory->Get("yplus");
tree->SetEntryList(elist);
tree->Draw("py");
If a TEventList object is used as input, a new TEntryList object is created
inside the SetEventList function. In case of a TChain, all tree headers are loaded
for this transformation. This new object is owned by the chain and is deleted
with it, unless the user extracts it by calling GetEntryList() function.
See also comments to SetEventList() function of TTree and TChain.
If arrays are used in the selection critera, the entry entered in the
list are all the entries that have at least one element of the array that
satisfy the selection.
Example:
tree.Draw(">>pyplus","fTracks.fPy>0");
tree->SetEventList(pyplus);
tree->Draw("fTracks.fPy");
will draw the fPy of ALL tracks in event with at least one track with
a positive fPy.
To select only the elements that did match the original selection
use TEventList::SetReapplyCut or TEntryList::SetReapplyCut.
Example:
tree.Draw(">>pyplus","fTracks.fPy>0");
pyplus->SetReapplyCut(kTRUE);
tree->SetEventList(pyplus);
tree->Draw("fTracks.fPy");
will draw the fPy of only the tracks that have a positive fPy.
Note: Use tree->SetEventList(0) if you do not want use the list as input.
How to obtain more info from TTree::Draw
Once TTree::Draw has been called, it is possible to access useful
information still stored in the TTree object via the following functions:
-GetSelectedRows() // return the number of entries accepted by the
//selection expression. In case where no selection
//was specified, returns the number of entries processed.
-GetV1() //returns a pointer to the double array of V1
-GetV2() //returns a pointer to the double array of V2
-GetV3() //returns a pointer to the double array of V3
-GetW() //returns a pointer to the double array of Weights
//where weight equal the result of the selection expression.
where V1,V2,V3 correspond to the expressions in
TTree::Draw("V1:V2:V3",selection);
Example:
Root > ntuple->Draw("py:px","pz>4");
Root > TGraph *gr = new TGraph(ntuple->GetSelectedRows(),
ntuple->GetV2(), ntuple->GetV1());
Root > gr->Draw("ap"); //draw graph in current pad
creates a TGraph object with a number of points corresponding to the
number of entries selected by the expression "pz>4", the x points of the graph
being the px values of the Tree and the y points the py values.
Important note: By default TTree::Draw creates the arrays obtained
with GetV1, GetV2, GetV3, GetW with a length corresponding to the
parameter fEstimate. By default fEstimate=1000000 and can be modified
via TTree::SetEstimate. A possible recipee is to do
tree->SetEstimate(tree->GetEntries());
You must call SetEstimate if the expected number of selected rows
is greater than 1000000.
You can use the option "goff" to turn off the graphics output
of TTree::Draw in the above example.
Automatic interface to TTree::Draw via the TTreeViewer
A complete graphical interface to this function is implemented
in the class TTreeViewer.
To start the TTreeViewer, three possibilities:
- select TTree context menu item "StartViewer"
- type the command "TTreeViewer TV(treeName)"
- execute statement "tree->StartViewer();"
--
SeoKonKang - 20 Apr 2010