Re: TBranch::GetEntry(Int_t)

From: Kristjan H Gulbrandsen (gulbrand@mit.edu)
Date: Wed Nov 17 1999 - 10:13:48 MET


Here is an example of a situation where I get into trouble.
Consider the following class.

class Example{

 public:

  Example();
  virtual ~Example();
  void Make_Branch(Char_t *name);
  void Fill_Branch(Char_t *name,Int_t value1,Float_t value2);
  void Use_Branch(Char_t *name, Int_t entry_number);

 protected:

  Int_t fparam1;
  Float_t fparam2;
  TTree *tr;

};

Example::Example(){

  tr = new TTree("tree","Tree");

}

Example::~Example(){

  delete tr;

}

void Example::Make_Branch(Char_t *name){

  TBranch *br = tr->Branch(name,&fparam1,"param1/I:param2/F",1024);
  ((TLeaf *) (br->GetListOfLeaves()->At(0)))->SetAddress(&fparam1);
  ((TLeaf *) (br->GetListOfLeaves()->At(1)))->SetAddress(&fparam2);

}

void Example::Fill_Branch(Char_t *name,Int_t value1,Float_t value2){

  fparam1=value1;
  fparam2=value2;

  tr->GetBranch(name)->Fill();

}

void Example::Use_Branch(Char_t *name, Int_t entry_number){

  tr->GetBranch(name)->GetEntry(entry_number);
  cout << "value1 is " << fparam1 << ", value2 is " << fparam2 << ".\n";
  // more code using this data

}

so load this into root and run the following commands.
 
root [1] Example *Instance = new Example();
root [2] Instance->Make_Branch("Branch1");
root [3] Instance->Make_Branch("Branch2");
root [4] Instance->Fill_Branch("Branch1",1,1.1);
root [5] Instance->Fill_Branch("Branch1",2,2.1);
root [6] Instance->Fill_Branch("Branch2",3,3.1);
root [7] Instance->Fill_Branch("Branch2",4,4.1);
root [8] Instance->Use_Branch("Branch2",1);
value1 is 4, value2 is 4.1.
root [9] Instance->Use_Branch("Branch1",1);
value1 is 2, value2 is 2.1.
root [10] Instance->Use_Branch("Branch2",1);
value1 is 2, value2 is 2.1.

The output of Use_Branch is listed below the statements where it
is executed. The problem comes about when you have branches of
similar structure so you use the same holder for there information.
The alternative to this in this case would be to create a new
set of variables for every branch which I don't like to do because
I have to keep track of all of them for destruction. This is why
I think an option to force the tree to give you your data would
be useful.

                                Kris Gulbrandsen
                                gulbrand@mit.edu


On Tue, 16 Nov 1999, Rene Brun wrote:

> Hi Kris,
> TBranch::GetEntry tests if you try to read from a file the same entry
> than in the previous call for the same tree and branch. This is clearly
> to save time. The typical situation were this test is essential is when
>   - you read only one branch (branch->GetEntry(entry);
>   - skip all the other branches if some test using the branch variables
>     decide so.
>   - invoke tree->GetEntry(entry) to read the complete event. There is no
> need
>     to read again the first branch (or branches).
> 
> I do not understand in which situation you can get a problem.
> 
> Rene Brun
>   
> Kristjan H Gulbrandsen wrote:
> >
> > Does anybody know why the first line TBranch::GetEntry is
> >   
> >      if (fReadEntry == entry) return 1;
> >
> > ?
> >
> > The effect is to not give your object or set the value of the
> > leaves (if you use basic types). It seems rather annoying if
> > you somehow changed some values and would like to get the
> > same entry again. I end in most of my code just getting some
> > dummy entry often just to ensure that I really get the data
> > I want. I think it would be nice if this behavior could be
> > overridden somehow.
> >
> > Besides a possible speed issue, if anybody knows any reasons
> > for this behavior, it would be helpful if they could clue me
> > in.
> > 
> >                                 Thanks,
> >
> >                                 Kris Gulbrandsen
> >                                 gulbrand@mit.edu
> 



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