/*
 * TriggerScanExpert
 * Author  Nagni
 * Modified by G. De Rosa
 * Version 1.2
 * Date 27 Apr 2006
 * Version 1.4
 * Date 26 Jun 2006: Inserted dependences on OnBoardTime and modified histogram ranges.
 *
 * Description:
 * Describe the performance of the Trigger.
 *
 * Parameters:
 * 	TString base            - the path to the root directory for the specific Pamela unpack session 
 * 	TString outDirectory    - the path where to save the output image (Default = base) 
 *      TString format          - the format which will be used for save the produced images (Default = "ps") 
 */

#include <TROOT.h>
#include <TFile.h>
#include <TString.h>
#include <TObjString.h>
#include <TTree.h>
#include <TBranch.h>
#include <TGraph.h>
#include <TStyle.h>
#include <TH2S.h>
#include <TPaveText.h>
#include <TCanvas.h>
#include <TLatex.h>
#include <TGraph.h>
#include <physics/trigger/TriggerEvent.h>
#include <EventHeader.h>
#include <PscuHeader.h>
#include <iostream>
#include <cstdlib>

using namespace std;

char bit(int decimal, char pos)
{
  return( (decimal>>pos)%2 );
}

void TriggerScanExpert(TString base, TString outDirectory = "", TString format = ""){
    
  std::stringstream sst;
  if (outDirectory == "") outDirectory = base.Data();
  TString filename = ((TObjString*)base.Tokenize('/')->Last())->GetString();
  
  TFile *file  =new TFile(base.Data()) ;
  if (!file){
    printf("file not Found \n");
    return;
  }
  
  TTree *PhysicsTr = (TTree*)file->Get("Physics");
  TBranch *TrigBr = PhysicsTr->GetBranch("Trigger");
  TBranch *HeadBr = PhysicsTr->GetBranch("Header");
  
  pamela::EventHeader *eh = 0;
  
  pamela::trigger::TriggerEvent *triggerEvent = 0;
  
  PhysicsTr->SetBranchAddress("Trigger", &triggerEvent);
  PhysicsTr->SetBranchAddress("Header", &eh);
  
  Long64_t nevents    = TrigBr->GetEntries();
  if (nevents <= 0) {
    printf("nevents = %llu \n", nevents);
    file->Close();
    return;
  }
  
  /* Histo DEF */
  
  /*
   * Pattern Trigger Rate histograms
   */
  
  TCanvas *PatternTrig0 = new TCanvas("PatternTrig0","PatternTrig0", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of Calo pattern trigger " << base.Data();
  TH1I *PatternTrig0Histo      = new TH1I("PatternTrig0Histo", sst.str().c_str(), 4, 0, 4);
  
  TCanvas *PatternTrig1 = new TCanvas("PatternTrig1","PatternTrig1", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of S4 pattern trigger " << base.Data();
  TH1I *PatternTrig1Histo      = new TH1I("PatternTrig1Histo", sst.str().c_str(), 3, 0, 3);
  
  
  TCanvas *PatternTrig2 = new TCanvas("PatternTrig2","PatternTrig2", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of S3 pattern trigger " << base.Data();
  TH1I *PatternTrig2Histo      = new TH1I("PatternTrig2Histo", sst.str().c_str(), 12, 0, 12);
  
  
  TCanvas *PatternTrig3 = new TCanvas("PatternTrig3","PatternTrig3", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of S2 pattern trigger " << base.Data();
  TH1I *PatternTrig3Histo      = new TH1I("PatternTrig3Histo", sst.str().c_str(), 8, 0, 8);
  
  
  TCanvas *PatternTrig4 = new TCanvas("PatternTrig4","PatternTrig4", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of S12 pattern trigger " << base.Data();
  TH1I *PatternTrig4Histo      = new TH1I("PatternTrig4Histo", sst.str().c_str(), 12, 0, 12);
  
  
  TCanvas *PatternTrig5 = new TCanvas("PatternTrig5","PatternTrig5", 1280, 1024);
  //----------
  sst.str("");
  sst << "Histogram of S11 pattern trigger " << base.Data();
  TH1I *PatternTrig5Histo      = new TH1I("PatternTrig5Histo", sst.str().c_str(), 16, 0, 16);
   
  int i  = 0;
  
  while(i < nevents){
    HeadBr->GetEntry(i);
    TrigBr->GetEntry(i);

    gStyle->SetOptStat(0000000);
    //    gStyle->SetStatY(0.85);

    int trte0=(int)triggerEvent->patterntrig[0];
    
    PatternTrig0Histo->AddBinContent(1,bit(trte0,0));
    PatternTrig0Histo->AddBinContent(2,bit(trte0,1));
    PatternTrig0Histo->AddBinContent(3,bit(trte0,2));
    PatternTrig0Histo->AddBinContent(4,bit(trte0,3));	  	  
    
    int trte1=(int)triggerEvent->patterntrig[1];
    
    PatternTrig1Histo->AddBinContent(1,bit(trte1,0));
    
    int trte2=(int)triggerEvent->patterntrig[2];	  
    
    PatternTrig2Histo->AddBinContent(1,bit(trte2,0));
    PatternTrig2Histo->AddBinContent(2,bit(trte2,1));
    PatternTrig2Histo->AddBinContent(3,bit(trte2,2));
    PatternTrig2Histo->AddBinContent(4,bit(trte2,3));
    PatternTrig2Histo->AddBinContent(5,bit(trte2,4));
    PatternTrig2Histo->AddBinContent(6,bit(trte2,5));
    PatternTrig2Histo->AddBinContent(7,bit(trte2,6));
    PatternTrig2Histo->AddBinContent(8,bit(trte2,7));
    PatternTrig2Histo->AddBinContent(9,bit(trte2,8));
    PatternTrig2Histo->AddBinContent(10,bit(trte2,9));
    PatternTrig2Histo->AddBinContent(11,bit(trte2,10));
    PatternTrig2Histo->AddBinContent(12,bit(trte2,11));
//     PatternTrig2Histo->AddBinContent(13,bit(trte2,12));
//     PatternTrig2Histo->AddBinContent(14,bit(trte2,13));
//     PatternTrig2Histo->AddBinContent(15,bit(trte2,14));
//     PatternTrig2Histo->AddBinContent(16,bit(trte2,15));
    
    int trte3=(int)triggerEvent->patterntrig[3];
    
    
    PatternTrig3Histo->AddBinContent(1,bit(trte3,0));
    PatternTrig3Histo->AddBinContent(2,bit(trte3,1));
    PatternTrig3Histo->AddBinContent(3,bit(trte3,2));
    PatternTrig3Histo->AddBinContent(4,bit(trte3,3));
    PatternTrig3Histo->AddBinContent(5,bit(trte3,4));
    PatternTrig3Histo->AddBinContent(6,bit(trte3,5));
    PatternTrig3Histo->AddBinContent(7,bit(trte3,6));
    PatternTrig3Histo->AddBinContent(8,bit(trte3,7));
//     PatternTrig3Histo->AddBinContent(9,bit(trte3,8));
//     PatternTrig3Histo->AddBinContent(10,bit(trte3,9));
//     PatternTrig3Histo->AddBinContent(11,bit(trte3,10));
//     PatternTrig3Histo->AddBinContent(12,bit(trte3,11));
//     PatternTrig3Histo->AddBinContent(13,bit(trte3,12));
//     PatternTrig3Histo->AddBinContent(14,bit(trte3,13));
//     PatternTrig3Histo->AddBinContent(15,bit(trte3,14));
//     PatternTrig3Histo->AddBinContent(16,bit(trte3,15));
    
    int trte4=(int)triggerEvent->patterntrig[4];
    
    
    PatternTrig4Histo->AddBinContent(1,bit(trte4,0));
    PatternTrig4Histo->AddBinContent(2,bit(trte4,1));
    PatternTrig4Histo->AddBinContent(3,bit(trte4,2));
    PatternTrig4Histo->AddBinContent(4,bit(trte4,3));
    PatternTrig4Histo->AddBinContent(5,bit(trte4,4));
    PatternTrig4Histo->AddBinContent(6,bit(trte4,5));
    PatternTrig4Histo->AddBinContent(7,bit(trte4,6));
    PatternTrig4Histo->AddBinContent(8,bit(trte4,7));
    PatternTrig4Histo->AddBinContent(9,bit(trte4,8));
    PatternTrig4Histo->AddBinContent(10,bit(trte4,9));
    PatternTrig4Histo->AddBinContent(11,bit(trte4,10));
    PatternTrig4Histo->AddBinContent(12,bit(trte4,11));
//     PatternTrig4Histo->AddBinContent(13,bit(trte4,12));
//     PatternTrig4Histo->AddBinContent(14,bit(trte4,13));
//     PatternTrig4Histo->AddBinContent(15,bit(trte4,14));
//     PatternTrig4Histo->AddBinContent(16,bit(trte4,15));
	  
    int trte5=(int)triggerEvent->patterntrig[5];
	  
	  
    PatternTrig5Histo->AddBinContent(1,bit(trte5,0));
    PatternTrig5Histo->AddBinContent(2,bit(trte5,1));
    PatternTrig5Histo->AddBinContent(3,bit(trte5,2));
    PatternTrig5Histo->AddBinContent(4,bit(trte5,3));
    PatternTrig5Histo->AddBinContent(5,bit(trte5,4));
    PatternTrig5Histo->AddBinContent(6,bit(trte5,5));
    PatternTrig5Histo->AddBinContent(7,bit(trte5,6));
    PatternTrig5Histo->AddBinContent(8,bit(trte5,7));
    PatternTrig5Histo->AddBinContent(9,bit(trte5,8));
    PatternTrig5Histo->AddBinContent(10,bit(trte5,9));
    PatternTrig5Histo->AddBinContent(11,bit(trte5,10));
    PatternTrig5Histo->AddBinContent(12,bit(trte5,11));
    PatternTrig5Histo->AddBinContent(13,bit(trte5,12));
    PatternTrig5Histo->AddBinContent(14,bit(trte5,13));
    PatternTrig5Histo->AddBinContent(15,bit(trte5,14));
    PatternTrig5Histo->AddBinContent(16,bit(trte5,15));
	  
    i++;
  }
	
	
  //  gStyle->SetStatH(0.15);
  //  gStyle->SetStatW(0.15);

  /* Pattern Trigger draw*/

  PatternTrig5->cd();
  PatternTrig5Histo->SetMinimum(0.);
  PatternTrig5Histo->Draw("");  

  PatternTrig4->cd();
  PatternTrig4Histo->SetMinimum(0.);
  PatternTrig4Histo->Draw("");
		    
  PatternTrig3->cd();
  PatternTrig3Histo->SetMinimum(0.);
  PatternTrig3Histo->Draw("");
	
  PatternTrig2->cd();
  PatternTrig2Histo->SetMinimum(0.);
  PatternTrig2Histo->Draw("");
	    
  PatternTrig0->cd();
  PatternTrig0Histo->SetMinimum(0.);
  PatternTrig0Histo->Draw("");
	
  PatternTrig1->cd();
  PatternTrig1Histo->SetMinimum(0.);
  PatternTrig1Histo->Draw("");
	    

  //  gStyle->SetStatH(0.3);
  //  gStyle->SetStatW(0.3);
  
  // print the output
  const char *saveas = format;
  if ( !strcmp(saveas,"ps") ) {
    // ------print the ps
    
    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert." << saveas  << "(";

    PatternTrig5->Print(sst.str().c_str());
    PatternTrig4->Print(sst.str().c_str());
    PatternTrig3->Print(sst.str().c_str());    
    PatternTrig2->Print(sst.str().c_str());
    PatternTrig0->Print(sst.str().c_str());
    //
    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert." << saveas << ")";
    PatternTrig1->Print(sst.str().c_str());
    
  } else {

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert1." << saveas;
    PatternTrig5->SaveAs(sst.str().c_str());

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert2." << saveas;
    PatternTrig4->SaveAs(sst.str().c_str());

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert3." << saveas;
    PatternTrig3->SaveAs(sst.str().c_str());  

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert4." << saveas;
    PatternTrig2->SaveAs(sst.str().c_str());

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert5." << saveas;
    PatternTrig0->SaveAs(sst.str().c_str());

    sst.str("");
    sst << outDirectory.Data() << filename.Data() << "TriggerScanExpert6." << saveas;
    PatternTrig1->SaveAs(sst.str().c_str());
  }

}


int main(int argc, char* argv[]){
  TString path;
  TString outDir        ="./";
  TString format        ="ps";
  
  if (argc < 2){
    printf("You have to insert at least the file to analyze \n");
    printf("Try '--help' for more information. \n");
    exit(1);
  }  
  
  if (!strcmp(argv[1], "--help")){
    printf( "Usage: TriggerScanExpert FILE [OPTION] \n");
    printf( "\t --help                  Print this help and exit \n");	
    printf( "\t -outDir[path]           Path where to put the output [default ./] \n");
    printf( "\t -format[ps]             Format for output files [default 'ps'] \n");
    exit(1);
  }
  
  
  path=argv[1];
  
  for (int i = 2; i < argc; i++){
    
    if (!strcmp(argv[i], "-outDir")){
      if (++i >= argc){
	printf( "-outDir needs arguments. \n");
	printf( "Try '--help' for more information. \n");
	exit(1);
      } 
      else{
	outDir = argv[i];
	continue;
      }
    }
    
    
    
    if (!strcmp(argv[i], "-format")){
      if (++i >= argc){
	printf( "-format needs arguments. \n");
	printf( "Try '--help' for more information. \n");
	exit(1);
      } 
      else{
	format = argv[i];
	continue;
      }
    }
  }

  TriggerScanExpert(argv[1], outDir, format);

}
