75   std::size_t comment = 
line.find(
'#');
 
   78   std::size_t firstNotSpace = 
line.find_first_not_of(
" \t");
 
   79   if (firstNotSpace != std::string::npos)
 
   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 = 
""):
 
  158   fInputFiles(inputFiles), fOutputFile(
output), fTreeName(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()) {
 
  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;
 
  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(),
 
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Int_t gErrorIgnoreLevel
Error handling routines.
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 threads,...
auto Map(F func, unsigned nTimes, R redfunc, unsigned nChunks) -> std::vector< InvokeResult_t< F > >
Execute a function nTimes in parallel, dividing the execution in nChunks and providing a result per c...
A TChainElement describes a component of a TChain.
A chain is a collection of files containing TTree objects.
TObjArray * GetListOfFiles() const
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.
Long64_t Draw(const char *varexp, const TCut &selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0) override
Draw expression varexp for selected entries.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t InheritsFrom(const char *cl) const override
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() 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()
Change current directory to "this" directory.
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
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
const char * GetName() const override
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
The map contains in the first part the names of the histograms written in the output file,...
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()
Enable support for multi-threading within the ROOT code in particular, enables the global mutex to ma...