//
//   Show pulse distributions of the calorimeter PULSE calibration
//
//   FCaloPULSE.cxx      version 1.00  (2006-03-08)
//
//   The only input needed is the path to the directory created by YODA for the data file you want to analyze.
//
//   Changelog:
//
//   1.00 - 1.01 : Flight version, read unique YODA file. 
//
//   0.00 - 1.00 : clone of CaloPULSE v1r05.
//
#include <fstream>
#include <sstream>
#include <TTree.h>
#include <TClassEdit.h>
#include <TObject.h>
#include <TList.h>
#include <TSystem.h>
#include <TSystemDirectory.h>
#include <TString.h>
#include <TFile.h>
#include <TClass.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TH1F.h>
#include <TH2D.h>
#include <TLatex.h>
#include <TPad.h>
#include <TPaveLabel.h>
#include <TChain.h>
#include <TStyle.h>
//
#include <PamelaRun.h>
#include <physics/calorimeter/CalorimeterEvent.h>
#include <physics/trigger/TriggerEvent.h>
#include <CalibCalPedEvent.h>
#include <CalibCalPulse1Event.h>
#include <CalibCalPulse2Event.h>
#include <varDump/VarDumpEvent.h>
#include <varDump/VarDumpRecord.h>
#include <fcalostructs.h>
//
extern int OLDCaloFindCalibs(TString &, Calib &);
extern bool existfile(TString);
extern TString getFilename(const TString);
extern void PrintFigure(TString, TString, TString, TString, TCanvas&);
extern void ColorMIP(Float_t, int&);
//
using namespace std;
//
void FCaloPULSE(TString filename, TString outDir = "", Int_t tosave = 0, TString saveas = "eps"){
  const char* startingdir = gSystem->WorkingDirectory();
  if ( !strcmp(outDir.Data(),"") ) outDir = startingdir;
  //
  if ( !existfile(filename) ){
    printf(" %s :no such file or directory \n",filename.Data());
    return;
  };
  //
  TFile *File = new TFile(filename.Data());
  TTree *tr = (TTree*)File->Get("CalibCalPulse1");
  pamela::CalibCalPulse1Event *ce = 0;   
  pamela::EventHeader *ceh = new pamela::EventHeader(); 
  tr->SetBranchAddress("Header", &ceh);
  tr->SetBranchAddress("CalibCalPulse1", &ce);
  //
  TFile *vdFile = new TFile(filename.Data());
  TTree *vdtr = (TTree*)vdFile->Get("VarDump");
  pamela::VarDumpEvent  *vde = 0;
  pamela::VarDumpRecord *vdr = 0;
  vdtr->SetBranchAddress("VarDump", &vde);
  Long64_t nevents    = vdtr->GetEntries();
  stringstream ptype;
  stringstream stno;
  Int_t        tmpSize;    
  for (Int_t i = 0; i < nevents ; i++){
    vdtr->GetEntry(i);
    tmpSize = vde->Records->GetEntries();
    for (Int_t j = 0; j < tmpSize; j++){
      vdr = (pamela::VarDumpRecord*)vde->Records->At(j);	
      if ( (int)vdr->VAR_VALUE>32760 && (int)vdr->VAR_VALUE<32790 ){
	printf(" PULSE TYPE = %X ",vdr->VAR_VALUE);
	ptype.str("");
	ptype << " PULSE TYPE = ";
	ptype << hex << vdr->VAR_VALUE;
	vdr = (pamela::VarDumpRecord*)vde->Records->At(j+1);	
	printf(" STRIP = %X \n",vdr->VAR_VALUE);
	stno.str("");
	stno << " STRIP = ";
	stno << hex << vdr->VAR_VALUE;
      };
    };
  };    
  vdFile->Close();
  //
  TString fififile =  getFilename(filename);
  const char *file = fififile;
  //
  TCanvas *figura2 = new TCanvas("calpulse", "calpulse", 950, 850);
  figura2->cd();
  figura2->Range(0,0,100,100);
  stringstream errore;
  figura2->SetFillColor(10);
  errore.str("");
  errore << "EXPERT  --  File: " << file;
  errore << " ";
  TLatex *t=new TLatex();
  t->SetTextFont(32);
  t->SetTextColor(1);
  t->SetTextAlign(12);
  t->SetTextSize(0.015);
  t->DrawLatex(2.,99.,errore.str().c_str());
  //
  gPad->SetLogy();
  Long64_t ncalibs    = tr->GetEntries();
  TH1F *calpulse1;
  Int_t workornot = 1;
  int stoppa = 0;
  for (Int_t ci = 0; ci < ncalibs ; ci++){
    int stoppa = 0;
    int per = 0;
    tr->GetEntry(ci);
    gDirectory->Delete("calpulse");
    calpulse1 = new TH1F("calpulse","",96,-0.5,8000.);
    calpulse1->SetBit(TH1F::kCanRebin);
    for ( Int_t s=0 ; s<4 ;s++  ){
      if ( ce->unpackError  ) {
	per = 1;
      } else {
	per = 0;
	for ( Int_t d=0 ; d<11 ;d++  ){
	  for ( Int_t j=0; j<96 ;j++){
	    calpulse1->Fill(ce->calpuls[s][d][j]);
	    if ( ce->calpuls[s][d][j] != 0. ) stoppa = 1;
	    if ( ce->calpuls[s][d][j] < 0. ) workornot = 0;
	  };
	};
      };
    };
    if ( !per ){
      figura2->cd();
      figura2->SetFillColor(10);
      stringstream titolo;
      titolo.str("");
      titolo << "Pulse1 " << ptype.str().c_str();
      titolo << " " << stno.str().c_str();
      calpulse1->Draw();
      calpulse1->SetTitle(titolo.str().c_str());
      figura2->Modified();
      figura2->Update();
      stringstream figsave;
      figsave.str("");
      figsave << "pulse1_";
      figsave << ci;
      if ( tosave ) PrintFigure(filename,outDir,figsave.str().c_str(),saveas,*figura2);
    };
  };    	   
  //
  tr = new TTree();
  tr = (TTree*)File->Get("CalibCalPulse2");
  ncalibs    = tr->GetEntries();
  pamela::CalibCalPulse2Event *cee = 0;   
  tr->SetBranchAddress("CalibCalPulse2", &cee);
  //    
  figura2 = new TCanvas("calpulse", "calpulse", 950, 850);
  figura2->cd();
  //  stringstream errore;
  figura2->Range(0,0,100,100);
  figura2->SetFillColor(10);
  errore.str("");
  errore << "EXPERT  --  File: " << file;
  errore << " ";
  t=new TLatex();
  t->SetTextFont(32);
  t->SetTextColor(1);
  t->SetTextAlign(12);
  t->SetTextSize(0.015);
  t->DrawLatex(2.,99.,errore.str().c_str());
  gPad->SetLogy();
  ncalibs    = tr->GetEntries();
  TH1F *calpulse2;
  for (Int_t ci = 0; ci < ncalibs ; ci++){
    stoppa = 0;
    int per = 0;
    tr->GetEntry(ci);
    gDirectory->Delete("calpulse");
    calpulse2 = new TH1F("calpulse","",96,-0.5,8000.);
    calpulse2->SetBit(TH1F::kCanRebin);
    for ( Int_t s=0 ; s<4 ;s++  ){
      if ( cee->unpackError  ){
	per = 1;
      } else {
	per = 0;
	for ( Int_t d=0 ; d<11 ;d++  ){
	  for ( Int_t j=0; j<96 ;j++){
	    calpulse2->Fill(cee->calpuls[s][d][j]);
	    if ( cee->calpuls[s][d][j] != 0. ) {
	      stoppa = 1;
	    };
	    if ( cee->calpuls[s][d][j] < 0. ) workornot = 0;
	  };
	};
      };
    };
    if ( !per ){
      figura2->cd();
      figura2->SetFillColor(10);
      figura2->Range(0,0,100,100);
      stringstream titolo;
      titolo.str("");
      titolo << "Pulse2 " << ptype.str().c_str();
      titolo << " " << stno.str().c_str();
      calpulse2->SetTitle(titolo.str().c_str());
      calpulse2->Draw();
      figura2->Modified();
      figura2->Update();
      stringstream figsave;
      figsave.str("");
      figsave << "pulse2_";
      figsave << ci;
      if ( tosave ) PrintFigure(filename,outDir,figsave.str().c_str(),saveas,*figura2);
    };
  };    
  if ( stoppa ){
    if ( workornot ){
      printf("File %s is ok \n",filename.Data());
    } else {
      printf("File %s is NOT OK! \n",filename.Data());
    };
  };
}

void FCaloPULSEMATRA(TString filename, TString outDir = "", Int_t tosave = 0, TString saveas = "eps"){
  const char* startingdir = gSystem->WorkingDirectory();
  if ( !strcmp(outDir.Data(),"") ) outDir = startingdir;
  //
  if ( !existfile(filename) ){
    printf(" %s :no such file or directory \n",filename.Data());
    return;
  };
  //
  struct Calib calib;
  for (Int_t s=0; s<4;s++){
    for (Int_t d = 0; d<50; d++){
      calib.ttime[s][d] = 0 ;
      if ( d < 49 ) calib.time[s][d] = 0 ;
    };
  };
  //
  // first of all find the calibrations in the file 
  //
  OLDCaloFindCalibs(filename, calib);    
  //
  // print on the screen the results:   
  //
  printf(" ---------------------------------------------------------- \n \n");	
  Int_t calibex = 0;
  for (Int_t s=0; s<4;s++){
    Int_t stop = 0;
    for (Int_t d = 0; d<48; d++){
      if ( calib.ttime[s][d] != 0 ) {
	calibex++;
      };
      if ( calib.time[s][0] != 0 ){
	if ( d == 0 )  printf(" Section %i from time 0 to time %i use calibration at time %i \n",s,calib.time[s][d],calib.ttime[s][d]);
	if ( calib.time[s][d+1] != 0 ) {
	  printf(" Section %i from time %i to time %i use calibration at time %i \n",s,calib.time[s][d],calib.time[s][d+1],calib.ttime[s][d+1]);
	} else {
	  if ( !stop ){
	    printf(" Section %i from time %i use calibration at time %i \n",s,calib.time[s][d],calib.ttime[s][d+1]);		
	    stop = 1;
	  };
	};
      } else {
	if ( calib.ttime[s][d] != 0 ) printf(" Section %i from time 0 use calibration at time %i \n",s,calib.ttime[s][d]);
      };
    };
    printf("\n");	
  };
  Int_t workornot = 1;
  //
  TFile *vdFile = new TFile(filename.Data());
  TTree *vdtr = (TTree*)vdFile->Get("VarDump");
  pamela::VarDumpEvent  *vde = 0;
  pamela::VarDumpRecord *vdr = 0;
  vdtr->SetBranchAddress("VarDump", &vde);
  Long64_t nevents    = vdtr->GetEntries();
  //
  stringstream ptype;
  stringstream stno;
  Int_t tmpSize;    
  for (Int_t i = 0; i < nevents ; i++){
    vdtr->GetEntry(i);
    tmpSize = vde->Records->GetEntries();
    for (Int_t j = 0; j < tmpSize; j++){
      vdr = (pamela::VarDumpRecord*)vde->Records->At(j);	
      if ( (int)vdr->VAR_VALUE>32760 && (int)vdr->VAR_VALUE<32790 ){
	printf(" PULSE TYPE = %X ",vdr->VAR_VALUE);
	ptype.str("");
	ptype << " PULSE TYPE = ";
	ptype << hex << vdr->VAR_VALUE;
	vdr = (pamela::VarDumpRecord*)vde->Records->At(j+1);	
	printf(" STRIP = %X \n",vdr->VAR_VALUE);
	stno.str("");
	stno << " STRIP = ";
	stno << hex << vdr->VAR_VALUE;
      };
    };
  };    
  vdFile->Close();
  //
  TString fififile =  getFilename(filename);
  const char *file = fififile;
  //
  TFile *File = new TFile(filename.Data());
  TTree *tr = (TTree*)File->Get("CalibCalPulse1");
  tr->AddFriend("CalibCalPulse2", File);
  pamela::CalibCalPulse1Event *cee1 = 0;   
  pamela::CalibCalPulse2Event *cee = 0;   
  pamela::EventHeader *ceh = new pamela::EventHeader(); 
  tr->SetBranchAddress("Header", &ceh);
  tr->SetBranchAddress("CalibCalPulse1", &cee1);
  tr->SetBranchAddress("CalibCalPulse2", &cee);
  //
  Long64_t ncalibs    = tr->GetEntries();
  //
  TCanvas *figura2 = new TCanvas("Calorimeter_tracks", "Calorimeter_tracks", 750, 650);
  figura2->SetFillColor(10);
  //
  Int_t ci = 0;
  int stoppa = 0;
  while ( ci < ncalibs ){
    stoppa = 0;
    int per = 0;
    figura2->Clear();
    figura2->Range(0,0,100,100);
    stringstream errore;
    //figura2->SetFillColor(10);
    errore.str("");
    errore << "EXPERT  --  File: " << file;
    errore << " ";
    TLatex *t=new TLatex();
    t->SetTextFont(32);
    t->SetTextColor(1);
    t->SetTextAlign(12);
    t->SetTextSize(0.015);
    t->DrawLatex(2.,99.,errore.str().c_str());
    //
    // Book the histograms:
    //
    stringstream xview;
    xview.str("");
    xview << "x-view event " << (ci+1);
    stringstream yview;
    yview.str("");
    yview << "y-view event " << (ci+1);
    gDirectory->Delete(xview.str().c_str());
    gDirectory->Delete(yview.str().c_str());
    TH2F *Xview = new TH2F(xview.str().c_str(),"",96,-0.5,95.5,22,-0.5,21.5);
    TH2F *Yview = new TH2F(yview.str().c_str(),"",96,-0.5,95.5,22,-0.5,21.5);	
    //
    // figures:
    //
    Int_t bgcolor = 10;
    t=new TLatex();
    t->SetTextFont(32);
    t->SetTextColor(1);
    t->SetTextSize(0.03);
    t->SetTextAlign(12);
    //
    TPad *pd1 = new TPad("pd1","This is pad1",0.02,0.05,0.88,0.49,bgcolor);
    TPad *pd2 = new TPad("pd2","This is pad2",0.02,0.51,0.88,0.95,bgcolor);
    TPad *palette = new TPad("palette","This is palette",0.90,0.05,0.98,0.9,bgcolor);
    figura2->cd();
    t=new TLatex();
    t->SetTextFont(32);
    t->SetTextColor(1);
    t->SetTextSize(0.03);
    t->SetTextAlign(12);
    t->DrawLatex(92.,92.5,"MIP");
    pd1->Range(0,0,100,100);
    pd2->Range(0,0,100,100);
    palette->Range(0,0,100,100);
    pd1->SetTicks();
    pd2->SetTicks();
    pd1->Draw();
    pd2->Draw();
    palette->Draw();
    palette->cd();
    // palette
    TPaveLabel *box1 = new TPaveLabel(2,2,98,16.3,"0","");
    box1->SetTextFont(32);
    box1->SetTextColor(1);	
    box1->SetTextSize(0.25);	
    box1->SetFillColor(10);
    box1->Draw();
    TPaveLabel *box2 = new TPaveLabel(2,18.3,98,32.66,"0-2","");
    box2->SetTextFont(32);
    box2->SetTextColor(1);		
    box2->SetTextSize(0.25);	
    box2->SetFillColor(38);
    box2->Draw();
    TPaveLabel *box3 = new TPaveLabel(2,34.66,98,48.96,"2-10","");
    box3->SetTextFont(32);
    box3->SetTextColor(1);	
    box3->SetTextSize(0.25);	
    box3->SetFillColor(4);
    box3->Draw();
    TPaveLabel *box4 = new TPaveLabel(2,50.96,98,65.26,"10-100","");
    box4->SetTextFont(32);
    box4->SetTextColor(1);	
    box4->SetTextSize(0.25);	
    box4->SetFillColor(3);
    box4->Draw();
    TPaveLabel *box5 = new TPaveLabel(2,67.26,98,81.56,"100-500","");
    box5->SetTextFont(32);
    box5->SetTextColor(1);	
    box5->SetTextSize(0.2);	
    box5->SetFillColor(2);
    box5->Draw();
    TPaveLabel *box6 = new TPaveLabel(2,83.56,98,97.86,">500","");
    box6->SetTextFont(32);
    box6->SetTextColor(1);	
    box6->SetTextSize(0.25);	
    box6->SetFillColor(6);
    box6->Draw();
    figura2->cd();
    gStyle->SetOptDate(1);
    pd1->cd();	   
    gStyle->SetOptStat(0);
    Xview->SetXTitle("strip");
    Xview->SetYTitle("X - plane");
    Xview->GetYaxis()->SetTitleOffset(0.5);
    Xview->SetFillColor(bgcolor);	    
    Xview->Fill(1.,1.,1.);	    
    Xview->Draw("box");
    pd1->Update();
    pd2->cd();
    gStyle->SetOptStat(0);
    Yview->SetXTitle("strip");
    Yview->SetYTitle("Y - plane");
    Yview->GetYaxis()->SetTitleOffset(0.5);	
    Yview->SetFillColor(bgcolor);	    
    Yview->Fill(1.,1.,1.);	    
    Yview->Draw("box");
    pd2->Update();
    //	
    Int_t m = 0;
    Int_t l = 3;
    Int_t ss = 0;
    Float_t estrip = 0.;
    for ( Int_t s=0 ; s<4 ;s++  ){
      tr->GetEntry(ci);	
      if ( cee->unpackError  ){
	per = 1;
      } else {
	if ( s == 0 ) ss = 0;
	if ( s == 1 ) ss = 2;
	if ( s == 2 ) ss = 3;
	if ( s == 3 ) ss = 1;	       		
	per = 0;
	for ( Int_t d=0 ; d<11 ;d++  ){
	  Int_t pre = -1;
	  for ( Int_t j=0; j<96 ;j++){
	    figura2->cd();
	    if ( j%16 == 0 ) pre++;			
	    estrip = 0.;
	    if ( s == 2 ) m = 2*d+1;
	    if ( s == 3 ) m = 2*d;
	    if ( s == 0 ) m = 2*d;
	    if ( s == 1 ) m = 2*d+1;
	    if ( s == 3 ) l = 0;
	    if ( s == 2 ) l = 0;
	    if ( s == 1 ) l = 1;
	    if ( s == 0 ) l = 1;	
	    estrip = (cee->calpuls[ss][d][j]-cee1->calpuls[ss][d][j])/26.;
	    if ( estrip > 0.7 ){
	      xview.str("");
	      xview << "x-view event " << j;
	      xview << " " << m;
	      xview << " " << l;
	      yview.str("");
	      yview << "y-view event " << j;
	      yview << " " << m;
	      yview << " " << l;
	      gDirectory->Delete(xview.str().c_str());
	      gDirectory->Delete(yview.str().c_str());
	      TH2F *Xview = new TH2F(xview.str().c_str(),"",96,-0.5,95.5,22,-0.5,21.5);
	      TH2F *Yview = new TH2F(yview.str().c_str(),"",96,-0.5,95.5,22,-0.5,21.5);	
	      Int_t colo;
	      ColorMIP(estrip,colo);
	      Xview->SetFillColor(colo);
	      Yview->SetFillColor(colo);
	      if ( l == 0 ) {
		Xview->Fill(j,m,1.);
		pd1->cd();				    
		Xview->Draw("box same");
	      };				    
	      if ( l == 1 ) {
		Yview->Fill(j,m,1.);
		pd2->cd();
		Yview->Draw("box same");
	      };				
	    };	       
	    if ( cee->calpuls[s][d][j] != 0. ) {
	      stoppa = 1;
	    };
	    if ( cee->calpuls[s][d][j] < 0. ) workornot = 0;
	  };
	};
      };
      ci++;
    };
    if ( !per ){
      pd1->Update();
      pd2->Update();
      figura2->Modified();
      figura2->Update();
      stringstream figsave;
      figsave.str("");
      figsave << "pulsematra2_";
      figsave << ci;
      if ( tosave ) PrintFigure(filename,outDir,figsave.str().c_str(),saveas,*figura2);
    };
  };
  if ( stoppa ){
    if ( workornot ){
      printf("File %s is ok \n",filename.Data());
    } else {
      printf("File %s is NOT OK! \n",filename.Data());
    };
  };
}
