//
//   Shows calorimeter tracks - Emiliano Mocchiutti
//
//   CaloMATRA.c      version 3.00 (2005-11-23)
//
//   The only input needed is the path to the directory created by YODA for the data file you want to analyze.
//
//   Changelog:
//
//   2.12 - 3.00 (2005-11-23): now it can be run as a compiled program with graphic output!
//
//   2.11 - 2.12 (2005-11-15): compiled!
//
//   2.10 - 2.11 (2005-08-16): 64 bit arch bugs fixed.
//
//   2.09 - 2.10 (2005-07-25): don't load anymore yodaUtility.c use instead clones of routines.
//
//   2.08 - 2.09 (2005-07-12): small changes for compilation
//
//   2.07 - 2.08 (2005-06-28): changed to be inserted in package CaloQLOOK.
//
//   2.06 - 2.07 (2005-06-07): check if file is older than 050515_007.
//
//   2.05 - 2.06 (2005-04-07): changed tree name of level1 data.
//
//   2.04 - 2.05 (2005-03-30): changed call to WhatToDo subroutine according to the changes in WhatToDo
//
//   2.03 - 2.04 (2005-03-09): saveas input parameter introduced (required by Maurizio).
//
//   2.02 - 2.03 (2005-02-24): Changed colour background (required by Marco Casolino).
//
//   2.01 - 2.02 (2005-02-24): Changed variable definition from C/C++ style to ROOT style (int->Int_t).
//
//   2.00 - 2.01 (2005-02-07): User interaction routine changed. Maxevent bug fixed. Change default name for printed files.
//
//   1.04 - 2.00 (2005-01-20): Now it will access directly LEVEL1 ntuple instead of calibrating everything everytime.
//
//   1.03 - 1.04 (2005-01-17): Upgrade in the user-interaction capability and cleanup of the code
//
//   1.02 - 1.03 (2004-12-20): canvas is created once and then cleared.
//
//   1.01 - 1.02 (2004-12-17): bugs fixed and include the possibility of using a old calibration file to see the data
//
//   1.00 - 1.01 (2004-12-15): Include also yodaUtility.c
//
#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 <TApplication.h>
#if !defined (__CINT__)				
#include <event/PamelaRun.h>
#include <event/physics/calorimeter/CalorimeterEvent.h>
#include <event/physics/trigger/TriggerEvent.h>
#include <event/CalibCalPedEvent.h>
extern short int CaloLEVEL1(TString, TString, Int_t);
#include <caloclasses.h>
#endif
#include <CaloFunctions.h>

void CaloMATRA(TString filename, Int_t fromevent = 1, Int_t toevent = 0, TString tyhist="box", TString outDir = "", TString saveas = "gif"){
    gROOT->GetListOfCanvases()->Delete("a");
    gDirectory->GetList()->Delete();
    const char* startingdir = gSystem->WorkingDirectory();
    Int_t doflag = 1;
#if !defined (__CINT__)	
    TApplication app("app",0,0);
#endif
#if defined (__CINT__)	
    emicheckLib();
    stringstream llib;
    const char *pamlib = gSystem->ExpandPathName("$PAM_LIB");
    llib << pamlib << "/caloclasses_h.so"; 
    gSystem->Load(llib.str().c_str());
#endif
    if ( outDir == "" ) outDir = filename;
    //
    // Open LEVEL1 ntuple, if it doesn't exist call CaloLEVEL1.
    //
    TFile       *headerFile = 0;
    TFile       *caloFile = 0;
    headerFile = emigetFile(filename, "Physics", "Header");
    if ( !headerFile ){
    	printf("No header file, exiting...\n");
    	return;
    };
    caloFile = emigetFile(filename, "Physics.Level1", "Calorimeter");
    if ( !caloFile ){
	printf("\n WARNING: No calorimeter LEVEL1 file! \n\n I am going to call CaloLEVEL1, it could take some time to generate level1 data. \n\n");	
	headerFile->Close();
	gSystem->Exec("sleep 3");
	short int ERR = CaloLEVEL1(filename,"",0);	
	if ( ERR ) {
	    printf("\n I am not able to calibrate data, please call CaloLEVEL1 by hand \n\n Exiting... \n\n");
	    return;
	} else {
	    printf(" OK, back to CaloMATRA! \n\n");
	    headerFile = emigetFile(filename, "Physics", "Header");
	    caloFile = emigetFile(filename, "Physics.Level1", "Calorimeter");
	};
    };
    //Takes the tree of the header file
    TTree *otr = (TTree*)headerFile->Get("Pscu");
    otr->AddFriend("CaloLevel1",caloFile);
    //    
    CalorimeterLevel1 *calo = new CalorimeterLevel1();
    otr->SetBranchAddress("Event", &calo);
    //
    Long64_t nevents    = otr->GetEntries();
    stringstream titolo;
    //    char *titolo=" looong long line as workaround since root is not working other ways";
    //    char *stringa=" looong long line as workaround since root is not working other ways";
    stringstream stringa;
    //TString *file[17];
    //file = "dw_000000_000.dat";
    //file = getFilename(filename);
    TString fififile =  getFilename(filename);
    const char *file = fififile;
    //    
    //
    // input limits
    //
    if ( tyhist != "box" && tyhist != "lego" ) {
	printf("You can choose tyhist as box (default) or lego \n");
	return;
    };

    if ( fromevent > toevent && toevent ){
	printf("It must be fromevent < toevent \n");
	return;
    };


    if ( fromevent > nevents+1 || fromevent < 0 ) {
	printf("You can choose fromevent between 0 (all) and %i \n",(int)nevents+1);
	return;
    };

    if ( toevent > nevents+1 || toevent < 0 ) {
	printf("You can choose toevent between 0 (all) and %i \n",(int)nevents+1);
	return;
    };
    Int_t minevent = 0;
    Int_t maxevent = nevents;
    if ( fromevent == 0 ) {
	minevent = 0;
	maxevent = nevents;
    } else {
	minevent = fromevent - 1;
	if ( toevent > 0 ){
	    maxevent = toevent - 1;
	} else {
	    maxevent = fromevent -1;
	};
    };

    //
    // run over all the events
    //
    TCanvas *figura2 = new TCanvas("Calorimeter_tracks", "Calorimeter_tracks", 750, 650);
    figura2->SetFillColor(10);
    figura2->Range(0,0,100,100);
    Int_t i = minevent;
    while ( i < maxevent+1 ){
	figura2->Clear();
	//
	// variables definition
	//
	Int_t badstrip = 0;
	//
	// Book the histograms:
	//
	//
	stringstream xview;
	xview.str("");
	xview << "x-view event " << (i+1);
	stringstream yview;
	yview.str("");
	yview << "y-view event " << (i+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;
	TLatex *t=new TLatex();
	t->SetTextFont(32);
	t->SetTextColor(1);
	t->SetTextSize(0.03);
	t->SetTextAlign(12);
	titolo.str("");
	titolo << "Calorimeter tracks - file " << file;
	titolo << " - event number " << (i+1);
	//	sprintf(titolo,"Calorimeter tracks - file %s - event number %i ",file,i+1);	
	t->DrawLatex(0.5,97.,titolo.str().c_str());
	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);
	if ( tyhist == "box" ) {
	    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(tyhist);
	    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(tyhist);
	    pd2->Update();
	};
	//
	// read from the header of the event the absolute time at which it was recorded
	//
	otr->GetEntry(i);
	//
	// run over views and planes
	//
	for (Int_t m = 0; m < 22; m++){
	    for (Int_t l = 0; l < 2; l++){
		for (Int_t n = 0; n < 96; n++){
		    if ( calo->estrip[l][m][n] > 0.7 ) {
			//
			// OK, now in estrip we have the energy deposit in MIP of all the strips for this event (at the end of loops of course)
			//			
			if ( tyhist == "box" ){
			    xview.str("");
			    xview << "x-view event " << n;
			    xview << " " << m;
			    xview << " " << l;
			    yview.str("");
			    yview << "y-view event " << n;
			    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(calo->estrip[l][m][n],colo);
			    Xview->SetFillColor(colo);
			    Yview->SetFillColor(colo);
			    if ( l == 0 ) {
				Xview->Fill(n,m,1.);
				pd1->cd();				    
				Xview->Draw("box same");
			    };				    
			    if ( l == 1 ) {
				Yview->Fill(n,m,1.);
				pd2->cd();
				Yview->Draw("box same");
			    };
			} else {			    
			    if ( l == 0 ) Xview->Fill(n,m,calo->estrip[l][m][n]);
			    if ( l == 1 ) Yview->Fill(n,m,calo->estrip[l][m][n]);						    
			};
			if ( calo->good[l][m][n] != 0  ) badstrip++;
		    };		
		};
	    };
	};
	//
	figura2->cd();
	t=new TLatex();
	t->SetTextFont(32);
	t->SetTextColor(8);
	t->SetTextAlign(12);
	t->SetTextSize(0.02);
	Int_t qtot = (int)calo->qtot;
	Int_t nstrip = (int)calo->nstrip;
	stringa.str("");
	stringa << "QTOT = " << qtot;
	stringa << "          NSTRIP = " << nstrip;
	stringa << "          Bad strips = " << badstrip;
	stringa << " ";
	//sprintf(stringa,"QTOT = %i          NSTRIP = %i          Bad strips = %i ",qtot,nstrip,badstrip);	
	t->DrawLatex(30.,2.,stringa.str().c_str());
	figura2->Update();
	if ( tyhist == "lego" ){
	    pd1->cd();
	    gStyle->SetOptStat(0);
	    Xview->SetXTitle("strip");
	    Xview->SetYTitle("X - plane");
	    Xview->GetXaxis()->SetTitleOffset(1.5);
	    Xview->GetYaxis()->SetTitleOffset(1.5);
	    Xview->SetZTitle("MIP");	
	    Xview->Draw(tyhist);
	    pd1->Update();
	    pd2->cd();
	    gStyle->SetOptStat(0);
	    Yview->SetXTitle("strip");
	    Yview->SetYTitle("Y - plane");
	    Yview->GetXaxis()->SetTitleOffset(1.5);
	    Yview->GetYaxis()->SetTitleOffset(1.5);
	    Yview->SetZTitle("MIP");
	    Yview->Draw(tyhist);
	    pd2->Update();
	};
	pd1->Update();
	pd2->Update();
	figura2->Update();

	//
	// Interact with user: do you want to continue, exit or print the figure?
	//
	if ( i != maxevent ) { 
	    TString figty = "matra";
	    doflag = 1;
	    Float_t lastevno = 0;
	    Float_t firstevno = 0;
	    Int_t jumpto = 0;
	    Int_t ifout = WhatToDo(i,doflag, jumpto,nevents,lastevno,firstevno,file,outDir,figty,*figura2);	    
	    if ( maxevent < i+1 ) {
		maxevent = nevents;
		printf("WARNING: you have chosen an event number out of the starting range.\n         Range extended to %i\n\n",maxevent);		
	    };
	    if ( ifout ) return;
	} else {
	    const string fil = (const char*)filename;
	    Int_t posiz = fil.find("dw_");
	    if ( posiz == -1 ) posiz = fil.find("DW_");
	    Int_t posiz2 = posiz+13;
	    TString file2;
	    stringcopy(file2,filename,posiz,posiz2);
	    //
	    const char *figrec = file2;
	    const char *outdir = outDir;
	    stringstream figsave;    
	    const char *format = saveas;
	    figsave.str("");
	    figsave << outdir << "/" ;
	    figsave << figrec << "_matra_";
	    figsave << (i+1) << ".";
	    figsave << format;
	    //
	    figura2->SaveAs(figsave.str().c_str());

	    //	    char *figrec = 0;
	    //figrec = "dw_000000_000";
	    //memcpy(figrec, file, 13);		    
	    //const char *outdir = outDir;
	    //	    char *figsave = 0;
	    //const char *format = saveas;
	    //stringstream figsave;
	    //figsave.str("");
	    //figsave << outdir << "/";
	    //figsave << figrec << "_matra_";
	    //figsave << (i+1) << ".";
	    //figsave << format;
	    //	    figsave = Form("%s/%s_matra_%i.%s",outdir,figrec,i+1,format);	    
	    // figura2->SaveAs(figsave.str().c_str());
	};
	if ( doflag == 2 && i == 0 ) {
	    printf("\n WARNING: Cannot go backward! Going forward. \n");
	    doflag = 1;
	};
	if ( doflag == 2 && i>0 ) i--;
	if ( doflag == 1 ) i++;
	//	app.Run();
    };
    //
    // last warning (if the case)
    //
    figura2->Update();
    printf("\n");
    caloFile->Close();
    gSystem->ChangeDirectory(startingdir);
}
