Commit f41c67fa authored by Fabio Ravera's avatar Fabio Ravera
Browse files

Merge branch 'myDev' into 'Dev'

Periodic merge with OT

See merge request cms_tk_ph2/Ph2_ACF!208
parents 3bff317e e580e832
......@@ -257,7 +257,7 @@ else() # ------------------------------- Compilation in the otsdaq environment -
message(STATUS " Building the Antenna components")
endif(PH2_ANTENNA_FOUND)
# ZeroMQ
# ZeroMQ
find_package(ZMQ) #========================================================
if(ZMQ_FOUND)
find_package(PH2_USBINSTLIB)
......
......@@ -113,8 +113,8 @@ class DQMHistogramBase
myPad->GetUymax(),
myPad->GetUxmax(),
myPad->GetUymax(),
RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(1), isNoise),
RD53chargeConverter::VCAl2Charge(hist->GetXaxis()->GetBinLowEdge(hist->GetXaxis()->GetNbins()), isNoise),
RD53chargeConverter::VCal2Charge(hist->GetXaxis()->GetBinLowEdge(1), isNoise),
RD53chargeConverter::VCal2Charge(hist->GetXaxis()->GetBinLowEdge(hist->GetXaxis()->GetNbins()), isNoise),
510,
"-"));
axes.back()->SetTitle(electronAxisTitle);
......
......@@ -27,21 +27,21 @@ void DataReadbackOptimizationHistograms::book(TFile* theOutputFile, const Detect
size_t nSteps = (stopValueTAP0 - startValueTAP0 + 1 >= RD53Shared::MAXSTEPS ? RD53Shared::MAXSTEPS : stopValueTAP0 - startValueTAP0 + 1);
auto hTAP0scan = CanvasContainer<TH1F>("TAP0scan", "TAP0 scan", nSteps, startValueTAP0, stopValueTAP0 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP0scan, hTAP0scan, "TAP0 - driver", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP0scan, hTAP0scan, "TAP0 - driver", "Bit Error Rate (frames-with-err / frames)");
auto hTAP0 = CanvasContainer<TH1F>("TAP0", "TAP0 - driver", stopValueTAP0 - startValueTAP0 + 1, startValueTAP0, stopValueTAP0 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP0, hTAP0, "TAP0 - driver", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP0, hTAP0, "TAP0 - driver", "Entries");
nSteps = (stopValueTAP1 - startValueTAP1 + 1 >= RD53Shared::MAXSTEPS ? RD53Shared::MAXSTEPS : stopValueTAP1 - startValueTAP1 + 1);
auto hTAP1scan = CanvasContainer<TH1F>("TAP1scan", "TAP1 scan", nSteps, startValueTAP1, stopValueTAP1 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP1scan, hTAP1scan, "TAP1 - pre-emphasis-1", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP1scan, hTAP1scan, "TAP1 - pre-emphasis-1", "Bit Error Rate (frames-with-err / frames)");
auto hTAP1 = CanvasContainer<TH1F>("TAP1", "TAP1 - pre-emphasis-1", stopValueTAP1 - startValueTAP1 + 1, startValueTAP1, stopValueTAP1 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP1, hTAP1, "TAP1 - pre-emphasis-1", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP1, hTAP1, "TAP1 - pre-emphasis-1", "Entries");
nSteps = (stopValueTAP2 - startValueTAP2 + 1 >= RD53Shared::MAXSTEPS ? RD53Shared::MAXSTEPS : stopValueTAP2 - startValueTAP2 + 1);
auto hTAP2scan = CanvasContainer<TH1F>("TAP2scan", "TAP2 scan", nSteps, startValueTAP2, stopValueTAP2 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP2scan, hTAP2scan, "TAP2 - pre-emphasis-2", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP2scan, hTAP2scan, "TAP2 - pre-emphasis-2", "Bit Error Rate (frames-with-err / frames)");
auto hTAP2 = CanvasContainer<TH1F>("TAP2", "TAP2 - pre-emphasis-2", stopValueTAP2 - startValueTAP2 + 1, startValueTAP2, stopValueTAP2 + 1);
bookImplementer(theOutputFile, theDetectorStructure, TAP2, hTAP2, "TAP2 - pre-emphasis-2", "Bit Error Rate");
bookImplementer(theOutputFile, theDetectorStructure, TAP2, hTAP2, "TAP2 - pre-emphasis-2", "Entries");
}
bool DataReadbackOptimizationHistograms::fill(std::vector<char>& dataBuffer)
......
......@@ -34,23 +34,41 @@ void GainHistograms::book(TFile* theOutputFile, const DetectorContainer& theDete
auto hErrorFit2D = CanvasContainer<TH2F>("FitErrors", "Fit Errors", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, ErrorFit2D, hErrorFit2D, "Columns", "Rows");
auto hGain1D = CanvasContainer<TH1F>("Gain1D", "Gain1D", 100, 0, 20e-3);
bookImplementer(theOutputFile, theDetectorStructure, Gain1D, hGain1D, "Gain (ToT/VCal)", "Entries");
auto hIntercept1D = CanvasContainer<TH1F>("Intercept1D", "Intercept1D", 100, -INTERCEPT_HALFRANGE, INTERCEPT_HALFRANGE);
bookImplementer(theOutputFile, theDetectorStructure, Intercept1D, hIntercept1D, "Intercept (ToT)", "Entries");
auto hGain2D = CanvasContainer<TH2F>("Gain2D", "Gain Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Gain2D, hGain2D, "Column", "Row");
auto hSlope1D = CanvasContainer<TH1F>("Slope1D", "Slope1D", 100, -SLOPE_HALFRANGE, SLOPE_HALFRANGE);
bookImplementer(theOutputFile, theDetectorStructure, Slope1D, hSlope1D, "Slope (ToT/VCal)", "Entries");
auto hQuadratic1D = CanvasContainer<TH1F>("Quadratic1D", "Quadratic1D", 100, -QUADRATIC_HALFRANGE, QUADRATIC_HALFRANGE);
bookImplementer(theOutputFile, theDetectorStructure, Quadratic1D, hQuadratic1D, "Quadratic (ToT/VCal^{2})", "Entries");
auto hLog1D = CanvasContainer<TH1F>("Log1D", "Log1D", 100, -LOG_HALFRANGE, LOG_HALFRANGE);
bookImplementer(theOutputFile, theDetectorStructure, Log1D, hLog1D, "Log (ToT/ln(VCal))", "Entries");
auto hChi2DoF1D = CanvasContainer<TH1F>("Chi2DoF1D", "Chi2DoF1D", 100, 0, 2);
bookImplementer(theOutputFile, theDetectorStructure, Chi2DoF1D, hChi2DoF1D, "#chi^{2}/D.o.F.", "Entries");
auto hIntercept2D = CanvasContainer<TH2F>("Intercept2D", "Intercept Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Intercept2D, hIntercept2D, "Column", "Row");
auto hSlope2D = CanvasContainer<TH2F>("Slope2D", "Slope Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Slope2D, hSlope2D, "Column", "Row");
auto hQuadratic2D = CanvasContainer<TH2F>("Quadratic2D", "Quadratic Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Quadratic2D, hQuadratic2D, "Column", "Row");
auto hLog2D = CanvasContainer<TH2F>("Log2D", "Log Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Log2D, hLog2D, "Column", "Row");
auto hChi2DoF2D = CanvasContainer<TH2F>("Chi2DoF2D", "Chi2DoF Map", RD53::nCols, 0, RD53::nCols, RD53::nRows, 0, RD53::nRows);
bookImplementer(theOutputFile, theDetectorStructure, Chi2DoF2D, hChi2DoF2D, "Column", "Row");
}
bool GainHistograms::fill(std::vector<char>& dataBuffer)
{
ChannelContainerStream<OccupancyAndPh, uint16_t> theOccStreamer("GainOcc");
ChannelContainerStream<GainAndIntercept> theGainAndInterceptStreamer("GainGainAndIntercept");
ChannelContainerStream<GainFit> theGainStreamer("GainGain");
if(theOccStreamer.attachBuffer(&dataBuffer))
{
......@@ -59,10 +77,10 @@ bool GainHistograms::fill(std::vector<char>& dataBuffer)
DetectorData.cleanDataStored();
return true;
}
else if(theGainAndInterceptStreamer.attachBuffer(&dataBuffer))
else if(theGainStreamer.attachBuffer(&dataBuffer))
{
theGainAndInterceptStreamer.decodeChipData(DetectorData);
GainHistograms::fillGainAndIntercept(DetectorData);
theGainStreamer.decodeChipData(DetectorData);
GainHistograms::fillGain(DetectorData);
DetectorData.cleanDataStored();
return true;
}
......@@ -92,34 +110,65 @@ void GainHistograms::fillOccupancy(const DetectorDataContainer& OccupancyContain
}
}
void GainHistograms::fillGainAndIntercept(const DetectorDataContainer& GainAndInterceptContainer)
void GainHistograms::fillGain(const DetectorDataContainer& GainContainer)
{
for(const auto cBoard: GainAndInterceptContainer)
for(const auto cBoard: GainContainer)
for(const auto cOpticalGroup: *cBoard)
for(const auto cHybrid: *cOpticalGroup)
for(const auto cChip: *cHybrid)
{
if(cChip->getChannelContainer<GainAndIntercept>() == nullptr) continue;
if(cChip->getChannelContainer<GainFit>() == nullptr) continue;
auto* Gain1DHist = Gain1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Intercept1DHist =
Intercept1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Gain2DHist = Gain2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* Slope1DHist =
Slope1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Quadratic1DHist =
Quadratic1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Log1DHist = Log1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Chi2DoF1DHist =
Chi2DoF1D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH1F>>().fTheHistogram;
auto* Intercept2DHist =
Intercept2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* Slope2DHist =
Slope2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* Quadratic2DHist =
Quadratic2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* Log2DHist = Log2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* Chi2DoF2DHist =
Chi2DoF2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
auto* ErrorFit2DHist =
ErrorFit2D.at(cBoard->getIndex())->at(cOpticalGroup->getIndex())->at(cHybrid->getIndex())->at(cChip->getIndex())->getSummary<CanvasContainer<TH2F>>().fTheHistogram;
for(auto row = 0u; row < RD53::nRows; row++)
for(auto col = 0u; col < RD53::nCols; col++)
if(cChip->getChannel<GainAndIntercept>(row, col).fGain == RD53Shared::FITERROR)
if(cChip->getChannel<GainFit>(row, col).fChi2 == RD53Shared::FITERROR)
ErrorFit2DHist->Fill(col + 1, row + 1);
else if(cChip->getChannel<GainAndIntercept>(row, col).fGain != 0)
else if(cChip->getChannel<GainFit>(row, col).fChi2 != 0)
{
Gain1DHist->Fill(cChip->getChannel<GainAndIntercept>(row, col).fGain);
Intercept1DHist->Fill(cChip->getChannel<GainAndIntercept>(row, col).fIntercept);
Gain2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainAndIntercept>(row, col).fGain);
Intercept2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainAndIntercept>(row, col).fIntercept);
// #################
// # 1D histograms #
// #################
Intercept1DHist->Fill(cChip->getChannel<GainFit>(row, col).fIntercept);
Slope1DHist->Fill(cChip->getChannel<GainFit>(row, col).fSlope);
Quadratic1DHist->Fill(cChip->getChannel<GainFit>(row, col).fQuadratic);
Log1DHist->Fill(cChip->getChannel<GainFit>(row, col).fLog);
Chi2DoF1DHist->Fill(cChip->getChannel<GainFit>(row, col).fChi2 / cChip->getChannel<GainFit>(row, col).fDoF);
// #################
// # 2D histograms #
// #################
Slope2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fSlope);
Slope2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fSlopeError);
Intercept2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fIntercept);
Intercept2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fInterceptError);
Quadratic2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fQuadratic);
Quadratic2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fQuadraticError);
Log2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fLog);
Log2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fLogError);
Chi2DoF2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<GainFit>(row, col).fChi2 / cChip->getChannel<GainFit>(row, col).fDoF);
}
}
}
......@@ -129,8 +178,16 @@ void GainHistograms::process()
draw<TH2F>(Occupancy2D, "gcolz", true, "Charge (electrons)");
draw<TH2F>(ErrorReadOut2D, "gcolz");
draw<TH2F>(ErrorFit2D, "gcolz");
draw<TH1F>(Gain1D, "", true, "Gain (ToT/electrons)");
draw<TH1F>(Intercept1D);
draw<TH2F>(Gain2D, "gcolz");
draw<TH1F>(Slope1D, "", true, "Slope (ToT/electrons)");
draw<TH1F>(Quadratic1D);
draw<TH1F>(Log1D);
draw<TH1F>(Chi2DoF1D);
draw<TH2F>(Intercept2D, "gcolz");
draw<TH2F>(Slope2D, "gcolz");
draw<TH2F>(Quadratic2D, "gcolz");
draw<TH2F>(Log2D, "gcolz");
draw<TH2F>(Chi2DoF2D, "gcolz");
}
......@@ -14,7 +14,7 @@
#include "../System/SystemController.h"
#include "../Utils/ContainerFactory.h"
#include "../Utils/ContainerStream.h"
#include "../Utils/GainAndIntercept.h"
#include "../Utils/GainFit.h"
#include "../Utils/RD53Shared.h"
#include "DQMHistogramBase.h"
......@@ -24,7 +24,10 @@
// #############
// # CONSTANTS #
// #############
#define INTERCEPT_HALFRANGE 6 // [ToT]
#define INTERCEPT_HALFRANGE 30 // [ToT]
#define SLOPE_HALFRANGE 3e-2 // [ToT / VCal]
#define QUADRATIC_HALFRANGE 1e-5 // [ToT / VCal^2]
#define LOG_HALFRANGE 6 // [ToT / ln(VCal)]
class GainHistograms : public DQMHistogramBase
{
......@@ -35,7 +38,7 @@ class GainHistograms : public DQMHistogramBase
void reset() override{};
void fillOccupancy(const DetectorDataContainer& OccupancyContainer, int DELTA_VCAL);
void fillGainAndIntercept(const DetectorDataContainer& GainAndInterceptContainer);
void fillGain(const DetectorDataContainer& GainContainer);
private:
DetectorDataContainer DetectorData;
......@@ -43,10 +46,18 @@ class GainHistograms : public DQMHistogramBase
DetectorDataContainer Occupancy2D;
DetectorDataContainer ErrorReadOut2D;
DetectorDataContainer ErrorFit2D;
DetectorDataContainer Gain1D;
DetectorDataContainer Intercept1D;
DetectorDataContainer Gain2D;
DetectorDataContainer Slope1D;
DetectorDataContainer Quadratic1D;
DetectorDataContainer Log1D;
DetectorDataContainer Chi2DoF1D;
DetectorDataContainer Intercept2D;
DetectorDataContainer Slope2D;
DetectorDataContainer Quadratic2D;
DetectorDataContainer Log2D;
DetectorDataContainer Chi2DoF2D;
size_t nEvents;
size_t nSteps;
......
......@@ -93,9 +93,10 @@ void PhysicsHistograms::fill(const DetectorDataContainer& DataContainer)
{
if(cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy != 0)
{
Occupancy2DHist->SetBinContent(col + 1, row + 1, Occupancy2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy);
ToT1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row, col).fPh);
ToT2DHist->SetBinContent(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPh);
Occupancy2DHist->SetBinContent(col + 1, row + 1, Occupancy2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy);
ToT2DHist->SetBinError(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPhError);
}
if(cChip->getChannel<OccupancyAndPh>(row, col).readoutError == true) ErrorReadOut2DHist->Fill(col + 1, row + 1);
......
......@@ -107,6 +107,7 @@ void PixelAliveHistograms::fill(const DetectorDataContainer& DataContainer)
Occupancy2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy);
ToT1DHist->Fill(cChip->getChannel<OccupancyAndPh>(row, col).fPh);
ToT2DHist->SetBinContent(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPh);
ToT2DHist->SetBinError(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPhError);
}
if(cChip->getChannel<OccupancyAndPh>(row, col).readoutError == true) ErrorReadOut2DHist->Fill(col + 1, row + 1);
}
......
......@@ -94,6 +94,7 @@ void SCurveHistograms::fillOccupancy(const DetectorDataContainer& OccupancyConta
{
hOcc2D->Fill(DELTA_VCAL, cChip->getChannel<OccupancyAndPh>(row, col).fOccupancy + hOcc2D->GetYaxis()->GetBinWidth(0) / 2.);
ToT2DHist->SetBinContent(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPh);
ToT2DHist->SetBinError(col + 1, row + 1, ToT2DHist->GetBinContent(col + 1, row + 1) + cChip->getChannel<OccupancyAndPh>(row, col).fPhError);
}
if(cChip->getChannel<OccupancyAndPh>(row, col).readoutError == true) ErrorReadOut2DHist->Fill(col + 1, row + 1);
}
......@@ -128,10 +129,19 @@ void SCurveHistograms::fillThrAndNoise(const DetectorDataContainer& ThrAndNoiseC
ErrorFit2DHist->Fill(col + 1, row + 1);
else if(cChip->getChannel<ThresholdAndNoise>(row, col).fNoise != 0)
{
// #################
// # 1D histograms #
// #################
Threshold1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row, col).fThreshold);
Noise1DHist->Fill(cChip->getChannel<ThresholdAndNoise>(row, col).fNoise);
// #################
// # 2D histograms #
// #################
Threshold2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<ThresholdAndNoise>(row, col).fThreshold);
Threshold2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<ThresholdAndNoise>(row, col).fThresholdError);
Noise2DHist->SetBinContent(col + 1, row + 1, cChip->getChannel<ThresholdAndNoise>(row, col).fNoise);
Noise2DHist->SetBinError(col + 1, row + 1, cChip->getChannel<ThresholdAndNoise>(row, col).fNoiseError);
}
}
}
......
......@@ -98,7 +98,7 @@ constexpr float cap = 8.5; // [fF]
constexpr float ele = 1.6; // [e-19]
constexpr float offset = 64; // Due to VCal_High vs VCal_Med offset difference [e-]
constexpr float VCAl2Charge(float VCal, bool isNoise = false) { return (par0 / par1) * VCal / ele * cap * 1e4 + (isNoise == false ? offset : 0); }
constexpr float VCal2Charge(float VCal, bool isNoise = false) { return (par0 / par1) * VCal / ele * cap * 1e4 + (isNoise == false ? offset : 0); }
constexpr float Charge2VCal(float Charge) { return (Charge - offset) / (cap * 1e4) * ele / (par0 / par1); }
} // namespace RD53chargeConverter
......
......@@ -196,6 +196,7 @@ void RD53FWInterface::ConfigureFromXML(const BeBoard* pBoard)
{
RegManager::WriteStackReg(cVecReg);
RD53FWInterface::SendBoardCommand("user.ctrl_regs.fast_cmd_reg_1.load_config");
RD53FWInterface::SendBoardCommand("user.ctrl_regs.ext_tlu_reg2.dio5_load_config");
}
LOG(INFO) << BOLDBLUE << "\t--> Done" << RESET;
......@@ -1286,15 +1287,11 @@ double RD53FWInterface::RunBERtest(bool given_time, double frames_or_time, uint1
{
time2run = frames_or_time;
frames2run = time2run * fps;
LOG(INFO) << GREEN << "Running " << BOLDYELLOW << std::fixed << std::setprecision(1) << time2run << RESET << GREEN << "s will send about " << BOLDYELLOW << std::setprecision(0) << frames2run
<< RESET << GREEN << " frames" << RESET;
}
else
{
frames2run = frames_or_time;
time2run = frames2run / fps;
LOG(INFO) << GREEN << "Running " << BOLDYELLOW << std::fixed << std::setprecision(0) << frames2run << RESET << GREEN << " frames will take about " << BOLDYELLOW << std::setprecision(1)
<< time2run << RESET << GREEN << "s" << RESET;
}
// Configure number of printouts and calculate the frequency of printouts
......@@ -1318,10 +1315,10 @@ double RD53FWInterface::RunBERtest(bool given_time, double frames_or_time, uint1
// #########
WriteStackReg({{"user.ctrl_regs.PRBS_checker.start_checker", 1}, {"user.ctrl_regs.PRBS_checker.start_checker", 0}});
LOG(INFO) << BOLDGREEN << "===== BER run starting =====" << RESET;
LOG(INFO) << BOLDGREEN << "===== BER run starting =====" << std::fixed << std::setprecision(0) << RESET;
bool run_done = false;
int idx = 1;
uint64_t frameCounter = 0;
uint64_t frameCounter = 0, nErrors = 0;
while(run_done == false)
{
std::this_thread::sleep_for(std::chrono::seconds(static_cast<unsigned int>(time_per_step)));
......@@ -1335,10 +1332,11 @@ double RD53FWInterface::RunBERtest(bool given_time, double frames_or_time, uint1
return -1;
}
frameCounter = bits::pack<32, 32>(cntr_hi, cntr_lo);
nErrors += RegManager::ReadReg("user.stat_regs.prbs_ber_cntr");
double percent_done = frameCounter / frames2run * 100.;
LOG(INFO) << GREEN << "I've been running for " << BOLDYELLOW << time_per_step * idx << RESET << GREEN << "s (" << BOLDYELLOW << percent_done << RESET << GREEN << "% done)" << RESET;
LOG(INFO) << GREEN << "Current BER counter: " << BOLDYELLOW << RegManager::ReadReg("user.stat_regs.prbs_ber_cntr") << RESET << GREEN << " frames with error(s)" << RESET;
LOG(INFO) << GREEN << "Current BER counter: " << BOLDYELLOW << nErrors << RESET << GREEN << " frames with error(s)" << RESET;
if(given_time == true)
run_done = (time_per_step * idx >= time2run);
else
......@@ -1356,14 +1354,14 @@ double RD53FWInterface::RunBERtest(bool given_time, double frames_or_time, uint1
cntr_lo = RegManager::ReadReg("user.stat_regs.prbs_frame_cntr_low");
cntr_hi = RegManager::ReadReg("user.stat_regs.prbs_frame_cntr_high");
frameCounter = bits::pack<32, 32>(cntr_hi, cntr_lo);
auto nErrors = RegManager::ReadReg("user.stat_regs.prbs_ber_cntr");
nErrors += RegManager::ReadReg("user.stat_regs.prbs_ber_cntr");
LOG(INFO) << BOLDGREEN << "===== BER test summary =====" << RESET;
LOG(INFO) << GREEN << "Final number of PRBS frames sent: " << BOLDYELLOW << frameCounter << RESET;
LOG(INFO) << GREEN << "Final BER counter: " << BOLDYELLOW << nErrors << RESET << GREEN << " frames with error(s), i.e. " << BOLDYELLOW << nErrors / frameCounter * 100 << RESET << GREEN
<< "% of errors" << RESET;
LOG(INFO) << GREEN << "Final BER counter: " << BOLDYELLOW << nErrors << RESET << GREEN << " frames with error(s), i.e. BER = " << BOLDYELLOW << nErrors * nBitInClkPeriod / frames2run << RESET
<< GREEN << " bits/clk (" << BOLDYELLOW << nErrors / frames2run * 100 << RESET << GREEN << "%)" << RESET;
LOG(INFO) << BOLDGREEN << "====== End of summary ======" << RESET;
return nErrors;
return nErrors / frames2run;
}
} // namespace Ph2_HwInterface
......@@ -143,7 +143,7 @@ bool RD53lpGBTInterface::WriteChipMultReg(Chip* pChip, const std::vector<std::pa
// # LpGBT specific routine functions #
// ####################################
void RD53lpGBTInterface::ExternalPhaseAlignRx(Chip* pChip,
bool RD53lpGBTInterface::ExternalPhaseAlignRx(Chip* pChip,
const BeBoard* pBoard,
const OpticalGroup* pOpticalGroup,
BeBoardFWInterface* pBeBoardFWInterface,
......@@ -151,6 +151,7 @@ void RD53lpGBTInterface::ExternalPhaseAlignRx(Chip* pChip,
{
const double frames_or_time = 1; // @CONST@
const bool given_time = true;
bool allGood = true;
uint32_t frontendSpeed = static_cast<RD53FWInterface*>(pBeBoardFWInterface)->ReadoutSpeed();
LOG(INFO) << GREEN << "Phase alignment ongoing for LpGBT chip: " << BOLDYELLOW << pChip->getId() << RESET;
......@@ -159,7 +160,7 @@ void RD53lpGBTInterface::ExternalPhaseAlignRx(Chip* pChip,
if(static_cast<lpGBT*>(pChip)->getPhaseRxAligned() == true)
{
LOG(INFO) << BOLDBLUE << "\t--> The phase for this chip was already aligned (maybe from configuration file)" << RESET;
return;
return true;
}
for(const auto cHybrid: *pOpticalGroup)
......@@ -215,11 +216,16 @@ void RD53lpGBTInterface::ExternalPhaseAlignRx(Chip* pChip,
LOG(INFO) << BOLDBLUE << "\t--> Rx Group " << BOLDYELLOW << +cGroup << BOLDBLUE << " Channel " << BOLDYELLOW << +cChannel << BOLDBLUE << " has phase " << BOLDYELLOW << +bestPhase
<< RESET;
else
{
LOG(INFO) << BOLDBLUE << "\t--> Rx Group " << BOLDYELLOW << +cGroup << BOLDBLUE << " Channel " << BOLDYELLOW << +cChannel << BOLDRED << " has no good phase" << RESET;
allGood = false;
}
lpGBTInterface::ConfigureRxPhase(pChip, cGroup, cChannel, bestPhase);
static_cast<lpGBT*>(pChip)->setPhaseRxAligned(true); // @TMP@
static_cast<lpGBT*>(pChip)->setPhaseRxAligned(allGood); // @TMP@
}
return allGood;
}
} // namespace Ph2_HwInterface
......@@ -24,7 +24,7 @@ class RD53lpGBTInterface : public lpGBTInterface
bool WriteChipMultReg(Ph2_HwDescription::Chip* pChip, const std::vector<std::pair<std::string, uint16_t>>& RegVec, bool pVerifLoop = true) override;
uint16_t ReadChipReg(Ph2_HwDescription::Chip* pChip, const std::string& pRegNode) override;
void ExternalPhaseAlignRx(Ph2_HwDescription::Chip* pChip,
bool ExternalPhaseAlignRx(Ph2_HwDescription::Chip* pChip,
const Ph2_HwDescription::BeBoard* pBoard,
const Ph2_HwDescription::OpticalGroup* pOpticalGroup,
Ph2_HwInterface::BeBoardFWInterface* pBeBoardFWInterface,
......
......@@ -658,6 +658,7 @@ double lpGBTInterface::RunBERtest(Chip* pChip, uint8_t pGroup, uint8_t pChannel,
// # 320 Mbit/s = 2 #
// ####################
{
const double mainClock = 40e6; // @CONST@
const uint32_t nBitInClkPeriod = 32. / std::pow(2, frontendSpeed); // Number of bits in the 40 MHz clock period
const double fps = 1.28e9 / nBitInClkPeriod; // Frames per second
const int n_prints = 10; // Only an indication, the real number of printouts will be driven by the length of the time steps @CONST@
......@@ -665,20 +666,11 @@ double lpGBTInterface::RunBERtest(Chip* pChip, uint8_t pGroup, uint8_t pChannel,
double time2run;
if(given_time == true)
{
time2run = frames_or_time;
frames2run = time2run * fps;
LOG(INFO) << GREEN << "Running " << BOLDYELLOW << std::fixed << std::setprecision(0) << time2run << RESET << GREEN << "s will send about " << BOLDYELLOW << frames2run << RESET << GREEN
<< " frames" << RESET;
}
time2run = frames_or_time;
else
{
frames2run = frames_or_time;
time2run = frames2run / fps;
LOG(INFO) << GREEN << "Running " << BOLDYELLOW << std::fixed << std::setprecision(0) << frames2run << RESET << GREEN << " frames will take about " << BOLDYELLOW << time2run << RESET << GREEN
<< "s" << RESET;
}
uint32_t BERTMeasTime = (log2(time2run * 40e6) - 5) / 2.;
time2run = frames_or_time / fps;
uint32_t BERTMeasTime = (log2(time2run * mainClock) - 5) / 2.;
frames2run = fBERTMeasTimeMap[BERTMeasTime];
// Configure number of printouts and calculate the frequency of printouts
double time_per_step = std::min(std::max(time2run / n_prints, 1.), 3600.); // The runtime of the PRBS test will have a precision of one step (at most 1h and at least 1s)
......@@ -696,17 +688,16 @@ double lpGBTInterface::RunBERtest(Chip* pChip, uint8_t pGroup, uint8_t pChannel,
lpGBTInterface::StartBERT(pChip, true); // Stert
std::this_thread::sleep_for(std::chrono::microseconds(RD53Shared::DEEPSLEEP));
LOG(INFO) << BOLDGREEN << "===== BER run starting =====" << RESET;
LOG(INFO) << BOLDGREEN << "===== BER run starting =====" << std::fixed << std::setprecision(0) << RESET;
int idx = 1;
while(lpGBTInterface::IsBERTDone(pChip) == false)
{
std::this_thread::sleep_for(std::chrono::seconds(static_cast<unsigned int>(time_per_step)));
LOG(INFO) << GREEN << "I've been running for " << BOLDYELLOW << time_per_step * idx << RESET << GREEN << "s" << RESET;
LOG(INFO) << GREEN << "Current BER counter: " << BOLDYELLOW << lpGBTInterface::GetBERTErrors(pChip) << RESET << GREEN << " frames with error(s)" << RESET;
LOG(INFO) << GREEN << "Current BER counter: " << BOLDYELLOW << lpGBTInterface::GetBERTErrors(pChip) / nBitInClkPeriod << RESET << GREEN << " frames with error(s)" << RESET;
idx++;
}
frames2run = time_per_step * idx * fps;
LOG(INFO) << BOLDGREEN << "========= Finished =========" << RESET;
if(lpGBTInterface::IsBERTEmptyData(pChip) == true)
......@@ -718,17 +709,17 @@ double lpGBTInterface::RunBERtest(Chip* pChip, uint8_t pGroup, uint8_t pChannel,
// ########
// # Stop #
// ########
auto nErrors = lpGBTInterface::GetBERTErrors(pChip);
auto nErrors = lpGBTInterface::GetBERTErrors(pChip) / nBitInClkPeriod;
lpGBTInterface::StartBERT(pChip, false); // Stop
// Read PRBS frame counter
LOG(INFO) << BOLDGREEN << "===== BER test summary =====" << RESET;
LOG(INFO) << GREEN << "Final number of PRBS frames sent: " << BOLDYELLOW << frames2run << RESET;
LOG(INFO) << GREEN << "Final BER counter: " << BOLDYELLOW << nErrors << RESET << GREEN << " frames with error(s), i.e. " << BOLDYELLOW << nErrors / frames2run * 100 << RESET << GREEN
<< "% of errors" << RESET;
LOG(INFO) << GREEN << "Final BER counter: " << BOLDYELLOW << nErrors << RESET << GREEN << " frames with error(s), i.e. BER = " << BOLDYELLOW << nErrors * nBitInClkPeriod / frames2run << RESET
<< GREEN << " bits/clk (" << BOLDYELLOW << nErrors / frames2run * 100 << RESET << GREEN << "%)" << RESET;
LOG(INFO) << BOLDGREEN << "====== End of summary ======" << RESET;
return nErrors;
return nErrors / frames2run;
}
void lpGBTInterface::StartPRBSpattern(Chip* pChip)
......
......@@ -39,11 +39,14 @@ class lpGBTInterface : public ChipInterface
void StartPRBSpattern(Ph2_HwDescription::Chip* pChip);
void StopPRBSpattern(Ph2_HwDescription::Chip* pChip);
virtual void ExternalPhaseAlignRx(Ph2_HwDescription::Chip* pChip,
virtual bool ExternalPhaseAlignRx(Ph2_HwDescription::Chip* pChip,
const Ph2_HwDescription::BeBoard* pBoard,
const Ph2_HwDescription::OpticalGroup* pOpticalGroup,
Ph2_HwInterface::BeBoardFWInterface* pBeBoardFWInterface,
ReadoutChipInterface* pReadoutChipInterface){};
ReadoutChipInterface* pReadoutChipInterface)
{
return true;
};
// #######################################
// # LpGBT block configuration functions #
......@@ -220,6 +223,22 @@ class lpGBTInterface : public ChipInterface
{18, "READY"}};
std::map<std::string, uint8_t> revertedPUSMStatusMap;
std::map<uint8_t, double> fBERTMeasTimeMap = {{0, RD53Shared::setBits(4) + 1},
{1, RD53Shared::setBits(6) + 1},
{2, RD53Shared::setBits(8) + 1},
{3, RD53Shared::setBits(10) + 1},
{4, RD53Shared::setBits(12) + 1},
{5, RD53Shared::setBits(14) + 1},
{6, RD53Shared::setBits(16) + 1},
{7, RD53Shared::setBits(18) + 1},
{8, RD53Shared::setBits(20) + 1},
{9, RD53Shared::setBits(22) + 1},
{10, RD53Shared::setBits(24) + 1},
{11, RD53Shared::setBits(26) + 1},
{12, RD53Shared::setBits(28) + 1},
{13, RD53Shared::setBits(30) + 1},
{14, RD53Shared::setBits(32) + 1},
{15, RD53Shared::setBits(34) + 1}};
std::map<uint8_t, std::string> fEOMStatusMap = {{0, "smIdle"}, {1, "smResetCounters"}, {2, "smCount"}, {3, "smEndOfCount"}};