Newer
Older
TestStandRepository / Software / SensorCharacterisation / SensorCharacterisation.C
@Federica Lionetto Federica Lionetto on 8 May 2015 6 KB Added SensorCharacterisation
//************************************************
// Author: Federica Lionetto
// Created on: 08/05/2015
//************************************************

/*
SensorCharacterisation reads a text file (containing the bias voltage, the current, and the capacitance values measured with the probe station) and creates a ROOT file with the following information:
- current as a function of the bias voltage;
- inverse of the squared capacitance as a function of the bias voltage.

Compile with:

make

Run with:

./SensorCharacterisation [input text file] [additional folder]

where

- [input text file] is the complete path, including the folder and the filename, of the text file one wants to process;
- [additional folder] is the optional additional folder where the output will be saved.

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 SensorCharacterisation(char *filename, 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 < 2)
  {
    cout << "**************************************************" << endl;
    
    cout << "Error! Input file missing..." << endl;
    cout << "Please use the following format:" << endl;
    cout << "./SensorCharacterisation [1] [2]" << endl;
    cout << "with:" << endl;
    cout << "[1] = Input text file, complete path;" << endl;
    cout << "[2] = Additional folder, optional." << endl;
    cout << "Type ./SensorCharacterisation --info for more information." << endl;

    cout << "**************************************************" << endl;

    return 0;  
  }
  else
  {
    cout << "File to process: " << argv[1] << endl;
    if (argc == 2)
      SensorCharacterisation(argv[1]);
    else if (argc == 3)
      SensorCharacterisation(argv[1],argv[2]);
    else
    {
      cout << "Error! Too many arguments given..." << endl;
      
      return 0;
    }
    
    return 0;  
  }  
}

void SensorCharacterisation(char *filename, char *externalPath)
{
  cout << "**************************************************" << endl;
  cout << "Working on the ICV scan..." << endl;
  cout << "**************************************************" << endl;

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

  int found;

  string filename_as_string = string(filename);
  // Check that the filename provided corresponds to a text file.
  found = filename_as_string.find(".dat");
  if (found==string::npos)  {
    cout << "Error! The filename provided is not associated to a text file." << endl;
    return;
  }

  // Open input text file.
  ifstream datFile;
  std::string line;

  // Number of rows to be read from the text files.
  int rows;

  // Open file.
  // Determine number of rows to be read from the text file.
  datFile.open(filename_as_string.c_str());
  if (datFile.is_open()) {
    rows = 0;
    while (getline(datFile,line))
      rows++;
    cout << "Number of rows in the input text file: " << rows << endl;
    datFile.close();
  }
  else 
  {
    cout << "Unable to open file." << endl;
    return;
  }

  // Read the text file.
  // Remember that the first row must be skipped.  
  float V;
  float I;
  float IErr;
  float C;
  float CErr;

  Int_t i;

  // Read text file.
  vector<float> vV;
  vector<float> vI;
  vector<float> vC; // 1/C^2.
  vector<float> vVErr;
  vector<float> vIErr;
  vector<float> vCErr; // Uncertainty on 1/C^2, according to sigma(1/C^2) = 2/C^3*sigma(C).

  // Save information.
  datFile.open(filename_as_string.c_str());
  if (datFile.is_open()) {
    i = 0;
    while (getline(datFile,line)) {
      if (i>0) {
	// cout << line << endl;
	istringstream iss(line);
	iss >> V >> I >> IErr >> C >> CErr;
	vV.push_back(V);
	vI.push_back(I);
	vC.push_back(1./(C*C));
	vVErr.push_back(0.);
	vIErr.push_back(IErr);
	vCErr.push_back((2.*CErr)/(C*C*C));
      }
      i++;
    }
    datFile.close();
  }
  else
  {
    cout << "Unable to open file." << endl;
    return;
  }

  float *aV = &vV[0];
  float *aI = &vI[0];
  float *aC = &vC[0];
  float *aVErr = &vVErr[0];
  float *aIErr = &vIErr[0];
  float *aCErr = &vCErr[0]; 

  // Do some fanciness to get the directory right.
  string analysis = "/disk/groups/hep/flionett/TestStand/AnalysisResults";
  if (externalPath!=0)
    analysis = string(analysis+"/"+externalPath);

  string filename_as_string_no_path = filename_as_string.substr(filename_as_string.find_last_of('/')+1);
  string filename_as_string_no_path_no_extension = filename_as_string_no_path.substr(0,filename_as_string_no_path.length()-4);

  // Create a folder named AnalysisResults. Do not worry, nothing bad is going to happen if the folder already exists.
  string path_to_make = "mkdir -p "+analysis;
  system(path_to_make.c_str());
  cout << "Setting output to: " << path_to_make << endl;

  // Create a folder named Figures inside the folder named AnalysisResults.
  string path_to_make_figures = "mkdir "+analysis+"/Figures";
  system(path_to_make_figures.c_str());
  path_to_make_figures = "mkdir "+analysis+"/Figures"+"/SensorCharacterisation";
  system(path_to_make_figures.c_str());
  path_to_make_figures = "mkdir "+analysis+"/Figures"+"/SensorCharacterisation"+"/"+filename_as_string_no_path_no_extension;
  system(path_to_make_figures.c_str());
  cout << "Setting figures to: " << path_to_make_figures << endl;  

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

  // Open output ROOT file.
  TFile *output = TFile::Open(analysis+"/SensorCharacterisation-"+TString(filename_as_string_no_path_no_extension)+".root","RECREATE"); 

  TCanvas *cIVScan = new TCanvas("cIVScan","",400,300);
  TCanvas *cCVScan = new TCanvas("cCVScan","",400,300);

  int rowsData = rows-1;

  TGraphErrors *gIVScan = new TGraphErrors(rowsData,aV,aI,aVErr,aIErr);
  TGraphErrors *gCVScan = new TGraphErrors(rowsData,aV,aC,aVErr,aCErr);

  InitGraphErrors(gIVScan,"IV scan","Bias voltage (V)","Current (#muA)");
  InitGraphErrors(gCVScan,"CV scan","Bias voltage (V)","Capacitance^{-2} (nF^{-2})");

  DrawGraphErrors(cIVScan,gIVScan,"APE",path_to_figures);
  DrawGraphErrors(cCVScan,gCVScan,"APE",path_to_figures);

  output->Close();

  return;
}