//************************************************
// Author: Federica Lionetto
// Created on: 21/11/2014
//************************************************

/*
CheckAlignment reads all the ROOT files of a given alignment data taking, calls FindStrip for each of them to find the Beetle channel corresponding to the strip hit by the laser, calculates
- the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x (horizontal direction)
- the mean of the sum of the signal over noise ratio (ADC counts/noise) of four adjacent strips around that hit by the laser as a function of the position along x (horizontal direction) 
and creates a ROOT file with the following information:
- a graph with the mean of the sum of the ADC counts of four adjacent strips around that hit by the laser as a function of the position along x
- a graph with the mean of the sum of the signal over noise ratio (ADC counts/noise) of four adjacent strips around that hit by the laser as a function of the position along x.

The alignment data taking is identified by the following information:
- <sensor>, that is, the type of sensor (Hans410, ...);
- <filename>, that is, the filename excluding the position value and the run type.
- <z>, that is, the position along z;
- <firstx>, that is, the first position along x;
- <lastx>, that is, the last position along x;
- <stepx>, that is, the step between two subsequent data acquisitions (1 step = 5 microns).

Compile with:

make

Run with:

./CheckAlignment [sensor] [filename] [z] [firstx] [lastx] [stepx] [additional folder]

For example:

./CheckAlignment Hans410 ProcessRawData-20141121 0 0 75 3

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/FindStrip.C"
#include "../Tools/Par.C"

void CheckAlignment(char *sensor, char *filename, const Float_t z, const Float_t firstx, const Float_t lastx, const Float_t stepx, char *externalPath=0);

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

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

    cout << "Some comments." << endl;
    
    cout << "**************************************************" << endl;

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

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

    return 0;
  }
  else
  {
    cout << "Type of sensor: " << argv[1] << endl;
    cout << "Filename: " << argv[2] << endl;
    cout << "Position along z: " << argv[3] << endl;
    cout << "First position along x: " << argv[4] << endl;
    cout << "Last position along x: " << argv[5] << endl;
    cout << "Step between two subsequent data acquisitions: " << argv[6] << endl;
    if (argc == 7)
      CheckAlignment(argv[1],argv[2],atoi(argv[3]),atoi(argv[4]),atoi(argv[5]),atoi(argv[6]));
    else if (argc == 8)
      CheckAlignment(argv[1],argv[2],atoi(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 CheckAlignment(char *sensor, char *filename, const Float_t z, const Float_t firstx, const Float_t lastx, const Float_t stepx, char *externalPath)
{
  cout << "**************************************************" << endl;
  cout << "Checking alignment..." << 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)+"/Alignment";  
  string outputDirectory = "/disk/groups/hep/flionett/TestStand/AnalysisResults/"+string(sensor)+"/Alignment";
  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());

  ostringstream convertx;
  ostringstream convertz;
  string tempx;
  string tempz;

  convertz.str("");
  convertz << z;
  tempz = convertz.str();  

  cout << "Figures stored in: " << outputDirectory+"/Figures/"+filename+"-"+tempz+"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/"+filename+"-"+tempz+"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);

  int strip;
  string direction;

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

  string inputFindStrip;
  string outputFindStrip;

  Float_t noise[N];

  const Int_t steps = (Int_t)((lastx-firstx)/stepx+1);
  Float_t x[steps];
  Float_t mean4ADC[steps];
  Float_t signalOverNoise4ADC[steps];

  // Open output ROOT file.
  output_ROOT = outputDirectory+"/Alignment-"+filename+"-"+tempz+"z.root";
  TFile *output = TFile::Open(TString(output_ROOT),"RECREATE");

  for (Int_t step=0;step<steps;step++) {
    x[step] = firstx+step*stepx;

    // 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/%s-%dx-%dz-las.root",inputDirectory.c_str(),filename,(int)x[step],(int)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));

    inputFindStrip = input_ROOT;
    convertx.str("");
    convertx << x[step];
    tempx = convertx.str();
    outputFindStrip = outputDirectory+"/FindStrip-"+filename+"-"+tempx+"x-"+tempz+"z-las.root";
    FindStrip(inputFindStrip,outputFindStrip,path_to_figures,&strip,&direction);
  
    cout << "Histograms: " << endl;
    cout << Form("hADCPedSub%d",strip) << endl;
    cout << Form("hADCPedSub%d",strip+NSkip) << endl;
    cout << Form("hADCPedSub%d",strip-NSkip) << endl;
    cout << Form("hADCPedSub%d",strip-2*NSkip) << endl;
    cout << Form("hADCPedSub%d",strip+2*NSkip) << endl;

    // Find the pedestal run from which pedestals have been calculated and get the noise of each Beetle channel.
    string *PedFilename = new string();
    TBranch *b_PedFilename = 0;

    TTree *Header = (TTree *)input->Get("Header");
    int EventsHeader = Header->GetEntries();
    if (EventsHeader != 1)
    {
      cout << "Error! The ROOT file has been corrupted..." << endl;
      
      return ;
    }
    else 
    {
      Header->SetBranchAddress("PedFilename",&PedFilename,&b_PedFilename);
      
      Header->GetEntry();

      cout << "Pedestals calculated from: " << *PedFilename << endl; 

      // Get the noise of each Beetle channel.
      // Open input pedestal&noise text file.
      FILE *inputText = fopen(PedFilename->c_str(),"r");
      
      // Read noise.  
      for (int iChannel=0; iChannel<N; ++iChannel) {
	fscanf(inputText,"%*d%*c%*f%*c%*f%*c%f%*c%*f%*c",&(noise[iChannel]));
	// cout << iChannel << ", " << noise[iChannel] << endl;
      }
  
      // Close input pedestal&noise text file.
      fclose(inputText);
    }

    // Beetle channels where to look for signal.
    int ch1 = strip;
    int ch2 = strip+NSkip;
    int ch3 = strip-NSkip;
    int ch4;   
    if (direction == "left")
      ch4 = strip-2*NSkip;
    else if (direction == "right")
      ch4 = strip+2*NSkip;
    
    // Four adjacent strips.
    TH1D *hist1 = (TH1D *)input->Get(Form("hADCPedSub%d",ch1));
    TH1D *hist2 = (TH1D *)input->Get(Form("hADCPedSub%d",ch2));
    TH1D *hist3 = (TH1D *)input->Get(Form("hADCPedSub%d",ch3));
    TH1D *hist4 = (TH1D *)input->Get(Form("hADCPedSub%d",ch4));

    mean4ADC[step] = hist1->GetMean()+hist2->GetMean()+hist3->GetMean()+hist4->GetMean();
    signalOverNoise4ADC[step] = (hist1->GetMean())/noise[ch1]+(hist2->GetMean())/noise[ch2]+(hist3->GetMean())/noise[ch3]+(hist4->GetMean())/noise[ch4];

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

  output->cd();

  for (Int_t step=0;step<steps;step++)
    x[step] = x[step]*5.; // One step corresponds to 5 microns.

  // Four adjacent strips.
  TGraph *gcheckAlignmentMean4 = new TGraph(steps,x,mean4ADC);
  InitGraph(gcheckAlignmentMean4,"Check alignment - 4 adjacent strips","x (#mum)","ADC counts");
  TCanvas *ccheckAlignmentMean4 = new TCanvas(Form("ccheckAlignmentMean4-%s",filename),"",400,300);
  DrawGraph(ccheckAlignmentMean4,gcheckAlignmentMean4,"APC",path_to_figures);

  TGraph *gcheckAlignmentSignalOverNoise4 = new TGraph(steps,x,signalOverNoise4ADC);
  InitGraph(gcheckAlignmentSignalOverNoise4,"Check alignment - 4 adjacent strips","x (#mum)","S/N");
  TCanvas *ccheckAlignmentSignalOverNoise4 = new TCanvas(Form("ccheckAlignmentSignalOverNoise4-%s",filename),"",400,300);
  DrawGraph(ccheckAlignmentSignalOverNoise4,gcheckAlignmentSignalOverNoise4,"APC",path_to_figures);

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

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

  return;
}
