RE: [ROOT] Applying a selection string to select entries

From: Philippe Canal (pcanal@fnal.gov)
Date: Wed Jun 23 2004 - 16:02:02 MEST


Hi Sue,

For concrete example of the usage of TTreeFormula, you can take
a look a the implementation of TSelectorDraw.

In particular, you need to use TTreeFormula::GetNdata();

for ( int ient = 0; ient < tree->GetEntries(); ient++ ) {
  TObject* object = 0;
  tree -> SetBranchAddress("event",&object);
  tree -> LoadTree(ient);
  Int_t arraySize = treeformula->GetNdata();

  for (int jent = 0; jent < arraySize; ++jent ) {
     if ( treeformula -> EvalInstance(jent) == 0 ) {
       // if zero, the entry failed the cuts
     }
     else {
       npass++;
       cout << "Entry ient " << ient << " passed " << endl;
     }
  }
  if ( object ) delete object; object = 0;
}

Also note that the loading of the needed branch is associated
with (and only with) the call to treeformula -> EvalInstance(0).

Cheers,
Philippe.

-----Original Message-----
From: owner-roottalk@pcroot.cern.ch
[mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Sue Kasahara
Sent: Tuesday, June 22, 2004 7:50 PM
To: roottalk
Subject: [ROOT] Applying a selection string to select entries


Hi roottalk,
I have a question about how to best go about using a selection string to
select tree entries of a specific type.
In particular, I currently make use of the TTreeFormula class to allow
the user of our i/o framework to specify a selection string to select or 
reject tree entries.
This allows the user to "skim" to the record set of interest according 
to the user-specified selection string.  This works well when the 
selection string is applied to non-array
data members, but I'm having a  problem with the current implementation 
when it is applied to branches which store an array.

  The problem can be illustrated through the use of the 
$ROOTSYS/test/Event class.
I've run the $ROOTSYS/test/Event with arguments 400 1 99 to generate an 
output
file Event.root.  I then use the following test script to apply a 
selection string
through the TTreeFormula class to select the events of interest.

 {
// Test script to try allowing the user to select tree entries based
// on a user-specified selection string
// File Event.root was created via
// $ROOTSYS/test/Event 400 1 99

gSystem -> Load("libEvent.so");

TFile* file = new TFile("Event.root","READ");
TTree* tree = (TTree*)(file -> Get("T"));

std::string selection = "fFlag == 1";  // this works
//std::string selection = "fTracks.fPy>0"; // this only selects on the 
fPy of the first track
//std::string selection = "fTracks[0].fPy>0"; // results same as above
//std::string selection = "fTracks[].fPy>0"; // results same as above
tree -> Draw("Entry$",selection.c_str());

TTreeFormula* treeformula
   = new TTreeFormula("Py_Positive",selection.c_str(),tree);

Int_t npass = 0;
for ( int ient = 0; ient < tree->GetEntries(); ient++ ) {
  TObject* object = 0;
  tree -> SetBranchAddress("event",&object);
  tree -> LoadTree(ient);
  if ( treeformula -> EvalInstance() == 0 ) {
    // if zero, the entry failed the cuts
  }
  else {
    npass++;
    cout << "Entry ient " << ient << " passed " << endl;
  }
  if ( object ) delete object; object = 0;
}

cout << "Total of " << npass << " entries passed cut, out of "
     << tree->GetEntries() << "." << endl;

delete tree; tree = 0;
delete file; file = 0;

}

What I find is that when selecting on the non-array data member fFlag, e.g.:
  std::string selection = "fFlag == 1"; 
I am able to select a subset of tree entries as appropriate.
But when I apply a selection string on the TClonesArray fTracks data 
member fPy, e.g.:
  std::string selection = "fTracks.fPy>0"; // this only selects on the 
fPy of the first track
  std::string selection = "fTracks[0].fPy>0"; // results same as above
  std::string selection = "fTracks[].fPy>0"; // results same as above
I am unable to figure out how to apply a selection string which will 
loop over all
fTracks entries.  This is contrary to the results one obtains in 
TTree::Draw which will
produce different results for this:
  tree -> Draw("Entry$","fTracks[].fPy>0");
relative to this:
  tree -> Draw("Entry$","fTracks[0].fPy>0");

I am wondering if someone can please give me some advice on how to 
generalize the
application of TTreeFormula above to include the case of looping over 
array entries.
  I am using root version 4.00/04 dated 30 May 2004.
Thanks in advance for your help.
-Sue



This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:08 MET