Chain with friends

I have two NTuples in two separate files which I chain together and loop over, by manually calling GetEntry(). (Not using any generated code from MakeClass, for example).

There are two parts to my analysis, one that involves generating data which is going to be pretty much static once calculated, so I wish to store it in a third tree, which I make a friend of my chain, so that I may access these things through GetLeaf, or TChain->Draw(“friend.value”).

This seems to work fine for chains who only contain single trees. When I have two trees in the chain, generating the third works, too. But when I try to use it, I get this error:

root [3] ((TTree *)(((TDirectoryFile*)_file0.Get("BMC"))->Get( "additional" )))->Draw("lep1theta") Error in <TTreeFormula::DefinedVariable>: the branch "lep1theta" has to be enabled to be used Error in <TTreeFormula::Compile>: Part of the Variable "lep1theta" exists but some of it is not accessible or useable

“additional” is the third tree which contains data I’ve created. Why would I get this error?

Thanks in advance,

  • Peter

This is odd :slight_smile:.
Could you please post your ROOT file and I will take a quick look?

Cheers,
Philippe

Here it is.

The tree I’m referring to is BMC (standing for ‘both monte carlo’). It should contain the LMC events followed by the UMC events. This should be clear if you browse the tuple.

Regards,

Just to add something that might not be clear…

The file posted contains the `third tree’, created by me from 4 different TChains (using three different root files): data, lower (energy) MC, upper MC, and one containing the LMC followed by the UMC, by chaining together the files containing the LMC and UMC.

So then I make the trees in the file I posted a friend of these different TChains.

Hope this is reasonably clear, will elaborate more if necessary.

  • Peter

Hi,

Somehow, before saving the addition tree, you disable all branches. Hence the default state if for you branches to be disabled and you must
re-enabled them to be viewed. So the following code works for me: TTree *BMC_additional; _file0->GetObject("BMC/additional",BMC_additional); BMC_additional->SetBranchStatus("*",1); BMC_additional->Draw("lep1theta");

Cheers,
Philippe.

Note that strangely enough in this tree, after then entry 40000, the value of lep1theta is the same for all the remaining entries! This suggest a potential problem in the code producing this tree

Hmm. So there seem to be a few things going on that I don’t understand.

Here is roughly what I am doing: (I have just taken the order in which I’m doing things, this is not the exact code I’m using. I have effectively ‘unrolled’ lots of function calls. If this should work, then I will post the exact code if necessary)

TChain mychain( "zzNtuple" );
SetBranchStatus("*", false);
mychain.Add( "montecarlo_*_.root" ) // matches two files

SetBranchStatus( "desired", true );
TLeaf *l = mychain.GetLeaf( "desired" );
Float_t &myfloat = *((Float_t)l->GetValuePointer());

TTree *newtree = new TTree( "additional", "additional" );
newtree->Branch( "lep1theta", NULL, "lep1theta/F" );
mychain.AddFriend( newtree, "additional" );
l =  mychain.GetLeaf( "additional.lep1theta" );
Float_t &lep1theta = *((Float_t)l->GetValuePointer());

int numentries = mychain.GetNumEntries()
for ( i = 0; i < numentries; i++ )
{
    mychain.GetEntry( i );
    lep1theta = myfloat;
    newtree->Fill();    
}

This code works for all of the values in the first tree that mychain.Add() uses, but after that it seems it is not loading them correctly. Do I need to do LoadTree or something I am missing?

If anything is clear, again, I will elaborate.

Thanks in advance,

  • Peter

Hi,

The way you get/set the data address is incompatible with chain.
Also there is no need (and it actually hurts) to make the output tree a friend of the chain at this point.

[code]TChain mychain( “zzNtuple” );
SetBranchStatus("", false);
mychain.Add( "montecarlo_
_.root" ) // matches two files

SetBranchStatus( “desired”, true );
Float_t myfloat;
mychain->SetBranchAddress(“desired”,&myfloat);

Float_t lep1theta;
TTree *newtree = new TTree( “additional”, “additional” );
newtree->Branch( “lep1theta”, &lep1theta, “lep1theta/F” );
int numentries = mychain.GetNumEntries()

for ( i = 0; i < numentries; i++ )
{
mychain.GetEntry( i );
lep1theta = myfloat;
newtree->Fill();
}[/code]

Cheers,
Philippe.

PS. I believe you also have in your code (indirectly) something like

hmm, it works without setting the branch address for all of the cases that don’t involve more than one tree in the chain. I must set the branch address otherwise? This seems a bit like inconsistent behaviour, unless I’m doing anything I really shouldn’t be. I will try by setting the branch address tomorrow and let you know of my result. Also, as best as I can tell, I am not disabling the branches anymore and still getting a similar problem.

Cheers.

  • Peter

[quote]hmm, it works without setting the branch address for all of the cases that don’t involve more than one tree in the chain. [/quote]Yes, some of the manipulations you can do with a TTree do not work with a TChain. However all manipulations you can do with a TChain also works on a TTree.

In particular the addresses of the TLeaf(s) and TBranch(es) are specific to each TTree. When using a TChain those address will change (aka the one you retrieved will become invalid) each time the TChain comes from one file/TTree to another. [This is the same thing for the result of GetValuePointer).

[quote]Also, as best as I can tell, I am not disabling the branches anymore and still getting a similar problem. [/quote]All I can tell, is the message:Error in <TTreeFormula::DefinedVariable>: the branch "lep1theta" has to be enabled to be usedclearly indicate that the variable lep1theta has been disabled …

Cheers,
Philippe.