Newer
Older
TestStandRepository / Software / TbNtupleMaker / TbNtupleMaker.C
@Federica Lionetto Federica Lionetto on 7 Oct 2014 10 KB Added data
//************************************************
// Author: Federica Lionetto, Adam Davis, Biplab Dey, Paolo Gandini
// Created on: 07/30/2014
//************************************************

/*
TbNtupleMaker reads an Alibava file and creates a ROOT file (same filename) with the following information:
- int NEvents, the number of events read from the header of the Alibava file;
- int RunType, the run type;
- std::vector<double> PedByGain, the pedestals calculated by the Alibava;
- std::vector<double> NoiseByGain, the noise calculated by the Alibava;
- std::vector<double> Gain, the gain calculated by the Alibava;
- TH1F histo_PedByGain("histo_PedByGain","histo_PedByGain",N,0,N-1);
- TH1F histo_NoiseByGain("histo_NoiseByGain","histo_NoiseByGain",N,0,N-1);
- TH1F histo_Gain("histo_Gain","histo_Gain",N,0,N-1);
- string Date = a->date(), the date read from the header of the Alibava file;
- std::vector<unsigned short> ADC, the raw ADC counts, one per event;
- double TDCTime, the TDC time (meaningful only in radioactive source runs), one per event;
- double Temp, the temperature, one per event;
- int n, a counter, one per event (starting from 1).

The ROOT file will be saved in a folder named RootFiles in the same folder where the Alibava file is (if no external path is provided) or in the folder specified by the external path.

Compile with:

make

Run with:

./TbNtupleMaker [Alibava file] [external path]

where:
- [Alibava file] is the complete path, including the folder and the filename, of the Alibava file one wants to process;
- [external path] is the optional external path where the RootFiles folder will be created.

For example:

./TbNtupleMaker /.../run_xxxxxx_xxxx_xxxx.ali

or

./TbNtupleMaker /.../run_xxxxxx_xxxx_xxxx.ali /...
*/

//************************************************
// Types:
// 1 = calibration run
// 2 = laser synchronization run
// 3 = laser run
// 4 = radioactive source run
// 5 = pedestal run
//************************************************

#include <iostream>
#include <string>

#include <vector>

#include <cstdlib>

#include "TFile.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TTree.h"

#include "Alibava/AsciiRoot.h"

#ifdef __MAKECINT__
#pragma link C++ class vector<float>+;
#endif

using namespace std;

// Number of Beetle channels.
const int N = 256;

void TbNtupleMaker(char *filename, char *externalPath = 0);

int main(int argc, char *argv[])
{
  if(argc < 2)
  {
    cout << "**************************************************" << endl;

    cout << "Error! Input file missing..." << endl;
    cout << "Please use the following format:" << endl;
    cout << "./TbNtupleMaker [1] [2]" << endl;
    cout << "with:" << endl;
    cout << "[1] = Alibava file, complete path;" << endl;
    cout << "[2] = External path, optional." << endl;
    cout << "Type ./TbNtupleMaker --info for more information." << endl;

    cout << "**************************************************" << endl;
    
    return 0;
  }
  else if (string(argv[1]) == "--info") 
  {
    cout << "**************************************************" << endl;

    cout << "TbNtupleMaker reads an Alibava file and creates a ROOT file (same filename) with the following information:" << endl;
    cout << "- int NEvents, the number of events read from the header of the Alibava file;" << endl;
    cout << "- int RunType, the run type;" << endl;
    cout << "- std::vector<double> PedByGain, the pedestals calculated by the Alibava;" << endl;
    cout << "- std::vector<double> NoiseByGain, the noise calculated by the Alibava;" << endl;
    cout << "- std::vector<double> Gain, the gain calculated by the Alibava;" << endl;
    cout << "- TH1F histo_PedByGain;" << endl;
    cout << "- TH1F histo_NoiseByGain;" << endl;
    cout << "- TH1F histo_Gain;" << endl;
    cout << "- string Date = a->date(), the date read from the header of the Alibava file;" << endl;
    cout << "- std::vector<unsigned short> ADC, the raw ADC counts, one per event;" << endl;
    cout << "- double TDCTime, the TDC time (meaningful only in radioactive source runs), one per event;" << endl;
    cout << "- double Temp, the temperature, one per event;" << endl;
    cout << "- int n, a counter, one per event (starting from 1)." << endl;

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

    cout << "The ROOT file will be saved in a folder named RootFiles in the same folder where the Alibava file is (if no external path is provided) or in the folder specified by the external path." << endl;
    
    cout << "**************************************************" << endl;

    cout << "Compile with:" << endl;
    cout << "make" << endl;
    cout << "Run with:" << endl;
    cout << "./TbNtupleMaker [Alibava file] [external path]" << endl;
    cout << "where:" << endl;
    cout << "- [Alibava file] is the complete path, including the folder and the filename, of the Alibava file one wants to process;" << endl;
    cout << "- [external path] is the optional external path where the RootFiles folder will be created." << endl;
    cout << "For example:" << endl;
    cout << "./TbNtupleMaker /.../run_xxxxxx_xxxx_xxxx.ali" << endl;
    cout << "or" << endl;
    cout << "./TbNtupleMaker /.../run_xxxxxx_xxxx_xxxx.ali /..." << endl;   

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

      return 0;
    }
    
    return 0; 
  }
}



void TbNtupleMaker(char *filename, char *externalPath){
  cout << "**************************************************" << endl;
  cout << "Decoding raw data..." << endl;
  cout << "**************************************************" << endl;
 
  // Do not comment this line.
  gROOT->ProcessLine("#include <vector>");

  // Do some fanciness to get the directory right.
  string filename_as_string = string(filename);
  string prefix = filename_as_string.substr(0,filename_as_string.find_last_of('/'));
  if (externalPath!=0)
    prefix = string(externalPath);
  string ali_filename = filename_as_string.substr(filename_as_string.find_last_of('/')+1);
  TString outfilename = ((TString)prefix)+"/RootFiles/"+((TString)ali_filename);
  outfilename.ReplaceAll(".ali",".root");
  
  // Create a folder named RootFiles. Do not worry, nothing bad is going to happen if the folder already exists.
  cout << "Create a folder named RootFiles" << endl;
  cout << "Setting output to: " << prefix+"/RootFiles" << endl;
  string path_to_make = "mkdir "+prefix+"/RootFiles";
  system(path_to_make.c_str()); 

  // Open ROOT file.
  TFile *output = TFile::Open(outfilename,"RECREATE");
  
  // Open Alibava file.
  AsciiRoot *a = new AsciiRoot(filename);

  // Create tree structure in ROOT file, to be filled once per file.
  int NEvents;
  int RunType;
  std::vector<double> PedByGain;
  std::vector<double> NoiseByGain;
  std::vector<double> Gain;
  TH1F histo_PedByGain("histo_PedByGain","histo_PedByGain",N,0,N);
  TH1F histo_NoiseByGain("histo_NoiseByGain","histo_NoiseByGain",N,0,N);
  TH1F histo_Gain("histo_Gain","histo_Gain",N,0,N);
  TH1F histo_Signal20("histo_Signal20","Signal calculated by Alibava > 20, distribution over the strips",N,0,N);
  TH1F histo_Signal40("histo_Signal40","Signal calculated by Alibava > 40, distribution over the strips",N,0,N);
  TH1F histo_Signal60("histo_Signal60","Signal calculated by Alibava > 60, distribution over the strips",N,0,N);
  TH1F histo_TDC("histo_TDC","TDC distribution, ADC > 40",50,0,50);
  string Date = a->date();
  
  /////// vito
  TH1D** ADC_ch = new TH1D*[256];
  TH2D* ADCvsEv = new TH2D("ADCvsEv_%d",
			   "ADCvsEv_%d",
			   1e5, -0.5, 99999.5,
			   200, 399.5, 600.5 );

  for(int i=0; i<256; i++){
  
    ADC_ch[i] = new TH1D(Form("ADC_ch_%d", i),
			 Form("ADC_ch_%d", i),
			 1024, -0.5, 1023.5 );

  }


  // Allocate only necessary space.
  PedByGain.reserve(N);
  NoiseByGain.reserve(N);
  Gain.reserve(N);

  // Create tree structure in ROOT file, to be filled once per event.
  std::vector<unsigned short> ADC;
  double TDCTime;
  double Temp;
  int n;

  // Fill the header, once per file.
  TTree *Header = new TTree("Header","Header");

  Header->Branch("NEvents",&NEvents);
  Header->Branch("RunType",&RunType);
  Header->Branch("PedByGain",&PedByGain);
  Header->Branch("NoiseByGain",&NoiseByGain);
  Header->Branch("Gain",&Gain);
  Header->Branch("Date",&Date);

  NEvents = a->get_nevents();
  cout << "Number of events in the Alibava file: " << NEvents << endl;

  RunType = a->type();
  for(int iChannel=0; iChannel<N;++iChannel)
  {
    Gain[iChannel]= a->get_gain(iChannel);
    PedByGain[iChannel]=a->ped(iChannel);
    NoiseByGain[iChannel] = a->noise(iChannel);
    histo_Gain.SetBinContent(iChannel+1,a->get_gain(iChannel));
    histo_PedByGain.SetBinContent(iChannel+1,a->ped(iChannel));
    histo_NoiseByGain.SetBinContent(iChannel+1,a->noise(iChannel));
  }

  Header->Fill();
  cout << "Information in the header:" << endl;
  Header->Print();
  cout << "**************************************************" << endl;
  cout << "Date from Alibava file: " << Date <<endl;
  cout << "**************************************************" << endl;
  
  // Fill the data, once per event.
  TTree *EventInfo = new TTree("EventInfo","EventInfo");  
  EventInfo->Branch("n",&n);
  EventInfo->Branch("ADC",&ADC);
  EventInfo->Branch("TDCTime",&TDCTime); 
  EventInfo->Branch("Temp",&Temp);
 
  // Loop over events.
  for (int iEvent=0; iEvent<NEvents; iEvent++)
  {
    ADC.clear();
    a->read_event();

    // Loop over Beetle channels.
    for (int jChannel=0; jChannel<N; jChannel++)
    {
      if(a->data(jChannel)-PedByGain[jChannel]>20) histo_Signal20.Fill(jChannel);
      if(a->data(jChannel)-PedByGain[jChannel]>40) histo_Signal40.Fill(jChannel);
      if(a->data(jChannel)-PedByGain[jChannel]>60) histo_Signal60.Fill(jChannel);
      ADC.push_back(a->data(jChannel));
      ADC_ch[jChannel]->Fill( a->data(jChannel) );
      if(jChannel==200) ADCvsEv->Fill( iEvent, a->data(jChannel) );
    }

    n = iEvent+1;
    TDCTime =a->time();
    for(int t=0; t<N; t++) if(ADC.at(t)-PedByGain[t]>40) {histo_TDC.Fill(TDCTime,1); break;}
    Temp = a->temp();
    EventInfo->Fill();
  }

  cout << "Information in the data: " << endl;
  EventInfo->Print();

  // Close Alibava file.
  a->close();

  // Write and close ROOT file.
  for(int i=0; i<256; i++)
    ADC_ch[i]->Write();
    ADCvsEv->Write();

  output->Write();
  output->Close();

  return;
}