77 std::size_t comment = line.find(
'#');
78 line = line.substr(0, comment);
80 std::size_t firstNotSpace = line.find_first_not_of(
" \t");
81 if (firstNotSpace != std::string::npos)
82 line = line.substr(firstNotSpace);
88 std::size_t lastNotSpace = line.find_last_not_of(
" \t");
89 if (lastNotSpace != std::string::npos)
90 line = line.substr(0, lastNotSpace + 1);
102 static const std::string kCutIntr =
" if ";
104 std::size_t equal = line.find(
"=");
105 if (equal == std::string::npos)
106 return "Error: missing '='";
109 std::string histName = line.substr(0, equal);
111 if (histName.empty())
112 return "Error: no histName found";
115 std::size_t cutPos = line.find(kCutIntr, equal);
116 std::string histExpression;
117 if (cutPos == std::string::npos)
118 histExpression = line.substr(equal + 1);
120 histExpression = line.substr(equal + 1, cutPos - equal - 1);
122 if (histExpression.empty())
123 return "Error: no expression found";
127 if (cutPos != std::string::npos) {
128 histCut = line.substr(cutPos + kCutIntr.size());
131 return "Error: missing cut expression after 'if'";
137 auto check =
fHists.insert(std::make_pair((
const std::string&)histName,
138 std::make_pair(histExpression, histCut)));
142 return "Duplicate histogram name";
157 const std::vector<std::string>& inputFiles,
158 const std::vector<std::string>& expressions,
159 const std::string& treeName =
""):
162 for (
const std::string& expr: expressions) {
164 if (!errMessage.empty())
165 throw std::runtime_error(errMessage +
" in " + expr);
175 std::string treeName =
"";
176 std::unique_ptr<TFile> inputFile{
TFile::Open(firstInputFile.c_str())};
179 for (
TObject* keyAsObj : *inputFile->GetListOfKeys()) {
180 TKey* key =
static_cast<TKey*
>(keyAsObj);
188 if (treeName.empty())
191 ::Error(
"TSimpleAnalysis::Analyze",
"Multiple trees inside %s", firstInputFile.c_str());
197 if (treeName.empty()) {
198 ::Error(
"TSimpleAnalysis::Analyze",
"No tree inside %s", firstInputFile.c_str());
210 static const char* errors[] {
213 "invalid entry number",
214 "cannot open the file",
221 TIter next(fileElements);
223 if (chEl->GetLoadResult() < 0) {
224 ::Error(
"TSimpleAnalysis::Run",
"Load failure in file %s: %s",
225 chEl->GetTitle(), errors[-(chEl->GetLoadResult())]);
245 if (!probe->IsZombie()) {
273 if (ofile.IsZombie()) {
279 auto generateHisto = [&](
const std::pair<TChain*, TDirectory*>& job) {
280 TChain* chain = job.first;
283 std::vector<TH1F *> vPtrHisto(
fHists.size());
288 for (
const auto &histo :
fHists) {
289 const std::string& expr = histo.second.first;
290 const std::string& histoName = histo.first;
291 const std::string& cut = histo.second.second;
293 chain->
Draw((expr +
">>" + histoName).c_str(), cut.c_str(),
"goff");
294 TH1F *ptrHisto = (
TH1F*)taskDir->
Get(histoName.c_str());
298 return std::vector<TH1F *>();
300 vPtrHisto[i] = ptrHisto;
316 std::vector<std::pair<TChain*, TDirectory*>> vChains;
321 ch->
Add(inputfile.c_str());
327 vChains.emplace_back(std::make_pair(ch, taskDir));
330 auto vFileswHists = pool.
Map(generateHisto, vChains);
334 for (
auto&& histsOfJob: vFileswHists) {
335 if (histsOfJob.empty())
341 std::vector<TH1F *> vPtrHisto{vFileswHists[0]};
343 for (
unsigned j = 0; j <
fHists.size(); j++) {
344 for (
unsigned i = 1; i < vFileswHists.size(); i++) {
345 if (!vFileswHists[i][j]) {
348 vPtrHisto[j] =
nullptr;
352 vPtrHisto[j]->Add(vFileswHists[i][j]);
355 vPtrHisto[j]->Write();
364 chain->
Add(inputfile.c_str());
367 auto vHisto = generateHisto({chain,
gDirectory});
372 for (
auto histo: vHisto) {
388 if (line.find(
"=") == std::string::npos) {
402 std::string notEmptyLine;
405 getline(
fIn, notEmptyLine);
408 }
while (
fIn && notEmptyLine.empty());
433 std::string errMessage;
435 switch (readingSection) {
465 if (!errMessage.empty()) {
466 ::Error(
"TSimpleAnalysis::Configure",
"%s in %s:%d", errMessage.c_str(),
virtual const char * GetName() const
Returns name of object.
std::string fConfigFile
Name of the configuration file.
std::map< std::string, std::pair< std::string, std::string > > fHists
bool Run()
Execute all the TChain::Draw() as configured and stores the output histograms.
R__EXTERN Int_t gErrorIgnoreLevel
A TSimpleAnalysis object creates histograms from a TChain.
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
std::string HandleExpressionConfig(const std::string &line)
Handle the expression lines of the input file in order to pass the elements to the members of the obj...
bool SetTreeName()
Disambiguate tree name from first input file and set up fTreeName if it is empty. ...
bool RunSimpleAnalysis(const char *configurationFile)
Function that allows to create the TSimpleAnalysis object and execute its Configure and Analyze funct...
virtual const char * GetClassName() const
static bool CheckChainLoadResult(TChain *chain)
Returns true if there are no errors in TChain::LoadTree()
bool Configure()
This function has the aim of setting the arguments read from the input file.
Reading the name of the .root input files.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
1-D histogram with a float per channel (see TH1 documentation)}
A TChainElement describes a component of a TChain.
std::string GetLine(int &numbLine)
Skip subsequent empty lines read from fIn and returns the next not empty line.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
TObjArray * GetListOfFiles() const
virtual Long64_t Draw(const char *varexp, const TCut &selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Draw expression varexp for selected entries.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
std::string fTreeName
Name of the input tree.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
void Error(const char *location, const char *msgfmt,...)
This class provides a simple interface to execute the same task multiple times in parallel...
std::ifstream fIn
Stream for the input file.
The ROOT global object gROOT contains a list of all defined classes.
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Reading the name of the tree.
bool HandleInputFileNameConfig(const std::string &line)
Returns false if not a tree name, otherwise sets the name of the tree.
void EnableThreadSafety()
Enables the global mutex to make ROOT thread safe/aware.
static std::string ExtractTreeName(std::string &firstInputFile)
Extract the name of the tree from the first input file when the tree name isn't in the configuration ...
Describe directory structure in memory.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
std::vector< std::string > fInputFiles
.root input files
Mother of all ROOT objects.
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
A chain is a collection of files containing TTree objects.
static void DeleteCommentsAndSpaces(std::string &line)
Delete comments, leading and trailing white spaces in a string.
Reading the name of the output file.
TSimpleAnalysis(const std::string &file)
std::string fOutputFile
Output file in which are stored the histograms.
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.