#include <math.h>   // include the math headder to get the fabs function

#include "TString.h"
#include "TFile.h"
#include "TTree.h"

void myRootStuff(const char * fileName)
{
  // open the specified file
  TString treeName = "selectedtree";
  TFile f(fileName);

  // get the tree 'selectedtree' from the file
  // remembering to cast the object to its correct type
  TTree* tree = (TTree*)f.Get(treeName);

  if(!tree)
  {
    cout << "Unable to open tree: " << treeName << " in file "<< fileName << endl;
    return;
  }
  else
  {
    cout << "File " << fileName << " has been opened and contains a "<< treeName << endl;
  }

  // some interesting variables that we know we are interested in
  Float_t mes;       // a mass variable
  Float_t de;        // an energy difference variable
  Float_t newfish;   // an MVA fisher discriminant
  Float_t imass[3];  // invariant mass of B0, pi0 #1 and pi0 #2 in that order

  // set up to read the relevant branches of the old file
  tree->SetBranchAddress("mes",     &mes);
  tree->SetBranchAddress("de",      &de);
  tree->SetBranchAddress("newfish", &newfish);
  tree->SetBranchAddress("imass",    imass);  // get an array as an example too

  TFile newfile("newfile.root", "RECREATE");
  TTree newtree("newtree", "a new tree");
  TBranch * b_mes = newtree.Branch("mes", &mes, "Beam energy substituted mass/F");
  TBranch * b_de  = newtree.Branch("de", &de, "#Delta E/F");
  TBranch * b_f   = newtree.Branch("legendreFisher", &newfish, "a Fisher discriminant/F");

  for(int i=0; i < tree->GetEntries(); i++)
  {
    tree->GetEntry(i);
    if((mes > 5.2) && (mes < 5.29))
    {
      if(fabs(de)<0.4) newtree.Fill();
    }
  }

  cout << "Finished looping over the tree       " << treeName << endl;
  cout << "The original number of candidates is " << tree->GetEntries() << endl;
  cout << "The new number in the new tree       " << newtree.GetEntries() << endl;  

  // the file will be written out using this member function
  // there is no need oto close the file as this is done when the file
  // object goes out of scop or when delete is called on a pointer to that 
  // file.
  newfile.Write();

  cout << "finished looping over this ntuple - you can find the new reduced ntuple" << endl;
  cout << "as newfile.root" << endl;
}

