RE: [ROOT] sub-branch SetAddress/GetEvent behavior question

From: Philippe Canal (pcanal@fnal.gov)
Date: Mon Jul 30 2001 - 22:47:40 MEST


Hi Kate,

As you discovered, the Branch->SetAddress is not functionning as expected with
the new tree I/O (it seems that the address that it currently expect is the
beginning address of the Event object).

Anyway, there is a work around, which is to call TBranchElement::GetValue
at each iteration rather than using SetAddress. 

For example here is testread5.

void testread5()
{

// Attempt to access sub-branch directly

  gSystem->Load("libEvent");
  TFile file("Event.root");
  TTree *evtree = (TTree*)file.Get("T");
  int nevent = evtree->GetEntries();
  printf("nevent %d\n",nevent);

  int ntr = 0;
  int *p_ntr = 0;
  TBranchElement *branch = (TBranchElement*)T->GetBranch("fNtrack");

   nevent = 3;
   for(int i=0;i<nevent;i++) {
      branch->GetEntry(i);
      ntr = branch->GetValue(0,0);
      printf("i %d, ntr=%d\n",i,ntr);
   }
}

Cheers,
Philippe.

-----Original Message-----
From: owner-roottalk@pcroot.cern.ch
[mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Kate Scholberg
Sent: Monday, July 30, 2001 2:33 PM
To: Rene Brun
Cc: roottalk@pcroot.cern.ch
Subject: Re: [ROOT] sub-branch SetAddress/GetEvent behavior question


> > > However I notice something strange with the second approach: your
> > > macro only works if I do *not* load the shared library with the class
> > > info (amsmc.sl in the files I sent).  If I load the lib, GetEntry
> > > reads nothing for the sub-branch.
> > >
> >
> > You must have an incompatibility between your shared lib and Root.
> > Could you recompile your shared lib in particular the CINT dictionary?
> >
>
> I think some shared lib incompatibility is basically my problem.  The
> library is compiled with up-to-date dictionary, but I am now looking
> carefully at the classes (which I did not write) and noticing some
> things which may not be kosher with respect to the examples in the
> docs (for instance, they don't seem to have default constructors).
> Next I'll try simplifying/modifying some of these classes to see if I
> can get this to work.


Hi,

I've returned to working on this after a break...

Now I am not so sure that the problem is with my shared lib.
I've tried to replicate the behavior using the Event class in
the $ROOTSYS/test directory (for Root 2.25 and 3.01, on Linux
and OSF).  Accessing the sub-branch directly still doesn't work
(in this case, it doesn't seem to matter if I load the lib or not).

I made only one change to Event.h, which was to make the Event class
data members public.  Then I compiled the shared lib, and ran the
Event executable with default arguments to make Event.root.

The following macro works fine:

------------------------------------------------------------
void testread()
{
 // Set top-level branch address and navigate object -- works

  gROOT->Reset();

  gSystem.Load("libEvent");
  TFile file("Event.root");
  TTree *evtree = (TTree*)file->Get("T");
  int nevent = evtree->GetEntries();

  Event* event = new Event;
  evtree->SetBranchAddress("event", &event);

  nevent = 3;
  for(int i=0;i<nevent;i++)
    {

      evtree->GetEvent(i);

      printf("%d fNtrack, top level branch address set %d\n",i,event->fNtrack);

    }


}
------------------------------------------------------------

However, this isn't what I want to do.  I want to avoid setting the
top-level branch address, and instead go to the fNtrack sub-branch
directly.

Your suggested macro of July 6 is adapted below for this class:

------------------------------------------------------------

void testread2()
{

// Attempt to access sub-branch directly

  gROOT->Reset();
  gSystem.Load("libEvent");
  TFile file("Event.root");
  TTree *evtree = (TTree*)file->Get("T");
  int nevent = evtree->GetEntries();
  printf("nevent %d\n",nevent);

  int ntr = 0;
  evtree->SetBranchStatus("*",0);
  evtree->SetBranchStatus("fNtrack",1);
  evtree->SetBranchAddress("fNtrack", &ntr);

   nevent = 3;
   for(int i=0;i<nevent;i++) {
      evtree->GetEntry(i);
      printf("i %d, ntr=%d\n",i,ntr);
    }

}

------------------------------------------------------------

.. but this just returns zeroes (no error messages).

Your first suggestion of July 6 is implemented in:

------------------------------------------------------------

void testread3()
{

// Attempt to access sub-branch directly

  gROOT->Reset();
  gSystem.Load("libEvent");

  TFile file("Event.root");
  TTree *evtree = (TTree*)file->Get("T");
  int nevent = evtree->GetEntries();
  printf("nevent %d\n",nevent);

  int ntr=0;
  TBranch *branch = T->GetBranch("fNtrack");
  branch->SetAddress(&ntr);
  nevent = 3;
  for(int i=0;i<nevent;i++) {
      branch->GetEntry(i);
      printf("i %d, ntr=%d\n",i,ntr);
    }

}

------------------------------------------------------------

But this doesn't work either.  (Strangely, for my original
classes/libs, these solutions work under some conditions but not
others.)

Any ideas?

Thanks for any help,

Kate Scholberg
schol@mit.edu



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:53 MET