TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple. It uses TTreeReaderValue<T> and TTreeReaderArray<T> to access the data. Example code can be found in tutorials/tree/hsimpleReader.C and tutorials/trees/h1analysisTreeReader.h and tutorials/trees/h1analysisTreeReader.C for a TSelector. Roottest contains an example showing the full power. A simpler analysis example - the one from the tutorials - can be found below: it histograms a function of the px and py branches.
// A simple TTreeReader use: read data from hsimple.root (written by hsimple.C) #include "TFile.h" #include "TH1F.h" #include "TTreeReader.h" #include "TTreeReaderValue.h" void hsimpleReader() { // Create a histogram for the values we read. TH1F *myHist = new TH1F("h1", "ntuple", 100, -4, 4); // Open the file containing the tree. TFile *myFile = TFile::Open("$ROOTSYS/tutorials/hsimple.root"); // Create a TTreeReader for the tree, for instance by passing the // TTree's name and the TDirectory / TFile it is in. TTreeReader myReader("ntuple", myFile); // The branch "px" contains floats; access them as myPx. TTreeReaderValue<Float_t> myPx(myReader, "px"); // The branch "py" contains floats, too; access those as myPy. TTreeReaderValue<Float_t> myPy(myReader, "py"); // Loop over all entries of the TTree or TChain. while (myReader.Next()) { // Just access the data as if myPx and myPy were iterators (note the '*' // in front of them): myHist->Fill(*myPx + *myPy); } myHist->Draw(); }
A more complete example including error handling and a few combinations of TTreeReaderValue and TTreeReaderArray would look like this:
#include <TFile.h> #include <TH1.h> #include <TTreeReader.h> #include <TTreeReaderValue.h> #include <TTreeReaderArray.h> #include "TriggerInfo.h" #include "Muon.h" #include "Tau.h" #include <vector> #include <iostream> bool CheckValue(ROOT::TTreeReaderValueBase* value) { if (value->GetSetupStatus() < 0) { std::cerr << "Error " << value->GetSetupStatus() << "setting up reader for " << value->GetBranchName() << '\n'; return false; } return true; } // Analyze the tree "MyTree" in the file passed into the function. // Returns false in case of errors. bool analyze(TFile* file) { // Create a TTreeReader named "MyTree" from the given TDirectory. // The TTreeReader gives access to the TTree to the TTreeReaderValue and // TTreeReaderArray objects. It knows the current entry number and knows // how to iterate through the TTree. TTreeReader reader("MyTree", file); // Read a single float value in each tree entries: TTreeReaderValue<float> weight(reader, "event.weight"); if (!CheckValue(weight)) return false; // Read a TriggerInfo object from the tree entries: TTreeReaderValue<TriggerInfo> triggerInfo(reader, "triggerInfo"); if (!CheckValue(triggerInfo)) return false; // Read a vector of Muon objects from the tree entries: TTreeReaderValue<std::vector<Muon>> muons(reader, "muons"); if (!CheckValue(muons)) return false; // Read the pT for all jets in the tree entry: TTreeReaderArray<double> jetPt(reader, "jets.pT"); if (!CheckValue(jetPt)) return false; // Read the taus in the tree entry: TTreeReaderArray<Tau> taus(reader, "taus"); if (!CheckValue(taus)) return false; // Now iterate through the TTree entries and fill a histogram. TH1* hist = new TH1F("hist", "TTreeReader example histogram", 10, 0., 100.); while (reader.Next()) { if (reader.GetEntryStatus() == kEntryValid) { std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n'; } else { switch (reader.GetEntryStatus()) { kEntryValid: // Handled above. break; kEntryNotLoaded: std::cerr << "Error: TTreeReader has not loaded any data yet!\n"; break; kEntryNoTree: std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n"; break; kEntryNotFound: // Can't really happen as TTreeReader::Next() knows when to stop. std::cerr << "Error: The entry number doe not exist\n"; break; kEntryChainSetupError: std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n"; break; kEntryChainFileError: std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n"; break; kEntryDictionaryError: std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n"; break; } return false; } // Access the TriggerInfo object as if it's a pointer. if (!triggerInfo->hasMuonL1()) continue; // Ditto for the vector<Muon>. if (!muons->size()) continue; // Access the jetPt as an array, whether the TTree stores this as // a std::vector, std::list, TClonesArray or Jet* C-style array, with // fixed or variable array size. if (jetPt.GetSize() < 2 || jetPt[0] < 100) continue; // Access the array of taus. if (!taus.IsEmpty()) { float currentWeight = *weight; for (int iTau = 0, nTau = taus.GetSize(); iTau < nTau; ++iTau) { // Access a float value - need to dereference as TTreeReaderValue // behaves like an iterator hist->Fill(taus[iTau].eta(), currentWeight); } } } // TTree entry / event loop } |
virtual | ~TTreeReader() |
void | TObject::AbstractMethod(const char* method) const |
virtual void | TObject::AppendPad(Option_t* option = "") |
virtual void | TObject::Browse(TBrowser* b) |
static TClass* | Class() |
virtual const char* | TObject::ClassName() const |
virtual void | TObject::Clear(Option_t* = "") |
virtual TObject* | TObject::Clone(const char* newname = "") const |
virtual Int_t | TObject::Compare(const TObject* obj) const |
virtual void | TObject::Copy(TObject& object) const |
virtual void | TObject::Delete(Option_t* option = "")MENU |
virtual Int_t | TObject::DistancetoPrimitive(Int_t px, Int_t py) |
virtual void | TObject::Draw(Option_t* option = "") |
virtual void | TObject::DrawClass() constMENU |
virtual TObject* | TObject::DrawClone(Option_t* option = "") constMENU |
virtual void | TObject::Dump() constMENU |
virtual void | TObject::Error(const char* method, const char* msgfmt) const |
virtual void | TObject::Execute(const char* method, const char* params, Int_t* error = 0) |
virtual void | TObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0) |
virtual void | TObject::ExecuteEvent(Int_t event, Int_t px, Int_t py) |
virtual void | TObject::Fatal(const char* method, const char* msgfmt) const |
virtual TObject* | TObject::FindObject(const char* name) const |
virtual TObject* | TObject::FindObject(const TObject* obj) const |
Long64_t | GetCurrentEntry() const |
virtual Option_t* | TObject::GetDrawOption() const |
static Long_t | TObject::GetDtorOnly() |
Long64_t | GetEntries(Bool_t force) const |
TTreeReader::EEntryStatus | GetEntryStatus() const |
virtual const char* | TObject::GetIconName() const |
virtual const char* | TObject::GetName() const |
virtual char* | TObject::GetObjectInfo(Int_t px, Int_t py) const |
static Bool_t | TObject::GetObjectStat() |
virtual Option_t* | TObject::GetOption() const |
virtual const char* | TObject::GetTitle() const |
TTree* | GetTree() const |
virtual UInt_t | TObject::GetUniqueID() const |
virtual Bool_t | TObject::HandleTimer(TTimer* timer) |
virtual ULong_t | TObject::Hash() const |
virtual void | TObject::Info(const char* method, const char* msgfmt) const |
virtual Bool_t | TObject::InheritsFrom(const char* classname) const |
virtual Bool_t | TObject::InheritsFrom(const TClass* cl) const |
virtual void | TObject::Inspect() constMENU |
void | TObject::InvertBit(UInt_t f) |
virtual TClass* | IsA() const |
Bool_t | IsChain() const |
virtual Bool_t | TObject::IsEqual(const TObject* obj) const |
virtual Bool_t | TObject::IsFolder() const |
Bool_t | TObject::IsOnHeap() const |
virtual Bool_t | TObject::IsSortable() const |
Bool_t | TObject::IsZombie() const |
virtual void | TObject::ls(Option_t* option = "") const |
void | TObject::MayNotUse(const char* method) const |
Bool_t | Next() |
virtual Bool_t | TObject::Notify() |
void | TObject::Obsolete(const char* method, const char* asOfVers, const char* removedFromVers) const |
void | TObject::operator delete(void* ptr) |
void | TObject::operator delete(void* ptr, void* vp) |
void | TObject::operator delete[](void* ptr) |
void | TObject::operator delete[](void* ptr, void* vp) |
void* | TObject::operator new(size_t sz) |
void* | TObject::operator new(size_t sz, void* vp) |
void* | TObject::operator new[](size_t sz) |
void* | TObject::operator new[](size_t sz, void* vp) |
TTreeReader& | operator=(const TTreeReader&) |
virtual void | TObject::Paint(Option_t* option = "") |
virtual void | TObject::Pop() |
virtual void | TObject::Print(Option_t* option = "") const |
virtual Int_t | TObject::Read(const char* name) |
virtual void | TObject::RecursiveRemove(TObject* obj) |
void | TObject::ResetBit(UInt_t f) |
virtual void | TObject::SaveAs(const char* filename = "", Option_t* option = "") constMENU |
virtual void | TObject::SavePrimitive(ostream& out, Option_t* option = "") |
void | TObject::SetBit(UInt_t f) |
void | TObject::SetBit(UInt_t f, Bool_t set) |
void | SetChain(const char*, TFileCollection*) |
virtual void | TObject::SetDrawOption(Option_t* option = "")MENU |
static void | TObject::SetDtorOnly(void* obj) |
TTreeReader::EEntryStatus | SetEntry(Long64_t entry) |
TTreeReader::EEntryStatus | SetLocalEntry(Long64_t entry) |
static void | TObject::SetObjectStat(Bool_t stat) |
void | SetTree(TTree* tree) |
void | SetTree(const char*, TDirectory*) |
virtual void | TObject::SetUniqueID(UInt_t uid) |
virtual void | ShowMembers(TMemberInspector& insp) const |
virtual void | Streamer(TBuffer&) |
void | StreamerNVirtual(TBuffer& ClassDef_StreamerNVirtual_b) |
virtual void | TObject::SysError(const char* method, const char* msgfmt) const |
Bool_t | TObject::TestBit(UInt_t f) const |
Int_t | TObject::TestBits(UInt_t f) const |
TTreeReader() | |
TTreeReader(TTree* tree) | |
TTreeReader(const TTreeReader&) | |
TTreeReader(const char* keyname, TDirectory* dir = __null) | |
TTreeReader(const char*, TFileCollection*) | |
virtual void | TObject::UseCurrentStyle() |
virtual void | TObject::Warning(const char* method, const char* msgfmt) const |
virtual Int_t | TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) |
virtual Int_t | TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const |
void | DeregisterValueReader(ROOT::TTreeReaderValueBase* reader) |
virtual void | TObject::DoError(int level, const char* location, const char* fmt, va_list va) const |
ROOT::TNamedBranchProxy* | FindProxy(const char* branchname) const |
TCollection* | GetProxies() |
void | Initialize() |
void | TObject::MakeZombie() |
void | RegisterValueReader(ROOT::TTreeReaderValueBase* reader) |
TTreeReader::EEntryStatus | SetEntryBase(Long64_t entry, Bool_t local) |
static TObject::<anonymous> | TObject::kBitMask | |
static TObject::EStatusBits | TObject::kCanDelete | |
static TObject::EStatusBits | TObject::kCannotPick | |
static TTreeReader::EEntryStatus | kEntryChainFileError | |
static TTreeReader::EEntryStatus | kEntryChainSetupError | |
static TTreeReader::EEntryStatus | kEntryDictionaryError | |
static TTreeReader::EEntryStatus | kEntryNoTree | |
static TTreeReader::EEntryStatus | kEntryNotFound | |
static TTreeReader::EEntryStatus | kEntryNotLoaded | |
static TTreeReader::EEntryStatus | kEntryValid | |
static TObject::EStatusBits | TObject::kHasUUID | |
static TObject::EStatusBits | TObject::kInvalidObject | |
static TObject::<anonymous> | TObject::kIsOnHeap | |
static TObject::EStatusBits | TObject::kIsReferenced | |
static TObject::EStatusBits | TObject::kMustCleanup | |
static TObject::EStatusBits | TObject::kNoContextMenu | |
static TObject::<anonymous> | TObject::kNotDeleted | |
static TObject::EStatusBits | TObject::kObjInCanvas | |
static TObject::<anonymous> | TObject::kOverwrite | |
static TObject::<anonymous> | TObject::kSingleKey | |
static TObject::<anonymous> | TObject::kWriteDelete | |
static TObject::<anonymous> | TObject::kZombie |
ROOT::TBranchProxyDirector* | fDirector | proxying director, owned |
TDirectory* | fDirectory | directory (or current file for chains) |
TTreeReader::EEntryStatus | fEntryStatus | status of most recent read request |
THashTable | fProxies | attached ROOT::TNamedBranchProxies; owned |
TTree* | fTree | tree that's read |
deque<ROOT::TTreeReaderValueBase*> | fValues | readers that use our director |
static TTreeReader::EPropertyBits | kBitIsChain |
{ return fTree ? (force ? fTree->GetEntries() : fTree->GetEntriesFast() ) : -1; }