#define rpc_offline_cxx
#include "rpc_offline.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <string>
#include <cstdio>
#include "TPad.h"
#include "TLegend.h"
#include "TPaveText.h"
#include "TText.h"
#include <math.h>
#include <sys/stat.h>
#include "TGaxis.h"
#include "IniFile.h"

using namespace std;
using std::cout;
using std::endl;
using std::vector;
using std::stringstream;

#define size 20
#define reference_station 1
int FEBS[13][size], run;
float surface = 37800;  //re4/3 area in cm2
string name_set_tn[size], name_set_tw[size], name_set_b[size], etapartition, Trigger_layer;
float hv_set_tn[size], hv_set_tw[size], hv_set_b[size], i_set_tn[size], i_set_tw[size], i_set_b[size], hv_mon_tn[size], hv_mon_tw[size], hv_mon_b[size];
float temperature, humidity, pressure;

int main(int argc, char **argv) {
    
    int feb[13], station;
    char temp1[128], run_config_file[256];
    string rff_conf_line, rff_mat_line, rff_mat_line1, rff_mat_line2, rff_mat_line3, rff_mat_line4;
    string run_str_tmp, run_config;
    string variablestring1, variablestring2, variablestring3, variablestring4, chamber_tn, chamber_tw, chamber_b;
    float curr1, vset1, vmon1, curr2, vset2, vmon2, curr3, vset3, vmon3;
    
    bool verbose_openfile = 0;
    
    stringstream stst;
    ifstream in(argv[1]);
    strcpy(temp1,argv[1]);
    
    if (verbose_openfile) cout << " " << endl << " " << endl << "-----------------------------------------------------" << endl;
    if (verbose_openfile) cout << "Opening file: " << temp1 << endl;
    rpc_offline pa(temp1);
    stst << temp1;
    stst >> run_str_tmp;
    
    
    // Reading the run number
    ifstream runname("/home/user/re4data/TDC/run");
    if (runname.is_open()) {
        while(runname.good()) {
            runname >> run;
        }
    }
    
    
    // Reading the daq info
    run_config = "/home/user/re4data/TDC/daqinfo";
    //run_config = "daqinfo";
    if (verbose_openfile) cout << "Run config file: " << run_config << endl;
    strcpy(run_config_file,run_config.c_str());
    
    ifstream rff(run_config_file);
    if (rff.is_open()) {
        if (verbose_openfile) cout << "Run config file: " << run_config_file << " is opened." << endl;
        
        // This is the header of the daqinfo file
        rff >> variablestring1  >> temperature >> humidity >> pressure;
        if (verbose_openfile) cout << "Temp: " << temperature << " humidity: " << humidity << " pressure: " << pressure << endl;
        
        rff >> variablestring2  >> etapartition >> variablestring3 >> Trigger_layer;
        if (verbose_openfile) cout << "Eta partition: " << etapartition << " trigger: " << Trigger_layer << endl;
        
        getline(rff, rff_conf_line);
        if (verbose_openfile) cout << "reading this line: " << rff_conf_line << endl;
        
        getline(rff, rff_conf_line);
        if (verbose_openfile) cout << "reading this line: " << rff_conf_line << endl;
        
        while(rff.good()) {
            getline(rff, rff_conf_line);
            
            rff >> chamber_tn >> curr1 >> vset1 >> vmon1 >> station;
            rff >> chamber_tw >> curr2 >> vset2 >> vmon2 >> station;
            rff >> chamber_b >> curr3 >> vset3 >> vmon3 >> station;
            rff >> variablestring1  >> feb[1] >> feb[2] >> feb[3] >> feb[4] >> feb[5] >> feb[6] >> feb[7] >> feb[8] >> feb[9] >> feb[10] >> feb[11] >> feb[12];
            
            if (verbose_openfile) cout << " " << endl << " " << endl;
            if (verbose_openfile) cout << "Gap: " << chamber_tn << " current: " << curr1 << " vset: " << vset1 << " vmon1: " << vmon1 << " station=" << station << endl;
            if (verbose_openfile) cout << "Gap: " << chamber_tw << " current: " << curr2 << " vset: " << vset2 << " vmon2: " << vmon2 << " station=" << station << endl;
            if (verbose_openfile) cout << "Gap: " << chamber_b << " current: " << curr3 << " vset: " << vset3 <<  " vmon3: " << vmon3 << " station=" << station << endl;
            if (verbose_openfile) cout << "FEB values: " << feb[1] <<" "<< feb[2] <<" "<< feb[3] <<" "<< feb[4] <<" "<< feb[5] <<" "<< feb[6] <<" "<< feb[7] <<" "<< feb[8] <<" "<< feb[9] <<" "<< feb[10] <<" "<< feb[11] <<" "<< feb[12] << endl;
            
            hv_set_tn[station] = vset1;
            hv_set_tw[station] = vset2;
            hv_set_b[station] = vset3;
            
            hv_mon_tn[station] = vmon1;
            hv_mon_tw[station] = vmon2;
            hv_mon_b[station] = vmon3;
            
            name_set_tn[station] = chamber_tn;
            name_set_tw[station] = chamber_tw;
            name_set_b[station] = chamber_b;
            
            i_set_tn[station] = curr1;
            i_set_tw[station] = curr2;
            i_set_b[station] = curr3;
            
            for ( int ll = 1; ll <= 12; ll++ ) {
                FEBS[ll][station] = feb[ll];
            }
        }
    }
    if (verbose_openfile) cout << "------------------------------ " << endl << " " << endl;
    
    pa.StripProfile();
}

void rpc_offline::StripProfile() {
    
    // Defining variables
    char hname[256], htitle[256], infovalue[512], infovalue0[512], infovalue1[512], infovalue2[512], infovalue3[512], infovalue4[512], infovalue5[512], infovalue55[512], infovalue6[512], stringaexec[100], temp[20];
    char string_temperature[100], string_humidity[100], string_pressure[100], string_feb[100], string_run[100];
    string conf_line, mat_line, titlestring, info, strip_prof_string = "", strip_prof_noise_string = "", clustersizedistr = "", timestamp;
    int map_module, map_module1, map_station, map_start, map_start1, map_finish, map_finish1, trigger_bit = -99, rpctrigger_bit, aModule, aModule1, i_station, noise_windows_min, noise_windows_max, firedchannel, firedchannelA, firedchannelB, firedchannelC, counter=0, kk, nn, jj, canale, temp1, temp2, cluster;
    int max_station, old_station, nicehit=0, nicehitA=0, nicehitB=0, nicehitC=0, counterA=0, counterB=0, counterC=0;
    int trigger_biteta = 0, trg_module = 0;
    int reference_module, reference_module1, reference_map_start, reference_map_finish, reference_map_module1, reference_map_start1, reference_map_finish1;
    float chamber_efficiency[size], chamber_efficiencyA[size], chamber_efficiencyB[size], chamber_efficiencyC[size], noiserate[size], chamber_clustersize, err_eff, err_effA, err_effB, err_effC, err_noise, amountoftime, timewindow, clusterization[128], cosmicrate = 0.5;  //Hz/cm2;
    TH1F *h_Strip[size];
    TH1F *h_Stripnoise[size];
    TH1F *h_clustersize[size];
    struct stat st1;
    struct stat st2;
    FILE *stream;
    
    // Cosmetics settings
    int strip_start = 0, strip_finish = 96, maxbins = 100, csize_max = 200;
    int strip_bin = strip_finish - strip_start;
    int text_xmin = 55, text_xmax = 104, text_ymin = (maxbins - maxbins/3.8), text_ymax = maxbins;
    
    // Variables settings
    int trg_windows_min = -40, trg_windows_max = 40;  // Time window in ns.
    int delaytrg = 5, delayrpctrg = 80;               // Time in ns between: [master trigger] and [small counter] ; [rpc trigger]
    int noisegate = 200, delaynoise = 100;
    int maxprocessable = 0;      			          // Leave zero for automatic, put a value if you like to impose a value
    string site="CERN";					              // This is the site production
    
    // Defining verboses
    bool verbose_trg = 0, verbose_map = 0, verbose_filling = 0, verbose_filling2 = 0, verbose_filling_detailed = 0, verbose_filling_eff_counts = 0;
    bool verbose_dump = 0, verbose_filling_eff_noise = 0, verbose_clustering1 = 0;
    
    
    // Initialization
    for ( kk = 0; kk <= size; kk++ ) {
        chamber_efficiency[kk] = 0;
        chamber_efficiencyA[kk] = 0;
        chamber_efficiencyB[kk] = 0;
        chamber_efficiencyC[kk] = 0;
        noiserate[kk] = 0;
    }
    
    if (fChain == 0) return;
    if( c1 ) delete c1;
    c1 = new TCanvas(3);
    Long64_t nentries = fChain->GetEntriesFast();
    if (maxprocessable > 0) nentries = maxprocessable;
    Long64_t nbytes = 0, nb = 0;
    
    trg_windows_min=trg_windows_min*10;
    trg_windows_max=trg_windows_max*10;
    noise_windows_min = trg_windows_max + delaynoise;
    noise_windows_max = noise_windows_min + noisegate;
    
    
    // Reading the runtime
    ifstream runtime("/home/user/re4data/TDC/runtime");
    if (runtime.is_open()) {
        while(runtime.good()) {
            runtime >> amountoftime;
        }
    }
    
    // Reading the mapping file (retrieving reference station)
    {
        ifstream map_file("/home/user/workspace/rpcupgrade/Offline/mapping.txt");
        if (map_file.is_open()){
            while(map_file.good()){
                map_file >> map_station >> map_module >> map_start >> map_finish >> map_module1 >> map_start1 >> map_finish1;
                if ( map_station == reference_station ) {
                    reference_module = map_module;
                    reference_map_start = map_start;
                    reference_map_finish = map_finish;
                    reference_map_module1 = map_module1 ;
                    reference_map_start1 = map_start1;
                    reference_map_finish1 = map_finish1;
                }
            }
        }
        map_file.close();
        cout << " " << endl;
        cout << " --------------------------" << endl;
        cout << " REFERENCE DETECTOR IS ON STATION " << reference_station << " ( module = " << reference_module << ", " << reference_map_start << "<channel<" << reference_map_finish;
        if ( reference_map_module1 > 0 ) {
            cout << " and module = " << reference_module1 << ", " << reference_map_start1 << "<channel<" << reference_map_finish1 << " )" << endl;
        }
        else {
            cout << " )" << endl;
        }
        cout << " --------------------------" << endl;
        cout << " " << endl;
    }
    
    
    
    // Reading the timewindow
    IniFile * ini = new IniFile( "/home/user/workspace/rpcupgrade/TDC/rpc.ini"  );
    ini->Read();
    cout << "Trigger Windows Width: " << ini->Int( "Module2", "TriggerWindowWidth", 1000 ) << endl;
    timewindow = ini->Int( "Module2", "TriggerWindowWidth", 1000 );
    timewindow=timewindow*25/1000000000;      // expressing time windows in sec:
    
    // Reading the trigger bit
    ifstream conf_file("/home/user/workspace/rpcupgrade/Offline/offline.cfg");
    if (conf_file.is_open()){
        while(conf_file.good()){
            getline(conf_file, conf_line);
            mat_line = "trigger : ";
            if ( ((int)conf_line.find(mat_line))!=-1){
                conf_line.erase(0,mat_line.length());
                trigger_bit = atoi(conf_line.c_str());
            }
            conf_file.close();
        }
    }
    conf_file.close();
    
    // Reading the trigger bit (eta partition)
    ifstream conf_file2("/home/user/workspace/rpcupgrade/Offline/offline_eta.cfg");
    if (conf_file2.is_open()){
        while(conf_file2.good()){
            getline(conf_file2, conf_line);
            mat_line = "trigger : ";
            if ( ((int)conf_line.find(mat_line))!=-1){
                conf_line.erase(0,mat_line.length());
                trigger_biteta = atoi(conf_line.c_str());
            }
            conf_file2.close();
        }
    }
    conf_file2.close();
    
    if (verbose_trg) cout << " " << endl << " " << endl << "-----------------------------------------------------" << endl;
    if (verbose_trg) cout << "Master trigger bit :  " << trigger_bit << endl;
    if (verbose_trg) cout << "Trigger bit (eta patition):  " << trigger_biteta << endl;
    if (verbose_trg) cout << "-----------------------------------------------------" << endl << " " << endl << " " << endl;
    
    
    
    
    // Defining empty template for strip profiles
    ifstream map_file1("/home/user/workspace/rpcupgrade/Offline/mapping.txt");
    if (map_file1.is_open()){
        if (verbose_map) cout << " " << endl;
        while(map_file1.good()){
            
            map_file1 >> map_station >> map_module >> map_start >> map_finish >> map_module1 >> map_start1 >> map_finish1;
            if (verbose_map) cout << " Station: " << map_station << " module=" << map_module << " starting at channel: " << map_start << " and finishing at: " << map_finish << "while module2 is: " << map_module1 << " starting at channel: " << map_start1 << " amd finishing at: " << map_finish1 << endl;
            
            
            
            // Extracting chamber ID
            size_t pos;
            pos = name_set_tn[map_station].find("_tn");
            name_set_tn[map_station] = name_set_tn[map_station].substr (0,pos);
            if (verbose_map) cout << "Forming the tempate for chamber: " << name_set_tn[map_station] << endl;
            
            
            // Forming a nice histogram title for strip profile
            titlestring = "Strips Chamber ID: ";
            titlestring = titlestring + name_set_tn[map_station];
            titlestring = titlestring + " at station: ";
            stringstream sstm;
            sstm << titlestring << map_station;
            titlestring = sstm.str();
            titlestring = titlestring + " TRG: ";
            titlestring = titlestring + Trigger_layer;
            titlestring = titlestring + " (eta=";
            titlestring = titlestring + etapartition;
            titlestring = titlestring + ")";
            strcpy( htitle, titlestring.c_str() );
            h_Strip[map_station] = new TH1F(htitle, htitle, strip_bin, strip_start, strip_finish);
            
            
            // Forming a nice histogram title for cluster size
            titlestring = "Cluster size Chamber ID: ";
            titlestring = titlestring + name_set_tn[map_station];
            titlestring = titlestring + " at station: ";
            stringstream sstm3;
            sstm3 << titlestring << map_station;
            titlestring = sstm3.str();
            titlestring = titlestring + " TRG: ";
            titlestring = titlestring + Trigger_layer;
            titlestring = titlestring + " (eta=";
            titlestring = titlestring + etapartition;
            titlestring = titlestring + ")";
            strcpy( htitle, titlestring.c_str() );
            h_clustersize[map_station] = new TH1F(htitle, htitle, strip_bin, strip_start, strip_finish);
            
            
            // Forming a nice histogram title for noise profile
            titlestring = "Noisy strips Chamber ID: ";
            titlestring = titlestring + name_set_tn[map_station];
            titlestring = titlestring + " at station: ";
            stringstream sstm2;
            sstm2 << titlestring << map_station;
            titlestring = sstm2.str();
            titlestring = titlestring + " TRG: ";
            titlestring = titlestring + Trigger_layer;
            titlestring = titlestring + " (eta=";
            titlestring = titlestring + etapartition;
            titlestring = titlestring + ")";
            strcpy( htitle, titlestring.c_str() );
            h_Stripnoise[map_station] = new TH1F(htitle, htitle, strip_bin, strip_start, strip_finish);
            
            max_station = map_station;
        }
        if (verbose_map) cout << " " << endl;
    }
    map_file1.close();
    
    
    
    // Calculating time of run
    strcpy(stringaexec,"/home/user/re4data/TDC/");
    sprintf(temp, "%d",run);
    strcat(stringaexec,temp);
    strcat(stringaexec,".info");
    int ierr1 = stat (stringaexec,&st1);
    int newdate1 = st1.st_mtime;
    // Writing the current timestamps on a file (do debug)
    //if( (stream = fopen( "/home/user/re4data/TDC/timestamp1", "w" )) != NULL ) {
    //   fprintf (stream, "%d\n",newdate1);
    //   fclose( stream );
    //}
    
    
    strcpy(stringaexec,"/home/user/re4data/TDC/");
    sprintf(temp, "%d",run);
    strcat(stringaexec,temp);
    strcat(stringaexec,".root");
    int ierr2 = stat (stringaexec,&st2);
    int newdate2 = st2.st_mtime;
    // Writing the current timestamps on a file (do debug)
    //if( (stream = fopen( "/home/user/re4data/TDC/timestamp2", "w" )) != NULL ) {
    //   fprintf (stream, "%d\n",newdate2);
    //   fclose( stream );
    //}
    
    //int timerun = nentries * cosmicrate;
    
    ifstream map_file("/home/user/workspace/rpcupgrade/Offline/mapping.txt");
    
    if (map_file.is_open()){
        while(map_file.good()){
            
            //Reading the mapping file
            map_file >> i_station >> aModule  >> map_start >> map_finish >> aModule1  >> map_start1 >> map_finish1;
            cout << " " << endl << endl;
            cout  << "STATION: " << i_station << endl;
            
            if (verbose_map) cout << " " << endl << "Module: " << aModule << " Station: " << i_station << " starting at channel: " << map_start << " and finishing at: " << map_finish << endl << " " << endl;
            chamber_efficiency[i_station];
            
            for ( Long64_t jentry = 0; jentry < nentries; jentry++ ) {
                
                if ( jentry%100 == 0 ) cout << " Event: " << jentry << "/" << nentries << "\r" << flush;
                
                // Initialization working variables and Cluster vectors
                {
                    //cout << Starting with Initialization << endl;
                    nicehit = 0;
                    nicehitA = 0;
                    nicehitB = 0;
                    nicehitC = 0;
                    firedchannel = 0;
                    firedchannelA = 0;
                    firedchannelB = 0;
                    firedchannelC = 0;
                    kk = 0;
                    
                    for ( jj = 0; jj < 128; jj++ ) {
                        clusterization[jj] = 0;
                    }
                }
                
                Long64_t ientry = LoadTree(jentry);
                if (ientry < 0) break;
                nb = fChain->GetEntry(jentry);
                nbytes += nb;
                // if (Cut(ientry) < 0) continue;
                
                
                // Initialization of master trigger and small counter
                //vector<unsigned int> * TRIG = _Data[ trg_module ][ trigger_bit ];
                //vector<unsigned int> * HITS_PER_CHANNEL = HitsPerChannel[ trg_module ];
                //if ( HITS_PER_CHANNEL->at( trigger_bit ) < 1) continue;
                
                // Looping over all channels
                {
                for ( unsigned aChannel = map_start; aChannel < map_finish; aChannel++ ) {
                    
                    
                    // Vector Initialization
                    vector<unsigned int> * HITS_PER_CHANNELC = HitsPerChannel[ aModule ];
                    vector<unsigned int> * CH = _Data[ aModule ][ aChannel ];
                    
                    
                    // Printing informations inside the event
                    {
                        if (verbose_filling) cout << " " << endl << "***Event: " << jentry << "  " << "Module: " << aModule << "   " << "Station: " << i_station << "   " << "Channel: " << aChannel << endl;
                        if (verbose_filling2) cout << "***Hits per channel: " << HITS_PER_CHANNELC->at( aChannel ) << endl << " " << endl;
                    }
                    
                    if( HITS_PER_CHANNELC->at( aChannel ) > 0 ) {                        
                        noiserate[i_station] = noiserate[i_station] + 1;
                    }
                    
                }
                if ( aModule1 > 0 ) {
                    for ( unsigned aChannel = map_start1; aChannel < map_finish1; aChannel++ ) {
                        
                        // Vector Initialization
                        vector<unsigned int> * HITS_PER_CHANNELC1 = HitsPerChannel[ aModule1 ];
                        vector<unsigned int> * CH1 = _Data[ aModule1 ][ aChannel ];
                        
                        
                        // Printing informations inside the event
                        {
                            if (verbose_filling) cout << " " << endl << "***Event: " << jentry << "  " << "Module: " << aModule1 << "   " << "Station: " << i_station << "   " << "Channel: " << aChannel << endl;
                            if (verbose_filling2) cout << "***Hits per channel: " << HITS_PER_CHANNELC1->at( aChannel ) << endl << " " << endl;
                        }
                        
                        if( HITS_PER_CHANNELC1->at( aChannel ) > 0 ) {
                            noiserate[i_station] = noiserate[i_station] + 1;
                        }
                    }
                }
                }

            }
        }
    }
    map_file.close();
    cout << " " << endl;
    
    // Writing plots
    for (int i_station = 1; i_station <= max_station; i_station++){        
        
        // Printing summary informations
        {
        cout << "Station " << i_station << " noisy hits: " << noiserate[i_station] << " in entries=" << nentries << "  ( timewindows= " << timewindow << " s )" << endl;
        
        noiserate[i_station] = (noiserate[i_station] / (nentries * timewindow ) / surface ) ;
        cout << "Station " << i_station << " noisy rate = " << "\33[0;31m" << noiserate[i_station] << " +- " << sqrt(noiserate[i_station]) << " Hz/cm2." << "\33[0m" << endl << endl;
        }
        
    }
}
 +- " << noiserror << " Hz/cm2." << "\33[0m" << endl << endl;
        }
        
    }
}
