Skip to content

Commit 8d580a4

Browse files
authored
[PWGHF] Cache prongs propagation in trackIndexSkimCreator (#17906)
1 parent d848b80 commit 8d580a4

1 file changed

Lines changed: 67 additions & 39 deletions

File tree

PWGHF/TableProducer/trackIndexSkimCreator.cxx

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,38 @@ struct HfTrackIndexSkimCreator {
17241724
}
17251725
}
17261726

1727+
/// One track of the collision under study, propagated to that collision's primary vertex.
1728+
/// \tparam TTrackIndex is the iterator type of the track-collision associations
1729+
/// \tparam TTrack is the iterator type of the track table
1730+
template <typename TTrackIndex, typename TTrack>
1731+
struct HfPropagatedProng {
1732+
TTrackIndex trackIndex; ///< track-collision association, carries isSelProng and isIdentifiedPid
1733+
TTrack track; ///< track row
1734+
o2::track::TrackParCov trackParVar; ///< track parameters at the PCA to the primary vertex
1735+
std::array<float, 3> pVec{}; ///< momentum at the PCA to the primary vertex
1736+
std::array<float, 2> dcaInfo{}; ///< DCA (xy, z) to the primary vertex
1737+
};
1738+
1739+
/// Fill the per-collision cache of tracks propagated to the collision's primary vertex, so that
1740+
/// each track is propagated once per collision instead of once per pair or triplet.
1741+
/// \param collision is the collision under study
1742+
/// \param trackIndices are the track associations of this collision
1743+
/// \param prongs is the cache to be filled, in the order of trackIndices
1744+
template <typename TTracks, typename TCollision, typename TTrackIndices, typename TProng>
1745+
void fillPropagatedProngCache(TCollision const& collision, TTrackIndices const& trackIndices, std::vector<TProng>& prongs)
1746+
{
1747+
prongs.clear();
1748+
const auto thisCollId = collision.globalIndex();
1749+
for (auto trackIndex = trackIndices.begin(); trackIndex != trackIndices.end(); ++trackIndex) {
1750+
const auto track = trackIndex.template track_as<TTracks>();
1751+
auto& prong = prongs.emplace_back(TProng{trackIndex, track, getTrackParCov(track), track.pVector(), {track.dcaXY(), track.dcaZ()}});
1752+
if (thisCollId != track.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it
1753+
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, prong.trackParVar, 2.f, noMatCorr, &prong.dcaInfo);
1754+
getPxPyPz(prong.trackParVar, prong.pVec);
1755+
}
1756+
}
1757+
}
1758+
17271759
/// Method to perform selections for 2-prong candidates before vertex reconstruction
17281760
/// \param pVecTrack0 is the momentum array of the first daughter track
17291761
/// \param pVecTrack1 is the momentum array of the second daughter track
@@ -2319,6 +2351,12 @@ struct HfTrackIndexSkimCreator {
23192351
}
23202352
*/
23212353

2354+
// per-collision caches of the tracks propagated to the primary vertex, declared here so that their capacity is reused
2355+
using TrackIndexIterator = decltype(positiveFor2And3Prongs->sliceByCached(aod::track::collisionId, 0, cache).begin());
2356+
using PropagatedProng = HfPropagatedProng<TrackIndexIterator, decltype(tracks.rawIteratorAt(0))>;
2357+
std::vector<PropagatedProng> prongsPos{};
2358+
std::vector<PropagatedProng> prongsNeg{};
2359+
23222360
for (const auto& collision : collisions) {
23232361

23242362
/// retrieve PV contributors for the current collision
@@ -2398,39 +2436,36 @@ struct HfTrackIndexSkimCreator {
23982436
std::optional<decltype(positiveSoftPions->sliceByCached(aod::track::collisionId, 0, cache))> groupedTrackIndicesSoftPionsPos;
23992437
std::optional<decltype(negativeSoftPions->sliceByCached(aod::track::collisionId, 0, cache))> groupedTrackIndicesSoftPionsNeg;
24002438
int lastFilledD0 = -1; // index to be filled in table for D* mesons
2401-
for (auto trackIndexPos1 = groupedTrackIndicesPos1.begin(); trackIndexPos1 != groupedTrackIndicesPos1.end(); ++trackIndexPos1) {
2402-
const auto trackPos1 = trackIndexPos1.template track_as<TTracks>();
2439+
2440+
// propagate each track to this collision's PV once, instead of once per pair or triplet
2441+
fillPropagatedProngCache<TTracks>(collision, groupedTrackIndicesPos1, prongsPos);
2442+
fillPropagatedProngCache<TTracks>(collision, groupedTrackIndicesNeg1, prongsNeg);
2443+
2444+
for (std::size_t iPos1 = 0; iPos1 < prongsPos.size(); ++iPos1) {
2445+
const auto& trackIndexPos1 = prongsPos[iPos1].trackIndex;
2446+
const auto& trackPos1 = prongsPos[iPos1].track;
2447+
const auto& trackParVarPos1 = prongsPos[iPos1].trackParVar;
2448+
const auto& pVecTrackPos1 = prongsPos[iPos1].pVec;
2449+
const auto& dcaInfoPos1 = prongsPos[iPos1].dcaInfo;
24032450

24042451
// retrieve the selection flag that corresponds to this collision
24052452
const auto isSelProngPos1 = trackIndexPos1.isSelProng();
24062453
const bool sel2ProngStatusPos = TESTBIT(isSelProngPos1, CandidateType::Cand2Prong);
24072454
const bool sel3ProngStatusPos1 = TESTBIT(isSelProngPos1, CandidateType::Cand3Prong);
24082455

2409-
auto trackParVarPos1 = getTrackParCov(trackPos1);
2410-
std::array pVecTrackPos1{trackPos1.pVector()};
2411-
std::array dcaInfoPos1{trackPos1.dcaXY(), trackPos1.dcaZ()};
2412-
if (thisCollId != trackPos1.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it
2413-
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos1, 2.f, noMatCorr, &dcaInfoPos1);
2414-
getPxPyPz(trackParVarPos1, pVecTrackPos1);
2415-
}
2416-
24172456
// first loop over negative tracks
2418-
for (auto trackIndexNeg1 = groupedTrackIndicesNeg1.begin(); trackIndexNeg1 != groupedTrackIndicesNeg1.end(); ++trackIndexNeg1) {
2419-
const auto trackNeg1 = trackIndexNeg1.template track_as<TTracks>();
2457+
for (std::size_t iNeg1 = 0; iNeg1 < prongsNeg.size(); ++iNeg1) {
2458+
const auto& trackIndexNeg1 = prongsNeg[iNeg1].trackIndex;
2459+
const auto& trackNeg1 = prongsNeg[iNeg1].track;
2460+
const auto& trackParVarNeg1 = prongsNeg[iNeg1].trackParVar;
2461+
const auto& pVecTrackNeg1 = prongsNeg[iNeg1].pVec;
2462+
const auto& dcaInfoNeg1 = prongsNeg[iNeg1].dcaInfo;
24202463

24212464
// retrieve the selection flag that corresponds to this collision
24222465
const auto isSelProngNeg1 = trackIndexNeg1.isSelProng();
24232466
const bool sel2ProngStatusNeg = TESTBIT(isSelProngNeg1, CandidateType::Cand2Prong);
24242467
const bool sel3ProngStatusNeg1 = TESTBIT(isSelProngNeg1, CandidateType::Cand3Prong);
24252468

2426-
auto trackParVarNeg1 = getTrackParCov(trackNeg1);
2427-
std::array pVecTrackNeg1{trackNeg1.pVector()};
2428-
std::array dcaInfoNeg1{trackNeg1.dcaXY(), trackNeg1.dcaZ()};
2429-
if (thisCollId != trackNeg1.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it
2430-
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg1, 2.f, noMatCorr, &dcaInfoNeg1);
2431-
getPxPyPz(trackParVarNeg1, pVecTrackNeg1);
2432-
}
2433-
24342469
uint isSelected2ProngCand = n2ProngBit; // bitmap for checking status of two-prong candidates (1 is true, 0 is rejected)
24352470

24362471
if (config.debug) {
@@ -2638,7 +2673,8 @@ struct HfTrackIndexSkimCreator {
26382673

26392674
if (config.do3Prong && is2ProngCandidateGoodFor3Prong) { // if 3 prongs are enabled and the first 2 tracks are selected for the 3-prong channels
26402675
// second loop over positive tracks
2641-
for (auto trackIndexPos2 = trackIndexPos1 + 1; trackIndexPos2 != groupedTrackIndicesPos1.end(); ++trackIndexPos2) {
2676+
for (std::size_t iPos2 = iPos1 + 1; iPos2 < prongsPos.size(); ++iPos2) {
2677+
const auto& trackIndexPos2 = prongsPos[iPos2].trackIndex;
26422678

26432679
uint isSelected3ProngCand = n3ProngBit;
26442680
if (!TESTBIT(trackIndexPos2.isSelProng(), CandidateType::Cand3Prong)) { // continue immediately
@@ -2655,18 +2691,13 @@ struct HfTrackIndexSkimCreator {
26552691
isSelected3ProngCand = 0;
26562692
}
26572693

2658-
const auto trackPos2 = trackIndexPos2.template track_as<TTracks>();
2659-
2660-
auto trackParVarPos2 = getTrackParCov(trackPos2);
2661-
std::array dcaInfoPos2{trackPos2.dcaXY(), trackPos2.dcaZ()};
2694+
const auto& trackPos2 = prongsPos[iPos2].track;
2695+
const auto& trackParVarPos2 = prongsPos[iPos2].trackParVar;
2696+
const auto& dcaInfoPos2 = prongsPos[iPos2].dcaInfo;
26622697

26632698
// preselection of 3-prong candidates
26642699
if (isSelected3ProngCand) {
2665-
std::array pVecTrackPos2{trackPos2.pVector()};
2666-
if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it
2667-
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos2, 2.f, noMatCorr, &dcaInfoPos2);
2668-
getPxPyPz(trackParVarPos2, pVecTrackPos2);
2669-
}
2700+
const auto& pVecTrackPos2 = prongsPos[iPos2].pVec;
26702701

26712702
if (config.debug) {
26722703
for (int iDecay3P = 0; iDecay3P < kN3ProngDecays; iDecay3P++) {
@@ -2913,7 +2944,8 @@ struct HfTrackIndexSkimCreator {
29132944
}
29142945

29152946
// second loop over negative tracks
2916-
for (auto trackIndexNeg2 = trackIndexNeg1 + 1; trackIndexNeg2 != groupedTrackIndicesNeg1.end(); ++trackIndexNeg2) {
2947+
for (std::size_t iNeg2 = iNeg1 + 1; iNeg2 < prongsNeg.size(); ++iNeg2) {
2948+
const auto& trackIndexNeg2 = prongsNeg[iNeg2].trackIndex;
29172949

29182950
int isSelected3ProngCand = n3ProngBit;
29192951
if (!TESTBIT(trackIndexNeg2.isSelProng(), CandidateType::Cand3Prong)) { // continue immediately
@@ -2930,17 +2962,13 @@ struct HfTrackIndexSkimCreator {
29302962
isSelected3ProngCand = 0;
29312963
}
29322964

2933-
auto trackNeg2 = trackIndexNeg2.template track_as<TTracks>();
2934-
auto trackParVarNeg2 = getTrackParCov(trackNeg2);
2935-
std::array dcaInfoNeg2{trackNeg2.dcaXY(), trackNeg2.dcaZ()};
2965+
const auto& trackNeg2 = prongsNeg[iNeg2].track;
2966+
const auto& trackParVarNeg2 = prongsNeg[iNeg2].trackParVar;
2967+
const auto& dcaInfoNeg2 = prongsNeg[iNeg2].dcaInfo;
29362968

29372969
// preselection of 3-prong candidates
29382970
if (isSelected3ProngCand) {
2939-
std::array pVecTrackNeg2{trackNeg2.pVector()};
2940-
if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it
2941-
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg2, 2.f, noMatCorr, &dcaInfoNeg2);
2942-
getPxPyPz(trackParVarNeg2, pVecTrackNeg2);
2943-
}
2971+
const auto& pVecTrackNeg2 = prongsNeg[iNeg2].pVec;
29442972

29452973
if (config.debug) {
29462974
for (int iDecay3P = 0; iDecay3P < kN3ProngDecays; iDecay3P++) {

0 commit comments

Comments
 (0)