From 5057e90442aed5274282ecdb27aadfdde7f4f6e6 Mon Sep 17 00:00:00 2001
From: Adrien Matta <matta@lpccaen.in2p3.fr>
Date: Mon, 10 May 2021 09:30:57 +0200
Subject: [PATCH] * Fully functional .tree file support         - User can
 build Friends entry by hand         - User can use .tree file as entry point
 to automatically           generate friends input         - User can use -T
 flag with .tree file

---
 NPLib/Core/NPOptionManager.cxx |   4 +-
 NPLib/Core/RootInput.cxx       | 109 +++++++--------------------------
 NPLib/Core/RootInput.h         |  12 ++--
 Projects/S034/RunToTreat.txt   |   4 ++
 4 files changed, 33 insertions(+), 96 deletions(-)
 create mode 100644 Projects/S034/RunToTreat.txt

diff --git a/NPLib/Core/NPOptionManager.cxx b/NPLib/Core/NPOptionManager.cxx
index eb1cdef77..a38c8569e 100644
--- a/NPLib/Core/NPOptionManager.cxx
+++ b/NPLib/Core/NPOptionManager.cxx
@@ -222,9 +222,7 @@ void NPOptionManager::CreateRunToTreatFile(std::string file, std::string tree){
   if(!run.is_open())
     exit(1);
 
-  run << "TTreeName" << std::endl;
-  run << " " << tree << std::endl;
-  run << "RootFileName" << std::endl;
+  run << "Tree " << tree << std::endl;
   run << " " << file << std::endl << std::endl;
   run.close();
   fRunToReadFileName=".RunToTreat.txt";
diff --git a/NPLib/Core/RootInput.cxx b/NPLib/Core/RootInput.cxx
index 30258e260..e14e60357 100644
--- a/NPLib/Core/RootInput.cxx
+++ b/NPLib/Core/RootInput.cxx
@@ -82,7 +82,7 @@ void RootInput::ReadInputFile(NPL::InputParser& parser){
     vector<NPL::InputBlock*> friends = parser.GetAllBlocksWithToken("Friend");
     unsigned int sizeF = friends.size();
     for(unsigned int i = 0 ; i < sizeF ; i++){
-      pFriends.insert(pair< string,vector<string> > (friends[i]->GetMainValue(),friends[i]->GetLines()));
+      pFriendsPath.insert(pair< string,vector<string> > (friends[i]->GetMainValue(),friends[i]->GetLines()));
     }
 }
 
@@ -90,17 +90,17 @@ void RootInput::ReadInputFile(NPL::InputParser& parser){
 void  RootInput::ReadTreeFile(std::string path){
   ifstream tree(path.c_str());
   path=path.substr(0,path.rfind("/")+1);
-  path+="/";
   std::string buffer;
   bool first=true;
+  unsigned int count = 0 ;
   while(tree>>buffer){
     if(first){
       pTreePath.push_back(path+buffer);
+      count++;
       first=false;
     }
     else{
-      vector<string> friends={path+buffer};
-      pFriends.insert(pair<string,vector<string>>(pTreeName, friends));
+      pFriendsTreePath[count++].push_back(path+buffer);
     }
   }
 }
@@ -163,15 +163,28 @@ RootInput::RootInput(std::string configFileName){
     }
   }
   
-  // Add all the friends
-  for(auto it = pFriends.begin(); it!=pFriends.end() ; it++){
-    unsigned int size = it->second.size();
-    for(unsigned int i = 0 ; i < size ; i++){
-     cout << "  - Adding friend : " << it->second[i].c_str() << endl;
-     pRootChain->AddFriend(it->first.c_str(),it->second[i].c_str());
+  // Case of user made Friends
+  for(auto it = pFriendsPath.begin(); it!=pFriendsPath.end() ; it++){
+    TChain* chain = new TChain(it->first.c_str());
+    cout << "  - Adding friend : " << endl;
+    for(auto itp = it->second.begin() ; itp!=it->second.end() ; itp++){
+     cout << "    - " << (*itp).c_str() << endl;
+     chain->Add((*itp).c_str());
     }
+    pRootChain->AddFriend(chain);
   }
 
+  // Case of tree file
+  for(auto it = pFriendsTreePath.begin(); it!=pFriendsTreePath.end() ; it++){
+    TChain* chain = new TChain(pTreeName.c_str());
+    cout << "  - Adding friend : " << endl;
+    for(auto itp = it->second.begin() ; itp!=it->second.end() ; itp++){
+      cout << "    - " << (*itp).c_str() << endl;
+      chain->Add((*itp).c_str());
+    } 
+    pRootChain->AddFriend(chain);
+  }
+  
   if (!pRootFile) 
     pRootFile = new TFile(firstfile.c_str());
 
@@ -183,76 +196,6 @@ RootInput::RootInput(std::string configFileName){
     std::cout << "\033[1;32mROOTInput:  " << pRootChain->GetEntries() << " entries loaded in the input chain\033[0m" << std::endl ;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-void RootInput::AddFriendChain(std::string RunToAdd){
-  NumberOfFriend++;
-  std::ostringstream suffix_buffer;
-  suffix_buffer << "_" << NumberOfFriend ; 
-  std::string suffix = suffix_buffer.str();
-  bool CheckTreeName     = false;
-  bool CheckRootFileName = false;
-
-  // Read configuration file Buffer
-  std::string lineBuffer, dataBuffer;
-
-  // Open file
-  std::ifstream inputConfigFile;
-  inputConfigFile.open(RunToAdd.c_str());
-
-  TChain* localChain = new TChain();
-  
-  std::cout << "/////////////////////////////////" << std::endl;
-  std::cout << "Adding friend to current TChain" << std::endl;
-
-  if (!inputConfigFile) {
-    std::cout << "Run to Add file :" << RunToAdd << " not found " << std::endl; 
-    return;
-  }
-
-  else {
-    while (!inputConfigFile.eof()) {
-      getline(inputConfigFile, lineBuffer);
-
-      // search for token giving the TTree name
-      if (lineBuffer.compare(0, 9, "TTreeName") == 0) {
-        inputConfigFile >> dataBuffer;
-        // adding suffix to insure uniquity of the chain name
-        dataBuffer+suffix;
-        // initialize localChain
-        localChain->SetName(dataBuffer.c_str());
-        CheckTreeName = true ;
-      }
-
-      // search for token giving the list of Root files to treat
-      else if (lineBuffer.compare(0, 12, "RootFileName") == 0  &&  localChain) {
-        CheckRootFileName = true ;
-
-        while (!inputConfigFile.eof()) {
-          inputConfigFile >> dataBuffer;
-
-          // ignore comment Line 
-          if (dataBuffer.compare(0, 1, "%") == 0) {
-            inputConfigFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
-          }
-
-          else if (!inputConfigFile.eof()) {
-            localChain->Add(dataBuffer.c_str());
-            std::cout << "Adding file " << dataBuffer << " to TChain" << std::endl;
-          }
-        }
-      }
-    }
-  }
-
-  if (!CheckRootFileName || !CheckTreeName) 
-    std::cout << "WARNING: Token not found for InputTree Declaration : Input Tree has not be Added to the current Chain" << std::endl;
-
-  else
-    pRootChain->AddFriend( localChain->GetName() );
-
-  std::cout << "/////////////////////////////////" << std::endl;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 std::string RootInput::DumpAsciiFile(const char* type, const char* folder){
   std::string name="fail";
@@ -332,9 +275,3 @@ RootInput::~RootInput(){
   pRootFile->Close();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-TChain* MakeFriendTrees(std::string RunToRead1,std::string RunToRead2){
-  RootInput:: getInstance(RunToRead1)	;
-  RootInput:: getInstance()->AddFriendChain(RunToRead2);
-  return RootInput:: getInstance()->GetChain();
-}
diff --git a/NPLib/Core/RootInput.h b/NPLib/Core/RootInput.h
index 9c92768fd..51c479956 100644
--- a/NPLib/Core/RootInput.h
+++ b/NPLib/Core/RootInput.h
@@ -73,9 +73,7 @@ public:
    TFile*   GetFile()   {return pRootFile;}
    void     SetChain(TChain* c)  {pRootChain = c;} 
 
-   // Add a Friend chain to the input chain
-   void     AddFriendChain(std::string RunToAdd);
-
+   // Read Input file
    void     ReadOldStyleInputFile(NPL::InputParser& parser);
    void     ReadInputFile(NPL::InputParser& parser);
    void     ReadTreeFile(std::string path);
@@ -85,12 +83,12 @@ private:
    TFile    *pRootFile;
    std::string pTreeName;// the main tree name
    std::vector<std::string> pTreePath;// the main tree path
-   std::multimap<std::string,std::vector<std::string>> pFriends;// list of Friends tree indexed by their tree name
+   // Used for user made tree friends
+   std::multimap<std::string,std::vector<std::string>> pFriendsPath;// list of Friends tree indexed by their tree name
+   // Used for .tree file input
+   std::map<unsigned int, std::vector<std::string>> pFriendsTreePath;// list of Friends tree path indexed by number
    int NumberOfFriend;
   
 };
 
-// A convenient function related to Root Input, coded Here so it can be called within ROOT CINT
-TChain* MakeFriendTrees(std::string,std::string);
-
 #endif // ROOTINPUT_HH
diff --git a/Projects/S034/RunToTreat.txt b/Projects/S034/RunToTreat.txt
new file mode 100644
index 000000000..08d603cc6
--- /dev/null
+++ b/Projects/S034/RunToTreat.txt
@@ -0,0 +1,4 @@
+Tree RawTree
+  root/mrdc/run0570/run0570.tree
+  root/mrdc/run0582/run0582.tree
+
-- 
GitLab