#include <stdlib.h>
 
#include <stdio.h>
 
#include <TSystem.h>
 
#include <TSystemFile.h>
 
#include <TString.h>
 
#include <TSystemDirectory.h>
 
#include <TList.h>
 
#include <TH1F.h>
 
#include <TH2F.h>
 
#include <TGraph.h>
 
#include <TTree.h>
 
#include <TFile.h>
 
#include <TCanvas.h>
 
#include <iostream>
 
 
 
void ana(TString fname);
 
 
 
void processRaw(TString fname){
 
        TString troot= fname + "_x0_y0.root";
 
        if(!gSystem->AccessPathName(troot)){
 
          cout << "ROOT File exists  "  << troot << endl;
 
        } else {
 
          cout << "Processing.  "  << troot << endl;
 
          ana(fname);
 
        }
 
}
 
 
 
class mytree {
 
        private:
 
     TH2F hdpo[4];      
 
     TH1F hadc[4];
 
     TH1F htdc[4];
 
     TGraph hgr;         
 
     TTree *tree;
 
     TFile *hfile;
 
         
 
    int voltage;
 
        int temperature;
 
        public:
 
        mytree( );
 
        ~mytree();
 
        int init(TString, TDirectory *);
 
        int event(TString);
 
        TString id;
 
        TString sn;
 
};
 
 
 
 
 
 
 
        
 
mytree *ptree;  
 
int mytree::init(TString fname, TDirectory *dir)
 
    {           
 
        cerr << "init " << fname << endl;
 
        
 
    if(!gSystem->AccessPathName(fname)){
 
//              cout << fname <<" exists. Remove it" << endl;
 
//              return -1;
 
        }       
 
    if (hfile) return -1;       
 
        
 
    hfile = new TFile (fname,"RECREATE","ROOT FILE with SiPM qdc and tdf");
 
   
 
    tree = new TTree("tree","sipm data tree");
 
        
 
    tree->Branch("voltage",&voltage,"voltage/I");
 
        tree->Branch("temp",&temperature,"temperature/I");
 
        tree->Branch("id","TString",&id);
 
        tree->Branch("sn","TString",&sn);
 
        tree->Branch("dpo2","TH2F",&hdpo[2]);
 
        tree->Branch("dpo3","TH2F",&hdpo[3]);
 
        tree->Branch("qdc2","TH1F",&hadc[2]);
 
        tree->Branch("qdc3","TH1F",&hadc[3]);
 
        tree->Branch("tdc2","TH1F",&htdc[2]);
 
        tree->Branch("tdc3","TH1F",&htdc[3]);
 
        tree->Branch("thscan","TGraph",&hgr, 32000, 0); 
 
        
 
        return 0;
 
        
 
        }
 
        
 
        
 
        
 
        TObject * getHisto(TDirectory *f,TString cname, TString hname , int subpad){
 
                                
 
                          auto  c=(TCanvas *) f->Get(cname);
 
                          if(!c) return NULL;
 
                          auto  p=(TPad *) c->GetPrimitive(cname + Form("_%d",subpad+1));
 
                          if(!p) return NULL;
 
                          //p->ls();
 
                          auto o= (TObject *) p->GetPrimitive(hname + Form("_%02d",subpad));
 
                          if (!o) return NULL;
 
                          auto o1=o->Clone();
 
                         
 
                          delete p;
 
                          delete c;
 
                          o1->ls();
 
              return o1;                        
 
                        }
 
                        
 
    int mytree::event(TString fname){
 
                
 
                 TFile *f= new TFile(fname +  "_x0_y0.root");      
 
                 TString bname=gSystem->BaseName(fname.Data());
 
                 TString pname=gSystem->DirName(gSystem->DirName(fname.Data()));
 
                 sn =gSystem->BaseName(gSystem->DirName(fname.Data()));
 
                 TObjArray *ppname = pname.Tokenize("_"); 
 
                 id = ((TObjString *)(ppname->At(1)))->String();
 
                 
 
                if (!hfile || !tree) init("sipm.root",f);
 
                
 
        TObjArray *t = bname.Tokenize("_."); 
 
        t->Print();
 
                for (Int_t i = 0; i < t->GetEntries(); i++) 
 
                        cout << ((TObjString *)(t->At(i)))->String() << endl;
 
                voltage = (((TObjString *)(t->At(2)))->String()).Atof(); 
 
                temperature = (((TObjString *)(t->At(1)))->String()).Atof();
 
                        
 
                cout << pname << " " << voltage << " " << temperature << endl;
 
        for (int i=0;i<4;i++){
 
                        
 
                        TH1F* h0=(TH1F *)getHisto(f,"c_adc","qdc",i);
 
                    TH1F* h1=(TH1F *)getHisto(f,"c_cftdif","cftdif",i);
 
                        TH2F* h2=(TH2F *)getHisto(f,"c_dpo","dpo",i);
 
                        
 
                        hadc[i]=(h0)?*h0:TH1F();
 
                        htdc[i]=(h1)?*h1:TH1F();
 
                        hdpo[i]=(h2)?*h2:TH2F();
 
                
 
                }
 
                f->Close();
 
                delete f;
 
                auto gr= new TGraph(fname + ".thr");
 
                hgr = (gr)?*gr:TGraph();
 
                TString grname= id + "_" + sn  + Form("_%d_%d", temperature, voltage);
 
                hgr.SetName(grname);
 
                hgr.ls();
 
                
 
        if (tree) tree->Fill();         
 
                else cerr <<"Error No tree" << endl;
 
                        
 
                        
 
            
 
                        
 
return 0;
 
                 
 
          
 
    }
 
        
 
        mytree::mytree(){
 
                
 
            hfile = NULL;
 
        }
 
        mytree::~mytree(){
 
                
 
        
 
    // End of the loop
 
    tree->Print();
 
    // Save all objects in this file
 
    hfile->Write();
 
    // Close the file. Note that this is automatically done when you leave
 
    // the application.
 
    hfile->Close();
 
 
 
}
 
 
 
void process_results( TString dirname=".", TString ext=".dat", int mode=0 , int level=0) { 
 
  TSystemDirectory dir(dirname, dirname); 
 
  TList *files = dir.GetListOfFiles(); 
 
  
 
  if (mode && level==0){          
 
          ptree= new mytree();
 
  }
 
  if (files) { 
 
    TSystemFile *file; 
 
    TString fname; 
 
    TIter next(files); 
 
    while ((file=(TSystemFile*)next())) { 
 
      fname = file->GetName(); 
 
          cout << "*" << fname.Data()   << endl;
 
          if (file->IsDirectory()){
 
                  cout << "DIR:" << fname.Data()   << endl;
 
                  if ( !fname.EqualTo(".") && !fname.EqualTo("..")){
 
                    process_results(dirname  + TString("/") + fname , ext, mode, level+1);
 
                  }
 
          } else {        
 
              cout << "FILE:" << fname.Data()   << endl;
 
      if ( fname.EndsWith(ext) ){
 
      TSubString k = fname.SubString("run"); 
 
      TString kk(k);
 
        if( kk.Length()>0 ) {
 
                         TString name = dirname  + TString("/") + fname;
 
             cout << "#######" << fname.Data() << "  " << name  << endl;
 
                         
 
                         if (mode) ptree->event(name);
 
                         else processRaw(name); 
 
                         
 
        }     
 
      } 
 
    } 
 
  } 
 
  
 
  }
 
  if (level==0 && ptree) delete ptree;
 
}