Hello,
I tried to use the second “more complete” example of usage of TTreeReader, that can be found here. I list the problems I encountered in decreasing order of importance:
[ul][li]The CheckValue method to validate a TTreeReaderValue always returns false, because TTreeReaderValues that have been just created have a setup status of -7[/li]
[li]CheckValue takes a pointer but a TTreeReaderValue is passed by value instead (and ChekValue should take a reference to TTreeReaderValueBase instead of a pointer to avoid passing null pointers to it)[/li]
[li]TTreeReaderValueBase is now in namespace ROOT::Internal, not just ROOT[/li]
[li]I had to remove from the code all mentions of #include "TriggerInfo.h"
#include "Muon.h"
#include "Tau.h" and things depending on them[/li]
[li]an unnamed TH1F is declared: TH1F("hist", "TTreeReader example histogram", 10, 0., 100.); and later used as variable “hist”[/li][/ul]
thanks for the remarks: a JIRA item was opened about your post to improve asap the documentation - sft.its.cern.ch/jira/browse/ROOT-7687
For what concerns these lines
(and the whole example) I think the spirit of this piece of code is to show how to plug TTreeReader in a real Physics analysis with names and entities widely known within the analysisers’ community.
Hello,
sorry I just saw the message (looking forward to mail notifications for post replies ).
I report below the code I ended up with, but the issue remains that the CheckValue function always returns false, because TTreeReaderValues’ status after their creation is invalid (-7). It might be a different bug, or simply a behaviour that should be better documented and differently handled in CheckValue here.
EDIT: corrected a typo, corrected the lack of case keyword in switch statements, qualified EntryStatuses with “TTreeReader::”
#include "TFile.h"
#include "TH1.h"
#include "TTreeReader.h"
#include "TTreeReaderValue.h"
#include "TTreeReaderArray.h"
#include <vector>
#include <iostream>
bool CheckValue(ROOT::Internal::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_t> px(reader, "px");
if (!CheckValue(&px)) return false;
TH1F hist("hist", "TTreeReader example histogram", 10, -3, 3);
while (reader.Next()) {
if (reader.GetEntryStatus() == TTreeReader::kEntryValid) {
std::cout << "Loaded entry " << reader.GetCurrentEntry() << '\n';
} else {
switch (reader.GetEntryStatus()) {
case TTreeReader::kEntryValid:
// Handled above.
break;
case TTreeReader::kEntryNotLoaded:
std::cerr << "Error: TTreeReader has not loaded any data yet!\n";
break;
case TTreeReader::kEntryNoTree:
std::cerr << "Error: TTreeReader cannot find a tree names \"MyTree\"!\n";
break;
case TTreeReader::kEntryNotFound:
// Can't really happen as TTreeReader::Next() knows when to stop.
std::cerr << "Error: The entry number does not exist\n";
break;
case TTreeReader::kEntryChainSetupError:
std::cerr << "Error: TTreeReader cannot access a chain element, e.g. file without the tree\n";
break;
case TTreeReader::kEntryChainFileError:
std::cerr << "Error: TTreeReader cannot open a chain element, e.g. missing file\n";
break;
case TTreeReader::kEntryDictionaryError:
std::cerr << "Error: TTreeReader cannot find the dictionary for some data\n";
break;
case TTreeReader::kEntryLast:
std::cerr << "Warning: TTreeReader reached fLastEntry\n";
break;
}
return false;
}
hist.Fill(*px);
} // TTree entry / event loop
hist.Print();
return true;
}
I removed the parts I could not compile because I don’t have TriggerInfo.h, Muon.h, Tau.h and have not access to the related objects.
For my part I believe code examples in the documentation should be “plug-and-play” for the users, so they can test and experiment right away, but anyway that is the code that works for me (except for the TTreeReaderValue::GetSetupStatus problem).
[quote=“eguiraud”]Hello,
I tried to use the second “more complete” example of usage of TTreeReader, that can be found here. I list the problems I encountered in decreasing order of importance:
[ul][li]The CheckValue method to validate a TTreeReaderValue always returns false, because TTreeReaderValues that have been just created have a setup status of -7[/li][/ul]
[/quote]
Thanks, moved after TTreeReader::Next()
Absolutely, thanks, fixed!
Fixed! But I think that’s wrong; I will move TTreeReaderValueBase into ROOT::Details::.
Right - this is a mockup. I wanted to show that it can read actual objects, as that’s often what people have.