Re: Workaround for TChain bug in ROOT 2.22.10

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Aug 24 1999 - 15:05:36 MEST


Hi Matt,
Thanks for posting the problem with TTree::MakeClass in case of a
TChain.
The small fix I posted a few weeks ago is not sufficient.
The temporary fix that you are proposing is OK.
In the code generated, replace the statements like
   b_branchname->SetAddress(AAA);
by
   fTree->SetBranchAddress("branchname",AAA);

This fix will work when you read all the branches from a TChain.
I have modified TTree::MakeClass in my development version (2.23/01)
to support TChains in general. With this version, you should be able
to read one branch from a TChain.

Rene Brun


Matthew D. Langston wrote:
> 
> I reported a bug with "class TChain" a few days ago in which the
> analysis skeleton generated by "TTree::MakeClass" didn't work when
> instantiated with a TChain* (see
> http://root.cern.ch/root/roottalk/roottalk99/1944.html).
> 
> I have a fix and a workaround for this bug, which I thought I would
> share with the list.
> 
> The problem is in `TREE_Chain.cxx'.  Please note that this bug can
> affect *all* uses of a "TChain" in your analysis code, and is *not*
> limited to the code generated by "TTree::MakeClass".
> 
> I have a patch to the source code which fixes this bug which I would be
> happy to share with whomever may need it.  However, using my patch would
> require you to patch your sources and rebuild ROOT.  You can do this if
> you wish, but there is an easier workaround that doesn't require you to
> rebuild ROOT, which is the subject of the rest of this e-mail.  Besides,
> the ROOT Team will probably come up with a more elegant solution than
> mine in the next release of ROOT.
> 
> The executive summary for the workaround is that you must use the method
> "TChain::SetBranchAddress" instead of the methods "TTree::GetBranch"
> followed by "TTree::SetAddress".
> 
> For example, consider the following example, in which we write to stdout
> an element from a branch named "foo" (consisting of a float) which comes
> from a "TTree" named "T" (which consists of a "TChain" of files):
> 
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>                              begin example
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>    TChain* tree = new TChain( "T" );
>    tree->Add( "foo-1.root" );
>    tree->Add( "foo-2.root" );
>    tree->Add( "foo-3.root" );
>    tree->Add( "foo-4.root" );
> 
>    float foo;
> 
>    // The next two lines are broken.
>    TBranch* b_foo = tree->GetBranch( "foo" );
>    b_foo->SetAddress( &foo );
> 
>    size_t nevent = static_cast< size_t >( tree->GetEntries() );
>    for ( size_t i = 0; i < nevent; ++i )
>    {
>       tree->GetEntry( i );
>       cout << "foo = " << foo << endl;
>    }
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>                               end example
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> 
> Notice the comment, above, indicating which of the two lines are broken
> for "class TChain".  The workaround is to use the single method
> "TChain::SetBranchAddress" instead, as follows:
> 
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>                              begin example
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>    TChain* tree = new TChain( "T" );
>    tree->Add( "foo-1.root" );
>    tree->Add( "foo-2.root" );
>    tree->Add( "foo-3.root" );
>    tree->Add( "foo-4.root" );
> 
>    float foo;
> 
>    tree->SetBranchAddress( "foo" , &foo );
> 
>    size_t nevent = static_cast< size_t >( tree->GetEntries() );
>    for ( size_t i = 0; i < nevent; ++i )
>    {
>       tree->GetEntry( i );
>       cout << "foo = " << foo << endl;
>    }
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>                               end example
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> 
> Unfortunately, although this is a trivial way to workaround the bug, the
> code generated by "TTree::MakeClass" uses the first (broken) method.
> So, you will have to edit the automatically generated code by hand.
> Interestingly enough, the code generated by "TTree::MakeCode" does
> generate correct code (it uses "TChain::SetBranchAddress").
> 
> There was another proposed fix for this bug (see
> http://root.cern.ch/root/roottalk/roottalk99/1810.html), but I have
> confirmed that this does not work for ROOT 2.22.10.
> 
> --
> Matthew D. Langston
> SLD, Stanford Linear Accelerator Center
> langston@SLAC.Stanford.EDU



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:38 MET