//************************************************
// Author: Federica Lionetto
// Created on: 27/02/2015
//************************************************

/*
CCEBiasVoltageScan reads all the ROOT files of a given CCE bias voltage data taking and shows how the mu and sigma of the charge sharing coefficient eta vary as a function of the bias voltage.

The CCE bias voltage data taking is identified by the following information:
- <sensor>, that is, the type of sensor (Hans410, ...);
- <date>, that is, the date when the measurement was taken;
- <z>, that is, the position along z;
- <firstV>, that is, the first value of the bias voltage;
- <lastV>, that is, the last value of the bias voltage;
- <stepV>, that is, the step between two subsequent data acquisitions.

Compile with:

make

Run with:

./CCEBiasVoltageScan [sensor] [date] [z] [firstV] [lastV] [stepV] [additional folder]

For example:

./CCEBiasVoltageScan Hans410 20141121 176 100 200 20

A folder named AnalysisResults will be created in a fixed location and a ROOT file will be saved in there. A folder named Figures will be created inside the folder named AnalysisResults, with some monitoring plots.

If needed, an additional folder can be specified, that will be created inside the folder named AnalysisResults.
*/

#include "../Tools/Lib.C"
#include "../Tools/lhcbStyle.C"
#include "../Tools/Style.C"

#include "../Tools/Par.C"

void CCEBiasVoltageScan(char *sensor, char *date, char *z, const Float_t firstV, const Float_t lastV, const Float_t stepV, char *externalPath=0);

int main(int argc, char *argv[])
{
  getLHCbStyle();
  PersonalStyle();

  if ((argc == 2) && (string(argv[1]) == "--info"))
  {
    cout << "**************************************************" << endl;

    cout << "CCEBiasVoltageScan reads all the ROOT files of a given CCE bias voltage data taking and shows how the mu and sigma of the charge sharing coefficient eta vary as a function of the bias voltage." << endl;

    cout << "The CCE bias voltage data taking is identified by the following information:" << endl;
    cout << "- <sensor>, that is, the type of sensor (Hans410, ...);" << endl;
    cout << "- <date>, that is, the date when the measurement was taken;" << endl;
    cout << "- <z>, that is, the position along z;" << endl;
    cout << "- <firstV>, that is, the first value of the bias voltage;" << endl;
    cout << "- <lastV>, that is, the last value of the bias voltage;" << endl;
    cout << "- <stepV>, that is, the step between two subsequent data acquisitions." << endl;

    cout << "Compile with:" << endl;

    cout << "make" << endl;

    cout << "Run with:" << endl;

    cout << "./CCEBiasVoltageScan [sensor] [date] [z] [firstV] [lastV] [stepV] [additional folder]" << endl;

    cout << "For example:" << endl;

    cout << "./CCEBiasVoltageScan Hans410 20141121 176 100 200 20" << endl;

    cout << "A folder named AnalysisResults will be created in a fixed location and a ROOT file will be saved in there. A folder named Figures will be created inside the folder named AnalysisResults, with some monitoring plots." << endl;

    cout << "If needed, an additional folder can be specified, that will be created inside the folder named AnalysisResults." << endl;
    
    cout << "**************************************************" << endl;

    return 0;
  }
  else if (argc < 7)
  {
    cout << "**************************************************" << endl;

    cout << "Error! Arguments missing..." << endl;
    cout << "Please use the following format:" << endl;
    cout << "./CCEBiasVoltageScan [1] [2] [3] [4] [5] [6]" << endl;
    cout << "with:" << endl;
    cout << "[1] = Type of sensor (Hans410, ...);" << endl;
    cout << "[2] = Date;" << endl;
    cout << "[3] = Position along z;" << endl;
    cout << "[4] = First value of the bias voltage;" << endl;
    cout << "[5] = Last value of the bias voltage" << endl;
    cout << "[6] = Step between two subsequent data acquisitions;" << endl;
    cout << "[7] = Additional folder, optional." << endl;
    cout << "Type ./CCEBiasVoltageScan --info for more information." << endl;
    
    cout << "**************************************************" << endl;

    return 0;
  }
  else
  {
    cout << "Type of sensor: " << argv[1] << endl;
    cout << "Date: " << argv[2] << endl;
    cout << "Position along z: " << argv[3] << endl;
    cout << "First value of the bias voltage: " << argv[4] << endl;
    cout << "Last value of the bias voltage: " << argv[5] << endl;
    cout << "Step between two subsequent data acquisitions: " << argv[6] << endl;
    if (argc == 7)
      CCEBiasVoltageScan(argv[1],argv[2],argv[3],atoi(argv[4]),atoi(argv[5]),atoi(argv[6]));
    else if (argc == 8)
      CCEBiasVoltageScan(argv[1],argv[2],argv[3],atoi(argv[4]),atoi(argv[5]),atoi(argv[6]),argv[7]);
    else
    {
      cout << "Error! Too many arguments given..." << endl;
      
      return 0;
    }
    
    return 0;  
  }
}

void CCEBiasVoltageScan(char *sensor, char *date, char *z, const Float_t firstV, const Float_t lastV, const Float_t stepV, char *externalPath)
{
  cout << "**************************************************" << endl;
  cout << "Bias voltage scan of charge sharing coefficient..." << endl;
  cout << "**************************************************" << endl;

  // Do not comment this line.
  gROOT->ProcessLine("#include <vector>");

  // Do some fanciness to get the directory right.
  string inputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/CCEBiasVoltageScan";
  string outputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/CCEBiasVoltageScan";
  if (externalPath!=0)
    outputDirectory = string(outputDirectory+"/"+externalPath);
  cout << "The input directory is: " << inputDirectory << endl;
  cout << "The output directory is: " << outputDirectory << endl;

  // Create the outputDirectory directory if it does not exist.
  string path_to_make = "mkdir -p "+outputDirectory;
  system(path_to_make.c_str());

  cout << "Figures stored in: " << outputDirectory+"/Figures/"+"CCE-ProcessRawData-"+date+"-216-"+z+"z" << endl;

  // Create a directory named Figures inside the directory named outputDirectory if it does not exist.
  string path_to_make_figures = "mkdir -p "+outputDirectory+"/Figures/"+"CCE-ProcessRawData-"+date+"-216-"+z+"z";
  system(path_to_make_figures.c_str());

  TString path_to_figures = (string(path_to_make_figures)).substr((string(path_to_make_figures)).find_last_of(' ')+1);

  char char_input_ROOT[200];
  string input_ROOT;
  string output_ROOT;

  const Int_t steps = (Int_t)((lastV-firstV)/stepV+1);
  Float_t V[steps];
  Float_t uV[steps];

  Float_t muEtaSignalOverNoise[steps];
  Float_t sigmaEtaSignalOverNoise[steps];

  Float_t umuEtaSignalOverNoise[steps];
  Float_t usigmaEtaSignalOverNoise[steps];

  // Get information from tree.
  Float_t muEtaSignalOverNoise1;
  Float_t sigmaEtaSignalOverNoise1;

  Float_t umuEtaSignalOverNoise1;
  Float_t usigmaEtaSignalOverNoise1;

  TBranch *b_muEtaSignalOverNoise1 = 0;
  TBranch *b_sigmaEtaSignalOverNoise1 = 0;

  TBranch *b_umuEtaSignalOverNoise1 = 0;
  TBranch *b_usigmaEtaSignalOverNoise1 = 0;

  // Open output ROOT file.
  output_ROOT = outputDirectory+"/CCEBiasVoltageScan-"+date+"-216-"+z+"z"+".root";
  TFile *output = TFile::Open(TString(output_ROOT),"RECREATE");

  for (Int_t step=0;step<steps;step++) {
    V[step] = firstV+step*stepV;
    uV[step] = 0.;

    // Open input data ROOT files.
    // I did not find a better way to create a string containing the bias voltage.
    sprintf(char_input_ROOT,"%s/CCE-ProcessRawData-%s-%dV-216-%sz.root",inputDirectory.c_str(),date,(int)V[step],z);
    input_ROOT = string(char_input_ROOT);
    // Check that the filename provided corresponds to a ROOT file.
    int found = input_ROOT.find(".root");
    if (found==string::npos)  {
      cout << "Error! The filename provided is not associated to a ROOT file." << endl;
      return;
    }

    cout << "Open ROOT file #" << step+1 << ": " << input_ROOT << endl;
    TFile *input = TFile::Open(TString(input_ROOT));

    // Get information from tree.
    TTree *tFitResults = (TTree *)input->Get("tFitResults");
    int Events = tFitResults->GetEntries();
    if (Events != 1)
    {
      cout << "Error! The ROOT file has been corrupted..." << endl;
      
      return ;
    }
    else 
    {
      tFitResults->SetBranchAddress("muEtaSignalOverNoise",&muEtaSignalOverNoise1,&b_muEtaSignalOverNoise1);
      tFitResults->SetBranchAddress("sigmaEtaSignalOverNoise",&sigmaEtaSignalOverNoise1,&b_sigmaEtaSignalOverNoise1);
      tFitResults->SetBranchAddress("umuEtaSignalOverNoise",&umuEtaSignalOverNoise1,&b_umuEtaSignalOverNoise1);
      tFitResults->SetBranchAddress("usigmaEtaSignalOverNoise",&usigmaEtaSignalOverNoise1,&b_usigmaEtaSignalOverNoise1);

      tFitResults->GetEntry();
    }

    muEtaSignalOverNoise[step] = muEtaSignalOverNoise1;
    sigmaEtaSignalOverNoise[step] = sigmaEtaSignalOverNoise1;
    umuEtaSignalOverNoise[step] = umuEtaSignalOverNoise1;
    usigmaEtaSignalOverNoise[step] = usigmaEtaSignalOverNoise1;

    // Close input data ROOT files.
    input->Close();
  }

  output->cd();

  // Plot mu.
  TGraphErrors *gMuEtaSignalOverNoiseVSV = new TGraphErrors(steps,V,muEtaSignalOverNoise,uV,umuEtaSignalOverNoise);
  InitGraphErrors(gMuEtaSignalOverNoiseVSV,"Charge sharing coefficient - #mu","V (V)","#mu (#mum)");

  TCanvas *cMuEtaSignalOverNoiseVSV = new TCanvas(Form("cMuEtaSignalOverNoiseVSV-%s",date),"",550,300);
  DrawGraphErrors(cMuEtaSignalOverNoiseVSV,gMuEtaSignalOverNoiseVSV,"AP",path_to_figures);

  // Plot sigma.
  TGraphErrors *gSigmaEtaSignalOverNoiseVSV = new TGraphErrors(steps,V,sigmaEtaSignalOverNoise,uV,usigmaEtaSignalOverNoise);
  InitGraphErrors(gSigmaEtaSignalOverNoiseVSV,"Charge sharing coefficient - #sigma","V (V)","#sigma (#mum)");

  TCanvas *cSigmaEtaSignalOverNoiseVSV = new TCanvas(Form("cSigmaEtaSignalOverNoiseVSV-%s",date),"",550,300);
  DrawGraphErrors(cSigmaEtaSignalOverNoiseVSV,gSigmaEtaSignalOverNoiseVSV,"AP",path_to_figures);

  // Write output ROOT file.
  output->Write();

  // Close output ROOT file.
  output->Close();

  return;
}
