/**
* Header Scan
* Author  Nagni
* version 1.0
*
* Version 1.1 - 28 December 2004
* If outList does not exist the function exit to prompt
* If nevents = 0 the function exit to promt
*
* Version 1.2 - 3 January 2005
* Two canvases are created to see the graphs better
*
* Version 1.25 - 13 January 2005
* Changed Int_t to Float because of variable range size
* (UInt_t has been excluded beacuse of uncompatibility with TGraph)
*
* version 1.3  - 22 February 2005 - Nagni
* For compatibility with batch mode excution:
* 1) Added "include <iostream>" and "using namespace std" 
* 2) Removed gROOT->Reset()
*
* Version 1.4
* Date 08 March 2005
* Added "format" parameter for saving the produced image in various formats
* (for a complete list of types refer to TPad::SaveAs method)
*
* Version 1.5
* Date 09 February 2006 - Marcelli
* Update to work with new Yoda output
*
* Version 1.6
* Date 27 February 2006 - Marcelli
* For compilation: 
*     Added function "int main(int argc, char* argv[])"
*
*
* Description: This script creates two canvases with five pads. The first pad shows packetID variable (for all packets) vs. OBT.
*     	       The second pad shows the number of physic packets vs. OBT. The third pad shows the lenght of Physic packets (byte) vs. OBT.
*              The fourth pad shows the packetcounter of physic packets vs. OBT. The fifth pad shows PacketCounter vs. File Offset.
*
* Parameters:
* 	       TSTring base          - the path to the root directory for the specific Pamela unpack session
*                                      There is no default value, without this input the program will not run
*              TString outDir        - the path where to save the output image (Default = ./) 
*              TString format        - the format which will be used fo rsave the produced images (Default = "jpg") 
*/



#include <sstream>
#include <iostream>
#include "TString.h"
#include "TStyle.h"
#include "TFile.h"
#include "TList.h"
#include "TTree.h"
#include "TObjString.h"
#include "TCanvas.h"
#include "TGraph.h"
#include "TH1F.h"
#include "TGaxis.h"
#include "EventHeader.h"
#include "PscuHeader.h"


using namespace std;

void HeaderScan(TString base, TString outDir, TString format)
{

  TList *list = new TList;
  Int_t numkey;
  TObject *key = new TObject;
  const char *name;
  TTree* tr = new TTree;
  Long64_t totevents=0, totphysevents=0;
  Float_t id;
  Long64_t nevents=0;

  //------- load root file --------------

  TFile *file = new TFile(base.Data());
  
  if (!file){
    printf("No such file in the directory has been found");
    return;
  }
  if (outDir == "" ) outDir = ".";
  
  list = file->GetListOfKeys(); 
  
  numkey = file->GetNkeys();
  
  pamela::EventHeader *eh=0;
  pamela::PscuHeader *ph=0;
  
  ///-----to know the total number f events end of physics events----//////
  
  for (Int_t i=0; i<numkey; i++){
    key = list->At(i);
    name=(key->GetName());
    //cout<<name<<"\n";
    tr = (TTree*)file->Get(name); 
    if (tr->IsZombie()) continue;
    nevents = tr->GetEntries(); 
    totevents+=nevents;
    tr->SetBranchAddress("Header", &eh);  
    for (Int_t j = 0; j < nevents; j++){
      tr->GetEntry(j); 
      ph = eh->GetPscuHeader();
      if(ph->GetPacketId1() == 0x10) ++totphysevents;
    }
     
  }

  const Long64_t totalevents=totevents; 
  const Long64_t totalphysevents=totphysevents;
  
  /////////////////////////////////////////////////
  
  TString filename = ((TObjString*)base.Tokenize('/')->Last())->GetString(); 
  filename = ((TObjString*)filename.Tokenize('.')->First())->GetString();
  stringstream oss;
  oss.str("");
  oss << filename.Data();
  
  Float_t obt[totalevents], pcktId[totalevents], pcktLenght[totalphysevents], pcktCounter[totalphysevents], offset[totalevents], allCounter[totalevents];
  Float_t obtphysevents=0;
  

  totphysevents=0;
  totevents=0;
  for (Int_t i=0; i<numkey; i++){
    key = list->At(i);
    name=(char *)(key->GetName());
    tr = (TTree*)file->Get(name);
    if (tr->IsZombie()) continue;
    tr->SetBranchAddress("Header", &eh);
    nevents = tr->GetEntries();
    for (Int_t j = 0; j < nevents; j++){
      tr->GetEntry(j);  
      ph = eh->GetPscuHeader();
      obt[j+totevents]=ph->GetOrbitalTime() ;
      pcktId[j+totevents]=ph->GetPacketId1();
      offset[j+totevents]=ph->GetFileOffset();
      if(pcktId[j+totevents]==16){
	pcktLenght[totphysevents]=ph->GetPacketLenght();
	pcktCounter[totphysevents]=ph->GetCounter();
	totphysevents=totphysevents+1;
      }	
      offset[j+totevents]=ph->GetFileOffset();
      allCounter[j+totevents]= ph->GetCounter();
    } 
    totevents=totevents+nevents; 
  }
  
  
  Float_t  mintime=obt[0], maxtime=obt[0], minlen=pcktLenght[0], maxlen=pcktLenght[0], mincount=pcktCounter[0], maxcount=pcktCounter[0];   
  
  
  for (Int_t t=0; t<totalevents; t++){
    if(obt[t]<mintime) mintime=obt[t];
    if(obt[t]>maxtime) maxtime=obt[t];
  } 
  for (Int_t t=0; t<totalphysevents; t++){
    if(pcktLenght[t]<=minlen) minlen=pcktLenght[t];
    if(pcktLenght[t]>=maxlen) maxlen=pcktLenght[t];
    if(pcktCounter[t]<=mincount) mincount=pcktCounter[t];
    if(pcktCounter[t]>=maxcount) maxcount=pcktCounter[t];
  }
  
  
  Float_t    nbintime   = (maxtime-mintime)/1000;
  Float_t    nbinlen    = (maxlen-minlen)/100;
  Float_t    nbincount  = (maxcount-mincount)/100;
  
  
  ///---------------------------TO GRAPH---------------------------------------------///
  TCanvas *finalCanv1 = new TCanvas("Header_1", base, 1280, 1024);
  TCanvas *finalCanv2 = new TCanvas("Header_2", base, 1280, 1024);
  finalCanv1->Divide(3);
  finalCanv1->SetFillColor(10);
  finalCanv2->Divide(2);
  finalCanv2->SetFillColor(10);

  
  TGraph *grPcktId1 = new TGraph(totalevents, obt, pcktId);
  TGraph *grPcktLenght = new TGraph(totalevents, obt, pcktLenght);
  TGraph *grPcktCounter = new TGraph(totalevents, obt, pcktCounter);
  TGraph *grFileOffset = new TGraph(totalevents, offset, allCounter);
  
  TGaxis::SetMaxDigits(3);

  //-----canvas 1-------------------------------/// 
  finalCanv1->cd(1);
  
  stringstream oss1;
  oss1.str("");
  oss1 << "OBT (ms) with t0 = " << mintime << "ms";
  
  gStyle->SetTitleH(0.06);
  grPcktId1->SetTitle(oss.str().c_str());
  grPcktId1->GetXaxis()->SetTitle(oss1.str().c_str());
  grPcktId1->GetXaxis()->CenterTitle();
  grPcktId1->GetXaxis()->SetLabelSize(0.03);
  grPcktId1->GetYaxis()->SetTitle("Packet ID");
  grPcktId1->GetYaxis()->CenterTitle();
  grPcktId1->SetMarkerSize(4);
  grPcktId1->Draw("AP");
  
  
  finalCanv1->cd(2);
  oss1.str("");
  oss1 << "OBT (min) with t0 = " << mintime << "ms";
  
  TH1F *h1 = new TH1F ("h1", oss.str().c_str(), (int)(nbintime/60), mintime, maxtime);
  
  for (Int_t i=0; i<numkey; i++){
    key = list->At(i);
    name=(char *)(key->GetName());
    tr = (TTree*)file->Get(name); 
    if (tr->IsZombie()) continue;
    tr->SetBranchAddress("Header", &eh);
    nevents = tr->GetEntries();
    for (Int_t j = 0; j < nevents; j++){
      tr->GetEntry(j);  
      ph = eh->GetPscuHeader();
      if((ph->GetPacketId1()) == 16){
	obtphysevents=ph->GetOrbitalTime();
	h1->Fill(obtphysevents);
      }	
    } 
  }
  
  h1->SetMarkerStyle(6);
  h1->GetXaxis()->SetTitle(oss1.str().c_str());
  h1->GetXaxis()->CenterTitle();
  h1->GetXaxis()->SetLabelSize(0.03);
  h1->GetYaxis()->SetTitle("number of Physic packets");
  h1->GetYaxis()->CenterTitle();
  h1->Draw();
  
  
  finalCanv1->cd(3);
  oss1.str("");
  oss1 << "OBT (ms) with t0 = " << mintime << "ms";
  
  grPcktLenght->SetTitle(oss.str().c_str());
  grPcktLenght->GetXaxis()->SetTitle(oss1.str().c_str());
  grPcktLenght->GetXaxis()->CenterTitle();
  grPcktLenght->GetXaxis()->SetLabelSize(0.03);
  grPcktLenght->GetYaxis()->SetTitle("Lenght of Physic packets   (byte)");
  grPcktLenght->GetYaxis()->CenterTitle();
  grPcktLenght->GetYaxis()->SetLabelSize(0.03);
  grPcktLenght->SetMarkerSize(4);
  grPcktLenght->Draw("AP");
  
  
  finalCanv1->cd(2);
  h1->Draw();
  
  finalCanv1->Update();
  
  
  ///---------canvas 2-----------------------------//
  finalCanv2->cd(1);
  
  grPcktCounter->SetTitle(oss.str().c_str());
  grPcktCounter->GetXaxis()->SetTitle(oss1.str().c_str());
  grPcktCounter->GetXaxis()->SetTitleSize(0.04);
  grPcktCounter->GetXaxis()->CenterTitle();
  grPcktCounter->GetXaxis()->SetLabelSize(0.03);
  grPcktCounter->GetYaxis()->SetTitle("PacketCounter of Physic packets");
  grPcktCounter->GetYaxis()->SetTitleSize(0.04);
  grPcktCounter->GetYaxis()->CenterTitle();
  grPcktCounter->GetYaxis()->SetLabelSize(0.03);
  grPcktCounter->SetMarkerSize(4);
  grPcktCounter->SetMinimum(mincount);
  grPcktCounter->SetMaximum(maxcount);
  grPcktCounter->Draw("AP");
   
  finalCanv2->cd(2);
  
  grFileOffset->SetTitle(oss.str().c_str());
  grFileOffset->GetXaxis()->SetTitle("File Offset");
  grFileOffset->GetXaxis()->CenterTitle();
  grFileOffset->GetXaxis()->SetTitleSize(0.04);
  grFileOffset->GetXaxis()->SetLabelSize(0.03);
  grFileOffset->GetYaxis()->SetTitle("Packet counter");
  grFileOffset->GetYaxis()->CenterTitle();
  grFileOffset->GetYaxis()->SetTitleSize(0.04);
  grFileOffset->GetYaxis()->SetLabelSize(0.03);
  grFileOffset->SetMarkerSize(4);
  grFileOffset->Draw("AP");
  
  finalCanv1->Update();
  
  
  //-------to save---------------------------///
  oss.str("");
  oss1.str("");
  
  oss << outDir.Data() << filename.Data();
  oss1 << outDir.Data() << filename.Data();

  oss  << "_HeaderScan_1." << format.Data();
  oss1 << "_HeaderScan_2." << format.Data();
  
  finalCanv1->SaveAs(oss.str().c_str());
  finalCanv2->SaveAs(oss1.str().c_str());
  
  
  file->Close();
  
}



int main(int argc, char* argv[]){
  TString path;
  TString outDir     = "./";
  TString format     = "jpg";
    
 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: HeaderScan 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[jpg|ps|gif]    Format for output files [default 'jpg'] \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;
      }
    }
   

  }

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

}
