//
//   Look for calibrations in the file - Emiliano Mocchiutti
//
//   CaloFINDCALIBS.c      version 2.06  (2005-11-16)
//
//   The only input needed is the path to the directory created by YODA for the data file you want to analyze.
//
//   Changelog:
//
//   2.05 - 2.06 (2005-11-16): compiled!
//
//   2.04 - 2.05 (2005-08-04): changes to fix bugs using 64 bit architecture.
//
//   2.03 - 2.04 (2005-07-25): Don't load anymore yodaUtility.c use clone of routines instead
//
//   2.02 - 2.03 (2005-06-28): Inserted in the new software architecture.
//
//   2.01 - 2.02 (2005-06-07): Check if file is older than 050515_007.
//
//   2.00 - 2.01 (2005-06-06): Added CaloMySQLFINDCALIBS script to look at calibrations using MySQL database (corrispondent to CaloFINDCALIBS).
//
//   1.05 - 2.00 (2005-05-31): Added CaloMySQLFILLCALIBS program to fill the MySQL database with calorimeter calibration informations.
//
//   1.04 - 1.05 (2005-05-17): Changes according to the changes to CaloFindCalibs subroutine.
//
//   1.03 - 1.04 (2005-04-06): Changes according to the new CaloFindCalibs subroutine.
//
//   1.02 - 1.03 (2005-02-24): Changed variable definition from C/C++ style to ROOT style (int->Int_t).
//
//   1.01 - 1.02 (2005-01-17): Cleanup of the code
//
//   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 <calomysqlstruct.h>
#if !defined (__CINT__)				
#include <event/PamelaRun.h>
#include <event/physics/calorimeter/CalorimeterEvent.h>
#include <event/physics/trigger/TriggerEvent.h>
#include <event/CalibCalPedEvent.h>
#include <caloclasses.h>
extern short int cquerymysql(char [], const char []);
extern short int creadmysql(char [], char const [], struct Mystruct &);
#endif
#include <CaloFunctions.h>

void CaloFINDCALIBS(TString filename){
    gROOT->GetListOfCanvases()->Delete();
    gDirectory->GetList()->Delete();
    emicheckLib();
    struct Calib calib;
    //    
    for (Int_t s=0; s<4;s++){
	for (Int_t d = 0; d<51; d++){
	    calib.ttime[s][d] = 0 ;
	    calib.time[s][d] = 0 ;
	};
    };
    //
    // first of all find the calibrations in the file 
    //
    Int_t wused = 0;
    CaloFindCalibs(filename, filename, wused, calib);        
    //
    // print on the screen the results:   
    //
    const char *ffile = filename;		
    printf(" ------ %s ------- \n \n",ffile);	
    Int_t calibex = 0;
    TString pfile;
    for (Int_t s=0; s<4;s++){
	printf(" ** SECTION %i **\n",s);
	for (Int_t d = 0; d<51; d++){
	    if ( calib.ttime[s][d] != 0 ) {
		calibex++;
		if ( calib.fcode[s][d] != 10 ){
		    TString file2 = "";
		    stringcopy(file2,filename);
		    pfile = (TString)whatnamewith(file2,calib.fcode[s][d]);		    
		} else {
		    pfile = (TString)filename;
		};
		const char *ffile = pfile;		
		printf(" - from time %i to time %i use calibration at\n time %i, file: %s \n",calib.time[s][d],calib.time[s][d+1],calib.ttime[s][d],ffile);
	    };
	};
	printf("\n");	
    };
    printf(" ----------------------------------------------------------------------- \n \n");	
    if ( calibex < 4 ) {
	printf("No full calibration data in this file!\n");
    };
    //
    return;
}

void CaloOLDFINDCALIBS(TString filename){
    gROOT->GetListOfCanvases()->Delete();
    gDirectory->GetList()->Delete();
    emicheckLib();
    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");	
    };
    printf(" ---------------------------------------------------------- \n");	
    const char *ffile = filename;
    printf(" %s  \n",ffile);	
    if ( calibex < 4 ) {
	printf("No full calibration data in this file!\n");
    };
    //
    return;
}

void CaloMySQLFILLCALIBS(TString filename, Int_t FORCE = 0){
    gDirectory->GetList()->Delete();
    const char* startingdir = gSystem->WorkingDirectory();
    TString path;
    stringcopy(path,startingdir);
    emicheckLib();
    struct Calib calib;
    struct Mystruct mystruct;
#if defined (__CINT__)		
    const char *pam_lib=gSystem->Getenv("PAM_LIB");
    stringstream libload;
    libload.str("");
    libload << pam_lib << "/libqumy";
    gSystem->Load(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libqumy_C";
    gSystem->Load(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libreadmy";
    gSystem->Load(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libreadmy_C";
    gSystem->Load(libload.str().c_str());
#endif
    printf("\n");
    Int_t wused = 0;
    TString nfilen;
    Int_t calibex = 0;
    TString pfile;
    const char *ffile;
    Int_t chkmysql = 0;
    calib.db = "romemuons";
    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 *file = file2;
    //    char *file = 0;
    //file = "dw_000000_000";
    //char *file0 = filename;
    //string fil = filename;
    //Int_t posiz = fil.find("dw_");
    //if ( posiz == -1 ) posiz = fil.find("DW_");
    //if ( posiz == -1 ) return;
    //memcpy(file, file0+posiz, 13);
    stringstream tablename;
    tablename.str("");
    tablename << "calocalib_" << file;
    TString tabula;
    tabula = tablename.str().c_str();
    const string myfil = (const char *)filename;
    Int_t myposiz = myfil.find("dw_");
    if ( myposiz == -1 ) myposiz = myfil.find("DW_");
    if ( myposiz == -1 ) return;
    stringcopy(calib.basepath,filename,0,myposiz);
    // 
    // check existence of database
    //
    printf("Check existence of database %s...\n",calib.db);
    stringstream qy;
    qy.str("");
    qy << "use " << calib.db;    
    chkmysql = cquerymysql(calib.db,qy.str().c_str());	
    if ( chkmysql ) {
	printf(" - the database %s does not exists -\nCreating database %s ... \n",calib.db,calib.db);
	qy.str("");
	qy << "create database " << calib.db;
	chkmysql = cquerymysql("mysql",qy.str().c_str());	
	if ( chkmysql ) {
	    if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
	    if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
	    printf("ERROR: problems querying MySQL database! \nExiting...\n");
	    goto end;
	} else {
	    printf("...done!\n\n");
	};
    } else {
	printf("...OK it exists! \n\n");
    };
    //
    if ( !FORCE ){
	printf("Not in FORCE mode, check existence of table %s...\n",tablename.str().c_str());
	// 
	// if not in force mode check if calibration exists and contains any data:
	//
	qy.str("");
	qy << "select * from " << tablename.str().c_str();
	chkmysql = creadmysql(calib.db,qy.str().c_str(),mystruct);	
	if ( chkmysql || mystruct.totime == -1 ) {
	    if ( chkmysql == 1 || chkmysql == 2 ){
		if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
		if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
		goto end;
	    };
	    if ( mystruct.totime == -1 ){
		printf("- the table exists but it is empty, dropping empty table...\n");
		qy.str("");
		qy << "drop table " << tablename.str().c_str();		
		chkmysql = cquerymysql(calib.db,qy.str().c_str());	
		if ( chkmysql ) {
		    if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
		    if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
		    printf("ERROR: problems querying MySQL database! \nExiting...\n");
		    goto end;
		} else {
		    printf("...done!\n\n");
		    chkmysql = 3;
		};	
	    };
	    if ( chkmysql == 3 ){
		printf("- the table %s does not exists - \nCreating calibration table %s ... \n",tablename.str().c_str(),tablename.str().c_str());

		qy.str("");
		qy << "create table " << tablename.str().c_str();
		qy << " ( id int auto_increment not null, section tinyint(1) unsigned zerofill default '0' not null, obtjump tinyint(1) unsigned zerofill default '0' not null,  fromtime int(30) unsigned default '0' not null, totime int(30) unsigned default '0' not null, calibtime int(30) unsigned default '0' not null, calcalibfile varchar(25) default '' not null, primary key (id) )";
		chkmysql = cquerymysql(calib.db,qy.str().c_str());	
		if ( chkmysql ) {
		    if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
		    if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
		    printf("ERROR: problems querying MySQL database! \nExiting...\n");
		    goto end;
		} else {
		    printf("...done!\n\n");
		};
	    };
	} else {
	    printf("- the table exists -\nExiting! Use FORCE = 1 to override \n\n");
	    goto end;
	};
    } else {
	// 
	// if in force mode drop the old table
	//       
	qy.str("");
	qy << "drop table " << tablename.str().c_str();	
	chkmysql = cquerymysql(calib.db,qy.str().c_str());	
	qy.str("");
	qy << "create table " << tablename.str().c_str();
	qy << " ( id int auto_increment not null, section tinyint(1) unsigned zerofill default '0' not null, obtjump tinyint(1) unsigned zerofill default '0' not null,  fromtime int(30) unsigned default '0' not null, totime int(30) unsigned default '0' not null, calibtime int(30) unsigned default '0' not null, calcalibfile varchar(25) default '' not null, primary key (id) )";
	printf("Creating calibration table %s ... \n",tablename.str().c_str());
	chkmysql = cquerymysql(calib.db,qy.str().c_str());	
	if ( chkmysql ) {
	    if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
	    if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
	    printf("ERROR: problems querying MySQL database! \nExiting...\n");
	    goto end;
	} else {
	    printf("...done!\n");
	};
    };
    //
    for (Int_t s=0; s<4;s++){
	for (Int_t d = 0; d<51; d++){
	    calib.ttime[s][d] = 0 ;
	    calib.time[s][d] = 0 ;
	};
    };
    //
    // first of all find the calibrations in the file 
    //
    wused = 0;
    stringcopy(nfilen,filename);
    CaloFindCalibs(nfilen, nfilen, wused, calib);        
    //
    // print on the screen the results:   
    //
    ffile = (const char *)nfilen;		
    printf(" ------ %s ------- \n \n",ffile);	
    calibex = 0;
    file2 = "";
    for (Int_t s=0; s<4;s++){
	printf(" ** SECTION %i **\n",s);
	for (Int_t d = 0; d<51; d++){
	    if ( calib.ttime[s][d] != 0 ) {
		calibex++;
		if ( calib.fcode[s][d] != 10 ){
		    file2 = "";
		    stringcopy(file2,nfilen);
		    pfile = (TString)whatnamewith(file2,calib.fcode[s][d]);		    
		} else {
		    pfile = (TString)nfilen;
		};

		//		char *mfile = 0;
		//mfile = "dw_000000_000";
		//char *mfile0 = pfile;
		//string mfil = pfile;
		//Int_t posiz = fil.find("dw_");
		//if ( posiz == -1 ) posiz = fil.find("DW_");
		//if ( posiz == -1 ) return;
		//memcpy(mfile, mfile0+posiz, 13);

		const string fil = (const char*)pfile;
		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 *mfile = file2;
		stringstream tablefilename;
		tablefilename.str("");
		tablefilename << mfile;

		//
		const char *caliba=calib.basepath;
		printf(" - from time %i to time %i use calibration at\n time %i, file: %s%s00 \n",calib.time[s][d],calib.time[s][d+1],calib.ttime[s][d],caliba,tablefilename.str().c_str());
		stringstream myquery;
		myquery.str("");
		const char *tabula2 = tabula;
		//
		myquery << "insert into " << tabula2;
		myquery << " values (0," << s;
		myquery << "," << calib.obtjump;
		myquery << "," << calib.time[s][d];
		myquery << "," << calib.time[s][d+1];
		myquery << "," << calib.ttime[s][d];
		myquery << ",\"" << tablefilename.str().c_str();
		myquery << "\")";
		Int_t chkmysql = cquerymysql(calib.db,myquery.str().c_str());		
		if ( chkmysql ) {
		    if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
		    if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
		    printf("ERROR: problems querying MySQL database! \nExiting...\n");
		    goto end;
		};
	    };
	};
	printf("\n");	
    };
    printf(" ----------------------------------------------------------------------- \n \n");	
    if ( calibex < 4 ) {
	printf("No full calibration data in this file!\n");
    };
    //
 end:
#if defined (__CINT__)		
    char *pam_lib=gSystem->Getenv("PAM_LIB");
    libload.str("");
    libload << pam_lib << "/libreadmy";    
    gSystem->Unload(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libreadmy_C";    
    gSystem->Unload(libload.str().c_str());
    char *pam_lib=gSystem->Getenv("PAM_LIB");
    stringstream libload;
    libload.str("");
    libload << pam_lib << "/libqumy";    
    gSystem->Unload(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libqumy_C";    
    gSystem->Unload(libload.str().c_str());
#endif
    return;
}

void CaloMySQLFINDCALIBS(TString filename){
    emicheckLib();
    const char* startingdir = gSystem->WorkingDirectory();
    TString path;
    stringcopy(path,startingdir);
    struct Calib calib;
    struct Mystruct mystruct;
    //
    const string myfil = (const char *)filename;
    Int_t myposiz = myfil.find("dw_");
    if ( myposiz == -1 ) myposiz = myfil.find("DW_");
    if ( myposiz == -1 ) return;

    stringcopy(calib.basepath,filename,0,myposiz);
    stringcopy(calib.yodalev,filename,myposiz+13,myposiz+15);
    //
    calib.mysql = 1;
    //
#if defined (__CINT__)	
    const char *pam_lib=gSystem->Getenv("PAM_LIB");
    stringstream libload;
    libload.str("");
    libload << pam_lib << "/libreadmy";
    gSystem->Load(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libreadmy_C";
    gSystem->Load(libload.str().c_str());
#endif
    Int_t chkmysql = 0;
    calib.db = "romemuons";
    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 *file = file2;
    stringstream tablename;
    tablename.str("");
    tablename << "calocalib_" << file;
    //
    Int_t calibex = 0;
    Int_t etime = 0;
    const char *ffile = filename;		
    //
    stringstream qy;
    qy.str("");
    printf("\nTry the connection to the MySQL database in Trieste...\n");
    qy << "select * from " << tablename.str().c_str();
    chkmysql = creadmysql(calib.db,qy.str().c_str(),mystruct);	
    if ( chkmysql || mystruct.totime == -1 ) {
	printf("\n- ERROR: problems querying MySQL database! -\n\n- ERROR: Cannot use the MySQL database! -\n\n");
	if ( mystruct.totime == -1 ) printf("- ERROR: it seems there are no data in table called %s -\n\n",tablename.str().c_str());
	if ( chkmysql == 1 ) printf("- ERROR: problems in MySQL initialization -\n\n");
	if ( chkmysql == 2 ) printf("- ERROR: problems in MySQL login, check username and password -\n\n");
	if ( chkmysql == 3 ) printf("- ERROR: it seems there is no table called %s -\n\n",tablename.str().c_str());
	gSystem->ChangeDirectory(path);
	goto veryend;
    } else {
	printf("...OK the connection is fine! \n\n Using database \"%s\", table \"%s\"\n\n",calib.db,tablename.str().c_str());
    };
    calib.tablename = tablename.str().c_str();

    calib.obtjump = 0;
    calib.time[0][0] = -1;
    calib.time[1][0] = -1;
    calib.time[2][0] = -1;
    calib.time[3][0] = -1;
    calibex = 0;
    etime = 0;    		
    printf(" ------ %s ------- \n \n",ffile);	
    //    stringstream qy;
    qy.str("");
    const char *caliba;
    const char *yodala;
    const char *fila;
    for (Int_t s = 0; s < 4; s++){
	etime = 0;
	printf(" ** SECTION %i **\n",s);
	while ( etime > -1 ){
	    if ( !calib.obtjump ){
		if ( etime > calib.time[s][0] ){
		    Int_t chkmysql = 0;
		    stringstream myfile;
		    const char *tabula = calib.tablename;
		    qy.str("");
		    qy << "select * from " << tabula;
		    qy << " where section = " << s;
		    qy << " and fromtime >= " << calib.time[s][0];
		    qy << " limit 1";
		    chkmysql = creadmysql(calib.db,qy.str().c_str(),mystruct);	
		    if ( mystruct.totime == -1 ){
			etime = -2;
			goto notend;
		    };
		    if ( chkmysql ) {
			printf("- ERROR: problems querying MySQL database! -\n- ERROR: Empty table? -\n\n");
			goto veryend;
		    } else {
			calib.time[s][0] = mystruct.totime;
			calib.time[s][1] = mystruct.fromtime;
			calib.ttime[s][0] = mystruct.calibtime;
			caliba = calib.basepath;
			yodala = calib.yodalev;
			fila = mystruct.calcalibfile;
			myfile.str("");
			myfile << caliba;
			myfile << fila;
			myfile << yodala << "/";
			calib.obtjump = mystruct.obtjump;
			printf(" - From time %i to time %i use calibration at\ntime %i, file: %s\n",calib.time[s][1],calib.time[s][0],calib.ttime[s][0],myfile.str().c_str());
			calibex++;
		    };
		    Int_t pedeerr = 0;
		    pedeerr = CaloPede(myfile.str().c_str(),s,calib.ttime[s][0],calib);
		    if ( pedeerr ) {
			printf("\n\nERROR: problems opening calibration file! \n\nERROR: YODA version of the calibration file is not %s? \n\n",yodala);
			goto veryend;
		    };		    
		};
	    };
	    etime = calib.time[0][0]+1;
	notend:
	    printf(" ");
	};
	printf("\n");
    };
    printf(" ----------------------------------------------------------------------- \n \n");	
    if ( calibex < 4 ) {
	printf("No full calibration data in this file!\n");
    };
 veryend:
#if defined (__CINT__)	
    gSystem->ChangeDirectory(path);
    char *pam_lib=gSystem->Getenv("PAM_LIB");    
    libload.str("");
    libload << pam_lib << "/libreadmy";    
    gSystem->Unload(libload.str().c_str());
    libload.str("");
    libload << pam_lib << "/libreadmy_C";    
    gSystem->Unload(libload.str().c_str());
#endif
    return;
}
