44constexpr float kNoValidCharge = std::numeric_limits<float>::max();
50 float weightedPadSum = 0.f;
51 float weightedTimeSum = 0.f;
52 float totalCharge = 0.f;
53 uint16_t maxCharge = 0;
58 for (
const auto& cl : fragments) {
59 const float clPad = cl.getPad();
60 const float clTime = cl.getTime();
61 const uint16_t clqTot = cl.getQtot();
62 const uint16_t clqMax = cl.
qMax;
64 weightedPadSum += clPad * clqTot;
65 weightedTimeSum += clTime * clqTot;
66 totalCharge += clqTot;
67 maxCharge = std::max(maxCharge, clqMax);
70 if (totalCharge > o2::tpc::ClusterNative::maxRegularQtot) {
71 combinedCluster.setSaturatedQtot(
static_cast<uint32_t
>(totalCharge));
73 combinedCluster.
qTotPacked =
static_cast<uint16_t
>(totalCharge);
75 combinedCluster.
qMax = maxCharge;
76 combinedCluster.
padPacked =
static_cast<uint16_t
>(weightedPadSum / totalCharge * o2::tpc::ClusterNative::scalePadPacked);
77 combinedCluster.
timeFlagsPacked = (
static_cast<uint32_t
>(weightedTimeSum / totalCharge * o2::tpc::ClusterNative::scaleTimePacked) & 0xFFFFFF) | (firstCluster.
timeFlagsPacked & 0xFF000000);
78 return combinedCluster;
82const CalculatedEdx::RowFragment& CalculatedEdx::pickDominantFragment(
const std::vector<RowFragment>& fragments)
84 const RowFragment* dominant = &fragments[0];
85 for (
const auto& frag : fragments) {
86 if (frag.cl.getQtot() > dominant->cl.getQtot()) {
96 rebuildTPCCorrMapPOD();
99void CalculatedEdx::rebuildTPCCorrMapPOD()
104 mTPCCorrMapBuffer = std::move(
buffer);
105 mTPCCorrMap = mTPCCorrMapBuffer.
get();
114 LOGP(warning,
"CalculatedEdx::setTPCCorrMap() called after setRefit(); invalidating the existing refitter, call setRefit() again before using it.");
119 if (corrMapRef && lumiScale >= 0) {
121 auto& correction = mTPCCorrMapFull->getCorrection();
125 rebuildTPCCorrMapPOD();
132 LOGP(warning,
"CalculatedEdx::setTPCVDrift() called after setRefit(); invalidating the existing refitter, call setRefit() again before using it.");
137 rebuildTPCCorrMapPOD();
142 mTracks = vTPCTracksArrayInp;
143 mTPCTrackClIdxVecInput = tpcTrackClIdxVecInput;
144 mClusterIndex = &clIndex;
150 mNHbfPerTf = nHbfPerTf;
151 mWarnedMissingRefit =
false;
154 mTPCRefitterOccMap.resize(sizeOcc);
155 std::fill(mTPCRefitterOccMap.begin(), mTPCRefitterOccMap.end(), 0);
156 if (!mClusterIndex || !mTracks || !mTPCTrackClIdxVecInput) {
158 mTPCRefitterShMap.clear();
163 mRefit = std::make_unique<o2::gpu::GPUO2InterfaceRefit>(mClusterIndex, mTPCCorrMap, mFieldNominalGPUBz, mTPCTrackClIdxVecInput->data(), nHbfPerTf, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size());
166void CalculatedEdx::fillMissingClusters(
int missingClusters[4],
const float minChargeTot[4],
const float minChargeMax[4],
int method, std::array<std::vector<float>, 5>& chargeTotROC, std::array<std::vector<float>, 5>& chargeMaxROC)
168 if (method != 0 && method != 1) {
169 LOGP(info,
"Unrecognized subthreshold cluster treatment. Not adding virtual charges to the track!");
177 if (minChargeTot[
roc] >= kNoValidCharge || minChargeMax[
roc] >= kNoValidCharge) {
180 const float chargeTot = (method == 1) ? minChargeTot[
roc] / 2.f : minChargeTot[
roc];
181 const float chargeMax = (method == 1) ? minChargeMax[
roc] / 2.f : minChargeMax[
roc];
182 for (
int i = 0;
i < missingClusters[
roc];
i++) {
184 chargeTotROC[
roc].emplace_back(chargeTot);
185 chargeTotROC[4].emplace_back(chargeTot);
187 chargeMaxROC[
roc].emplace_back(chargeMax);
188 chargeMaxROC[4].emplace_back(chargeMax);
193void CalculatedEdx::handleSameRowClusters(
o2::tpc::TrackTPC& track, std::vector<std::pair<unsigned char, unsigned char>>& rowOrder, std::map<std::pair<unsigned char, unsigned char>, std::vector<int>>& clustersByRow, std::set<std::pair<unsigned char, unsigned char>>& mergeableRows, std::map<
int, std::tuple<unsigned char, unsigned char, unsigned int>>& clusterReferencesByIndex)
196 const int nClusters = track.getNClusterReferences();
199 for (
int iCl = 0; iCl <
nClusters; iCl++) {
200 unsigned char sectorIndex = 0;
201 unsigned char rowIndex = 0;
202 unsigned int clusterIndexNumb = 0;
204 track.getClusterReference(*mTPCTrackClIdxVecInput, iCl, sectorIndex, rowIndex, clusterIndexNumb);
206 const auto rowKey = std::make_pair(sectorIndex, rowIndex);
207 if (clustersByRow.find(rowKey) == clustersByRow.end()) {
208 rowOrder.emplace_back(rowKey);
212 clustersByRow[rowKey].emplace_back(iCl);
215 clusterReferencesByIndex[iCl] = std::make_tuple(sectorIndex, rowIndex, clusterIndexNumb);
226 float minPad = 1e9f, maxPad = -1e9f, minTime = 1e9f, maxTime = -1e9f;
229 minPad = std::min(minPad, cl.getPad());
230 maxPad = std::max(maxPad, cl.getPad());
231 minTime = std::min(minTime, cl.getTime());
232 maxTime = std::max(maxTime, cl.getTime());
234 if ((maxPad - minPad) > mSameRowMaxPadDiff || (maxTime - minTime) > mSameRowMaxTimeDiff) {
238 mergeableRows.insert(rowKey);
242void CalculatedEdx::handleSameRowClusters(
const std::vector<o2::tpc::ClusterNative>&
clusters,
const ClInfoVec& clusterInfos, std::vector<std::pair<unsigned char, unsigned char>>& rowOrder, std::map<std::pair<unsigned char, unsigned char>, std::vector<int>>& clustersByRow, std::set<std::pair<unsigned char, unsigned char>>& mergeableRows)
247 for (
int iCl = 0; iCl <
nClusters; iCl++) {
248 const auto rowKey = std::make_pair(clusterInfos[iCl].sectorIndex, clusterInfos[iCl].rowIndex);
249 if (clustersByRow.find(rowKey) == clustersByRow.end()) {
250 rowOrder.emplace_back(rowKey);
254 clustersByRow[rowKey].emplace_back(iCl);
264 float minPad = 1e9f, maxPad = -1e9f, minTime = 1e9f, maxTime = -1e9f;
267 minPad = std::min(minPad, cl.getPad());
268 maxPad = std::max(maxPad, cl.getPad());
269 minTime = std::min(minTime, cl.getTime());
270 maxTime = std::max(maxTime, cl.getTime());
272 if ((maxPad - minPad) > mSameRowMaxPadDiff || (maxTime - minTime) > mSameRowMaxTimeDiff) {
276 mergeableRows.insert(rowKey);
288 const bool refitFailed = refitTrack(track);
291 std::vector<std::pair<unsigned char, unsigned char>> rowOrder;
292 std::map<std::pair<unsigned char, unsigned char>, std::vector<int>> clustersByRow;
293 std::set<std::pair<unsigned char, unsigned char>> mergeableRows;
294 std::map<int, std::tuple<unsigned char, unsigned char, unsigned int>> clusterReferencesByIndex;
298 rowData.reserve(rowOrder.size());
301 std::array<std::vector<unsigned int>, 4> occupancyROC;
304 unsigned char rowIndexOld = 255;
305 unsigned char sectorIndexOld = 255;
308 for (
const auto& rowKey : rowOrder) {
310 const unsigned char rowIndex = rowKey.second;
311 const unsigned char sectorIndex = rowKey.first;
313 std::vector<o2::tpc::ClusterNative> fragmentClusters;
314 std::vector<bool> fragmentIsShared;
318 fragmentClusters.emplace_back(track.getCluster(*mTPCTrackClIdxVecInput, clusterIdx, *mClusterIndex));
319 const auto& [fragSectorIndex, fragRowIndex, clusterIndexNumb] = clusterReferencesByIndex[clusterIdx];
320 const unsigned int absoluteIndex = mClusterIndex->
clusterOffset[fragSectorIndex][fragRowIndex] + clusterIndexNumb;
324 const bool mergeable = mergeableRows.count(rowKey) > 0;
325 gatherRowClusterDataForRow(track, fragmentClusters, fragmentIsShared, sectorIndex, rowIndex, mergeable, rowIndexOld, sectorIndexOld, occupancyROC, rowData, refitFailed);
327 rowIndexOld = rowIndex;
328 sectorIndexOld = sectorIndex;
332 double*
const averageOccROC[4] = {&averageOcc.
IROC, &averageOcc.
OROC1, &averageOcc.
OROC2, &averageOcc.
OROC3};
334 unsigned int sumOcc = 0;
335 size_t nValidOcc = 0;
336 for (
const unsigned int occ : occupancyROC[
roc]) {
337 if (occ !=
static_cast<unsigned int>(-1)) {
343 *averageOccROC[
roc] =
static_cast<double>(sumOcc) / nValidOcc;
354 if (!mWarnedMissingRefit) {
355 LOGP(
error,
"CalculatedEdx: setRefit() is set but there is no refitter for the track's cluster references (setMembers() missing, or the refitter was dropped by setTPCCorrMap()/setTPCVDrift()), propagating the original tracks instead");
356 mWarnedMissingRefit =
true;
363 const bool failed = (mRefit->RefitTrackAsGPU(track,
true,
true) < 0) || std::isnan(
track.getParam(1));
376 if (nCl == 0 || nCl != clusterInfos.size() || nCl > std::numeric_limits<uint16_t>::max()) {
380 if (!mExtClusterAccess) {
381 mExtClusterAccess = std::make_unique<o2::tpc::ClusterNativeAccess>();
383 auto&
access = *mExtClusterAccess;
384 std::memset(
access.nClusters, 0,
sizeof(
access.nClusters));
385 for (
const auto& info : clusterInfos) {
386 if (
info.sectorIndex >= constants::MAXSECTOR ||
info.rowIndex >= constants::MAXGLOBALPADROW) {
391 const auto* refsBefore = mExtClusterRefs.data();
392 const auto* shMapBefore = mExtShMap.data();
393 mExtClusters.resize(nCl);
395 mExtShMap.assign(nCl, 0);
396 access.clustersLinear = mExtClusters.data();
397 access.clustersMCTruth =
nullptr;
400 std::map<std::pair<unsigned char, unsigned char>,
unsigned int> nPlaced;
401 auto* sectorRowIndices =
reinterpret_cast<uint8_t*
>(mExtClusterRefs.data() +
nCl);
402 for (
size_t iCl = 0; iCl <
nCl; ++iCl) {
403 const auto&
info = clusterInfos[iCl];
404 const unsigned int indexInRow = nPlaced[{
info.sectorIndex,
info.rowIndex}]++;
405 const unsigned int linearIndex =
access.clusterOffset[
info.sectorIndex][
info.rowIndex] + indexInRow;
406 mExtClusters[linearIndex] =
clusters[iCl];
408 mExtClusterRefs[iCl] = indexInRow;
409 sectorRowIndices[iCl] =
info.sectorIndex;
410 sectorRowIndices[iCl +
nCl] =
info.rowIndex;
414 if (!mRefitExt || refsBefore != mExtClusterRefs.data() || shMapBefore != mExtShMap.data()) {
415 mRefitExt = std::make_unique<o2::gpu::GPUO2InterfaceRefit>(mExtClusterAccess.get(), mTPCCorrMap, mFieldNominalGPUBz, mExtClusterRefs.data(), mNHbfPerTf, mExtShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size());
430bool CalculatedEdx::propagateTrackToX(
o2::track::TrackParCov& track,
float xPosition,
unsigned char sectorIndex)
const
433 bool check =
track.rotate(o2::math_utils::detail::sector2Angle<float>(sectorIndex));
439 check =
track.rotate(o2::math_utils::detail::sector2Angle<float>(sectorIndex));
446 check =
track.rotateParam(o2::math_utils::detail::sector2Angle<float>(sectorIndex));
448 check =
track.propagateParamTo(xPosition, mFieldNominalGPUBz);
457void CalculatedEdx::gatherRowClusterDataForRow(
o2::tpc::TrackTPC& track,
const std::vector<o2::tpc::ClusterNative>& fragmentClusters,
const std::vector<bool>& fragmentIsShared,
unsigned char sectorIndex,
unsigned char rowIndex,
bool mergeable,
unsigned char rowIndexOld,
unsigned char sectorIndexOld, std::array<std::vector<unsigned int>, 4>& occupancyROC, std::vector<RowClusterData>& rowData,
bool refitFailed)
460 row.sectorIndex = sectorIndex;
461 row.rowIndex = rowIndex;
462 row.mergeable = mergeable;
466 const CRU cru(
Sector(sectorIndex), region);
467 const auto stack = cru.gemStack();
469 const int stackNumber =
static_cast<int>(
stack);
473 row.stackID = stackID;
474 row.stackNumber = stackNumber;
478 row.fragments.reserve(fragmentClusters.size());
479 for (
size_t iFrag = 0; iFrag < fragmentClusters.size(); ++iFrag) {
483 frag.isShared = fragmentIsShared[iFrag];
486 frag.threshold = mCalibCont.getZeroSupressionThreshold(sectorIndex, rowIndex, frag.pad);
487 frag.gain = mCalibCont.getGain(sectorIndex, rowIndex, frag.pad);
488 frag.gainResidual = mCalibCont.getResidualGain(sectorIndex, rowIndex, frag.pad);
490 row.fragments.emplace_back(std::move(frag));
494 if (mergeable && fragmentClusters.size() > 1) {
495 row.mergedFragment.cl = buildMergedClusterSum(fragmentClusters);
498 row.mergedFragment.threshold = mCalibCont.getZeroSupressionThreshold(sectorIndex, rowIndex,
row.mergedFragment.pad);
499 row.mergedFragment.gain = mCalibCont.getGain(sectorIndex, rowIndex,
row.mergedFragment.pad);
500 row.mergedFragment.gainResidual = mCalibCont.getResidualGain(sectorIndex, rowIndex,
row.mergedFragment.pad);
501 row.mergedFragment.isShared =
row.fragments[0].isShared;
505 std::array<std::vector<unsigned int>, 4>::size_type occStackIdx;
515 if (mergeable && fragmentClusters.size() > 1) {
516 occupancyROC[occStackIdx].emplace_back(
row.mergedFragment.occupancy);
518 for (
const auto& frag :
row.fragments) {
519 occupancyROC[occStackIdx].emplace_back(frag.occupancy);
525 if (mPropagateToClusterX) {
526 float sumX = 0.f, sumQ = 0.f;
527 for (
const auto& cl : fragmentClusters) {
529 mTPCCorrMap->Transform(sectorIndex, rowIndex, cl.getPad(), cl.getTime(),
x,
y,
z,
track.getTime0());
530 sumX +=
x * cl.getQtot();
531 sumQ += cl.getQtot();
534 xPosition = sumX / sumQ;
538 if (mUseRefit || mPropagateTrack || !mPropagateParams) {
541 check = propagateTrackToX(track, xPosition, sectorIndex);
545 check =
track.rotateParam(o2::math_utils::detail::sector2Angle<float>(sectorIndex));
547 check =
track.propagateParamTo(xPosition, mFieldNominalGPUBz);
554 row.propagationFailed = (!
check || std::isnan(
track.getParam(1)));
555 row.refitFellBack = mUseRefit && refitFailed && !
row.propagationFailed;
557 if (
row.propagationFailed) {
558 ++mNPropagationFailed;
559 }
else if (
row.refitFellBack) {
567 row.sameSectorAsPrevRow = (sectorIndexOld == sectorIndex);
568 row.missingClusters = (rowIndexOld == 255) ? 0 : (
std::abs(static_cast<
int>(rowIndex) - static_cast<
int>(rowIndexOld)) - 1);
571 row.missingClusterGapDeadOrEdge =
false;
572 if (
row.missingClusters > 0 &&
row.missingClusters <= mMaxMissingCl) {
574 const RowClusterData& prevRow = rowData.back();
576 const int rowLo = std::min<int>(rowIndex, rowIndexOld);
577 const int rowHi = std::max<int>(rowIndex, rowIndexOld);
579 for (
int missingRow = rowLo + 1; missingRow < rowHi; ++missingRow) {
583 const float yPrevOwn = gpuGeom.LinearPad2Y(sectorIndexOld, rowIndexOld, prevRow.fragments[0].cl.getPad());
584 float yPrev = yPrevOwn;
585 if (sectorIndexOld != sectorIndex) {
587 row.missingClusterGapDeadOrEdge =
true;
589 const float dAlpha = o2::math_utils::detail::sector2Angle<float>(sectorIndexOld) - o2::math_utils::detail::sector2Angle<float>(sectorIndex);
590 yPrev = gpuGeom.Row2X(rowIndexOld) * std::sin(dAlpha) + yPrevOwn * std::cos(dAlpha);
592 const float yCur = gpuGeom.LinearPad2Y(sectorIndex, rowIndex,
row.fragments[0].cl.getPad());
593 const float yLo = (rowLo ==
static_cast<int>(rowIndexOld)) ? yPrev : yCur;
594 const float yHi = (rowHi ==
static_cast<int>(rowIndexOld)) ? yPrev : yCur;
595 for (
int k = 1; k <=
row.missingClusters && !
row.missingClusterGapDeadOrEdge; ++k) {
596 const unsigned char missingRow =
static_cast<unsigned char>(rowLo + k);
597 const float frac =
static_cast<float>(k) / (
row.missingClusters + 1);
598 const float missingPad = gpuGeom.LinearY2Pad(sectorIndex, missingRow, yLo + (yHi - yLo) * frac);
599 if (missingPad < 0.f || missingPad >= gpuGeom.NPads(missingRow)) {
600 row.missingClusterGapDeadOrEdge =
true;
605 if (mCalibCont.isDead(
static_cast<unsigned int>(sectorIndex),
static_cast<gpu::tpccf::Row>(missingRow),
static_cast<gpu::tpccf::Pad>(missingPadClamped))) {
606 row.missingClusterGapDeadOrEdge =
true;
612 rowData.emplace_back(std::move(
row));
623 const bool refitFailed = refitTrack(track,
clusters, clusterInfos);
626 std::vector<std::pair<unsigned char, unsigned char>> rowOrder;
627 std::map<std::pair<unsigned char, unsigned char>, std::vector<int>> clustersByRow;
628 std::set<std::pair<unsigned char, unsigned char>> mergeableRows;
632 rowData.reserve(rowOrder.size());
635 std::array<std::vector<unsigned int>, 4> occupancyROC;
638 unsigned char rowIndexOld = 255;
639 unsigned char sectorIndexOld = 255;
642 for (
const auto& rowKey : rowOrder) {
644 const unsigned char rowIndex = rowKey.second;
645 const unsigned char sectorIndex = rowKey.first;
647 std::vector<o2::tpc::ClusterNative> fragmentClusters;
648 std::vector<bool> fragmentIsShared;
652 fragmentClusters.emplace_back(
clusters[clusterIdx]);
654 fragmentIsShared.emplace_back(clusterInfos[clusterIdx].isShared);
657 const bool mergeable = mergeableRows.count(rowKey) > 0;
658 gatherRowClusterDataForRow(track, fragmentClusters, fragmentIsShared, sectorIndex, rowIndex, mergeable, rowIndexOld, sectorIndexOld, occupancyROC, rowData, refitFailed);
660 rowIndexOld = rowIndex;
661 sectorIndexOld = sectorIndex;
665 double*
const averageOccROC[4] = {&averageOcc.
IROC, &averageOcc.
OROC1, &averageOcc.
OROC2, &averageOcc.
OROC3};
667 unsigned int sumOcc = 0;
668 size_t nValidOcc = 0;
669 for (
const unsigned int occ : occupancyROC[
roc]) {
670 if (occ !=
static_cast<unsigned int>(-1)) {
676 *averageOccROC[
roc] =
static_cast<double>(sumOcc) / nValidOcc;
684 int nClsROC[4] = {0, 0, 0, 0};
685 int nClsSubThreshROC[4] = {0, 0, 0, 0};
689 LOGP(warning,
"Unrecognized sameRowClusterMethod {} (expected 0, 1, or 2); treating same-row cluster groups as method 0 (do not merge)", settings.
sameRowClusterMethod);
694 std::array<std::vector<float>, nType> chargeTotROC;
695 std::array<std::vector<float>, nType> chargeMaxROC;
696 for (
int i = 0;
i < nType; ++
i) {
702 float minChargeTotROC[4] = {kNoValidCharge, kNoValidCharge, kNoValidCharge, kNoValidCharge};
703 float minChargeMaxROC[4] = {kNoValidCharge, kNoValidCharge, kNoValidCharge, kNoValidCharge};
706 std::vector<unsigned int> occupancyVector;
710 occupancyVector.reserve(rowData.size());
714 const int edgeRowCut = std::min<int>(
static_cast<int>(rowData.size()) / 2, mSubThreshEdgeRows);
716 for (
size_t iRowData = 0; iRowData < rowData.size(); ++iRowData) {
717 const auto&
row = rowData[iRowData];
721 std::vector<const RowFragment*>
samples;
723 const bool doMerge =
row.mergeable &&
row.fragments.size() > 1 && sameRowClusterMethod != 0;
726 for (
const auto& frag :
row.fragments) {
729 }
else if (sameRowClusterMethod == 2) {
730 samples.push_back(&pickDominantFragment(
row.fragments));
736 const bool isCombined =
row.fragments.size() > 1;
739 const int missingClusters =
row.missingClusters;
741 if ((missingClusters > 0) && (missingClusters <= mMaxMissingCl) && !
row.missingClusterGapDeadOrEdge && (
static_cast<int>(iRowData) >= edgeRowCut) && !excludeSectorBoundary) {
743 nClsSubThreshROC[
roc] +=
row.missingClustersStack[
roc];
744 nClsROC[
roc] +=
row.missingClustersStack[
roc];
748 for (
const auto& sample :
samples) {
750 occupancyVector.emplace_back(sample->occupancy);
754 float chargeTot = sample->cl.getQtot();
755 float chargeMax = sample->cl.getQmax();
758 float effectiveLength = 1.0f;
759 float effectiveLengthTot = 1.0f;
760 float effectiveLengthMax = 1.0f;
762 float gainResidual = 1.0f;
763 float corrTot = 1.0f;
764 float corrMax = 1.0f;
768 const uint8_t flagsCl = sample->cl.getFlags();
779 excludeCl += 0b01000;
782 excludeCl += 0b010000;
785 excludeCl += 0b0100000;
788 excludeCl += 0b01000000;
791 excludeCl += 0b010000000;
793 if (
row.propagationFailed) {
794 excludeCl += 0b01000000000;
800 chargeTot /= effectiveLength;
801 chargeMax /= effectiveLength;
805 float topoChargeTot = chargeTot;
806 float topoChargeMax = chargeMax;
807 if (gainFullApplied) {
812 topoChargeTot *= sample->gain;
813 topoChargeMax *= sample->gain;
820 chargeTot /= effectiveLengthTot;
821 chargeMax /= effectiveLengthMax;
826 corrTot = mCalibCont.getResidualCorrection(
row.stackID,
ChargeType::Tot,
row.trackSnapshot.getTgl(),
row.trackSnapshot.getSnp());
827 corrMax = mCalibCont.getResidualCorrection(
row.stackID,
ChargeType::Max,
row.trackSnapshot.getTgl(),
row.trackSnapshot.getSnp());
829 chargeTot /= corrTot;
832 chargeMax /= corrMax;
838 gainResidual = sample->gainResidual;
839 chargeTot /= gainResidual;
840 chargeMax /= gainResidual;
844 const float time = sample->cl.getTime() - trackTime0;
858 const float localX = gpuGeom.Row2X(
row.rowIndex);
859 const float localY = gpuGeom.LinearPad2Y(
row.sectorIndex,
row.rowIndex, sample->cl.getPad());
862 const float globalX = g2D.x();
863 const float globalY = g2D.y();
868 (*debugStreamer) <<
"dEdxDebugCl"
869 <<
"trackIndex=" << mDebugTrackIndex
870 <<
"trackParam=" << trackParam
871 <<
"cl=" << sample->cl
872 <<
"chargeTot=" << chargeTot
873 <<
"chargeMax=" << chargeMax
874 <<
"excludeCl=" << excludeCl
875 <<
"region=" <<
row.region
876 <<
"rowIndex=" <<
row.rowIndex
877 <<
"sectorIndex=" <<
row.sectorIndex
878 <<
"stack=" <<
row.stackNumber
879 <<
"localX=" << localX
880 <<
"localY=" << localY
881 <<
"globalX=" << globalX
882 <<
"globalY=" << globalY
883 <<
"isShared=" << sample->isShared
884 <<
"isCombined=" << isCombined
885 <<
"refitFellBack=" <<
row.refitFellBack
886 <<
"topologyCorr=" << effectiveLength
887 <<
"topologyCorrTot=" << effectiveLengthTot
888 <<
"topologyCorrMax=" << effectiveLengthMax
890 <<
"fullGain=" << sample->gain
891 <<
"gainResidual=" << gainResidual
892 <<
"residualCorrTot=" << corrTot
893 <<
"residualCorrMax=" << corrMax
894 <<
"scCorr=" << scCorr
895 <<
"occupancy=" << sample->occupancy
896 <<
"inputClusterIndices=" <<
row.inputClusterIndices
900 if (excludeCl != 0) {
906 if (chargeTot < minChargeTotROC[
row.stackNumber]) {
907 minChargeTotROC[
row.stackNumber] = chargeTot;
910 if (chargeMax < minChargeMaxROC[
row.stackNumber]) {
911 minChargeMaxROC[
row.stackNumber] = chargeMax;
915 chargeTotROC[0].emplace_back(chargeTot);
916 chargeMaxROC[0].emplace_back(chargeMax);
919 chargeTotROC[1].emplace_back(chargeTot);
920 chargeMaxROC[1].emplace_back(chargeMax);
923 chargeTotROC[2].emplace_back(chargeTot);
924 chargeMaxROC[2].emplace_back(chargeMax);
927 chargeTotROC[3].emplace_back(chargeTot);
928 chargeMaxROC[3].emplace_back(chargeMax);
932 chargeTotROC[4].emplace_back(chargeTot);
933 chargeMaxROC[4].emplace_back(chargeMax);
939 float cappedMinChargeTotROC[4], cappedMinChargeMaxROC[4];
941 cappedMinChargeTotROC[
roc] = (minChargeTotROC[
roc] >= kNoValidCharge) ? minChargeTotROC[
roc] :
std::
min(minChargeTotROC[
roc], settings.maxSubthresholdChargeTot);
942 cappedMinChargeMaxROC[
roc] = (minChargeMaxROC[
roc] >= kNoValidCharge) ? minChargeMaxROC[
roc] :
std::
min(minChargeMaxROC[
roc], settings.maxSubthresholdChargeMax);
947 if (minChargeTotROC[
roc] >= kNoValidCharge || minChargeMaxROC[
roc] >= kNoValidCharge) {
948 nClsROC[
roc] -= nClsSubThreshROC[
roc];
949 nClsSubThreshROC[
roc] = 0;
953 if (mNSubThresholdFilledPerSettings.size() <= settingsIndex) {
954 mNSubThresholdFilledPerSettings.resize(settingsIndex + 1, 0);
956 mNSubThresholdFilledPerSettings[settingsIndex] += nClsSubThreshROC[0] + nClsSubThreshROC[1] + nClsSubThreshROC[2] + nClsSubThreshROC[3];
960 output.NHitsSubThresholdIROC = nClsROC[0];
961 output.NHitsSubThresholdOROC1 = nClsROC[1];
962 output.NHitsSubThresholdOROC2 = nClsROC[2];
963 output.NHitsSubThresholdOROC3 = nClsROC[3];
967 output.NHitsIROC = nClsROC[0] - nClsSubThreshROC[0];
968 output.NHitsOROC1 = nClsROC[1] - nClsSubThreshROC[1];
969 output.NHitsOROC2 = nClsROC[2] - nClsSubThreshROC[2];
970 output.NHitsOROC3 = nClsROC[3] - nClsSubThreshROC[3];
973 auto chargeTotVector = mDebug ? chargeTotROC[4] : std::vector<float>();
974 auto chargeMaxVector = mDebug ? chargeMaxROC[4] : std::vector<float>();
991 float minChargeTot = minChargeTotROC[0], minChargeMax = minChargeMaxROC[0];
993 minChargeTot = (minChargeTotROC[
roc] < minChargeTot) ? minChargeTotROC[
roc] : minChargeTot;
994 minChargeMax = (minChargeMaxROC[
roc] < minChargeMax) ? minChargeMaxROC[
roc] : minChargeMax;
997 (*debugStreamer) <<
"dEdxDebugTrack"
998 <<
"trackIndex=" << mDebugTrackIndex
999 <<
"track=" << trackOrig
1001 <<
"averageOcc=" << averageOcc
1002 <<
"nCl=" << rowData.size()
1003 <<
"minChargeTot=" << minChargeTot
1004 <<
"minChargeMax=" << minChargeMax
1005 <<
"chargeTotVector=" << chargeTotVector
1006 <<
"chargeMaxVector=" << chargeMaxVector
1007 <<
"occupancy=" << occupancyVector
1008 <<
"mcLabel=" <<
label
1016 if (settingsList.empty()) {
1024 const float trackTime0 = track.getTime0();
1027 std::vector<RowClusterData> rowData;
1028 gatherRowClusterData(track, rowData, averageOcc);
1031 outputs.resize(settingsList.size());
1032 for (
size_t i = 0;
i < settingsList.size(); ++
i) {
1033 calculatedEdxFromRowData(rowData, settingsList[
i],
i, trackTime0, trackOrig, averageOcc, outputs[
i], mcLabel);
1037void CalculatedEdx::calculatedEdx(
o2::tpc::TrackTPC& track,
const std::vector<o2::tpc::ClusterNative>&
clusters,
const ClInfoVec& clusterInfos,
dEdxInfo&
output,
AverageOccupancy& averageOcc,
float low,
float high,
CorrectionFlags correctionMask,
ClusterFlags clusterMask,
int subthresholdMethod,
int stackBoundaryMethod,
const char* debugRootFile,
float maxSubthresholdChargeTot,
float maxSubthresholdChargeMax,
int sameRowClusterMethod)
1041 settings.
high = high;
1055 const float trackTime0 = track.getTime0();
1057 std::vector<RowClusterData> rowData;
1058 gatherRowClusterData(track,
clusters, clusterInfos, rowData, averageOcc);
1060 calculatedEdxFromRowData(rowData, settings, 0, trackTime0, trackOrig, averageOcc,
output);
1066 if (settingsList.empty()) {
1074 const float trackTime0 = track.getTime0();
1077 std::vector<RowClusterData> rowData;
1078 gatherRowClusterData(track,
clusters, clusterInfos, rowData, averageOcc);
1081 outputs.resize(settingsList.size());
1082 for (
size_t i = 0;
i < settingsList.size(); ++
i) {
1083 calculatedEdxFromRowData(rowData, settingsList[
i],
i, trackTime0, trackOrig, averageOcc, outputs[
i], mcLabel);
1087void CalculatedEdx::calculatedEdx(
o2::tpc::TrackTPC& track,
dEdxInfo&
output,
AverageOccupancy& averageOcc,
float low,
float high,
CorrectionFlags correctionMask,
ClusterFlags clusterMask,
int subthresholdMethod,
int stackBoundaryMethod,
const char* debugRootFile,
float maxSubthresholdChargeTot,
float maxSubthresholdChargeMax,
int sameRowClusterMethod)
1091 settings.
high = high;
1105 const float trackTime0 = track.getTime0();
1107 std::vector<RowClusterData> rowData;
1108 gatherRowClusterData(track, rowData, averageOcc);
1110 calculatedEdxFromRowData(rowData, settings, 0, trackTime0, trackOrig, averageOcc,
output);
1121 size_t firstCl =
charge.size() * low;
1122 size_t lastCl =
charge.size() * high;
1124 for (
size_t iCl = firstCl; iCl < lastCl; ++iCl) {
1139 const float snp = track.getSnp();
1140 const float tgl = track.getTgl();
1141 const float snp2 = snp * snp;
1142 const float tgl2 = tgl * tgl;
1144 const float effectiveLength = padLength * std::sqrt((1 + tgl2) / (1 - snp2));
1145 return effectiveLength;
1150 const float snp = std::abs(track.getSnp());
1151 const float tgl = track.getTgl();
1152 constexpr float maxSnp2 = 0.99f;
1153 float snp2 = snp * snp;
1154 if (snp2 > maxSnp2) {
1157 const float tgl2 = tgl * tgl;
1158 const float sec2 = 1.f / (1.f - snp2);
1159 const float tanTheta = std::sqrt(tgl2 * sec2);
1161 const float z = std::abs(track.getParam(1));
1162 const float padTmp = cl.getPad();
1163 const float absRelPad = std::abs(padTmp -
int(padTmp + 0.5f));
1164 const float relTime = cl.getTime() - int(cl.getTime() + 0.5f);
1166 const float effectiveLength = mCalibCont.getTopologyCorrection(region, chargeType, tanTheta, snp,
z, absRelPad, relTime, threshold,
charge);
1167 return effectiveLength;
1173 const int nTimeBinsPerOccupBin = 16;
1174 const int iBinOcc = clTime / nTimeBinsPerOccupBin + 2;
1175 if (!mRefit || iBinOcc < 0 ||
static_cast<size_t>(iBinOcc) >= mTPCRefitterOccMap.size()) {
1178 return mTPCRefitterOccMap[iBinOcc];
1184 const auto& boundaries = mStackBoundaries[stackNumber];
1186 for (
unsigned char boundary : boundaries) {
1187 if (rowIndex == boundary) {
1192 if (stackBoundaryMethod == 2) {
1193 if (rowIndex == boundaries[0] + 1 || rowIndex == boundaries[1] - 1) {
1200void CalculatedEdx::loadCalibsFromCCDB(
long runNumberOrTimeStamp,
const bool isMC,
const bool loadSCCorrMap,
const bool useSCCorrMap,
const bool useVDrift,
const float corrMapLumiScale)
1204 cm.setURL(
"http://alice-ccdb.cern.ch/");
1206 auto tRun = runNumberOrTimeStamp;
1207 if (runNumberOrTimeStamp < 10000000) {
1208 auto runDuration = cm.getRunDuration(runNumberOrTimeStamp);
1209 tRun = runDuration.first + (runDuration.second - runDuration.first) / 2;
1211 LOGP(info,
"Timestamp: {}", tRun);
1212 cm.setTimestamp(tRun);
1224 const float minGain = 0;
1225 const float maxGain = 2;
1226 mCalibCont.
setGainMap(*gainMap, minGain, maxGain);
1243 LOGP(info,
"Magnetic field: {}", bz);
1249 propagator->setMatLUT(matLut);
1252 const bool prevFatalWhenNull = cm.getFatalWhenNull();
1253 cm.setFatalWhenNull(
false);
1258 if (loadSCCorrMap || useSCCorrMap) {
1263 LOGP(warning,
"no {} at {}: no space-charge correction",
o2::tpc::CDBTypeMap.at(avgMapType), tRun);
1267 if (loadSCCorrMap && avgMap) {
1270 derMap->rectifyAfterReadingFromFile();
1273 LOGP(warning,
"no {} at {}: the dE/dx space-charge correction is not available",
o2::tpc::CDBTypeMap.at(derMapType), tRun);
1278 if (useSCCorrMap && avgMap) {
1280 float lumiScale = corrMapLumiScale;
1285 if (lumiScale < 0) {
1293 LOGP(info,
"cluster transform: using CCDB space-charge correction map {}, lumi scale {}",
o2::tpc::CDBTypeMap.at(avgMapType), (refMap && lumiScale >= 0) ? fmt::format(
"{}", lumiScale) :
"none");
1296 LOGP(info,
"cluster transform: no space-charge correction");
1303 LOGP(info,
"cluster transform vDrift calib: corrFact={:.5f} refVDrift={:.5f} timeOffset={:.4f}us", vd->corrFact, vd->refVDrift, vd->getTimeOffset());
1308 LOGP(info,
"cluster transform: nominal vDrift/t0");
1310 cm.setFatalWhenNull(prevFatalWhenNull);
1314 deadCMCreator.
init();
1315 deadCMCreator.
load(tRun);
1324 const bool prevFatalWhenNull = cm.getFatalWhenNull();
1325 cm.setFatalWhenNull(
false);
1328 cm.setFatalWhenNull(prevFatalWhenNull);
1329 if (!scalerTree || meanIDC <= 0) {
1330 LOGP(warning,
"no TPC scaler or mean IDC of the map ({}) at {}, the space-charge map is not scaled", meanIDC, timeStamp);
1338 const float integrationTimeMS = std::min(std::abs(
weights->mFirstTimeStampMS), 500.f);
1339 if (integrationTimeMS > 0) {
1345 LOGP(warning,
"time stamp {} not covered by the TPC scaler window [{}, {}] ms, using the unweighted mean scaler", timeStamp, scaler.
getStartTimeStampMS() + scaler.
getIonDriftTimeMS(), endMS);
1350 LOGP(info,
"TPC scaler at {}: {}, map mean IDC: {}", timeStamp, instIDC, meanIDC);
1351 return instIDC > 0 ? instIDC / meanIDC : -1.f;
1357 setGainMapFromFile(localCCDBFolder,
"/TPC/Calib/PadGainFull/snapshot.root",
"ccdb_object");
1370 setVDriftFromFile(localCCDBFolder,
"/TPC/Calib/VDriftTgl/snapshot.root",
"ccdb_object");
1376 std::unique_ptr<TFile> corrMapFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1377 auto* corrMap = (corrMapFile && !corrMapFile->IsZombie()) ? (
o2::gpu::TPCFastTransform*)corrMapFile->Get(
object) :
nullptr;
1379 LOGP(warning,
"no {} in {}{}: no space-charge correction",
object, folder, file);
1383 corrMap->rectifyAfterReadingFromFile();
1385 LOGP(info,
"cluster transform: using space-charge correction map from {}", corrMapFile->GetName());
1390 std::unique_ptr<TFile> vdFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1391 if (!vdFile || vdFile->IsZombie()) {
1392 LOGP(warning,
"no {}{}: cluster transform at nominal vDrift/t0", folder, file);
1397 LOGP(info,
"cluster transform vDrift calib from {}: corrFact={:.5f} refVDrift={:.5f} timeOffset={:.4f}us", vdFile->GetName(), vd->corrFact, vd->refVDrift, vd->getTimeOffset());
1404 calibTrackTopology.
loadFromFile(fmt::format(
"{}{}", folder, file).
data(),
object);
1410 std::unique_ptr<TFile> gainMapFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1411 if (!gainMapFile->IsZombie()) {
1412 LOGP(info,
"Using file: {}", gainMapFile->GetName());
1420 std::unique_ptr<TFile> gainMapResidualFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1421 if (!gainMapResidualFile->IsZombie()) {
1422 LOGP(info,
"Using file: {}", gainMapResidualFile->GetName());
1423 std::unordered_map<std::string, o2::tpc::CalDet<float>>* gainMapResidual = (std::unordered_map<std::string, o2::tpc::CalDet<float>>*)gainMapResidualFile->Get(
object);
1430 std::unique_ptr<TFile> calibdEdxResidualFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1431 if (!calibdEdxResidualFile->IsZombie()) {
1432 LOGP(info,
"Using file: {}", calibdEdxResidualFile->GetName());
1440 std::unique_ptr<TFile> zeroSuppressionFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1441 if (!zeroSuppressionFile->IsZombie()) {
1442 LOGP(info,
"Using file: {}", zeroSuppressionFile->GetName());
1443 std::unordered_map<std::string, o2::tpc::CalDet<float>>* zeroSupressionThresholdMap = (std::unordered_map<std::string, o2::tpc::CalDet<float>>*)zeroSuppressionFile->Get(
object);
1450 std::unique_ptr<TFile> magFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1451 if (!magFile->IsZombie()) {
1452 LOGP(info,
"Using file: {}", magFile->GetName());
1456 LOGP(info,
"Magnetic field: {}", bz);
1464 std::unique_ptr<TFile> matLutFile(TFile::Open(fmt::format(
"{}{}", folder, file).
data()));
1465 if (!matLutFile->IsZombie()) {
1466 LOGP(info,
"Using file: {}", matLutFile->GetName());
1468 propagator->setMatLUT(matLut);
Simple interface to the CDB manager.
Class of a TPC cluster in TPC-native coordinates (row, time)
std::vector< double > sum
Header of the General Run Parameters object for B field values.
char error[CURL_ERROR_SIZE]
std::vector< int > clusterIndices
class to create TPC fast space charge correction
static MatLayerCylSet * rectifyPtrFromFile(MatLayerCylSet *ptr)
static int initFieldFromGRP(const o2::parameters::GRPMagField *grp, bool verbose=false)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static BasicCCDBManager & instance()
static size_t fillOccupancyMapGetSize(uint32_t nHbfPerTf, const GPUParam *param=nullptr)
static void fillSharedClustersAndOccupancyMap(const o2::tpc::ClusterNativeAccess *cl, const gsl::span< const o2::tpc::TrackTPC > trks, const o2::tpc::TPCClRefElem *trackRef, uint8_t *shmap, uint32_t *ocmap=nullptr, uint32_t nHbfPerTf=0, const GPUParam *param=nullptr)
static float getNominalGPUBz(T &src)
GEMstack gemStack() const
void loadCalibsFromCCDB(long runNumberOrTimeStamp, const bool isMC=false, const bool loadSCCorrMap=true, const bool useSCCorrMap=true, const bool useVDrift=true, const float corrMapLumiScale=-1.f)
void setFieldNominalGPUBz(const float field)
void setVDriftFromFile(const char *folder, const char *file, const char *object)
load the drift-velocity calibration (VDriftCorrFact) from a local file and rebuild mTPCCorrMap
void calculatedEdx(TrackTPC &track, dEdxInfo &output, AverageOccupancy &averageOcc, float low=2.f/128.f, float high=77.f/128.f, CorrectionFlags correctionMask=CorrectionFlags::TopologyPol|CorrectionFlags::dEdxResidual, ClusterFlags clusterMask=ClusterFlags::None, int subthresholdMethod=0, int stackBoundaryMethod=0, const char *debugRootFile="dEdxDebug.root", float maxSubthresholdChargeTot=100000.f, float maxSubthresholdChargeMax=100000.f, int sameRowClusterMethod=2)
void setTPCCorrMap(const o2::gpu::TPCFastTransform &corrMap, const o2::gpu::TPCFastTransform *corrMapRef=nullptr, float lumiScale=-1.f)
void setTrackTopologyCorrectionFromFile(const char *folder, const char *file, const char *object)
void setZeroSuppressionThresholdFromFile(const char *folder, const char *file, const char *object)
void setPropagatorFromFile(const char *folder, const char *file, const char *object)
unsigned int getOccupancy(float clTime) const
void setRefit(const unsigned int nHbfPerTf=32)
set the refitter
float getTrackTopologyCorrectionPol(const o2::tpc::TrackTPC &track, const o2::tpc::ClusterNative &cl, const unsigned int region, const float charge, ChargeType chargeType, const float threshold) const
void calculatedEdxMultipleSettings(TrackTPC &track, std::vector< dEdxInfo > &outputs, AverageOccupancy &averageOcc, const std::vector< dEdxSettings > &settingsList, const MCCompLabel *mcLabel=nullptr)
float getTPCScalerLumiScale(long timeStamp, float meanIDC) const
void setMembers(std::vector< o2::tpc::TPCClRefElem > *tpcTrackClIdxVecInput, const o2::tpc::ClusterNativeAccess &clIndex, std::vector< o2::tpc::TrackTPC > *vTPCTracksArrayInp)
void setTPCCorrMapFromFile(const char *folder, const char *file, const char *object)
load the space-charge correction map for the cluster transform from a local file; without the file,...
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
void loadCalibsFromLocalCCDBFolder(const char *localCCDBFolder, const bool useSCCorrMap=true, const bool useVDrift=true)
void fillMissingClusters(int missingClusters[4], const float minChargeTot[4], const float minChargeMax[4], int method, std::array< std::vector< float >, 5 > &chargeTotROC, std::array< std::vector< float >, 5 > &chargeMaxROC)
float getTruncMean(std::vector< float > &charge, float low, float high) const
void setResidualCorrectionFromFile(const char *folder, const char *file, const char *object)
float getTrackTopologyCorrection(const o2::tpc::TrackTPC &track, const unsigned int region) const
bool isInStackBoundaries(int stackNumber, unsigned char rowIndex, int stackBoundaryMethod)
void handleSameRowClusters(o2::tpc::TrackTPC &track, std::vector< std::pair< unsigned char, unsigned char > > &rowOrder, std::map< std::pair< unsigned char, unsigned char >, std::vector< int > > &clustersByRow, std::set< std::pair< unsigned char, unsigned char > > &mergeableRows, std::map< int, std::tuple< unsigned char, unsigned char, unsigned int > > &clusterReferencesByIndex)
void setMagneticFieldFromFile(const char *folder, const char *file, const char *object)
void setGainMapResidualFromFile(const char *folder, const char *file, const char *object)
void setStreamer(const char *debugRootFile)
void setGainMapFromFile(const char *folder, const char *file, const char *object)
void setGainMap(const CalDet< float > &gainMap, const float minGain, const float maxGain)
setting the gain map map from a CalDet
void setPolTopologyCorrection(const CalibdEdxTrackTopologyPol &calibTrackTopology)
void setDeadChannelMap(const CalDet< bool > &deadMap)
setting the gain map map from a CalDet
void setZeroSupresssionThreshold(const CalDet< float > &thresholdMap)
void setResidualCorrection(const CalibdEdxCorrection &residualCorr)
void setGainMapResidual(const CalDet< float > &gainMapResidual, const float minResidualGain=0.7f, const float maxResidualGain=1.3f)
setting the gain map map from a CalDet
calibration class for the track topology correction of the dE/dx using multvariate polynomials
void loadFromFile(const char *fileName, const char *name)
void setFromContainer(const CalibdEdxTrackTopologyPolContainer &container)
float getCorrection(const float time, unsigned char sector, unsigned char padrow, int pad) const
void setCorrectionMaps(o2::gpu::TPCFastTransform *avg, o2::gpu::TPCFastTransform *der, const float lumi)
void init(std::string_view url="")
void load(long timeStampOrRun)
const CalDet< bool > & getDeadChannelMap() const
static const std::vector< unsigned int > PADSPERROW[NREGIONS]
number of pads per row in region
static unsigned int getLocalRowFromGlobalRow(const unsigned int row)
static Mapper & instance(const std::string mappingDir="")
const PadRegionInfo & getPadRegionInfo(const unsigned char region) const
static constexpr unsigned int PADROWS
total number of pad rows
static GlobalPosition3D LocalToGlobal(const LocalPosition3D &pos, const double alpha)
GlobalPosition2D getPadCentre(const PadSecPos &padSec) const
static constexpr unsigned REGION[PADROWS]
region for global pad row
float getPadHeight() const
static constexpr int MAXSECTOR
static TPCFastSpaceChargeCorrectionHelper * instance()
Singleton.
void addCorrections(o2::gpu::TPCFastSpaceChargeCorrection &mainCorrection, double scale, const std::vector< std::pair< const o2::gpu::TPCFastSpaceChargeCorrection *, double > > &additionalCorrections)
float getMeanScaler(double timestamp, o2::tpc::Side side) const
void setIonDriftTimeMS(float ionDriftTimeMS)
float getIonDriftTimeMS() const
double getStartTimeStampMS() const
double getEndTimeStampMS(o2::tpc::Side side) const
void useWeights(bool useWeights)
enable usage of weights
void setFromTree(TTree &tpcScalerTree)
set this object from input tree
void setScalerWeights(const TPCScalerWeights &weights)
setting the weights for the scalers
GLsizei const GLuint const GLfloat * weights
GLuint GLsizei const GLchar * label
GLuint GLint GLboolean GLint GLenum access
GLdouble GLdouble GLdouble z
uint8_t int statusCode int
uint8_t itsSharedClusterMap uint8_t
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
o2::track::TrackParCov int int int float int nCl
const bool const int TrackITSInternal< NLayers > & track
Global TPC definitions and constants.
@ ExcludeSingleCl
flag to exclude single clusters in dEdx calculation
@ ExcludeSubthresholdCl
flag to exclude subthreshold clusters in dEdx calculation
@ ExcludeSplitPadCl
flag to exclude split pad clusters in dEdx calculation
@ ExcludeEdgeCl
flag to exclude sector edge clusters in dEdx calculation
@ ExcludeSectorBoundaries
flag to exclude sector boundary clusters in subthreshold cluster treatment
@ ExcludeSplitCl
flag to exclude split pad or time clusters in dEdx calculation
@ ExcludeSplitTimeCl
flag to exclude split time clusters in dEdx calculation
@ ExcludeSamePadRowCl
flag to exclude clusters in the same pad row in dEdx calculation
@ ExcludeSharedCl
flag to exclude clusters shared between tracks in dEdx calculation
math_utils::Point2D< float > LocalPosition2D
std::vector< ClInfo > ClInfoVec
const std::unordered_map< CDBType, const std::string > CDBTypeMap
Storage name in CCDB for each calibration and parameter type.
CorrectionFlags
dEdx calculation class
@ TopologyPol
flag for topology correction from polynomials
@ TopologySimple
flag for simple analytical topology correction
@ dEdxResidual
flag for residual dEdx correction
@ dEdxSC
flag for space-charge dEdx correction
@ GainFull
flag for full gain map from calibration container
@ GainResidual
flag for residuals gain map from calibration container
@ CalScaler
Scaler from IDCs or combined estimator.
@ CalVDriftTgl
ITS-TPC difTgl vdrift calibration.
@ CalScalerWeights
Weights for scalers.
@ CalCorrMapMC
Cluster correction map (high IR rate distortions) for MC.
@ CalPadGainFull
Full pad gain calibration.
@ ConfigFEEPad
FEE pad-by-pad configuration map.
@ CalPadGainResidual
ResidualpPad gain calibration (e.g. from tracks)
@ CalCorrMapRef
Cluster correction reference map (static distortions)
@ CalTimeGain
Gain variation over time.
@ CalTimeGainMC
Gain variation over time for MC.
@ CalCorrMap
Cluster correction map (high IR rate distortions)
average cluster occupancy of a track, per TPC region
simple struct to enable writing the MultivariatePolynomialCT to file
unsigned int nClustersTotal
unsigned int clusterOffset[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
GEM stack identification.
bundles the settings of one calculatedEdx() call (everything except the track/output/averageOcc) used...
float maxSubthresholdChargeMax
upper limit for the per-region minimum qMax used as the virtual charge of a subthreshold cluster (def...
CorrectionFlags correctionMask
corrections to apply
unsigned short subthresholdMethod
subthreshold cluster charge filling method
std::string debugRootFile
debug streamer output file used if mDebug is set
float maxSubthresholdChargeTot
upper limit for the per-region minimum qTot used as the virtual charge of a subthreshold cluster (def...
ClusterFlags clusterMask
clusters to exclude
unsigned short stackBoundaryMethod
stack boundary cluster exclusion method
float high
higher cluster cut
float low
lower cluster cut
unsigned short sameRowClusterMethod
same (sector,row) cluster group combination method: 0 = do not merge (one sample per cluster),...
std::vector< Cluster > clusters