25#include "TMatrixDSym.h"
26#include "TDecompChol.h"
34#include "TStopwatch.h"
41#include <fairlogger/Logger.h>
54 mSmoothPol2[
VoxX] =
true;
55 mSmoothPol2[
VoxF] =
true;
59 mIsInitialized =
true;
66 LOG(info) <<
"Initialization complete";
73 LOG(
error) <<
"Binning already initialized, not changing y/x binning";
78 LOGP(info,
"Empty binning provided, will use default uniform y/x binning with {} bins", mNY2XBins);
80 }
else if (
binning.size() == 1) {
83 LOGP(info,
"Setting uniform binning for y/x with {} bins",
bins - 1);
87 const int nBins =
binning.size() - 1;
88 if (std::abs(
binning[0] + 1.f) > param::sEps || std::abs(
binning[nBins] - 1.f) > param::sEps) {
89 LOG(
error) <<
"Provided binning for y/x not in range -1 to 1: " <<
binning[0] <<
" - " <<
binning[nBins] <<
". Not changing y/x binning";
93 LOGP(info,
"Setting custom binning for y/x with {} bins", nBins);
95 mUniformBins[
VoxF] =
false;
98 mY2XBinsCenter.clear();
99 for (
int iBin = 0; iBin < nBins; ++iBin) {
101 mY2XBinsDI.push_back(.5f / mY2XBinsDH[iBin]);
102 mY2XBinsCenter.push_back(
binning[iBin] + mY2XBinsDH[iBin]);
103 LOGF(info,
"Bin %i: center (%.3f), half bin width (%.3f)", iBin, mY2XBinsCenter.back(), mY2XBinsDH.back());
110 if (mIsInitialized) {
111 LOG(
error) <<
"Binning already initialized, not changing z/x binning";
116 LOGP(info,
"Empty binning provided, will use default uniform z/x binning with {} bins", mNZ2XBins);
118 }
else if (
binning.size() == 1) {
121 LOGP(info,
"Setting uniform binning for z/x with {} bins",
bins);
125 int nBins =
binning.size() - 1;
126 if (std::abs(
binning[0]) > param::sEps || std::abs(
binning[nBins] - 1.f) > param::sEps) {
127 LOG(
error) <<
"Provided binning for z/x not in range 0 to 1: " <<
binning[0] <<
" - " <<
binning[nBins] <<
". Not changing z/x binning";
131 LOGP(info,
"Setting custom binning for z/x with {} bins", nBins);
133 mUniformBins[
VoxZ] =
false;
136 mZ2XBinsCenter.clear();
138 LOGP(info,
"Using maxZ2X {} for setZ2XBinning", maxZ2X);
139 for (
int iBin = 0; iBin < nBins; ++iBin) {
140 mZ2XBinsDH.push_back(.5f * (
binning[iBin + 1] -
binning[iBin]) * maxZ2X);
141 mZ2XBinsDI.push_back(.5f / mZ2XBinsDH[iBin]);
142 mZ2XBinsCenter.push_back(
binning[iBin] * maxZ2X + mZ2XBinsDH[iBin]);
143 LOGF(info,
"Bin %i: center (%.3f), half bin width (%.3f)", iBin, mZ2XBinsCenter.back(), mZ2XBinsDH.back());
153 if (mNXBins > 0 && mNXBins < param::NPadRows) {
155 LOGF(info,
"X-binning is uniform with %i bins from %.2f to %.2f", mNXBins, param::MinX, param::MaxX);
156 mDXI = mNXBins / (param::MaxX - param::MinX);
158 mUniformBins[
VoxX] =
true;
161 LOGF(info,
"X-binning is per pad-row");
162 mNXBins = param::NPadRows;
163 mUniformBins[
VoxX] =
false;
164 mDX = param::RowDX[0];
170 mMaxY2X.resize(mNXBins);
171 mDY2XI.resize(mNXBins);
172 mDY2X.resize(mNXBins);
175 for (
int ix = 0; ix < mNXBins; ++ix) {
178 if (mUniformBins[
VoxX]) {
179 row = int(std::min_element(param::RowX, param::RowX + param::NPadRows, [
x](
float a,
float b) {
return std::abs(
a -
x) < std::abs(
b -
x); }) - param::RowX);
181 const float halfWidth = 0.5f * mapper.getNumberOfPadsInRowSector(
row) * mapper.getPadRegionInfo(
Mapper::REGION[
row]).getPadWidth();
182 mMaxY2X[ix] = halfWidth /
x;
183 mDY2XI[ix] = mNY2XBins / (2.f * mMaxY2X[ix]);
184 mDY2X[ix] = 1.f / mDY2XI[ix];
186 if (mUniformBins[
VoxF]) {
187 LOGF(info,
"Y/X-binning is uniform with %i bins from -MaxY2X to +MaxY2X (values depend on X-bin)", mNY2XBins);
188 for (
int ip = 0; ip < mNY2XBins; ++ip) {
189 mY2XBinsDH.push_back(1.f / mNY2XBins);
190 mY2XBinsDI.push_back(.5f / mY2XBinsDH[ip]);
191 mY2XBinsCenter.push_back(-1.f + (ip + 0.5f) * 2.f * mY2XBinsDH[ip]);
192 LOGF(info,
"Bin %i: center (%.3f), half bin width (%.3f)", ip, mY2XBinsCenter.back(), mY2XBinsDH.back());
197 mDZ2XI = mNZ2XBins / mMaxZ2X;
198 mDZ2X = 1.0f / mDZ2XI;
199 if (mUniformBins[
VoxZ]) {
200 LOGF(info,
"Z/X-binning is uniform with %i bins from 0 to %f", mNZ2XBins, mMaxZ2X);
201 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
202 mZ2XBinsDH.push_back(.5f * mDZ2X);
203 mZ2XBinsDI.push_back(mDZ2XI);
204 mZ2XBinsCenter.push_back((iz + 0.5f) * mDZ2X);
205 LOGF(info,
"Bin %i: center (%.3f), half bin width (%.3f)", iz, mZ2XBinsCenter.back(), mZ2XBinsDH.back());
209 mNVoxPerSector = mNY2XBins * mNZ2XBins * mNXBins;
210 LOGF(info,
"Each TPC sector is divided into %i voxels", mNVoxPerSector);
216 if (mInitResultsContainer.test(iSec)) {
219 mInitResultsContainer.set(iSec);
220 mVoxelResults[iSec].resize(mNVoxPerSector);
221 for (
int ix = 0; ix < mNXBins; ++ix) {
222 for (
int ip = 0; ip < mNY2XBins; ++ip) {
223 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
225 VoxRes& resVox = mVoxelResults[iSec][binGlb];
233 LOG(
debug) <<
"initialized the container for the main results";
239 for (
int iSec = 0; iSec < SECTORSPERSIDE * SIDES; ++iSec) {
240 mXBinsIgnore[iSec].reset();
241 std::fill(mVoxelResults[iSec].
begin(), mVoxelResults[iSec].
end(),
VoxRes());
242 std::fill(mValidFracXBins[iSec].
begin(), mValidFracXBins[iSec].
end(), 0);
250 if (
x < param::RowX[param::NRowsAccumulated[0] - 1] + param::RowDX[0]) {
252 ix = (
x - (param::RowX[0] - .5f * param::RowDX[0])) / param::RowDX[0];
257 }
else if (
x >= param::RowX[param::NRowsAccumulated[param::NROCTypes - 2]] - .5f * param::RowDX[param::NROCTypes - 1]) {
259 ix = (
x - (param::RowX[param::NRowsAccumulated[param::NROCTypes - 2]] - .5f * param::RowDX[param::NROCTypes - 1])) / param::RowDX[param::NROCTypes - 1] + param::NRowsAccumulated[param::NROCTypes - 2];
260 if (ix >= param::NPadRows) {
264 }
else if (
x > param::RowX[param::NRowsAccumulated[0]] - .5f * param::RowDX[1] &&
x < param::RowX[param::NRowsAccumulated[1] - 1] + .5f * param::RowDX[1]) {
266 ix = (
x - (param::RowX[param::NRowsAccumulated[0]] - .5f * param::RowDX[1])) / param::RowDX[1] + param::NRowsAccumulated[0];
267 }
else if (
x > param::RowX[param::NRowsAccumulated[1]] - .5f * param::RowDX[2] &&
x < param::RowX[param::NRowsAccumulated[2] - 1] + .5f * param::RowDX[2]) {
269 ix = (
x - (param::RowX[param::NRowsAccumulated[1]] - .5f * param::RowDX[2])) / param::RowDX[2] + param::NRowsAccumulated[1];
280 if (std::abs(
z /
x) > mMaxZ2X) {
289 if (bx < 0 || bx >= mNXBins) {
294 if (bp < 0 || bp >= mNY2XBins) {
307 mKernelType = kernel;
309 mKernelScaleEdge[
VoxX] = scX;
310 mKernelScaleEdge[
VoxF] = scP;
311 mKernelScaleEdge[
VoxZ] = scZ;
313 mKernelWInv[
VoxX] = (bwX > 0) ? 1. / bwX : 1.;
314 mKernelWInv[
VoxF] = (bwP > 0) ? 1. / bwP : 1.;
315 mKernelWInv[
VoxZ] = (bwZ > 0) ? 1. / bwZ : 1.;
319 mStepKern[
VoxX] =
static_cast<int>(nearbyint(bwX + 0.5));
320 mStepKern[
VoxF] =
static_cast<int>(nearbyint(bwP + 0.5));
321 mStepKern[
VoxZ] =
static_cast<int>(nearbyint(bwZ + 0.5));
324 mStepKern[
VoxX] =
static_cast<int>(nearbyint(bwX * 5. + 0.5));
325 mStepKern[
VoxF] =
static_cast<int>(nearbyint(bwP * 5. + 0.5));
326 mStepKern[
VoxZ] =
static_cast<int>(nearbyint(bwZ * 5. + 0.5));
328 LOG(
error) <<
"given kernel type is not defined";
331 if (mStepKern[
i] < 1) {
346 std::vector<VoxRes>& secDataTmp = mVoxelResults[iSec];
347 for (
int iVox = 0; iVox < mNVoxPerSector; ++iVox) {
348 secDataTmp[iVox].stat[
VoxX] = statsIn[iVox].meanPos[
VoxX];
349 secDataTmp[iVox].stat[
VoxF] = statsIn[iVox].meanPos[
VoxF];
350 secDataTmp[iVox].stat[
VoxZ] = statsIn[iVox].meanPos[
VoxZ];
351 secDataTmp[iVox].stat[
VoxDim] = statsIn[iVox].nEntries;
358 std::vector<VoxRes>& secDataTmp = mVoxelResults[iSec];
359 for (
int iVox = 0; iVox < mNVoxPerSector; ++iVox) {
360 const auto& voxStat = mVoxStatsIn[iVox];
361 VoxRes& resVox = secDataTmp[iVox];
362 for (
int iDim =
VoxDim; iDim--;) {
363 const auto sumStat = (resVox.
stat[
VoxDim] + voxStat.nEntries);
367 double norm = 1. / sumStat;
368 resVox.
stat[iDim] = (resVox.
stat[iDim] * resVox.
stat[
VoxDim] + voxStat.meanPos[iDim] * voxStat.nEntries) * norm;
377 LOGP(info,
"Processing {} voxel residuals for sector {}", mLocalResidualsIn.size(), iSec);
380 float effT0corr = (iSec < SECTORSPERSIDE) ? mEffT0Corr : -1. * mEffT0Corr;
381 std::vector<size_t> binData;
382 for (
const auto&
res : mLocalResidualsIn) {
386 std::vector<size_t> binIndices(binData.size());
389 std::vector<VoxRes>& secData = mVoxelResults[iSec];
392 std::vector<float> dyVec;
393 std::vector<float> dzVec;
394 std::vector<float> tgVec;
399 size_t currVoxBin = -1;
400 unsigned int nPointsInVox = 0;
401 unsigned int nProcessed = 0;
402 while (nProcessed < binData.size()) {
404 int idx = binIndices[nProcessed];
405 if (currVoxBin != binData[idx]) {
407 VoxRes& resVox = secData[currVoxBin];
410 currVoxBin = binData[idx];
416 dyVec.push_back(mLocalResidualsIn[idx].dy * param::MaxResid / 0x7fff);
417 dzVec.push_back(mLocalResidualsIn[idx].dz * param::MaxResid / 0x7fff -
418 mEffVdriftCorr * secData[currVoxBin].stat[
VoxZ] * secData[currVoxBin].stat[
VoxX] -
420 tgVec.push_back(mLocalResidualsIn[idx].tgSlp * param::MaxTgSlp / 0x7fff);
427 VoxRes& resVox = secData[currVoxBin];
430 LOG(info) <<
"extracted residuals for sector " << iSec;
433 LOG(info) <<
"number of validated X rows: " << nRowsOK;
435 LOG(warning) <<
"sector " << iSec <<
": all X-bins disabled, abandon smoothing";
447 while (nProcessed < binData.size()) {
448 int idx = binIndices[nProcessed];
449 if (currVoxBin != binData[idx]) {
451 VoxRes& resVox = secData[currVoxBin];
456 currVoxBin = binData[idx];
461 dyVec.push_back(mLocalResidualsIn[idx].dy * param::MaxResid / 0x7fff);
462 tgVec.push_back(mLocalResidualsIn[idx].tgSlp * param::MaxTgSlp / 0x7fff);
468 VoxRes& resVox = secData[currVoxBin];
474 for (
int ix = 0; ix < mNXBins; ++ix) {
478 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
479 for (
int ip = 0; ip < mNY2XBins; ++ip) {
481 VoxRes& resVox = secData[voxBin];
486 LOG(info) <<
"Done processing residuals for sector " << iSec;
493 int nPoints = dy.size();
494 if (nPoints < mParams->minEntriesPerVoxel) {
500 std::array<float, 7> zResults;
502 std::vector<size_t>
indices(dz.size());
508 std::array<float, 2>
res{0.f};
509 std::array<float, 3> err{0.f};
512 LOG(
debug) <<
"failed robust linear fit, sigMAD = " << sigMAD;
515 float corrErr = err[0] * err[2];
516 corrErr = corrErr > 0 ? err[1] / std::sqrt(corrErr) : -999;
520 resVox.
D[
ResZ] = zResults[1];
521 resVox.
E[
ResX] = std::sqrt(err[2]);
522 resVox.
E[
ResY] = std::sqrt(err[0]);
523 resVox.
E[
ResZ] = zResults[4];
530 std::array<float, 7> yResults;
531 std::vector<size_t> indicesY(dy.size());
537 resVox.
D[
ResY] = yResults[1];
538 resVox.
D[
ResZ] = zResults[1];
540 resVox.
E[
ResY] = yResults[4];
541 resVox.
E[
ResZ] = zResults[4];
547 LOGF(
debug,
"D[0]=%.2f, D[1]=%.2f, D[2]=%.2f, E[0]=%.2f, E[1]=%.2f, E[2]=%.2f, EXYCorr=%.4f, dYSigMAD=%.3f, dZSigLTM=%.3f",
557 size_t nPoints = tg.size();
558 LOG(
debug) <<
"processing voxel dispersions for vox " <<
getGlbVoxBin(resVox.
bvox) <<
" with " << nPoints <<
" points";
562 for (
size_t i = nPoints;
i--;) {
566 resVox.
E[
ResD] = resVox.
D[
ResD] / sqrt(2.f * nPoints);
577 mXBinsIgnore[iSec].reset();
578 std::vector<VoxRes>& secData = mVoxelResults[iSec];
580 int cntMaskedFit = 0;
581 int cntMaskedSigma = 0;
584 for (
int ix = 0; ix < mNXBins; ++ix) {
586 for (
int ip = 0; ip < mNY2XBins; ++ip) {
587 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
589 VoxRes& resVox = secData[binGlb];
617 mValidFracXBins[iSec][ix] =
static_cast<float>(cntValid) / (mNY2XBins * mNZ2XBins);
618 LOGP(
debug,
"Sector {}: xBin {} has {} % of voxels valid. Total masked due to fit: {} ,and sigma: {}",
619 iSec, ix, mValidFracXBins[iSec][ix] * 100., cntMaskedFit, cntMaskedSigma);
625 std::array<short, param::NPadRows> badStart;
626 std::array<short, param::NPadRows> badEnd;
627 bool prevBad =
false;
628 float fracBadRows = 0.f;
629 for (
int ix = 0; ix < mNXBins; ++ix) {
631 LOG(
debug) <<
"row " << ix <<
" is bad";
634 badEnd[nBadReg] = ix;
636 badStart[nBadReg] = ix;
637 badEnd[nBadReg] = ix;
650 fracBadRows /= mNXBins;
652 LOG(warning) <<
"sector " << iSec <<
": Fraction of bad X-bins: " << fracBadRows <<
" -> masking whole sector";
653 mXBinsIgnore[iSec].set();
655 for (
int iBad = 0; iBad < nBadReg; ++iBad) {
656 LOG(
debug) <<
"masking bad region " << iBad;
657 short badInReg = badEnd[iBad] - badStart[iBad] + 1;
658 short badInNextReg = iBad < (nBadReg - 1) ? badEnd[iBad] - badStart[iBad] + 1 : 0;
661 for (
int i = 0;
i < badInReg; ++
i) {
662 LOG(
debug) <<
"disabling too large patch in bad region " << iBad <<
", badStart(" << badStart[iBad] <<
"), i(" <<
i <<
")";
663 mXBinsIgnore[iSec].set(badStart[iBad] +
i);
668 for (
int i = badEnd[iBad] + 1;
i < badStart[iBad + 1]; ++
i) {
669 LOG(
debug) <<
"disabling too small good patch before bad region " << iBad + 1 <<
", badStart(" << badEnd[iBad] <<
"), badEnd(" << badStart[iBad + 1] <<
")";
670 mXBinsIgnore[iSec].set(
i);
677 for (
int i = 0;
i < badStart[0]; ++
i) {
678 LOG(
debug) <<
"disabling too small first good patch badStart(0), badEnd(" << badStart[0] <<
")";
679 mXBinsIgnore[iSec].set(
i);
682 if (mXBinsIgnore[iSec].
test(badStart[nBadReg - 1]) && (mNXBins - badEnd[nBadReg - 1] - 1) < mParams->
minGoodXBinsToCover) {
684 for (
int i = badEnd[nBadReg - 1] + 1;
i < mNXBins; ++
i) {
685 LOG(
debug) <<
"disabling too small last good patch badStart(" << badEnd[nBadReg - 1] <<
"), badEnd(" << mNXBins <<
")";
686 mXBinsIgnore[iSec].set(
i);
692 int nMaskedRows = mXBinsIgnore[iSec].count();
693 LOGP(info,
"Sector {}: out of {} voxels {} are masked. {} (low stat), {} (invalid fit) and {} (raw distrib sigma)",
694 iSec, mNVoxPerSector, cntMasked, cntLowStat, cntMaskedFit, cntMaskedSigma);
696 return mNXBins - nMaskedRows;
701 std::vector<VoxRes>& secData = mVoxelResults[iSec];
702 for (
int ix = 0; ix < mNXBins; ++ix) {
706 for (
int ip = 0; ip < mNY2XBins; ++ip) {
707 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
709 VoxRes& resVox = secData[voxBin];
710 resVox.
flags &= ~SmoothDone;
713 mNSmoothingFailedBins[iSec]++;
721 for (
int ix = 0; ix < mNXBins; ++ix) {
725 for (
int ip = 0; ip < mNY2XBins; ++ip) {
726 for (
int iz = 0; iz < mNZ2XBins; ++iz) {
728 VoxRes& resVox = secData[voxBin];
734 if (mDoAdhocCorrectionZ2X) {
743 if (mAdhocScalingX[iSec >= 18] != 0) {
744 const float aDX = resVox.
DS[
ResX] * mAdhocScalingX[iSec >= 18];
745 resVox.
D[
ResX] += aDX;
749 resVox.
D[
ResZ] += aDX * z2x;
750 resVox.
DS[
ResZ] += aDX * z2x;
762 std::array<int, VoxDim> minPointsDir{0};
763 const float kTrialStep = 0.5;
764 std::array<bool, ResDim> doDim{
false};
766 doDim[
i] = (whichDim & (0x1 <<
i)) > 0;
772 int matSize = sSmtLinDim;
775 if (mSmoothPol2[
i]) {
782 findVoxel(
x, p, iSec < SECTORSPERSIDE ?
z : -
z, ix0, ip0, iz0);
783 std::vector<VoxRes>& secData = mVoxelResults[iSec];
785 VoxRes& voxCenter = secData[binCenter];
786 LOG(
debug) <<
"getting smooth estimate around voxel " << binCenter;
790 std::array<std::array<double, sMaxSmtDim*(sMaxSmtDim + 1) / 2>,
ResDim> cmat;
791 int maxNeighb = 10 * 10 * 10;
792 std::vector<VoxRes*> currVox;
793 currVox.reserve(maxNeighb);
794 std::vector<float> currCache;
795 currCache.reserve(maxNeighb *
VoxHDim);
797 std::array<int, VoxDim> maxTrials;
798 maxTrials[
VoxZ] = mNZ2XBins / 2;
799 maxTrials[
VoxF] = mNY2XBins / 2;
802 std::array<int, VoxDim> trial{0};
805 std::fill(mLastSmoothingRes.begin(), mLastSmoothingRes.end(), 0);
806 memset(&cmat[0][0], 0,
sizeof(cmat));
810 float stepX = mStepKern[
VoxX] * (1. + kTrialStep * trial[
VoxX]);
811 float stepF = mStepKern[
VoxF] * (1. + kTrialStep * trial[
VoxF]);
812 float stepZ = mStepKern[
VoxZ] * (1. + kTrialStep * trial[
VoxZ]);
816 stepX += kTrialStep * mStepKern[
VoxX];
817 stepF += kTrialStep * mStepKern[
VoxF];
818 stepZ += kTrialStep * mStepKern[
VoxZ];
822 float kWXI =
getDXI(ix0) * mKernelWInv[
VoxX] * mStepKern[
VoxX] / stepX;
823 float kWFI =
getDY2XI(ix0, ip0) * mKernelWInv[
VoxF] * mStepKern[
VoxF] / stepF;
825 int iStepX =
static_cast<int>(nearbyint(stepX + 0.5));
826 int iStepF =
static_cast<int>(nearbyint(stepF + 0.5));
827 int iStepZ =
static_cast<int>(nearbyint(stepZ + 0.5));
828 int ixMin = ix0 - iStepX;
829 int ixMax = ix0 + iStepX;
832 ixMax = std::min(
static_cast<int>(nearbyint(ix0 + stepX * mKernelScaleEdge[
VoxX])), mNXBins - 1);
833 kWXI /= mKernelScaleEdge[
VoxX];
835 if (ixMax >= mNXBins) {
837 ixMin = std::max(
static_cast<int>(nearbyint(ix0 - stepX * mKernelScaleEdge[
VoxX])), 0);
838 kWXI /= mKernelScaleEdge[
VoxX];
841 int ipMin = ip0 - iStepF;
842 int ipMax = ip0 + iStepF;
845 ipMax = std::min(
static_cast<int>(nearbyint(ip0 + stepF * mKernelScaleEdge[
VoxF])), mNY2XBins - 1);
846 kWFI /= mKernelScaleEdge[
VoxF];
848 if (ipMax >= mNY2XBins) {
849 ipMax = mNY2XBins - 1;
850 ipMin = std::max(
static_cast<int>(nearbyint(ip0 - stepF * mKernelScaleEdge[
VoxF])), 0);
851 kWFI /= mKernelScaleEdge[
VoxF];
854 int izMin = iz0 - iStepZ;
855 int izMax = iz0 + iStepZ;
858 izMax = std::min(
static_cast<int>(nearbyint(iz0 + stepZ * mKernelScaleEdge[
VoxZ])), mNZ2XBins - 1);
859 kWZI /= mKernelScaleEdge[
VoxZ];
861 if (izMax >= mNZ2XBins) {
862 izMax = mNZ2XBins - 1;
863 izMin = std::max(
static_cast<int>(nearbyint(iz0 - stepZ * mKernelScaleEdge[
VoxZ])), 0);
864 kWZI /= mKernelScaleEdge[
VoxZ];
867 std::vector<unsigned short> nOccX(ixMax - ixMin + 1, 0);
868 std::vector<unsigned short> nOccF(ipMax - ipMin + 1, 0);
869 std::vector<unsigned short> nOccZ(izMax - izMin + 1, 0);
871 int nbCheck = (ixMax - ixMin + 1) * (ipMax - ipMin + 1) * (izMax - izMin + 1);
872 if (nbCheck >= maxNeighb) {
873 maxNeighb = nbCheck + 100;
874 currCache.reserve(maxNeighb *
VoxHDim);
875 currVox.reserve(maxNeighb);
877 std::array<double, 3> u2Vec;
880 for (
int ix = ixMin; ix <= ixMax; ++ix) {
881 for (
int ip = ipMin; ip <= ipMax; ++ip) {
882 for (
int iz = izMin; iz <= izMax; ++iz) {
884 VoxRes& voxNb = secData[binNb];
895 float dxw = dx * kWXI;
896 float dfw = df * kWFI;
897 float dzw = dz * kWZI;
898 u2Vec[0] = dxw * dxw;
899 u2Vec[1] = dfw * dfw;
900 u2Vec[2] = dzw * dzw;
902 if (kernelWeight < 1
e-6) {
909 currVox[nbOK] = &voxNb;
920 std::array<int, VoxDim> nPoints{0};
921 for (
int i = ixMax - ixMin + 1;
i--;) {
926 for (
int i = ipMax - ipMin + 1;
i--;) {
931 for (
int i = izMax - izMin + 1;
i--;) {
936 bool enoughPoints =
true;
937 std::array<bool, VoxDim> incrDone{
false};
939 if (nPoints[
i] < minPointsDir[
i]) {
941 enoughPoints =
false;
942 if (trial[
i] < maxTrials[
i] && !incrDone[
i]) {
946 }
else if (trial[
i] == maxTrials[
i]) {
949 if (
i !=
j && trial[
j] < maxTrials[
j] && !incrDone[
j]) {
959 if (!(incrDone[
VoxX] || incrDone[
VoxF] || incrDone[
VoxZ])) {
960 LOG(
error) << fmt::format(
"trial limit reached, skipping this voxel: incrDone[VoxX] {}, incrDone[VoxF] {}, incrDone[VoxZ] {}", incrDone[
VoxX], incrDone[
VoxF], incrDone[
VoxZ]);
963 LOG(
debug) <<
"sector " << iSec <<
": increasing filter bandwidth around voxel " << binCenter;
971 for (
int iNb = 0; iNb < nbOK; ++iNb) {
976 double dxi2 = dxi * dxi;
977 double dfi2 = dfi * dfi;
978 double dzi2 = dzi * dzi;
979 const VoxRes* voxNb = currVox[iNb];
980 for (
int iDim = 0; iDim <
ResDim; ++iDim) {
984 double vi = voxNb->
D[iDim];
986 if (mUseErrInSmoothing && std::abs(voxNb->
E[iDim]) > 1
e-6) {
988 wi /= (voxNb->
E[iDim] * voxNb->
E[iDim]);
990 std::array<double, sMaxSmtDim*(sMaxSmtDim + 1) / 2>& cmatD = cmat[iDim];
991 double* rhsD = &mLastSmoothingRes[iDim * sMaxSmtDim];
992 unsigned short iMat = 0;
993 unsigned short iRhs = 0;
996 rhsD[iRhs++] += wi * vi;
998 cmatD[iMat++] += wi * dxi;
999 cmatD[iMat++] += wi * dxi2;
1000 rhsD[iRhs++] += wi * dxi * vi;
1002 cmatD[iMat++] += wi * dfi;
1003 cmatD[iMat++] += wi * dxi * dfi;
1004 cmatD[iMat++] += wi * dfi2;
1005 rhsD[iRhs++] += wi * dfi * vi;
1007 cmatD[iMat++] += wi * dzi;
1008 cmatD[iMat++] += wi * dxi * dzi;
1009 cmatD[iMat++] += wi * dfi * dzi;
1010 cmatD[iMat++] += wi * dzi2;
1011 rhsD[iRhs++] += wi * dzi * vi;
1014 if (mSmoothPol2[
VoxX]) {
1015 cmatD[iMat++] += wi * dxi2;
1016 cmatD[iMat++] += wi * dxi * dxi2;
1017 cmatD[iMat++] += wi * dfi * dxi2;
1018 cmatD[iMat++] += wi * dzi * dxi2;
1019 cmatD[iMat++] += wi * dxi2 * dxi2;
1020 rhsD[iRhs++] += wi * dxi2 * vi;
1022 if (mSmoothPol2[
VoxF]) {
1023 cmatD[iMat++] += wi * dfi2;
1024 cmatD[iMat++] += wi * dxi * dfi2;
1025 cmatD[iMat++] += wi * dfi * dfi2;
1026 cmatD[iMat++] += wi * dzi * dfi2;
1027 cmatD[iMat++] += wi * dxi2 * dfi2;
1028 cmatD[iMat++] += wi * dfi2 * dfi2;
1029 rhsD[iRhs++] += wi * dfi2 * vi;
1031 if (mSmoothPol2[
VoxZ]) {
1032 cmatD[iMat++] += wi * dzi2;
1033 cmatD[iMat++] += wi * dxi * dzi2;
1034 cmatD[iMat++] += wi * dfi * dzi2;
1035 cmatD[iMat++] += wi * dzi * dzi2;
1036 cmatD[iMat++] += wi * dxi2 * dzi2;
1037 cmatD[iMat++] += wi * dfi2 * dzi2;
1038 cmatD[iMat++] += wi * dzi2 * dzi2;
1039 rhsD[iRhs++] += wi * dzi2 * vi;
1048 TMatrixDSym matrix(matSize);
1049 TDecompChol chol(matSize);
1050 TVectorD rhsVec(matSize);
1051 for (
int iDim = 0; iDim <
ResDim; ++iDim) {
1056 std::array<double, sMaxSmtDim*(sMaxSmtDim + 1) / 2>& cmatD = cmat[iDim];
1057 double* rhsD = &mLastSmoothingRes[iDim * sMaxSmtDim];
1062 matrix(++
row, 0) = cmatD[++iMat];
1063 matrix(++
row, 0) = cmatD[++iMat];
1064 matrix(
row, 1) = cmatD[++iMat];
1065 matrix(0,
row) = matrix(
row, 0);
1066 matrix(++
row, 0) = cmatD[++iMat];
1067 matrix(
row, 1) = cmatD[++iMat];
1068 matrix(
row, 2) = cmatD[++iMat];
1069 matrix(0,
row) = matrix(
row, 0);
1070 matrix(1,
row) = matrix(
row, 1);
1071 matrix(++
row, 0) = cmatD[++iMat];
1072 matrix(
row, 1) = cmatD[++iMat];
1073 matrix(
row, 2) = cmatD[++iMat];
1074 matrix(
row, 3) = cmatD[++iMat];
1075 matrix(0,
row) = matrix(
row, 0);
1076 matrix(1,
row) = matrix(
row, 1);
1077 matrix(2,
row) = matrix(
row, 2);
1079 if (mSmoothPol2[
VoxX]) {
1080 const int colLim = (++
row) + 1;
1081 for (
int iCol = 0; iCol < colLim; ++iCol) {
1082 matrix(
row, iCol) = cmatD[++iMat];
1083 matrix(iCol,
row) = matrix(
row, iCol);
1086 if (mSmoothPol2[
VoxF]) {
1087 const int colLim = (++
row) + 1;
1088 for (
int iCol = 0; iCol < colLim; ++iCol) {
1089 matrix(
row, iCol) = cmatD[++iMat];
1090 matrix(iCol,
row) = matrix(
row, iCol);
1093 if (mSmoothPol2[
VoxZ]) {
1094 const int colLim = (++
row) + 1;
1095 for (
int iCol = 0; iCol < colLim; ++iCol) {
1096 matrix(
row, iCol) = cmatD[++iMat];
1097 matrix(iCol,
row) = matrix(
row, iCol);
1100 rhsVec.SetElements(rhsD);
1101 chol.SetMatrix(matrix);
1103 fitRes = chol.Solve(rhsVec);
1108 LOG(
error) <<
"solution for smoothing failed, trying to increase filter bandwidth";
1111 res[iDim] = rhsVec[0];
1124 for (
size_t i = u2vec.size();
i--;) {
1128 w *= 3. / 4. * (1. - u2vec[
i]);
1132 for (
size_t i = u2vec.size();
i--;) {
1149 if (
x.size() !=
y.size()) {
1150 LOG(
error) <<
"x and y must not have different sizes for fitPoly1Robust (" <<
x.size() <<
" != " <<
y.size() <<
")";
1152 size_t nPoints =
x.size();
1157 std::array<float, 7> yResults;
1158 std::vector<size_t> indY(nPoints);
1167 int nPointsUsed = std::lrint(yResults[0]);
1168 int vecOffset = std::lrint(yResults[5]);
1171 medFit(nPointsUsed, vecOffset,
x,
y,
a,
b, err);
1173 std::vector<float> ycm(nPoints);
1174 for (
size_t i = nPoints;
i-- > 0;) {
1175 ycm[
i] =
y[
i] - (
a +
b *
x[
i]);
1177 std::vector<size_t>
indices(nPoints);
1184 float sigMAD =
getMAD2Sigma({ycm.begin() + vecOffset, ycm.begin() + vecOffset + nPointsUsed});
1190 nPointsUsed = std::lrint(yResults[0]);
1191 vecOffset = std::lrint(yResults[5]);
1192 medFit(nPointsUsed, vecOffset,
x,
y,
a,
b, err);
1203 float aa,
bb,
chi2 = 0.f;
1206 err[0] = err[1] = err[2] = 999.f;
1210 float sx = 0.f, sxx = 0.f, sy = 0.f, sxy = 0.f;
1217 float del = nPoints * sxx - sx * sx;
1218 float delI = 1. / del;
1219 aa = (sxx * sy - sx * sxy) * delI;
1220 bb = (nPoints * sxy - sx * sy) * delI;
1221 err[0] = sxx * delI;
1223 err[2] = nPoints * delI;
1226 float tmp =
y[
j] - (aa +
bb *
x[
j]);
1229 float sigb = std::sqrt(
chi2 * delI);
1233 float b2 =
bb + std::copysign(3.f * sigb, f1);
1235 if (std::abs(f1 - f2) < sFloatEps) {
1240 while (f1 * f2 > 0.f) {
1241 bb = b2 + 1.6f * (b2 - b1);
1248 while (std::abs(b2 - b1) > sigb) {
1249 bb = b1 + .5f * (b2 - b1);
1250 if (
bb == b1 ||
bb == b2) {
1254 if (
f * f1 >= .0f) {
1271 std::vector<float> vecTmp(nPoints);
1273 for (
int j = nPoints;
j-- > 0;) {
1276 int nPointsHalf = nPoints / 2;
1278 for (
int i = 1;
i < nPoints;
i++) {
1279 float v = vecTmp[
i];
1282 if (vecTmp[
j] >
v) {
1283 vecTmp[
j + 1] = vecTmp[
j];
1290 aa = (nPoints & 0x1) ? vecTmp[nPointsHalf] : .5f * (vecTmp[nPointsHalf - 1] + vecTmp[nPointsHalf]);
1292 std::vector<float>::iterator nth = vecTmp.begin() + vecTmp.size() / 2;
1293 if (nPoints & 0x1) {
1294 std::nth_element(vecTmp.begin(), nth, vecTmp.end());
1297 std::nth_element(vecTmp.begin(), nth - 1, vecTmp.end());
1298 std::nth_element(nth, nth, vecTmp.end());
1299 aa = 0.5 * (*(nth - 1) + *(nth));
1303 for (
int j = nPoints;
j-- > 0;) {
1308 if (std::abs(
d) > sFloatEps) {
1336 mid = (l +
ir) >> 1;
1385 int nPoints =
data.size();
1392 std::vector<float>::iterator nth =
data.begin() +
data.size() / 2;
1393 if (nPoints & 0x1) {
1394 std::nth_element(
data.begin(), nth,
data.end());
1395 medianOfData = *nth;
1397 std::nth_element(
data.begin(), nth - 1,
data.end());
1398 std::nth_element(nth, nth,
data.end());
1399 medianOfData = .5f * (*(nth - 1) + (*nth));
1408 float medianOfAbsDeviations;
1409 if (nPoints & 0x1) {
1410 std::nth_element(
data.begin(), nth,
data.end());
1411 medianOfAbsDeviations = *nth;
1413 std::nth_element(
data.begin(), nth - 1,
data.end());
1414 std::nth_element(nth, nth,
data.end());
1415 medianOfAbsDeviations = .5f * (*(nth - 1) + (*nth));
1419 return k * medianOfAbsDeviations;
1426 double xMean = 0., yMean = 0.;
1427 int ncl =
params.points.size();
1428 for (
const auto& pnt :
params.points) {
1435 double su2 = 0., sv2 = 0., suv = 0., su3 = 0., sv3 = 0., su2v = 0., suv2 = 0.;
1436 for (
const auto& pnt :
params.points) {
1437 double ui = pnt.xLab - xMean;
1438 double vi = pnt.yLab - yMean;
1439 double ui2 = ui * ui;
1440 double vi2 = vi * vi;
1449 double rhsU = .5f * (su3 + suv2);
1450 double rhsV = .5f * (sv3 + su2v);
1451 double det = su2 * sv2 - suv * suv;
1452 double uc = (rhsU * sv2 - rhsV * suv) / det;
1453 double vc = (su2 * rhsV - suv * rhsU) / det;
1454 double r2 = uc * uc + vc * vc + (su2 + sv2) / ncl;
1455 params.xcLab = uc + xMean;
1456 params.ycLab = vc + yMean;
1459 for (
auto& pnt :
params.points) {
1460 double dx = pnt.xLab -
params.xcLab;
1461 double dxr = r2 - dx * dx;
1462 double ys = dxr > 0 ? sqrt(dxr) : 0.f;
1463 double dy = pnt.yLab -
params.ycLab;
1464 double dysp = dy - ys;
1465 double dysm = dy + ys;
1466 pnt.residHelixY = std::abs(dysp) < std::abs(dysm) ? dysp : dysm;
1470void fitCircle(
int nCl, std::array<float, param::NPadRows>&
x, std::array<float, param::NPadRows>&
y,
float& xc,
float& yc,
float&
r, std::array<float, param::NPadRows>& residHelixY)
1477 for (
int i = nCl;
i--;) {
1484 float su2 = 0.f, sv2 = 0.f, suv = 0.f, su3 = 0.f, sv3 = 0.f, su2v = 0.f, suv2 = 0.f;
1485 for (
int i = nCl;
i--;) {
1486 float ui =
x[
i] - xMean;
1487 float vi =
y[
i] - yMean;
1488 float ui2 = ui * ui;
1489 float vi2 = vi * vi;
1498 float rhsU = .5f * (su3 + suv2);
1499 float rhsV = .5f * (sv3 + su2v);
1500 float det = su2 * sv2 - suv * suv;
1501 float uc = (rhsU * sv2 - rhsV * suv) / det;
1502 float vc = (su2 * rhsV - suv * rhsU) / det;
1503 float r2 = uc * uc + vc * vc + (su2 + sv2) / nCl;
1508 for (
int i = nCl;
i--;) {
1509 float dx =
x[
i] - xc;
1510 float dxr = r2 - dx * dx;
1511 float ys = dxr > 0 ? sqrt(dxr) : 0.f;
1512 float dy =
y[
i] - yc;
1513 float dysp = dy - ys;
1514 float dysm = dy + ys;
1515 residHelixY[
i] = std::abs(dysp) < std::abs(dysm) ? dysp : dysm;
1526 int ncl =
params.points.size();
1531 double sumX = 0., sumY = 0., sumXY = 0., sumX2 = 0., nInv = 1. / ncl;
1532 for (
const auto& pnt :
params.points) {
1535 sumXY += pnt.sPath * pnt.zTrk;
1536 sumX2 += pnt.sPath * pnt.sPath;
1538 auto det = sumX2 - nInv * sumX * sumX;
1539 if (std::abs(det) < 1
e-12) {
1542 params.tgl = (sumXY - nInv * sumX * sumY) / det;
1557 float sumX = 0.f, sumY = 0.f, sumXY = 0.f, sumX2 = 0.f, nInv = 1.f / nCl;
1558 for (
int i = nCl;
i--;) {
1561 sumXY +=
x[
i] *
y[
i];
1562 sumX2 +=
x[
i] *
x[
i];
1564 float det = sumX2 - nInv * sumX * sumX;
1565 if (std::abs(det) < 1e-12f) {
1568 res[0] = (sumXY - nInv * sumX * sumY) / det;
1569 res[1] = nInv * sumY - nInv *
res[0] * sumX;
1582 LOG(warn) <<
"For the tree aliases to work you must initialize the binning before calling createOutputFile()";
1584 mFileOut = std::make_unique<TFile>(
filename,
"recreate");
1585 mTreeOut = std::make_unique<TTree>(
"voxResTree",
"Voxel results and statistics");
1586 mTreeOut->SetAlias(
"z2xBin",
"bvox[0]");
1587 mTreeOut->SetAlias(
"y2xBin",
"bvox[1]");
1588 mTreeOut->SetAlias(
"xBin",
"bvox[2]");
1589 mTreeOut->SetAlias(
"z2xAV",
"stat[0]");
1590 mTreeOut->SetAlias(
"y2xAV",
"stat[1]");
1591 mTreeOut->SetAlias(
"xAV",
"stat[2]");
1592 mTreeOut->SetAlias(
"fsector",
"bsec+0.5+9.*(y2xAV)/pi");
1593 mTreeOut->SetAlias(
"phi",
"(bsec%18+0.5+9.*(stat[1])/pi)/9*pi");
1594 mTreeOut->SetAlias(
"r",
"stat[2]");
1595 mTreeOut->SetAlias(
"z",
"z2xAV*xAV");
1596 mTreeOut->SetAlias(
"dX",
"D[0]");
1597 mTreeOut->SetAlias(
"dY",
"D[1]");
1598 mTreeOut->SetAlias(
"dZ",
"D[2]");
1599 mTreeOut->SetAlias(
"dXS",
"DS[0]");
1600 mTreeOut->SetAlias(
"dYS",
"DS[1]");
1601 mTreeOut->SetAlias(
"dZS",
"DS[2]");
1602 mTreeOut->SetAlias(
"dXE",
"E[0]");
1603 mTreeOut->SetAlias(
"dYE",
"E[1]");
1604 mTreeOut->SetAlias(
"dZE",
"E[2]");
1606 mTreeOut->SetAlias(
"entries",
"stat[3]");
1607 mTreeOut->SetAlias(
"fitOK", Form(
"(flags & %u) == %u",
DistDone,
DistDone));
1608 mTreeOut->SetAlias(
"dispOK", Form(
"(flags & %u) == %u",
DispDone,
DispDone));
1610 mTreeOut->SetAlias(
"masked", Form(
"(flags & %u) == %u",
Masked,
Masked));
1611 mTreeOut->Branch(
"voxRes", &mVoxelResultsOutPtr);
1626 printf(
"Dumping results for sector %i. Don't forget the call to closeOutputFile() in the end...\n", iSec);
1627 for (
int i = 0;
i < mNVoxPerSector; ++
i) {
1628 mVoxelResultsOut = mVoxelResults[iSec][
i];
1636 static float mres = 0, mvir = 0, mres0 = 0, mvir0 = 0;
1637 static ProcInfo_t procInfo;
1638 static TStopwatch
sw;
1639 const Long_t kMB = 1024;
1640 gSystem->GetProcInfo(&procInfo);
1641 mres =
float(procInfo.fMemResident) / kMB;
1642 mvir =
float(procInfo.fMemVirtual) / kMB;
1644 printf(
"RSS: %.3f(%.3f) VMEM: %.3f(%.3f) MB | CpuTime:%.3f RealTime:%.3f s\n",
1645 mres, mres - mres0, mvir, mvir - mvir0,
sw.CpuTime(),
sw.RealTime());
1654 mInitResultsContainer.reset();
std::vector< double > sum
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
configStandalone Reconstruction rec_tpc float
char error[CURL_ERROR_SIZE]
bounded_vector< float > bins
void fitCircle(int nCl, std::array< float, param::NPadRows > &x, std::array< float, param::NPadRows > &y, float &xc, float &yc, float &r, std::array< float, param::NPadRows > &residHelixY)
Definition of the TrackResiduals class.
static const SpacePointsCalibConfParam & Instance()
static Mapper & instance(const std::string mappingDir="")
static constexpr unsigned REGION[PADROWS]
region for global pad row
std::vector< LocalResid > & getLocalResVec()
float getDZ2XI(int iz=0) const
void setKernelType(KernelType kernel=KernelType::Epanechnikov, float bwX=2.1f, float bwP=2.1f, float bwZ=1.7f, float scX=1.f, float scP=1.f, float scZ=1.f)
bool getSmoothEstimate(int iSec, float x, float p, float z, std::array< float, ResDim > &res, int whichDim=0)
int getXBinExact(float x) const
void setY2XBinning(const std::vector< float > &binning)
void dumpResults(int iSec)
void processSectorResiduals(Int_t iSec)
static bool fitPoly1(int nCl, std::array< float, param::NPadRows > &x, std::array< float, param::NPadRows > &y, std::array< float, 2 > &res)
size_t getGlbVoxBin(int ix, int ip, int iz) const
void setStats(const std::vector< TrackResiduals::VoxStats > &statsIn, int iSec)
Set the voxel statistics directly from outside.
void closeOutputFile()
Closes the file with the debug output.
void clear()
clear member to be able to process new sector or new input files
void fillStats(int iSec)
Fill statistics from TTree.
void printMem() const
Prints the current memory usage.
void setZ2XBinning(const std::vector< float > &binning)
void initResultsContainer(int iSec)
@ DispDone
voxel dispersions have been processed
@ DistDone
voxel residuals have been processed
@ SmoothDone
voxel has been smoothed
int getNVoxelsPerSector() const
Get the total number of voxels per TPC sector (mNXBins * mNY2XBins * mNZ2XBins)
int getRowID(float x) const
void createOutputFile(const char *filename="debugVoxRes.root")
Creates a file for the debug output.
float getDY2XI(int ix, int iy=0) const
void findVoxel(float x, float y2x, float z2x, int &ix, int &ip, int &iz) const
float roFunc(int nPoints, int offset, const std::vector< float > &x, const std::vector< float > &y, float b, float &aa) const
void medFit(int nPoints, int offset, const std::vector< float > &x, const std::vector< float > &y, float &a, float &b, std::array< float, 3 > &err) const
static void fitCircle(int nCl, std::array< float, param::NPadRows > &x, std::array< float, param::NPadRows > &y, float &xc, float &yc, float &r, std::array< float, param::NPadRows > &residHelixY)
float getDXI(int ix) const
float fitPoly1Robust(std::vector< float > &x, std::vector< float > &y, std::array< float, 2 > &res, std::array< float, 3 > &err, float cutLTM) const
int getY2XBinExact(float y2x, int ix) const
bool findVoxelBin(int secID, float x, float y, float z, std::array< unsigned char, VoxDim > &bvox) const
Calculates the bin indices for given x, y, z in sector coordinates.
bool getXBinIgnored(int iSec, int bin) const
@ VoxDim
dimensionality of the voxels
void initBinning()
Initializes the binning in X, Y/X and Z.
float getMAD2Sigma(std::vector< float > data) const
void reset()
Resets all (also intermediate) results.
int getZ2XBinExact(float z2x) const
double getKernelWeight(std::array< double, 3 > u2vec) const
void processVoxelDispersions(std::vector< float > &tg, std::vector< float > &dy, VoxRes &resVox)
void init(bool doBinning=true)
float selectKthMin(const int k, std::vector< float > &data) const
@ ResD
index for dispersions
void setNY2XBins(int nBins)
void setNZ2XBins(int nBins)
int validateVoxels(int iSec)
void processVoxelResiduals(std::vector< float > &dy, std::vector< float > &dz, std::vector< float > &tg, VoxRes &resVox)
GLboolean GLboolean GLboolean b
GLenum const GLfloat * params
GLsizei GLenum const void * indices
GLboolean GLboolean GLboolean GLboolean a
GLubyte GLubyte GLubyte GLubyte w
GLdouble GLdouble GLdouble z
void Reorder(std::vector< T > &data, const std::vector< size_t > &index)
bool LTMUnbinnedSig(const std::vector< T > &data, std::vector< size_t > &index, std::array< float, 7 > ¶ms, float fracKeepMin, float sigTgt, bool sorted=false)
void SortData(std::vector< T > const &values, std::vector< size_t > &index)
bool LTMUnbinned(const std::vector< T > &data, std::vector< size_t > &index, std::array< float, 7 > ¶ms, float fracKeep)
Global TPC definitions and constants.
Enum< T >::Iterator begin(Enum< T >)
FIXME: do not use data model tables.
float minFracLTM
minimum fraction of points to keep when trimming data to fit expected sigma
float maxFitErrX2
maximum fit error for X2
float minValidVoxFracDrift
if more than this fraction of bins are bad for one pad row the whole pad row is declared bad
float maxGaussStdDev
maximum number of sigmas to be considered for gaussian kernel smoothing
int minEntriesPerVoxel
minimum number of points in voxel for processing
float LTMCut
fraction op points to keep when trimming input data
int maxBadXBinsToCover
a lower number of consecutive bad X bins will not be declared bad
float maxFitErrY2
maximum fit error for Y2
float maxSigY
maximum sigma for y of the voxel
float maxFitCorrXY
maximum fit correlation for x and y
float maxSigZ
maximum sigma for z of the voxel
int minGoodXBinsToCover
minimum number of consecutive good bins, otherwise bins are declared bad
float maxFracBadRowsPerSector
maximum fraction of bad rows before whole sector is masked
bool isBfieldZero
for B=0 we set the radial distortions to zero and don't fit dy vs tgSlp
Structure which gets filled with the results for each voxel.
std::array< unsigned char, VoxDim > bvox
voxel identifier: VoxZ, VoxF, VoxX
std::array< float, ResDim > E
their errors
float dYSigMAD
MAD estimator of dY sigma (dispersion after slope removal)
std::array< float, ResDim > D
values of extracted distortions
float dZSigLTM
Z sigma from unbinned LTM estimator.
unsigned char flags
status flag
std::array< float, ResDim > DS
smoothed residual
unsigned char bsec
sector ID (0-35)
float EXYCorr
correlation between extracted X and Y
std::array< float, VoxHDim > stat
statistics: averages of each voxel dimension + entries
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)