75 std::size_t
comment = line.find(
'#');
76 line = line.substr(0, comment);
78 std::size_t firstNotSpace = line.find_first_not_of(
" \t");
79 if (firstNotSpace != std::string::npos)
80 line = line.substr(firstNotSpace);
86 std::size_t lastNotSpace = line.find_last_not_of(
" \t");
87 if (lastNotSpace != std::string::npos)
88 line = line.substr(0, lastNotSpace + 1);
100 static const std::string kCutIntr =
" if ";
102 std::size_t
equal = line.find(
"=");
103 if (equal == std::string::npos)
104 return "Error: missing '='";
107 std::string histName = line.substr(0, equal);
109 if (histName.empty())
110 return "Error: no histName found";
113 std::size_t cutPos = line.find(kCutIntr, equal);
114 std::string histExpression;
115 if (cutPos == std::string::npos)
116 histExpression = line.substr(equal + 1);
118 histExpression = line.substr(equal + 1, cutPos - equal - 1);
120 if (histExpression.empty())
121 return "Error: no expression found";
125 if (cutPos != std::string::npos) {
126 histCut = line.substr(cutPos + kCutIntr.size());
129 return "Error: missing cut expression after 'if'";
135 auto check =
fHists.insert(std::make_pair((
const std::string&)histName,
136 std::make_pair(histExpression, histCut)));
140 return "Duplicate histogram name";
155 const std::vector<std::string>& inputFiles,
156 const std::vector<std::string>& expressions,
157 const std::string& treeName =
""):
160 for (
const std::string& expr: expressions) {
162 if (!errMessage.empty())
163 throw std::runtime_error(errMessage +
" in " + expr);
173 std::string treeName =
"";
174 std::unique_ptr<TFile> inputFile{
TFile::Open(firstInputFile.c_str())};
177 for (
TObject* keyAsObj : *inputFile->GetListOfKeys()) {
178 TKey* key =
static_cast<TKey*
>(keyAsObj);
186 if (treeName.empty())
189 ::Error(
"TSimpleAnalysis::Analyze",
"Multiple trees inside %s", firstInputFile.c_str());
195 if (treeName.empty()) {
196 ::Error(
"TSimpleAnalysis::Analyze",
"No tree inside %s", firstInputFile.c_str());
208 static const char* errors[] {
211 "invalid entry number",
212 "cannot open the file",
219 TIter next(fileElements);
221 if (chEl->GetLoadResult() < 0) {
222 ::Error(
"TSimpleAnalysis::Run",
"Load failure in file %s: %s",
223 chEl->GetTitle(), errors[-(chEl->GetLoadResult())]);
243 if (!probe->IsZombie()) {
271 if (ofile.IsZombie()) {
277 auto generateHisto = [&](
const std::pair<TChain*, TDirectory*>& job) {
278 TChain* chain = job.first;
281 std::vector<TH1F *> vPtrHisto(
fHists.size());
286 for (
const auto &histo :
fHists) {
287 const std::string& expr = histo.second.first;
288 const std::string& histoName = histo.first;
289 const std::string& cut = histo.second.second;
291 chain->
Draw((expr +
">>" + histoName).c_str(), cut.c_str(),
"goff");
292 TH1F *ptrHisto = (
TH1F*)taskDir->
Get(histoName.c_str());
296 return std::vector<TH1F *>();
298 vPtrHisto[i] = ptrHisto;
311 ROOT::TThreadExecutor pool(8);
314 std::vector<std::pair<TChain*, TDirectory*>> vChains;
319 ch->
Add(inputfile.c_str());
325 vChains.emplace_back(std::make_pair(ch, taskDir));
328 auto vFileswHists = pool.Map(generateHisto, vChains);
332 for (
auto&& histsOfJob: vFileswHists) {
333 if (histsOfJob.empty())
339 std::vector<TH1F *> vPtrHisto{vFileswHists[0]};
341 for (
unsigned j = 0; j <
fHists.size(); j++) {
342 for (
unsigned i = 1; i < vFileswHists.size(); i++) {
343 if (!vFileswHists[i][j]) {
346 vPtrHisto[j] =
nullptr;
350 vPtrHisto[j]->Add(vFileswHists[i][j]);
353 vPtrHisto[j]->Write();
362 chain->
Add(inputfile.c_str());
365 auto vHisto = generateHisto({chain,
gDirectory});
370 for (
auto histo: vHisto) {
386 if (line.find(
"=") == std::string::npos) {
400 std::string notEmptyLine;
403 getline(
fIn, notEmptyLine);
406 }
while (
fIn && notEmptyLine.empty());
431 std::string errMessage;
433 switch (readingSection) {
463 if (!errMessage.empty()) {
464 ::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...
bool equal(double d1, double d2, double stol=10000)
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...
tomato 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,...)
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.
A chain is a collection of files containg 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.