Read tree variables into array with cuts

I’m not sure what’s the best way to read tree variables into arrays with cuts applied to the entries.

The following code does not work too well - the output, which appears after the code, seems to be incorrect.
The ROOT version used is 6.06/08 on ubuntu 14.04

Any help would be appreciated!

Milind

using namespace std; 
#include <iostream>
#include "TFile.h"
#include "TTree.h"
#include "TTreeFormula.h"

void apd(string infile, string intree, string ann,     // ROOT file name, tree name, name to be used for ann
	 int nvars, double limits[][2], string vars[], // the strings name variables which are all floats
	 int ndata, string cuts){                      // cuts will be used as a tree selection

  TFile * rfptr = new TFile(infile.c_str());
  TTree * trptr = (TTree *)rfptr->Get(intree.c_str());
  TTreeFormula * tfptr = new TTreeFormula("ann_pdf_formula", cuts.c_str(), trptr);

  const int nvmax = 40; // Max possible number of variables
  float x[nvmax];
  for(int ivar = 0; ivar < nvars; ivar++){
    trptr->SetBranchAddress(vars[ivar].c_str(), &x[ivar]);
  } // End for ivar = 0 ... nvars
    
  // Loop over events
  long nentries = trptr->GetEntries();
  for(long ientry = 0; ientry < nentries; ientry++){
    trptr->GetEntry(ientry);
    if(tfptr->EvalInstance(ientry)){
      cout << " x = ";
      for(int ivar = 0; ivar < nvars; ivar++){
	cout << x[ivar] << "   ";
      } // End for ivar = 0 ... nvars
      cout << endl;
    } // End if(tfptr->EvalInstance(ientry))
  } // End for ientry = 0 ... nentries
} // End apd()

int main(int argc, char **argv){

  static const double mB   = 5.27926;
  static const double mphi = 1.019461;
  static const double mKS  = 0.497614;
  static const double mpi  = 0.13957018;
  static const double PI   = 3.141592653589793;

  string infile = "k0spi_0_0_a2cuts.root";
  string intree = "out_tree";
  string ann = "effy_ann";
  const int nvars = 4;
  double limits[nvars][2] = {{mKS+mpi, 1.8}, {-1., 1.}, {-1., 1.}, {-PI, PI}};
  string vars[nvars] = {"mkspi", "costh1", "costh2", "phiang"};
  int ndata = 10000;
  string cuts = "mbc_reco > 5.27";
  apd(infile, intree, ann, nvars, limits, vars, ndata, cuts);
}

x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
x = 0 0 5.7622e+32 4.56431e-41
… and so on

Hello,

The variables you are trying to read are all of type float, right?
Since you are on ROOT v6 you could also try TTreeReader technology, which simplifies the code and helps in getting all settings right. See https://root.cern.ch/doc/master/classTTreeReader.html .

G Ganis

Thanks! Your suggestion of using TTreeReader works, but cuts have to be applied the old-fashioned way: using if statements. It would be good to have the ability to make cuts in the “fast and friendly” way that a TChain.Draw() uses.

For instance, we can use
myChain.Draw(“mass:angle>>h2”, “(var1 > 0.) && (var2 < 2.)”, “LEGO2Z”);

Clearly something in ROOT already knows how to handle cuts and cut combinations.
I would like to know how to make cuts in this easy way using the suggested TTreeReader way of reading trees. Or is there another way of issuing a statement like the one above, where the 2D-histogram “h2” is replaced with an array (or vector), possibly even a multi-dimensional array?

Thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.