Filling a histogram using selectors

Hello I am trying to fill a histogram in what I believe is a very simple way, using selectors, my Analyze.C file:

#define Analyze_cxx

#include "Analyze.h"
#include <TH2.h>
#include <TStyle.h>


//********** Definition Section ************
TH1* chi2Hist = NULL;

void Analyze::Begin(TTree * /*tree*/)
{
  TString option = GetOption();
  chi2Hist = new TH1D("chi2", "Histogram of Chi2", 100, 0, 20);

   //********* Initialization section *********
}

void Analyze::SlaveBegin(TTree * /*tree*/) {}

Bool_t Analyze::Process(Long64_t entry)
{
  //********* Loop Section *********
  tree1->GetEntry(entry);
  chi2Hist->Fill(chi2);
  return kTRUE;
}

void Analyze::SlaveTerminate(){}

void Analyze::Terminate()
{
  chi2Hist->Draw();
  //********* Wrap-up section ********
}

The header was generated automatically and I did not touch it.

I then run:

TFile myFile(“experiment.root”)
tree1->Process(“Analyze.C”)

But I get the error:

error: no matching member function for call to 'Fill' chi2Hist->Fill(chi2); ~~~~~~~~~~^~~~ /opt/local/libexec/root6/include/root/TH1.h:220:21: note: candidate function not viable: no known conversion from 'TTreeReaderValue<Float_t>' to 'Double_t' (aka 'double') for 1st argument virtual Int_t Fill(Double_t x); ^ /opt/local/libexec/root6/include/root/TH1.h:221:21: note: candidate function not viable: requires 2 arguments, but 1 was provided virtual Int_t Fill(Double_t x, Double_t w); ^ /opt/local/libexec/root6/include/root/TH1.h:222:21: note: candidate function not viable: requires 2 arguments, but 1 was provided virtual Int_t Fill(const char *name, Double_t w);

So it seems that the member function of TH1, Fill(), only takes doubles as arguments. Is it correct that I should need to convert from TTreeReaderValue<Float_t> to Double_t manually somehow? If so, how?

Hi,

you should get the content of the TTreeReaderValue with the operator*:
root.cern.ch/doc/master/classTT … 3be5c04a6c
the compiler will then take care of the cast from float to double transparently.
In other words:

TTreeReaderValue<float> weightRV(reader, "MyFloat");
...
myHisto.Fill(*weightRV)

Cheers,
D

Sorry, my mistake, I should have mentioned my header file explicitly. For the sake of brevity I assumed its contents were stated implicitly by that fact I was using selectors:

[code]lyze_h
#define Analyze_h

#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TSelector.h>
#include <TTreeReader.h>
#include <TTreeReaderValue.h>
#include <TTreeReaderArray.h>

// Headers needed by this particular selector

class Analyze : public TSelector {
public :
TTreeReader fReader; //!the tree reader
TTree *fChain = 0; //!pointer to the analyzed TTree or TChain

// Readers to access the data (delete the ones you do not need).
TTreeReaderValue<Int_t> event = {fReader, “event”};
TTreeReaderValue<Float_t> ebeam = {fReader, “ebeam”};
TTreeReaderValue<Float_t> px = {fReader, “px”};
TTreeReaderValue<Float_t> py = {fReader, “py”};
TTreeReaderValue<Float_t> pz = {fReader, “pz”};
TTreeReaderValue<Float_t> zv = {fReader, “zv”};
TTreeReaderValue<Float_t> chi2 = {fReader, “chi2”};

Analyze(TTree * /tree/ =0) { }
virtual ~Analyze() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();

ClassDef(Analyze,0);

};

#endif

#ifdef Analyze_cxx
void Analyze::Init(TTree *tree)
{
// The Init() function is called when the selector needs to initialize
// a new tree or chain. Typically here the reader is initialized.
// It is normally not necessary to make changes to the generated
// code, but the routine can be extended by the user if needed.
// Init() will be called many times when running on PROOF
// (once per file to be processed).

fReader.SetTree(tree);
}

Bool_t Analyze::Notify()
{
// The Notify() function is called when a new file is opened. This
// can be either for a new TTree in a TChain or when when a new TTree
// is started when using PROOF. It is normally not necessary to make changes
// to the generated code, but the routine can be extended by the
// user if needed. The return value is currently not used.

return kTRUE;
}

#endif // #ifdef Analyze_cxx
[/code]

So in have already defined this:

TTreeReaderValue<Float_t> chi2 = {fReader, "chi2"};
and fReader is defined

TTreeReader fReader;
So I only changed the line:

chi2Hist->Fill(chi2);
to

chi2Hist->Fill(*chi2);
So in this case the deference operator is overloaded, which calls Get(), correct? But this gives the error:

[code]Error in <Get()>: Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?

*** Break *** segmentation violation

[/code]Thank you very much for your help!!!

Hi,

was Next called at some point?

Danilo

Hi, I am doing the same thing and experiencing every error you have posted.
Here is an quick but dirty way to solve all the things.
The problems appears because the tutorial’s root is lower than us (6.02), and the way we load data is different from the way the tutorial loaded.

Replace the header file into http://www.nevis.columbia.edu/~seligman/root-class/files/Analyze.h
Everything goes well.
PS. chi2 is still chi2, not *chi2

I have solved this with change chi2 into *chi2.
To do it properly, use the header file generated from root 6.06.