Skip to content

Commit fa6a42e

Browse files
authored
[PWGCF] Add Track-TwoPhotonResonance pair task to femto framework (#18353)
1 parent e60e903 commit fa6a42e

10 files changed

Lines changed: 416 additions & 25 deletions

‎PWGCF/Femto/Core/closePairRejection.h‎

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ constexpr const char PrefixCprTrackLcPion[] = "CprTrackLcPion";
9595
constexpr const char PrefixCprD0DaughterD0DaughterPos[] = "CprD0DaughterD0DaughterPos";
9696
constexpr const char PrefixCprD0DaughterD0DaughterNeg[] = "CprD0DaughterD0DaughterNeg";
9797
constexpr const char PrefixCprTrackResonanceDaughter[] = "CprTrackResonanceDaughter";
98+
constexpr const char PrefixCprTrackTwoPhotonResonanceDaughter[] = "CprTrackTwoPhotonResonanceDaughter";
9899
constexpr const char PrefixCprTrackKinkDaughter[] = "CprTrackKinkDaughter";
99100
constexpr const char PrefixCprV0DaughterV0DaughterPos[] = "CprV0DaughterV0DaughterPos";
100101
constexpr const char PrefixCprV0DaughterV0DaughterNeg[] = "CprV0DaughterV0DaughterNeg";
@@ -113,6 +114,8 @@ using ConfCprTrackLcPion = ConfCpr<PrefixCprTrackLcPion>;
113114
using ConfCprD0DaugherD0DaughterPos = ConfCpr<PrefixCprD0DaughterD0DaughterPos>;
114115
using ConfCprD0DaugherD0DaughterNeg = ConfCpr<PrefixCprD0DaughterD0DaughterNeg>;
115116
using ConfCprTrackResonanceDaughter = ConfCpr<PrefixCprTrackResonanceDaughter>;
117+
// no cut by default: CPR is a no-op for two-photon resonances (see ClosePairRejectionTrackTwoPhotonResonance)
118+
using ConfCprTrackTwoPhotonResonanceDaughter = ConfCpr<PrefixCprTrackTwoPhotonResonanceDaughter, false>;
116119
using ConfCprTrackKinkDaughter = ConfCpr<PrefixCprTrackKinkDaughter>;
117120
using ConfCprV0DaugherV0DaughterPos = ConfCpr<PrefixCprV0DaughterV0DaughterPos>;
118121
using ConfCprV0DaugherV0DaughterNeg = ConfCpr<PrefixCprV0DaughterV0DaughterNeg>;
@@ -152,6 +155,8 @@ constexpr char PrefixV0TwoTrackResonancePosMe[] = "CPR_V0Resonance_PosDau/ME/";
152155
constexpr char PrefixV0TwoTrackResonanceNegMe[] = "CPR_V0Resonance_NegDau/ME/";
153156
constexpr char PrefixTrackTwoTrackResonanceSe[] = "CPR_TrackResonanceDau/SE/";
154157
constexpr char PrefixTrackTwoTrackResonanceMe[] = "CPR_TrackResonanceDau/ME/";
158+
constexpr char PrefixTrackTwoPhotonResonanceSe[] = "CPR_TrackTwoPhotonResonanceDau/SE/";
159+
constexpr char PrefixTrackTwoPhotonResonanceMe[] = "CPR_TrackTwoPhotonResonanceDau/ME/";
155160
constexpr char PrefixTrackCascadeBachelorSe[] = "CPR_TrackCascadeBachelor/SE/";
156161
constexpr char PrefixTrackCascadeBachelorMe[] = "CPR_TrackCascadeBachelor/ME/";
157162
constexpr char PrefixTrackKinkSe[] = "CPR_TrackKink/SE/";
@@ -320,14 +325,22 @@ class CloseTrackRejection
320325
swapTracks = (mSwapDist(mRng) == 1);
321326
}
322327

323-
auto t1 = swapTracks ? track2 : track1;
324-
auto t2 = swapTracks ? track1 : track2;
328+
// get kinematics of the particles
329+
// if configured, randomly swap particle 1 and particle 2
330+
float eta1 = swapTracks ? track2.eta() : track1.eta();
331+
float eta2 = swapTracks ? track1.eta() : track2.eta();
332+
float phi1 = swapTracks ? track2.phi() : track1.phi();
333+
float phi2 = swapTracks ? track1.phi() : track2.phi();
334+
float signedPt1 = swapTracks ? track2.signedPt() : track1.signedPt();
335+
float signedPt2 = swapTracks ? track1.signedPt() : track2.signedPt();
336+
int chargeAbs1 = swapTracks ? mChargeAbsTrack2 : mChargeAbsTrack1;
337+
int chargeAbs2 = swapTracks ? mChargeAbsTrack1 : mChargeAbsTrack2;
325338

326-
mDeta = t1.eta() - t2.eta();
339+
mDeta = eta1 - eta2;
327340

328341
for (size_t i = 0; i < TpcRadii.size(); i++) {
329-
auto phistar1 = phistar(mMagField, TpcRadii.at(i), mChargeAbsTrack1 * t1.signedPt(), t1.phi());
330-
auto phistar2 = phistar(mMagField, TpcRadii.at(i), mChargeAbsTrack2 * t2.signedPt(), t2.phi());
342+
auto phistar1 = phistar(mMagField, TpcRadii.at(i), chargeAbs1 * signedPt1, phi1);
343+
auto phistar2 = phistar(mMagField, TpcRadii.at(i), chargeAbs2 * signedPt2, phi2);
331344
if (phistar1 && phistar2) {
332345
mDphistar.at(i) = RecoDecay::constrainAngle(phistar1.value() - phistar2.value(), -o2::constants::math::PI); // constrain angular difference between -pi and pi
333346
mDphistarMask.at(i) = true;
@@ -338,14 +351,14 @@ class CloseTrackRejection
338351
if (count > 0) {
339352
mAverageDphistar = std::accumulate(mDphistar.begin(), mDphistar.end(), 0.f) / count; // only average values if phistar could be computed
340353
} else {
341-
mAverageDphistar = 0.f; // if computation at all radii fail, set it 0
354+
mAverageDphistar = 0.f; // if computation at all radii failed, set it 0
342355
}
343356

344357
if (mPlotAngularCorrelation) {
345-
mPhi1 = t1.phi();
346-
mPhi2 = t2.phi();
347-
mEta1 = t1.eta();
348-
mEta2 = t2.eta();
358+
mPhi1 = phi1;
359+
mPhi2 = phi2;
360+
mEta1 = eta1;
361+
mEta2 = eta2;
349362
}
350363
}
351364

@@ -731,6 +744,32 @@ class ClosePairRejectionTrackKink
731744
CloseTrackRejection<prefix> mCtr;
732745
};
733746

747+
// PCM photon daughters are, for now, not indexed into the track table (see photonBuilder.h):
748+
// they are TPC-only tracks, so they cannot be confused for a global track the way two V0
749+
// daughters or a track and a V0 daughter can -- there is no detector-overlap effect to correct
750+
// for. This is a no-op placeholder so Track-TwoPhotonResonance pairs can use the same generic
751+
// pair-building code path.
752+
template <auto& prefix>
753+
class ClosePairRejectionTrackTwoPhotonResonance
754+
{
755+
public:
756+
template <typename T>
757+
void init(o2::framework::HistogramRegistry* /*registry*/,
758+
std::map<CprHist, std::vector<o2::framework::AxisSpec>> const& /*specs*/,
759+
T const& /*confCpr*/,
760+
int /*absChargeTrack*/)
761+
{
762+
}
763+
764+
void setMagField(float /*magField*/) {}
765+
766+
template <typename T1, typename T2, typename T3, typename T4>
767+
[[nodiscard]] bool isClosePair(T1 const& /*track*/, T2 const& /*resonance*/, T3 const& /*photonTable*/, T4 const& /*pairHistManager*/)
768+
{
769+
return false;
770+
}
771+
};
772+
734773
template <auto& prefix>
735774
class ClosePairRejectionMcParticleMcParticle
736775
{

‎PWGCF/Femto/Core/femtoUtils.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ inline double getPdgMass(int pdgCode)
141141
case kOmegaMinus:
142142
mass = o2::constants::physics::MassOmegaMinus;
143143
break;
144+
case kPi0:
145+
mass = o2::constants::physics::MassPi0;
146+
break;
147+
case o2::constants::physics::kEta:
148+
mass = o2::constants::physics::MassEta;
149+
break;
144150
default:
145151
LOG(warn) << "PDG code " << pdgCode << " is not suppored. Return 0... ";
146152
}

‎PWGCF/Femto/Core/modes.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ enum class Particle : o2::analysis::femto::datatypes::ParticleType {
113113
kKink = 4,
114114
kCascade = 5,
115115
kCharmHadron = 6,
116+
kTwoPhotonResonance = 7,
116117
};
117118

118119
enum class McOrigin : o2::analysis::femto::datatypes::McOriginType {

‎PWGCF/Femto/Core/pairBuilder.h‎

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "PWGCF/Femto/Core/pairProcessHelpers.h"
3030
#include "PWGCF/Femto/Core/particleCleaner.h"
3131
#include "PWGCF/Femto/Core/trackHistManager.h"
32+
#include "PWGCF/Femto/Core/twoPhotonResonanceHistManager.h"
3233
#include "PWGCF/Femto/Core/twoTrackResonanceHistManager.h"
3334
#include "PWGCF/Femto/Core/v0HistManager.h"
3435
#include "PWGCF/Femto/DataModel/FemtoTables.h"
@@ -1384,6 +1385,129 @@ class PairTrackV0Builder
13841385
int mMixingDepth = 5;
13851386
};
13861387

1388+
// Track-TwoPhotonResonance pair builder.
1389+
// Note: close pair rejection is a no-op (ClosePairRejectionTrackTwoPhotonResonance) and pair cleaning
1390+
// reuses the plain TrackTrackPairCleaner (globalIndex-only), since photon daughters are, for
1391+
// now, not indexed into FTracks: they are TPC-only tracks, so they cannot be confused for a
1392+
// global track the way two V0 daughters or a track and a V0 daughter can.
1393+
template <auto& prefixTrack,
1394+
auto& prefixResonance,
1395+
auto& prefixDau1,
1396+
auto& prefixDau2,
1397+
auto& prefixSe,
1398+
auto& prefixMe,
1399+
auto& prefixCprSe,
1400+
auto& prefixCprMe,
1401+
modes::TwoPhotonResonance resonanceType>
1402+
class PairTrackTwoPhotonResonanceBuilder
1403+
{
1404+
public:
1405+
PairTrackTwoPhotonResonanceBuilder() = default;
1406+
~PairTrackTwoPhotonResonanceBuilder() = default;
1407+
1408+
template <modes::Mode modeSe,
1409+
modes::Mode modeMe,
1410+
typename T1,
1411+
typename T2,
1412+
typename T3,
1413+
typename T4,
1414+
typename T5,
1415+
typename T6,
1416+
typename T7,
1417+
typename T8,
1418+
typename T9,
1419+
typename T10,
1420+
typename T11,
1421+
typename T12,
1422+
typename T13,
1423+
typename T14,
1424+
typename T15>
1425+
void init(o2::framework::HistogramRegistry* registry,
1426+
T1 const& confCollisionBinning,
1427+
T2 const& confTrackSelection,
1428+
T3 const& confResonanceSelection,
1429+
T4 const& confCpr,
1430+
T5 const& confMixing,
1431+
T6 const& confPairBinning,
1432+
T7 const& confPairCuts,
1433+
T8 const& confDauQaBinning,
1434+
std::map<T9, std::vector<o2::framework::AxisSpec>> const& colHistSpec,
1435+
std::map<T10, std::vector<o2::framework::AxisSpec>> const& trackHistSpec,
1436+
std::map<T11, std::vector<o2::framework::AxisSpec>> const& resonanceHistSpec,
1437+
std::map<T12, std::vector<o2::framework::AxisSpec>> const& dauHistSpec,
1438+
std::map<T13, std::vector<o2::framework::AxisSpec>> const& pairHistSpec,
1439+
std::map<T14, std::vector<o2::framework::AxisSpec>> const& cprHistSpec,
1440+
std::map<T15, std::vector<o2::framework::AxisSpec>> const& pairCleanerHistSpec)
1441+
{
1442+
mColHistManager.template init<modeSe>(registry, colHistSpec, confCollisionBinning);
1443+
1444+
mTrackHistManager.template init<modeSe>(registry, trackHistSpec, confTrackSelection);
1445+
mResonanceHistManager.template init<modeSe>(registry, resonanceHistSpec, dauHistSpec, confDauQaBinning);
1446+
1447+
mPairHistManagerSe.template init<modeSe>(registry, pairHistSpec, confPairBinning, confPairCuts, confMixing);
1448+
mPairHistManagerSe.setMass(confTrackSelection.pdgCodeAbs.value, confResonanceSelection.pdgCodeAbs.value);
1449+
mPairHistManagerSe.setCharge(confTrackSelection.chargeAbs.value, 1);
1450+
mCprSe.init(registry, cprHistSpec, confCpr, confTrackSelection.chargeAbs.value);
1451+
1452+
mPairHistManagerMe.template init<modeMe>(registry, pairHistSpec, confPairBinning, confPairCuts, confMixing);
1453+
mPairHistManagerMe.setMass(confTrackSelection.pdgCodeAbs.value, confResonanceSelection.pdgCodeAbs.value);
1454+
mPairHistManagerMe.setCharge(confTrackSelection.chargeAbs.value, 1);
1455+
mCprMe.init(registry, cprHistSpec, confCpr, confTrackSelection.chargeAbs.value);
1456+
1457+
mPcSe.template init<modeSe>(registry, pairCleanerHistSpec, confPairCuts);
1458+
mPcMe.template init<modeMe>(registry, pairCleanerHistSpec, confPairCuts);
1459+
1460+
// setup mixing
1461+
mMixingPolicy = static_cast<pairhistmanager::MixingPolicy>(confMixing.policy.value);
1462+
mMixingDepth = confMixing.depth.value;
1463+
}
1464+
1465+
/// \return true if at least one pair passed all pair selections (usable as pair trigger)
1466+
template <modes::Mode mode, typename T1, typename T2, typename T3, typename T4, typename T5>
1467+
bool processSameEvent(T1 const& col, T2& trackPartition, T3& resonancePartition, T4& photonTable, T5& cache)
1468+
{
1469+
auto trackSlice = trackPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
1470+
auto resonanceSlice = resonancePartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
1471+
if (trackSlice.size() < nLimitPartitionParticles || resonanceSlice.size() < nLimitPartitionParticles) {
1472+
return false;
1473+
}
1474+
mColHistManager.template fill<mode>(col);
1475+
mCprSe.setMagField(col.magField());
1476+
return pairprocesshelpers::processSameEvent<mode>(trackSlice, resonanceSlice, photonTable, col, mTrackHistManager, mResonanceHistManager, mPairHistManagerSe, mCprSe, mPcSe);
1477+
}
1478+
1479+
template <modes::Mode mode, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
1480+
void processMixedEvent(T1 const& cols, T2& trackPartition, T3& resonancePartition, T4& photonTable, T5& cache, T6& binsVtxMult, T7& binsVtxCent, T8& binsVtxMultCent)
1481+
{
1482+
switch (mMixingPolicy) {
1483+
case static_cast<int>(pairhistmanager::kVtxMult):
1484+
pairprocesshelpers::processMixedEvent<mode>(cols, trackPartition, resonancePartition, photonTable, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mCprMe, mPcMe);
1485+
break;
1486+
case static_cast<int>(pairhistmanager::kVtxCent):
1487+
pairprocesshelpers::processMixedEvent<mode>(cols, trackPartition, resonancePartition, photonTable, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPcMe);
1488+
break;
1489+
case static_cast<int>(pairhistmanager::kVtxMultCent):
1490+
pairprocesshelpers::processMixedEvent<mode>(cols, trackPartition, resonancePartition, photonTable, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mCprMe, mPcMe);
1491+
break;
1492+
default:
1493+
LOG(fatal) << "Invalid binning policiy specifed. Breaking...";
1494+
}
1495+
}
1496+
1497+
private:
1498+
colhistmanager::CollisionHistManager mColHistManager;
1499+
trackhistmanager::TrackHistManager<prefixTrack> mTrackHistManager;
1500+
twophotonresonancehistmanager::TwoPhotonResonanceHistManager<prefixResonance, prefixDau1, prefixDau2, resonanceType> mResonanceHistManager;
1501+
pairhistmanager::PairHistManager<prefixSe, modes::Particle::kTrack, modes::Particle::kTwoPhotonResonance> mPairHistManagerSe;
1502+
pairhistmanager::PairHistManager<prefixMe, modes::Particle::kTrack, modes::Particle::kTwoPhotonResonance> mPairHistManagerMe;
1503+
closepairrejection::ClosePairRejectionTrackTwoPhotonResonance<prefixCprSe> mCprSe;
1504+
closepairrejection::ClosePairRejectionTrackTwoPhotonResonance<prefixCprMe> mCprMe;
1505+
paircleaner::TrackTrackPairCleaner<paircleaner::PrefixPairCleanerTrackTwoPhotonResonanceSe> mPcSe;
1506+
paircleaner::TrackTrackPairCleaner<paircleaner::PrefixPairCleanerTrackTwoPhotonResonanceMe> mPcMe;
1507+
pairhistmanager::MixingPolicy mMixingPolicy = pairhistmanager::MixingPolicy::kVtxMult;
1508+
int mMixingDepth = 5;
1509+
};
1510+
13871511
template <auto& prefixTrack,
13881512
auto& prefixResonance,
13891513
auto& prefixPosDau,

‎PWGCF/Femto/Core/pairCleaner.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ constexpr char PrefixPairCleanerTrackLcSe[] = "TrackLcCleaner/SE/";
8484
constexpr char PrefixPairCleanerTrackLcMe[] = "TrackLcCleaner/ME/";
8585
constexpr char PrefixPairCleanerTrackResonanceSe[] = "TrackResonanceCleaner/SE/";
8686
constexpr char PrefixPairCleanerTrackResonanceMe[] = "TrackResonanceCleaner/ME/";
87+
constexpr char PrefixPairCleanerTrackTwoPhotonResonanceSe[] = "TrackTwoPhotonResonanceCleaner/SE/";
88+
constexpr char PrefixPairCleanerTrackTwoPhotonResonanceMe[] = "TrackTwoPhotonResonanceCleaner/ME/";
8789
constexpr char PrefixPairCleanerV0ResonanceSe[] = "V0ResonanceCleaner/SE/";
8890
constexpr char PrefixPairCleanerV0ResonanceMe[] = "V0ResonanceCleaner/ME/";
8991
constexpr char PrefixPairCleanerTrackKinkSe[] = "TrackKinkCleaner/SE/";

‎PWGCF/Femto/Core/pairHistManager.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,11 @@ constexpr char PrefixV0V0Me[] = "V0V0/ME/";
570570
constexpr char PrefixTrackResonanceSe[] = "TrackResonance/SE/";
571571
constexpr char PrefixTrackResonanceMe[] = "TrackResonance/ME/";
572572

573+
constexpr char PrefixTrackPi0Se[] = "TrackPi0/SE/";
574+
constexpr char PrefixTrackPi0Me[] = "TrackPi0/ME/";
575+
constexpr char PrefixTrackEtaSe[] = "TrackEta/SE/";
576+
constexpr char PrefixTrackEtaMe[] = "TrackEta/ME/";
577+
573578
constexpr char PrefixV0ResonanceSe[] = "V0Resonance/SE/";
574579
constexpr char PrefixV0ResonanceMe[] = "V0Resonance/ME/";
575580

‎PWGCF/Femto/Core/photonBuilder.h‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,11 @@ struct ConfPhotonTables : o2::framework::ConfigurableGroup {
304304

305305
/// \brief Builder for PCM photons (V0PhotonsKF + V0Legs, from PWGEM/PhotonMeson)
306306
///
307-
/// Unlike the strangeness V0 builder, daughter tracks are not indexed into FTracks: the
308-
/// conversion legs (V0Legs) carry a reduced set of columns and are not meant to be paired
309-
/// individually in femtoscopy, so only photon-level kinematics plus daughter PID/quality
307+
/// Unlike the strangeness V0 builder, daughter (conversion electron) tracks are, for now, not
308+
/// indexed into FTracks: the legs (V0Legs) are TPC-only tracks, so they cannot be confused for
309+
/// (i.e. share hits with/be the same reconstructed object as) a global track the way two V0
310+
/// daughters or a track and a V0 daughter can -- there is no detector-overlap effect for close
311+
/// pair rejection to correct for. Only photon-level kinematics plus daughter PID/quality
310312
/// diagnostics (FPhotonExtras) are stored.
311313
class PhotonBuilder
312314
{

0 commit comments

Comments
 (0)