80 std::size_t firstNotSpace =
line.find_first_not_of(
" \t");
81 if (firstNotSpace != std::string::npos)
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 =
""):
160 fInputFiles(inputFiles), fOutputFile(
output), fTreeName(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()) {
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(),
void Error(const char *location, const char *msgfmt,...)
R__EXTERN Int_t gErrorIgnoreLevel
static void DeleteCommentsAndSpaces(std::string &line)
Delete comments, leading and trailing white spaces in a string.
static bool CheckChainLoadResult(TChain *chain)
Returns true if there are no errors in TChain::LoadTree()
bool RunSimpleAnalysis(const char *configurationFile)
Function that allows to create the TSimpleAnalysis object and execute its Configure and Analyze funct...
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 ...
This class provides a simple interface to execute the same task multiple times in parallel,...
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
A TChainElement describes a component of a TChain.
A chain is a collection of files containing TTree objects.
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.
TObjArray * GetListOfFiles() const
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
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.
Bool_t cd(const char *path=nullptr) override
Change current directory to "this" directory.
Describe directory structure in memory.
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual Bool_t cd(const char *path=nullptr)
Change current directory to "this" directory.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
1-D histogram with a float per channel (see TH1 documentation)}
Book space in a file, create I/O buffers, to fill them, (un)compress them.
virtual const char * GetClassName() const
virtual const char * GetName() const
Returns name of object.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t IsZombie() const
A TSimpleAnalysis object creates histograms from a TChain.
std::string fConfigFile
Name of the configuration file.
std::vector< std::string > fInputFiles
.root input files
std::string GetLine(int &numbLine)
Skip subsequent empty lines read from fIn and returns the next not empty line.
@ kReadingInput
Reading the name of the .root input files.
@ kReadingOutput
Reading the name of the output file.
@ kReadingTreeName
Reading the name of the tree.
@ kReadingExpressions
Reading the expressions.
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...
std::ifstream fIn
Stream for the input file.
TSimpleAnalysis(const std::string &file)
bool Run()
Execute all the TChain::Draw() as configured and stores the output histograms.
std::string fOutputFile
Output file in which are stored the histograms.
bool HandleInputFileNameConfig(const std::string &line)
Returns false if not a tree name, otherwise sets the name of the tree.
bool SetTreeName()
Disambiguate tree name from first input file and set up fTreeName if it is empty.
bool Configure()
This function has the aim of setting the arguments read from the input file.
std::map< std::string, std::pair< std::string, std::string > > fHists
std::string fTreeName
Name of the input tree.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
void EnableThreadSafety()
Enables the global mutex to make ROOT thread safe/aware.
static void output(int code)