45 mNumberOfADCs{mADCMax - mADCMin + 1},
64 mXminT0 = mFirstTimeBin;
65 mXmaxT0 = mLastTimeBin;
67 mCalDets[
"T0"] =
CalPad(
"T0");
68 mCalDets[
"Width"] =
CalPad(
"Width");
69 mCalDets[
"Qtot"] =
CalPad(
"Qtot");
77 mNbinsT0 =
param.NbinsT0;
78 mXminT0 =
param.XminT0;
79 mXmaxT0 =
param.XmaxT0;
80 mNbinsQtot =
param.NbinsQtot;
81 mXminQtot =
param.XminQtot;
82 mXmaxQtot =
param.XmaxQtot;
83 mNbinsWidth =
param.NbinsWidth;
84 mXminWidth =
param.XminWidth;
85 mXmaxWidth =
param.XmaxWidth;
86 mFirstTimeBin =
param.FirstTimeBin;
87 mLastTimeBin =
param.LastTimeBin;
88 mADCMin =
param.ADCMin;
89 mADCMax =
param.ADCMax;
90 mNumberOfADCs = mADCMax - mADCMin + 1;
91 mPeakIntMinus =
param.PeakIntMinus;
92 mPeakIntPlus =
param.PeakIntPlus;
93 mMinimumQtot =
param.MinimumQtot;
94 mMinimumQmax =
param.MinimumQmax;
95 mMaxTimeBinRange =
param.MaxTimeBinRange;
100 const Int_t timeBin,
Float_t signal)
103 if (timeBin < mFirstTimeBin || timeBin > mLastTimeBin) {
112 if (signal < mADCMin || signal > mADCMax) {
120 if (!adcData.size()) {
122 adcData.resize(mLastTimeBin - mFirstTimeBin + 1);
126 adcData[timeBin - mFirstTimeBin] = signal;
130 auto& timeBinEntries = mTimeBinEntries[
roc];
131 if (!timeBinEntries.size()) {
132 timeBinEntries.resize(mLastTimeBin - mFirstTimeBin + 1);
134 ++timeBinEntries[timeBin - mFirstTimeBin];
147 auto timeRangeROCs = getTimeRangeROCs();
149 for (
const auto& [padROCPos, adcData] : mPulserData) {
156 const auto& elemPair = timeRangeROCs[
int(padROCPos.getROC())];
157 const auto data = processPadData(padROCPos, adcData, elemPair);
161 if (
data.isValid()) {
162 getHistoT0(padROCPos.getROC(),
true)->Fill(
data.mT0 + mFirstTimeBin, currentChannel);
163 getHistoQtot(padROCPos.getROC(),
true)->Fill(
data.mQtot, currentChannel);
164 getHistoSigma(padROCPos.getROC(),
true)->Fill(
data.mWidth, currentChannel);
170 for (
auto&
v : mTimeBinEntries) {
171 std::fill(
v.begin(),
v.end(), 0);
177 int nbins,
float min,
float max,
178 std::string_view
type,
bool create )
180 TH2S*
vec = rocVector[
roc].get();
181 if (
vec || !create) {
186 rocVector[
roc] = std::make_unique<TH2S>(Form(
"hCalib%s%02d",
type.data(),
roc.getRoc()),
187 Form(
"%s calibration histogram ROC %02d",
type.data(),
roc.getRoc()),
191 return rocVector[
roc].get();
202 const auto vectorSize = adcData.size();
204 const auto maxElement = std::max_element(std::begin(adcData) +
range.first, std::begin(adcData) +
range.last);
206 if (*maxElement < mMinimumQmax) {
210 const auto maxPosition = std::distance(std::begin(adcData), maxElement);
212 double weightedSum = 0.;
213 double weightedSum2 = 0.;
214 double chargeSum = 0.;
215 for (
int t = maxPosition - mPeakIntMinus; t <= maxPosition + mPeakIntPlus; ++t) {
216 const auto signal = adcData[t];
218 if (t < 0 || t >= vectorSize) {
221 weightedSum += signal * (t + 0.5);
222 weightedSum2 += signal * (t + 0.5) * (t + 0.5);
226 if (chargeSum > mMinimumQtot) {
227 weightedSum /= chargeSum;
228 weightedSum2 = std::sqrt(std::abs(weightedSum2 / chargeSum - weightedSum * weightedSum));
230 data.mT0 = weightedSum;
231 data.mWidth = weightedSum2;
232 data.mQtot = chargeSum;
239std::array<CalibPulser::ElemPair, ROC::MaxROC> CalibPulser::getTimeRangeROCs()
241 std::array<ElemPair, ROC::MaxROC> maxTimeBin;
243 for (
size_t iROC = 0; iROC < mTimeBinEntries.size(); ++iROC) {
244 const auto& timeBinEntries = mTimeBinEntries[iROC];
245 const auto size = timeBinEntries.size();
246 const auto maxElement = std::max_element(std::begin(timeBinEntries), std::end(timeBinEntries));
247 const auto maxPosition = std::distance(std::begin(timeBinEntries), maxElement);
249 maxTimeBin[iROC].first = (maxPosition > mMaxTimeBinRange) ? maxPosition - mMaxTimeBinRange : 0;
250 maxTimeBin[iROC].last = std::min(
size_t(maxPosition + mMaxTimeBinRange),
size - 1);
260 for (
auto&
v : mTimeBinEntries) {
261 std::fill(
v.begin(),
v.end(), 0);
264 std::vector<PtrVectorType*>
v{&mT0Histograms, &mWidthHistograms, &mQtotHistograms};
265 for (
auto histArray :
v) {
266 for (
auto& histPtr : *histArray) {
267 auto ptr = histPtr.get();
279 auto histT0 = mT0Histograms.at(
roc).get();
280 auto histWidth = mWidthHistograms.at(
roc).get();
281 auto histQtot = mQtotHistograms.at(
roc).get();
283 if (!histT0 || !histWidth || !histQtot) {
288 const auto arrT0 = histT0->GetArray();
289 const auto arrWidth = histWidth->GetArray();
290 const auto arrQtot = histQtot->GetArray();
293 for (
auto iChannel = 0; iChannel < numberOfPads; ++iChannel) {
294 const int offsetT0 = (mNbinsT0 + 2) * (iChannel + 1) + 1;
295 const int offsetQtot = (mNbinsQtot + 2) * (iChannel + 1) + 1;
296 const int offsetWidth = (mNbinsWidth + 2) * (iChannel + 1) + 1;
298 StatisticsData dataT0 = getStatisticsData(arrT0 + offsetT0, mNbinsT0, mXminT0, mXmaxT0);
299 StatisticsData dataWidth = getStatisticsData(arrWidth + offsetWidth, mNbinsWidth, mXminWidth, mXmaxWidth);
300 StatisticsData dataQtot = getStatisticsData(arrQtot + offsetQtot, mNbinsQtot, mXminQtot, mXmaxQtot);
302 mCalDets[
"T0"].getCalArray(
roc).setValue(iChannel, dataT0.
mCOG);
303 mCalDets[
"Width"].getCalArray(
roc).setValue(iChannel, dataWidth.
mCOG);
304 mCalDets[
"Qtot"].getCalArray(
roc).setValue(iChannel, dataQtot.
mCOG);
312 auto f = std::unique_ptr<TFile>(TFile::Open(
filename.c_str(),
"recreate"));
314 f->WriteObject(&mCalDets[
"T0"],
"T0");
315 f->WriteObject(&mCalDets[
"Width"],
"Width");
316 f->WriteObject(&mCalDets[
"Qtot"],
"Qtot");
319 printf(
"dump debug info\n");
322 for (
auto&
val : mT0Histograms) {
326 for (
auto&
val : mWidthHistograms) {
327 vWidth.Add(
val.get());
330 for (
auto&
val : mQtotHistograms) {
331 vQtot.Add(
val.get());
334 vT0.Write(
"T0Histograms", TObject::kSingleKey);
335 vWidth.Write(
"WidthHistograms", TObject::kSingleKey);
336 vQtot.Write(
"QtotHistograms", TObject::kSingleKey);
338 }
else if (
type == 1) {
339 f->WriteObject(
this,
"CalibPulser");
Implementation of the parameter class for the hardware clusterer.
static const CalibPulserParam & Instance()
const T getValue(const int sec, const int globalPadInSector) const
CalibPulser(PadSubset padSubset=PadSubset::ROC)
default constructor
std::vector< float > VectorType
void init()
initialize the clusterer from CalibPedestalParam
void endReader() final
Process the end of one raw reader.
void analyse()
Analyse the buffered pulser information.
Int_t updateROC(const Int_t roc, const Int_t row, const Int_t pad, const Int_t timeBin, const Float_t signal) final
void resetData()
Reset temporary data and histogrms.
std::vector< std::unique_ptr< TH2S > > PtrVectorType
void dumpToFile(const std::string filename, uint32_t type=0) final
Dump the relevant data to file.
int mDebugLevel
debug level
const Mapper & mMapper
TPC mapper.
static constexpr unsigned short getNumberOfPads(const GEMstack gemStack)
GlobalPadNumber getPadNumberInROC(const PadROCPos &rocPadPosition) const
Pad and row inside a ROC.
bool looped() const
if increment operator went above MaxROC
GLint GLint GLsizei GLint GLenum GLenum type
StatisticsData getStatisticsData(const T *arr, const size_t nBins, const double xMin, const double xMax)
Global TPC definitions and constants.
PadSubset
Definition of the different pad subsets.
double mCOG
calculated centre of gravity
constexpr size_t nChannels
std::vector< o2::ctf::BufferType > vec