[ROOT] Applying a selection string to select entries

From: Sue Kasahara (schubert@hep.umn.edu)
Date: Wed Jun 23 2004 - 02:49:47 MEST


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