Commit 873e6020 authored by Fabio Ravera's avatar Fabio Ravera
Browse files

Merge branch 'TestPulseCalibration' into 'Dev'

Test pulse calibration

See merge request !93
parents 77421748 339f14fd
#include <cstring>
#include "../Utils/Utilities.h"
#include "../Utils/Timer.h"
#include "../tools/Tool.h"
#include "../tools/PedeNoise.h"
#include "../tools/SignalScan.h"
#include "../tools/TPCalibration.h"
#include "../tools/SignalScanFit.h"
#include "../tools/LatencyScan.h"
#include "../Utils/argvparser.h"
#include "TROOT.h"
#include "TApplication.h"
using namespace Ph2_HwDescription;
using namespace Ph2_HwInterface;
using namespace Ph2_System;
using namespace CommandLineProcessing;
INITIALIZE_EASYLOGGINGPP
int main ( int argc, char* argv[] )
{
//configure the logger
el::Configurations conf ("settings/logger.conf");
el::Loggers::reconfigureAllLoggers (conf);
ArgvParser cmd;
// init
cmd.setIntroductoryDescription ( "CMS Ph2_ACF test pulse calibration tool to perform the calibration of threshold gain calibration" );
// error codes
cmd.addErrorCode ( 0, "Success" );
cmd.addErrorCode ( 1, "Error" );
// options
cmd.setHelpOption ( "h", "help", "Print this help page" );
cmd.defineOption ( "file", "Hw Description File . Default value: settings/d19c_test.xml", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative ( "file", "f" );
cmd.defineOption ( "start", "start value for test pulse amplitude, default: 165", ArgvParser::OptionRequiresValue );
cmd.defineOptionAlternative ( "start", "s" );
cmd.defineOption ( "end", "end of test pulse amplitudes to be tested, default: 255", ArgvParser::OptionRequiresValue );
cmd.defineOptionAlternative ( "end", "e" );
cmd.defineOption ( "stepsize", "stepsize for the test pulse calibration, default: 10", ArgvParser::OptionRequiresValue );
cmd.defineOption ( "output", "Output Directory . Default value: Results/", ArgvParser::OptionRequiresValue /*| ArgvParser::OptionRequired*/ );
cmd.defineOptionAlternative ( "output", "o" );
cmd.defineOption ( "batch", "Run the application in batch mode", ArgvParser::NoOptionAttribute );
cmd.defineOptionAlternative ( "batch", "b" );
int result = cmd.parse ( argc, argv );
if ( result != ArgvParser::NoParserError )
{
LOG (INFO) << cmd.parseErrorDescription ( result );
exit ( 1 );
}
// now query the parsing results
std::string cHWFile = ( cmd.foundOption ( "file" ) ) ? cmd.optionValue ( "file" ) : "settings/d19c_test.xml";
std::string cDirectory = ( cmd.foundOption ( "output" ) ) ? cmd.optionValue ( "output" ) : "Results/TPCalibration";
//reasonable start and end values for the CBC3 (for amplitudes lower than 165,
//larger test pulse charges, the behavior is not linear anymore)
int cStartAmp = (cmd.foundOption( "start" ) ) ? convertAnyInt(cmd.optionValue ( "start" ).c_str() ) : 165;
int cEndAmp = (cmd.foundOption( "end" ) ) ? convertAnyInt(cmd.optionValue ( "end" ).c_str() ) : 255;
int cStepSize = (cmd.foundOption( "stepsize" ) ) ? convertAnyInt(cmd.optionValue ( "stepsize" ).c_str() ) : 10;
bool batchMode = ( cmd.foundOption ( "batch" ) ) ? true : false;
TApplication cApp ( "Root Application", &argc, argv );
if ( batchMode ) gROOT->SetBatch ( true );
else TQObject::Connect ( "TCanvas", "Closed()", "TApplication", &cApp, "Terminate()" );
std::string cResultfile = "TPCalibration";
//Record the Pedestals for each Testpulse amplitude and then do a fit
std::stringstream outp;
LOG(INFO) << BOLDBLUE << "Do test pulse calibration for the range:" << RESET;
Timer t;
t.start();
TPCalibration cTBCalibrate;
cTBCalibrate.InitializeHw ( cHWFile, outp);
cTBCalibrate.InitializeSettings ( cHWFile, outp );
LOG (INFO) << outp.str();
cTBCalibrate.CreateResultDirectory ( cDirectory );
cTBCalibrate.InitResultFile ( cResultfile );
cTBCalibrate.StartHttpServer();
cTBCalibrate.ConfigureHw ();
cTBCalibrate.Initialise(false);
cTBCalibrate.Init(cStartAmp, cEndAmp, cStepSize);
//Now do the actual calirbation
cTBCalibrate.RunCalibration();
cTBCalibrate.SaveResults();
t.stop();
t.show("Time to run the test pulse calibration ");
return 0;
}
......@@ -269,7 +269,7 @@ std::string PedeNoise::sweepSCurves (uint8_t pTPAmplitude)
setFWTestPulse();
setSystemTestPulse ( fTestPulseAmplitude, cTGrpM.first, true, fHoleMode );
}
else if (fTestPulse && cTGrpM.first == -1)
else if (fAllChan && fTestPulse && cTGrpM.first == -1)
{
fTestPulse = false;
LOG (INFO) << RED << "Test groups disabled. Can't enable Test Pulse for Test Group " << cTGrpM.first << RESET ;
......
#include "TPCalibration.h"
TPCalibration::TPCalibration()
{
LOG(INFO) << "Constructor of TPCalibration" << RESET;
PedeNoise();
fTPCount = 0;
fStartAmp = 165;
fEndAmp = 255;
fStepsize = 10;
}
TPCalibration::~TPCalibration()
{
LOG(INFO) << "Close output file" << RESET;
fResultFile->Close();
}
void TPCalibration::Init(int pStartAmp, int pEndAmp, int pStepsize)
{
LOG(INFO) << "Initialize the test pulse calibration" << RESET;
LOG(INFO) << "Measure for amplitudes from " << pStartAmp << " till "
<< pEndAmp << " in steps of " << pStepsize << RESET;
fStartAmp = pStartAmp;
fStepsize = pStepsize;
fEndAmp = pEndAmp;
LOG(INFO) << "Initialise histograms" << RESET;
for(auto &cBoard : fBoardVector)
{
int cBeId = cBoard->getBeId();
LOG(INFO) << "BeBoard" << cBeId << RESET;
for(auto &cFe : cBoard->fModuleVector)
{
int cFeId = cFe->getFeId();
LOG(INFO) << " FE" << cFeId << RESET;
for(auto &cCbc: cFe->fCbcVector)
{
int cCbcId = cCbc->getCbcId();
LOG(INFO) << " - CBC" << cCbcId << RESET;
for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
{
TGraph* cChanCorr = new TGraph((fEndAmp-fStartAmp)/fStepsize + 1);
cChanCorr->SetTitle(Form("Correlation Channel %d", cChannel) );
cChanCorr->SetName(Form("CorrChannel%d", cChannel) );
cChanCorr->GetXaxis()->SetTitle("pedestal (VCth)");
cChanCorr->GetYaxis()->SetTitle("test pulse amplitude (ADC)");
bookHistogram(cCbc, Form("CorrChan%d", cChannel), cChanCorr);
}
TH1F* cChannelGain = new TH1F(Form("GainFe%dCbc%d",cFeId, cCbcId),
Form("GainFe%dCbc%d",cFeId, cCbcId),
NCHANNELS, -0.5, NCHANNELS - 0.5);
cChannelGain->GetXaxis()->SetTitle("channel");
cChannelGain->GetYaxis()->SetTitle("gain (Amp)");
bookHistogram(cCbc, "ChannelGain", cChannelGain);
TH1F* cChannelElGain = new TH1F(Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
Form("GainElectronsFe%dCbc%d",cFeId, cCbcId),
NCHANNELS, -0.5, NCHANNELS - 0.5);
cChannelElGain->GetXaxis()->SetTitle("channel");
cChannelElGain->GetYaxis()->SetTitle("gain (electrons)");
bookHistogram(cCbc, "ChannelElectronsGain", cChannelElGain);
}
}
}
}
void TPCalibration::RunCalibration()
{
LOG(INFO) << GREEN << "Start the test pulse calibration" << RESET;
fTPCount = 0;
for(int cTPAmp = fStartAmp; cTPAmp <= fEndAmp; cTPAmp += fStepsize)
{
LOG(INFO) << BLUE << "Measure pedestals for amplitude " << cTPAmp << RESET;
measureNoise(cTPAmp);
FillHistograms(cTPAmp);
fTPCount++;
}
FitCorrelations();
}
void TPCalibration::FillHistograms(int pTPAmp)
{
LOG(INFO) << "Fill the histogram with the measured pedestals" << RESET;
for(auto &cBoard : fBoardVector)
{
int cBeId = cBoard->getBeId();
LOG(INFO) << "BeBoard" << cBeId << RESET;
for(auto &cFe : cBoard->fModuleVector)
{
int cFeId = cFe->getFeId();
LOG(INFO) << " FE" << cFeId << RESET;
for(auto &cCbc: cFe->fCbcVector)
{
int cCbcId = cCbc->getCbcId();
LOG(INFO) << " - CBC" << cCbcId << RESET;
TH1F* cPedestalHist = dynamic_cast<TH1F*>(getHist(cCbc, "Cbc_Strippedestal"));
for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
{
TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
int bin = cChannel + 1;
float cPed = cPedestalHist->GetBinContent(bin);
cCorrGraph->SetPoint(fTPCount, cPed , pTPAmp);
//Reset the histograms, so that it can be refilled for the next
//test pulse amplitude
cPedestalHist->SetBinContent(bin, 0);
cPedestalHist->SetBinError(bin, 0);
}
}
}
}
}
void TPCalibration::FitCorrelations()
{
LOG(INFO) << BOLDBLUE << "Linear fit of the correlations" << RESET;
for(auto &cBoard : fBoardVector)
{
int cBeId = cBoard->getBeId();
LOG(INFO) << "BeBoard" << cBeId << RESET;
for(auto &cFe : cBoard->fModuleVector)
{
int cFeId = cFe->getFeId();
LOG(INFO) << " FE" << cFeId << RESET;
std::vector<float> cGainVec;
for(auto &cCbc: cFe->fCbcVector)
{
int cCbcId = cCbc->getCbcId();
TH1F* cChannelGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelGain"));
TH1F* cChannelElGain = dynamic_cast<TH1F*>(getHist(cCbc, "ChannelElectronsGain"));
for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
{
TGraph* cCorrGraph = dynamic_cast<TGraph*>(getHist(cCbc, Form("CorrChan%d", cChannel)));
cCorrGraph->Fit("pol1", "Q");
float cGain = cCorrGraph->GetFunction("pol1")->GetParameter(1);
float cGainErr = cCorrGraph->GetFunction("pol1")->GetParError(1);
cChannelGain->SetBinContent(cChannel + 1, cGain);
cChannelGain->SetBinError(cChannel + 1, cGainErr);
cChannelElGain->SetBinContent(cChannel + 1, ConvertAmpToElectrons(cGain, false));
cChannelElGain->SetBinError(cChannel + 1, ConvertAmpToElectrons(cGainErr, false));
cGainVec.push_back(cGain);
}
//Make a histogram of the Gains in Amplitudes and Electrons
TString cHistName = Form("GainHistFe%dCbc%d", cFeId, cCbcId);
float cBinWidth = 0.005;
float cMin = cChannelGain->GetMinimum()*0.9;
float cMax = cChannelGain->GetMaximum()*1.1;
TH1F* cGainHist = new TH1F(cHistName, cHistName, (cMax-cMin)/cBinWidth, cMin, cMax);
cGainHist->GetXaxis()->SetTitle("gain (Amp/VCth)");
cHistName = Form("GainElectronsHistFe%dCbc%d", cFeId, cCbcId);
TH1F* cGainElHist = new TH1F(cHistName, cHistName,(cMax-cMin)/cBinWidth,
ConvertAmpToElectrons(cMin, false),
ConvertAmpToElectrons(cMax, false));
cGainElHist->GetXaxis()->SetTitle("gain (electrons/VCth)");
for(auto cGain : cGainVec)
{
cGainHist->Fill(cGain);
cGainElHist->Fill(ConvertAmpToElectrons(cGain, false));
}
LOG(INFO) << " - CBC" << cCbcId << ": Gain = " << GREEN
<< cGainElHist->GetMean() << "+-" << cGainElHist->GetStdDev()
<< RESET;
bookHistogram(cCbc, "GainHist", cGainHist);
bookHistogram(cCbc, "GainElectronsHist", cGainElHist);
}
}
}
}
void TPCalibration::SaveResults()
{
LOG(INFO) << BOLDGREEN << "Write results to file: " << fResultFile->GetName()
<< RESET;
for(auto &cBoard : fBoardVector)
{
int cBeId = cBoard->getBeId();
TString cPath = Form("Be%d", cBeId);
fResultFile->mkdir(cPath);
for(auto &cFe : cBoard->fModuleVector)
{
int cFeId = cFe->getFeId();
cPath = Form("Be%d/Fe%d", cBeId, cFeId);
fResultFile->mkdir(cPath);
for(auto &cCbc: cFe->fCbcVector)
{
int cCbcId = cCbc->getCbcId();
cPath = Form("Be%d/Fe%d/Cbc%d", cBeId, cFeId, cCbcId);
fResultFile->mkdir(cPath);
fResultFile->cd(cPath);
TH1F* cChannelHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelGain"));
cChannelHist->Write();
TH1F* cChannelElHist = dynamic_cast<TH1F*> (getHist(cCbc, "ChannelElectronsGain"));
cChannelElHist->Write();
TH1F* cGainHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainHist"));
cGainHist->Write();
TH1F* cGainElHist = dynamic_cast<TH1F*>(getHist(cCbc, "GainElectronsHist"));
cGainElHist->Write();
cPath = Form("Be%d/Fe%d/Cbc%d/ChannelCorr", cBeId, cFeId, cCbcId);
fResultFile->mkdir(cPath);
fResultFile->cd(cPath);
for(int cChannel = 0; cChannel < NCHANNELS; cChannel++)
{
TGraph* cChanCorr = dynamic_cast<TGraph*> (getHist(cCbc, Form("CorrChan%d", cChannel)));
cChanCorr->Write();
}
}
}
}
fResultFile->Flush();
LOG(INFO) << "Results saved!" << RESET;
}
float TPCalibration::ConvertAmpToElectrons(float pTPAmp, bool pOffset=true)
{
// Test pulse step resolution (of 0.086fC = 537electrons)
// taken from the CBC3 manual (should be the same for CBC2)
// 255 equals no test pulse with decreasing values the injected charge
// increases
if(!pOffset)
{
return pTPAmp*537.;
}
return -(pTPAmp - 255)*537.;
}
#ifndef TPCalibration_h__
#define TPCalibration_h__
#include "Tool.h"
#include "TCanvas.h"
#include "TGraph.h"
#include "TH1F.h"
#include "PedeNoise.h"
using namespace Ph2_HwDescription;
using namespace Ph2_HwInterface;
using namespace Ph2_System;
class TPCalibration : public PedeNoise
{
private: //attributes
int fStartAmp;
int fEndAmp;
int fStepsize;
int fTPCount;
public: //methods
TPCalibration();
~TPCalibration();
void Init(int pStartAmp, int pEndAmp, int pStepsize);
void RunCalibration();
void SaveResults();
float ConvertAmpToElectrons(float pTPAmp, bool pOffset);
private: //methods
void FillHistograms(int pTPAmp);
void FitCorrelations();
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment