//
//- Emiliano Mocchiutti
//
//   FCaloCALIBSCAN.cxx      version 1.01  (2006-03-08)
//
//   The only input needed is 
//
//   Changelog:
//
//   1.00 - 1.01  (2006-03-08): Flight version, read unique YODA file.
//
//   0.00 - 1.00  (2006-03-08): Clone of CaloCALIBSCAN.
//
#include <fstream>
#include <sstream>
#include <string>
#include <stdlib.h>
#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 <fcalostructs.h>
//
extern bool existfile(TString);
extern void stringcopy(TString&, const TString&, Int_t, Int_t);
extern TString getFilename(const TString);
//
#include <caloclassesfun.h>
//
using namespace std;
//

short int FCaloCALIBSCAN(TString Filename, TString flist=""){
  const char* startingdir = gSystem->WorkingDirectory();
  TString calcalib;
  struct Calib calib;
  //
  stringstream file5;
  file5.str("");
  file5 << startingdir << "/CaloCALIBdata.root";
  //
  Int_t nfile = 0;
  Int_t calibex = 0;
  Int_t fileup = 0;
  if ( flist != "" ){
    printf("\n You have given an input file list \n\n Files: \n");
    ifstream in;
    in.open(flist, ios::in);
    char ctime[20];
    while (1) {       
      in >> ctime;
      if (!in.good()) break;
      printf(" File number %i = %s \n",nfile+1,ctime);	    
      nfile++;
    };
    in.close();
    if ( !nfile ) {
      printf("\n\n The list is empty, exiting... \n\n");	    
      return(0);
    };
  } else {
    nfile = 1;
  };
  printf("\n");
  //
  // First check if the calibration file exists:
  //
  Int_t EFILE = 0;
  printf(" Check the existence of CaloCALIBdata.root file: \n\n");
  //
  if ( !existfile((TString)file5.str().c_str()) ){
    printf(" %s :no such file or directory \n",file5.str().c_str());
    printf("\n OK, I will create it!\n\n");
    EFILE = 0;
  } else {
    printf(" The file already exists! It will be updated \n\n");
    EFILE = 1;    
  } 
  //
  // this must be done for each file.
  //
  Long64_t neven = 0;
  TTree *trl1 = 0;
  TFile *hfl1 = 0;
  CalorimeterCalibScan *calo = new CalorimeterCalibScan();   
  if ( EFILE == 1 ){
    //
    // If the file doesn't exist create it
    //
    hfl1 = new TFile(file5.str().c_str(),"UPDATE","Calorimeter calib data");
    //    calo = new CalorimeterCalibScan();   
    //
    trl1 = (TTree*)hfl1->Get("CaloCALIBdata");  
    trl1->SetBranchAddress("Event", &calo);		
	neven = trl1->GetEntries()-1;
	trl1->GetEntry(neven);
	calibex = calo->evno;
    } else {
	//
	// If the file doesn't exist create it
	//
	hfl1 = new TFile(file5.str().c_str(),"RECREATE","Calorimeter calib data");
	//
	//	calo = new CalorimeterCalibScan();   
	//
	trl1 = new TTree("CaloCALIBdata","PAMELA calorimeter calibration data");
	trl1->Branch("Event","CalorimeterCalibScan",&calo);	    
    };    
    //
    const char *filename2 = Filename;
    //
    TString lfile;
    TString sfile;
    //
    Int_t e = 0;
    ifstream in;
    in.open(flist, ios::in);
    char ctime[20];
    const char *nome;
    //
    TString fififile;
    const char *file;
    TString filename;
    //
    stringstream lfillo;
    //
    pamela::CalibCalPedEvent *ce = 0;
    pamela::PscuHeader *cph = 0;
    pamela::EventHeader *ceh = 0;
    Long64_t ncalibs = 0;
    Int_t s = -1;
    Int_t l = 0;
    Int_t m = 0;
    Int_t ss = 0;
    TTree *tr = 0;
    TFile *File = 0;
    //
    while ( e < nfile ){
	if ( flist != "" ){
	    in >> ctime;
	    lfillo.str("");
	    lfillo << filename2 << "/";
	    lfillo << ctime;
	    lfile = (TString)lfillo.str().c_str();
	    fififile = getFilename(lfile);
	    file = fififile;
	    lfillo.str("");
	    lfillo << file;
	    sfile = (TString)lfillo.str().c_str();
	} else {
	    lfillo.str("");
	    lfillo << filename2;
	    lfile = (TString)lfillo.str().c_str();
	    fififile = getFilename(lfile);
	    file = fififile;
	    lfillo.str("");
	    lfillo << file;
	    sfile = (TString)lfillo.str().c_str();
	};
	//
	filename = lfile;	
	nome = filename;
	printf("\n Processing file number %i: %s \n\n",e+1,nome);
	//
 	const string fil = (const char *)(gSystem->BaseName(filename));
	Int_t posiz = 0;
// 	Int_t posiz = fil.find("dw_");
// 	if ( posiz == -1 ) posiz = fil.find("DW_");
// 	if ( posiz == -1 ) return(-1);    
	TString filenam2=(TString)(gSystem->BaseName(filename));
 	TString year;
 	stringcopy(year,filenam2,posiz,posiz+5);   
 	const char *ye = year;
 	TString month;
 	stringcopy(month,filenam2,posiz+7,posiz+9);   
 	const char *mo = month;
 	TString day;
 	stringcopy(day,filenam2,posiz+11,posiz+13);   
 	const char *da = day;
// 	TString fno;
// 	stringcopy(fno,filename,posiz+10,posiz+13);   
// 	const char *fn = fno;
 	stringstream unino;
 	unino.str("");
 	unino << ye << mo;
 	unino << da;
// 	unino << da << fn;
	//
	//	stringstream unino;
	//	unino.str("");
	//	unino << (e+1);
	//	unino << ye;
	//
	//	printf("unino is %s \n",unino.str().c_str());
	//
	// upgrade data...
	//    
	if ( !existfile(filename) ){
	  printf(" %s :no such file or directory \n",filename.Data());
	  goto jumpfile;
	};
	File = new TFile(filename.Data());
	//	tr = new TTree;
	tr = (TTree*)File->Get("CalibCalPed");
	tr->SetBranchAddress("Header", &ceh);
	tr->SetBranchAddress("CalibCalPed", &ce);
	ncalibs    = tr->GetEntries();
	if ( ncalibs == 0 ) goto oltre;
	//calo = new CalorimeterCalibScan();
	s = -1;
	l = 0;
	m = 0;	
	calo->Clear();
	for (Int_t ci = 0; ci < ncalibs ; ci++){
	  //    calo = new CalorimeterCalibScan();
	    tr->GetEntry(ci);	
	    //
	    s++;
	    if ( s == 4 ) s = 0;
	    if ( s == 0 ) ss = 0;
	    if ( s == 1 ) ss = 2;
	    if ( s == 2 ) ss = 3;
	    if ( s == 3 ) ss = 1;
	    //
	    if ( s == 0 ){
		Double_t noca = (double)ci/100.;	    
		Double_t calno = atof(unino.str().c_str())+noca;
		calo->calno = calno;
		calibex++;
		calo->evno = calibex;
	    };
	    //
	    //
	    if (ce->cstwerr[s] != 0 && ce->cperror[s] == 0 ) {
		cph = ceh->GetPscuHeader(); 				
		calo->etime[ss] = cph->GetOrbitalTime();
		for ( Int_t d=0 ; d<11 ;d++  ){
		    Int_t pre = -1;
		    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;
		    for ( Int_t j=0; j<96 ;j++){
			if ( j%16 == 0 ) pre++;
			calo->calped[l][m][j] = ce->calped[ss][d][j];
			calo->cstwerr[ss] = ce->cstwerr[s];
			calo->cperror[ss] = ce->cperror[s];
			calo->calgood[l][m][j] = ce->calgood[ss][d][j];
			calo->calthr[l][m][pre] = ce->calthr[ss][d][pre];
			calo->calrms[l][m][j] = ce->calrms[ss][d][j]/4.;
			calo->calbase[l][m][pre] = ce->calbase[ss][d][pre];
			calo->calvar[l][m][pre] = ce->calvar[ss][d][pre];
		    };
		};
	    };
	    //
	    if ( s == 3 ){
		trl1->Fill();
		calo->Clear();
		//		calo = new CalorimeterCalibScan();		
	    };
	};
	//
	//if ( calo ) delete calo;
	//
	fileup++;
	//
	goto oltre;
    jumpfile: printf(" File not processed! \n ");
    oltre:
	if ( File ) File->Close();
	//	if ( tr ) delete tr;
	e++;
    };
    hfl1->Write();
    hfl1->Close();
    return(0);
}
