Using tree proxy to draw friend's tree variable


I am using ROOT v 4.04/02.

I would like two know if it is possible to use the TTree proxy mechanism to draw a variable that belongs to a friend TTree.
Are there any limitations ?

To give a concrete example
I have two trees, one named tree1 and the other named tree2.
I declare the second tree as a friend of the first one.

Then I create a file difference.cxx :

Float_t difference () { return (mPT-MissPT) }

where mPT belongs to tree1 and MissPT belongs to tree2.
If I execute tree1->Draw(“difference.cxx”)
I get :

root [0] .x draw_missPT.C Info in <TTreePlayer::DrawScript>: Will process tree/chain using generatedSel.h+ Info in <TUnixSystem::ACLiC>: creating shared library /cms4/ribeiro/new_Analysis/pro_macros/./ In file included from /cms4/ribeiro/new_Analysis/pro_macros/filesmYD6T.h:32, from /cms4/ribeiro/new_Analysis/pro_macros/filesmYD6T.cxx:16: /cms4/ribeiro/new_Analysis/pro_macros/difference.cxx: In member function `Float_t generatedSel::difference()': /cms4/ribeiro/new_Analysis/pro_macros/difference.cxx:2: `MissPT' undeclared (first use this function) /cms4/ribeiro/new_Analysis/pro_macros/difference.cxx:2: (Each undeclared identifier is reported only once for each function it appears in.) g++: /cms4/ribeiro/new_Analysis/pro_macros/./filesmYD6T.o: No such file or directory Error in <ACLiC>: Compilation failed! Error in <TSelector::GetSelector>: file generatedSel.h+ does not have a valid class deriving from TSelector

Am I doing something wrong ?
Of course this is a dummy example, because to plot the difference between the two variables I can do tree1->Draw(“mPT-MissPT”) and it works.

Best Regards

Pedro Ribeiro


You need to prepend the name of the friend (this is needed to insure that there is no naming clashes):

Float_t difference () { return (mPT-tree2.MissPT) }Cheers,

That’s it !
Thank you very much.

I have similar problem with tree proxy and tree (dp2) in my root file (dst090.root), see attach.

Double_t any() {
   return fAz;
[mucha@he112-37 ~]$ root dst090.root
root [0]
Attaching file dst090.root as _file0...
Warning in <TClass::TClass>: no dictionary for class TStrawTrack is available
Warning in <TClass::TClass>: no dictionary for class TWirePoint is available
root [1] dp2->Draw("any.C")
Fatal in <ROOT::TBranchProxyClassDescriptor::>: strcmp(fInfo->GetName(), type)==0 violated at line 58 of `treeplayer/src/TBranchProxyClassDescriptor.cxx'
 Generating stack trace...

root 5.02/00, gcc 4.0
dst090.root (11 KB)

I can reproduce the problem. I’ll work on a fix.


I updated the CVS repository with a fix for musinsky’s problem.
Note that the script still need to be update:

[quote]Double_t any() {
return fAz[0]; // plot the first element
} [/quote]since in your case, fAz is stored in a TClonesArray and since this drawing mechanism only calls the user function (any) once per entry.
To plot all value of fAz do

void any() { Int_t size = tracks->GetEntries(); for(int i=0; i<size; ++i) { htemp->Fill( fAz[i] ); } }anddp2->Draw("any.C","","nohist");The nohist is needed to prevent the return value of any to be histogramed. Without this would get a spurrious value filled in each time there is an event with 0 tracks.


Thanks Philippe, I will try your suggestion after compile new(CVS) root.


Hello Philippe,
i tryed your suggestion on new(CVS) root. All works, but I have any questions.

macro: only_Az.C

double only_Az() {
    return fAz[0]; // plot the first element



works, but return always any value (if tracks@.size() == 0 return 0). Since in our case exist events with 0 tracks, i tryed:


not works, empty histogram

modified macro: only2_Az.C

void only2_Az() {
    if (tracks->GetEntries())



problem with compilation, but:



Option “nohist” is necessary for compilation ? All works only with histogram with name htemp.
How change bining, range ? or how using other histograms ?

After load mylib:

TFile *_file0 = TFile::Open("dst090.root");


Error in <ACLiC>: Compilation failed!
Error in <TSelector::GetSelector>: file generatedSel.h+ does not have a valid class deriving from TSelector

I tryed to same procedure with Event.root and (from $ROOTSYS/test) => compilation failed, what is wrong ?

What do I need ?
In root file (see above, dst090.root):
if fFlag == 0 => chamber 1
if fFlag ==10 => chamber 2
how draw difference between fAz(chamber 1) and fAz(chamber 2) ? (if number of tracks is 2)
I try macro delta_Az.C:

void delta_Az() {
    double temp_az0 = 0, temp_az10 = 0;
    short count = 0;
    for (int i = 0; i < tracks->GetEntries(); i++) {
        if (fFlag[i] == 0 )  temp_az0  = fAz[i];
        if (fFlag[i] == 10 ) temp_az10 = fAz[1];
    if (count == 2) htemp->Fill(temp_az0-temp_az10);

this is correct ? maybe exist any more efficiency way ?

Best regards, Jan

Sorry to my poor english


Note that dp2->Draw(“any.C”,…); generates a file named generatedSel.h which you can look at to find some more details on what’s going on.

With no option, the generatedSel.h contains something likehtemp->Fill(any());
in the Process method of the selector. Hence the histogram always has at least one value per entries in the Tree.

With the option "nohist the generatedSel.h contains something likeany(); in the Process method of the selector. Hence the histogram does not have any entries unless the function any fills it.

So dp2->Draw("only_Az.C"); properly adds the default value (0) to the histogram when the tracks is empty.void only2_Az() { ... } dp2->Draw("only2_Az.C");will fail to compile since the return value of only2_Az is pass to htemp->Fill and only2_Az returns a void

Without the option nohist, your function has to return a numerical value!

[quote]How change bining, range ? or how using other histograms ?[/quote]See … :MakeProxy for details. For example you could do:TH1D *fMyhist; void only2_Az_Begin() { fMyhist = new TH1D("Myhis",200,-100,100); } void only2_Az() { if (tracks->GetEntries()) fMyhist->Fill(fAz[0]); }

This seems correct (beside the 1 instead of i in the setting of temp_az10).


Thanks Philippe !