Skip to content

Commit b2f0d29

Browse files
authored
[PWGCF] Add lite colshape table (#17410)
1 parent 265bbd7 commit b2f0d29

9 files changed

Lines changed: 240 additions & 130 deletions

File tree

PWGCF/Femto/Core/cascadeBuilder.h

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -793,15 +793,15 @@ struct CascadeBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup {
793793
class CascadeBuilderDerivedToDerived
794794
{
795795
public:
796-
CascadeBuilderDerivedToDerived() = default;
797-
~CascadeBuilderDerivedToDerived() = default;
798-
799796
template <typename T>
800797
void init(T& config)
801798
{
802799
mLimitXi = config.limitXi.value;
803800
mLimitOmega = config.limitOmega.value;
804801

802+
if (mLimitXi < 0 || mLimitOmega < 0) {
803+
LOG(fatal) << "Cascade limits must be non-negative (got " << mLimitXi << " and " << mLimitOmega << "). Breaking...";
804+
}
805805
if (mLimitXi == 0 && mLimitOmega == 0) {
806806
LOG(fatal) << "Both xi limit and omega limit are 0. Breaking...";
807807
}
@@ -810,34 +810,40 @@ class CascadeBuilderDerivedToDerived
810810
template <typename T1, typename T2, typename T3, typename T4>
811811
bool collisionHasTooFewXis(T1 const& col, T2 const& /*xiTable*/, T3& partitionXi, T4& cache)
812812
{
813+
if (mLimitXi == 0) { // xis disabled, cannot reject on them
814+
return false;
815+
}
813816
auto xiSlice = partitionXi->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
814-
return xiSlice.size() < mLimitXi;
817+
return xiSlice.size() < static_cast<int64_t>(mLimitXi);
815818
}
816819

817820
template <typename T1, typename T2, typename T3, typename T4>
818821
bool collisionHasTooFewOmegas(T1 const& col, T2 const& /*omegaTable*/, T3& partitionOmega, T4& cache)
819822
{
823+
if (mLimitOmega == 0) { // omegas disabled, cannot reject on them
824+
return false;
825+
}
820826
auto omegaSlice = partitionOmega->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
821-
return omegaSlice.size() < mLimitOmega;
827+
return omegaSlice.size() < static_cast<int64_t>(mLimitOmega);
822828
}
823829

824830
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
825831
void processXis(T1 const& col, T2 const& /*xiTable*/, T3 const& oldTrackTable, T4& partitionXi, T5& trackBuilder, T6& cache, T7& newXiTable, T8& newTrackTable, T9& newCollisionTable)
826832
{
833+
if (mLimitXi == 0) { // xis disabled
834+
return;
835+
}
836+
827837
auto xiSlice = partitionXi->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
828838

829839
for (auto const& xi : xiSlice) {
840+
auto bachelor = oldTrackTable.rawIteratorAt(utils::daughterRow(xi.bachelorId(), oldTrackTable));
841+
auto posDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(xi.posDauId(), oldTrackTable));
842+
auto negDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(xi.negDauId(), oldTrackTable));
830843

831-
// auto bachelor = xi.template bachelor_as<T3>();
832-
// auto posDaughter = xi.template posDau_as<T3>();
833-
// auto negDaughter = xi.template negDau_as<T3>();
834-
auto bachelor = oldTrackTable.rawIteratorAt(xi.bachelorId() - oldTrackTable.offset());
835-
auto posDaughter = oldTrackTable.rawIteratorAt(xi.posDauId() - oldTrackTable.offset());
836-
auto negDaughter = oldTrackTable.rawIteratorAt(xi.negDauId() - oldTrackTable.offset());
837-
838-
int bachelorIndex = trackBuilder.getDaughterIndex(bachelor, newTrackTable, newCollisionTable);
839-
int posDaughterIndex = trackBuilder.getDaughterIndex(posDaughter, newTrackTable, newCollisionTable);
840-
int negDaughterIndex = trackBuilder.getDaughterIndex(negDaughter, newTrackTable, newCollisionTable);
844+
int64_t bachelorIndex = trackBuilder.getDaughterIndex(bachelor, newTrackTable, newCollisionTable);
845+
int64_t posDaughterIndex = trackBuilder.getDaughterIndex(posDaughter, newTrackTable, newCollisionTable);
846+
int64_t negDaughterIndex = trackBuilder.getDaughterIndex(negDaughter, newTrackTable, newCollisionTable);
841847

842848
newXiTable.producedXis(newCollisionTable.producedCollision.lastIndex(),
843849
xi.signedPt(),
@@ -854,20 +860,20 @@ class CascadeBuilderDerivedToDerived
854860
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
855861
void processOmegas(T1 const& col, T2 const& /*omegaTable*/, T3 const& oldTrackTable, T4& partitionOmega, T5& trackBuilder, T6& cache, T7& newOmegaTable, T8& newTrackTable, T9& newCollisionTable)
856862
{
863+
if (mLimitOmega == 0) { // omegas disabled
864+
return;
865+
}
866+
857867
auto omegaSlice = partitionOmega->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache);
858868

859869
for (auto const& omega : omegaSlice) {
870+
auto bachelor = oldTrackTable.rawIteratorAt(utils::daughterRow(omega.bachelorId(), oldTrackTable));
871+
auto posDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(omega.posDauId(), oldTrackTable));
872+
auto negDaughter = oldTrackTable.rawIteratorAt(utils::daughterRow(omega.negDauId(), oldTrackTable));
860873

861-
// auto bachelor = omega.template bachelor_as<T3>();
862-
// auto posDaughter = omega.template posDau_as<T3>();
863-
// auto negDaughter = omega.template negDau_as<T3>();
864-
auto bachelor = oldTrackTable.rawIteratorAt(omega.bachelorId() - oldTrackTable.offset());
865-
auto posDaughter = oldTrackTable.rawIteratorAt(omega.posDauId() - oldTrackTable.offset());
866-
auto negDaughter = oldTrackTable.rawIteratorAt(omega.negDauId() - oldTrackTable.offset());
867-
868-
int bachelorIndex = trackBuilder.getDaughterIndex(bachelor, newTrackTable, newCollisionTable);
869-
int posDaughterIndex = trackBuilder.getDaughterIndex(posDaughter, newTrackTable, newCollisionTable);
870-
int negDaughterIndex = trackBuilder.getDaughterIndex(negDaughter, newTrackTable, newCollisionTable);
874+
int64_t bachelorIndex = trackBuilder.getDaughterIndex(bachelor, newTrackTable, newCollisionTable);
875+
int64_t posDaughterIndex = trackBuilder.getDaughterIndex(posDaughter, newTrackTable, newCollisionTable);
876+
int64_t negDaughterIndex = trackBuilder.getDaughterIndex(negDaughter, newTrackTable, newCollisionTable);
871877

872878
newOmegaTable.producedOmegas(newCollisionTable.producedCollision.lastIndex(),
873879
omega.signedPt(),

PWGCF/Femto/Core/collisionBuilder.h

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
291291
{collisionFilterNames.at(kFilterSphericityMax), mSphericityMax},
292292
{collisionFilterNames.at(kFilterRctFlags), mUseRctFlags ? 1.f : 0.f},
293293
});
294-
};
294+
}
295295

296296
/// \brief Initialize the Zorro trigger machinery for a new run. No-op if no triggers configured.
297297
template <typename T1, typename T2>
@@ -320,7 +320,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
320320
mMagField = MagField;
321321
}
322322

323-
float getMagneticField()
323+
[[nodiscard]] int getMagneticField()
324324
{
325325
return mMagField;
326326
}
@@ -491,14 +491,14 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
491491
}
492492

493493
this->assembleBitmask<SelectionHistName>();
494-
};
494+
}
495495

496496
protected:
497497
template <typename T>
498498
float computeSphericity(T const& tracks)
499499
{
500-
int minNumberTracks = 2;
501-
double maxSphericity = 2.f;
500+
const int64_t minNumberTracks = 2;
501+
const double maxSphericity = 2.f;
502502
if (tracks.size() <= minNumberTracks) {
503503
return maxSphericity;
504504
}
@@ -529,7 +529,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
529529

530530
// filter cuts
531531
float mVtxZMin = -12.f;
532-
float mVtxZMax = -12.f;
532+
float mVtxZMax = 12.f;
533533
float mSphericityMin = 0.f;
534534
float mSphericityMax = 1.f;
535535
float mMagFieldMin = -5.f;
@@ -539,7 +539,7 @@ class CollisionSelection : public baseselection::BaseSelection<float, o2::analys
539539
float mCentMin = 0.f;
540540
float mCentMax = 100.f;
541541

542-
int mMagField = 0.f;
542+
int mMagField = 0;
543543
float mSphericity = 0.f;
544544
float mCentrality = 0.f;
545545
float mMultiplicity = 0.f;
@@ -568,6 +568,7 @@ struct CollisionBuilderProducts : o2::framework::ProducesGroup {
568568
o2::framework::Produces<o2::aod::FColMults> producedMultiplicityEstimators;
569569
o2::framework::Produces<o2::aod::FColCents> producedCentralityEstimators;
570570
o2::framework::Produces<o2::aod::FColShapes> producedShapes;
571+
o2::framework::Produces<o2::aod::FLiteColShapes> producedLiteShapes;
571572
};
572573

573574
struct ConfCollisionTables : o2::framework::ConfigurableGroup {
@@ -580,6 +581,7 @@ struct ConfCollisionTables : o2::framework::ConfigurableGroup {
580581
o2::framework::Configurable<int> produceMults{"produceMults", -1, "Produce Multiplicities (-1: auto; 0 off; 1 on)"};
581582
o2::framework::Configurable<int> produceCents{"produceCents", -1, "Produce Centralities (-1: auto; 0 off; 1 on)"};
582583
o2::framework::Configurable<int> produceShapes{"produceShapes", -1, "Produce Event shape variables (-1: auto; 0 off; 1 on)"};
584+
o2::framework::Configurable<int> produceLiteShapes{"produceLiteShapes", -1, "Produce Lite Event shape variables (-1: auto; 0 off; 1 on)"};
583585
};
584586

585587
template <auto& SelectionHistName, auto& FilterHistName>
@@ -606,16 +608,22 @@ class CollisionBuilder
606608
mProducedMultiplicities = utils::enableTable("FColMults_001", confTable.produceMults.value, initContext);
607609
mProducedCentralities = utils::enableTable("FColCents_001", confTable.produceCents.value, initContext);
608610
mProducedShapes = utils::enableTable("FColShapes_001", confTable.produceShapes.value, initContext);
611+
mProducedLiteShapes = utils::enableTable("FLiteColShapes_001", confTable.produceLiteShapes.value, initContext);
609612

610613
if (mProducedCollisions && mProducedLiteCollisions) {
611614
LOG(fatal) << "FCols and FLiteCols are mutually exclusive -- enable only one. "
612615
<< "FLiteCols is meant to only replace FCols at the producer stage (for better compression in derived data); "
613616
<< "use the dedicated converter task to reconstruct FCols from FLiteCols downstream.";
614617
}
618+
if (mProducedShapes && mProducedLiteShapes) {
619+
LOG(fatal) << "FColShapes and FLiteColShapes are mutually exclusive -- enable only one. "
620+
<< "FLiteColShapes is meant to only replace FColShapes at the producer stage (for better compression in derived data); "
621+
<< "use the dedicated converter task to reconstruct FColShapes from FLiteColShapes downstream.";
622+
}
615623

616624
if (mProducedCollisions || mProducedLiteCollisions || mProducedCollisionMasks ||
617625
mProducedPositions || mProducedSphericities || mProducedMultiplicities ||
618-
mProducedCentralities) {
626+
mProducedCentralities || mProducedShapes || mProducedLiteShapes) {
619627
mFillAnyTable = true;
620628
} else {
621629
LOG(info) << "No tables configured, Selection object will not be configured...";
@@ -634,15 +642,14 @@ class CollisionBuilder
634642
if (mRunNumber != bc.runNumber()) {
635643
mRunNumber = bc.runNumber();
636644
if (mMagFieldForced == 0) {
637-
static o2::parameters::GRPMagField* grpo = nullptr;
638-
LOG(info) << "Get magentic field with Path: " << mGrpPath << "; Run number: " << mRunNumber;
639-
grpo = ccdb->template getForRun<o2::parameters::GRPMagField>(mGrpPath, mRunNumber);
645+
o2::parameters::GRPMagField* grpo = ccdb->template getForRun<o2::parameters::GRPMagField>(mGrpPath, mRunNumber);
646+
LOG(info) << "Get magnetic field with Path: " << mGrpPath << "; Run number: " << mRunNumber;
640647
if (grpo == nullptr) {
641648
LOG(fatal) << "GRP object not found for Run " << mRunNumber;
642649
}
643650
mMagField = static_cast<int>(grpo->getNominalL3Field()); // get magnetic field in kG
644651
} else {
645-
LOG(info) << "Force magentic field to " << mMagFieldForced << "kG";
652+
LOG(info) << "Force magnetic field to " << mMagFieldForced << "kG";
646653
mMagField = mMagFieldForced;
647654
}
648655

@@ -752,6 +759,12 @@ class CollisionBuilder
752759
mCollisionSelection.getEventPlane());
753760
}
754761

762+
if (mProducedLiteShapes) {
763+
collisionProducts.producedLiteShapes(
764+
o2::aod::femtocollisions::lite::binQvec(mCollisionSelection.getQvector()),
765+
o2::aod::femtocollisions::lite::binEventPlaneAngle(mCollisionSelection.getEventPlane()));
766+
}
767+
755768
mCollisionAlreadyFilled = true;
756769
}
757770

@@ -795,6 +808,7 @@ class CollisionBuilder
795808
bool mProducedMultiplicities = false;
796809
bool mProducedCentralities = false;
797810
bool mProducedShapes = false;
811+
bool mProducedLiteShapes = false;
798812
};
799813

800814
struct CollisionBuilderDerivedToDerivedProducts : o2::framework::ProducesGroup {

PWGCF/Femto/Core/femtoUtils.h

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ inline std::optional<T2> getIndex(const T1& index, const std::unordered_map<T1,
4747
return std::nullopt;
4848
}
4949

50+
/// Translate a global daughter index into a row of the current track table frame.
51+
/// Aborts if the index does not fall inside the frame, which would otherwise
52+
/// silently produce an out-of-range iterator.
53+
template <typename T>
54+
int64_t daughterRow(int64_t daughterId, T const& trackTable)
55+
{
56+
const int64_t row = daughterId - trackTable.offset();
57+
if (daughterId < 0 || row < 0 || row >= static_cast<int64_t>(trackTable.size())) {
58+
LOG(fatal) << "Daughter index " << daughterId << " out of range for track table (offset "
59+
<< trackTable.offset() << ", size " << trackTable.size() << "). Breaking...";
60+
}
61+
return row;
62+
}
63+
5064
template <typename T>
5165
float itsSignal(T const& track)
5266
{
@@ -243,7 +257,7 @@ inline int signum(T x)
243257
}
244258

245259
template <typename T>
246-
inline T binLinear(float value, float lo, float hi, float step)
260+
T binLinear(float value, float lo, float hi, float step)
247261
{
248262
float v = std::clamp(value, lo, hi);
249263
auto idx = static_cast<int64_t>(std::round((v - lo) / step));
@@ -253,46 +267,46 @@ inline T binLinear(float value, float lo, float hi, float step)
253267
}
254268

255269
template <typename T>
256-
inline float unBinLinear(T binned, float lo, float step)
270+
float unBinLinear(T binned, float lo, float step)
257271
{
258272
auto idx = static_cast<int64_t>(binned) - static_cast<int64_t>(std::numeric_limits<T>::min());
259273
return lo + static_cast<float>(idx) * step;
260274
}
261275

262276
template <typename T>
263-
inline T binLogSigned(float signedValue, float magMin, float magMax)
277+
T binLogSigned(float signedValue, float magMin, float magMax)
264278
{
265279
static_assert(std::is_unsigned_v<T>, "binLogSigned requires an unsigned storage type");
266-
constexpr uint32_t TotalBits = sizeof(T) * 8;
267-
constexpr uint32_t HalfLevels = 1u << (TotalBits - 1);
268-
uint32_t sign = (signedValue < 0.f) ? 1u : 0u;
269-
float mag = std::clamp(std::fabs(signedValue), magMin, magMax);
270-
float logLo = std::log(magMin);
271-
float logHi = std::log(magMax);
272-
float step = (logHi - logLo) / static_cast<float>(HalfLevels - 1);
273-
auto idx = static_cast<uint32_t>(std::round((std::log(mag) - logLo) / step));
274-
idx = std::clamp(idx, 0u, HalfLevels - 1);
275-
return static_cast<T>((sign << (TotalBits - 1)) | idx);
280+
constexpr uint64_t TotalBits = sizeof(T) * 8;
281+
constexpr uint64_t HalfLevels = uint64_t{1} << (TotalBits - 1);
282+
const uint64_t sign = (signedValue < 0.f) ? uint64_t{1} : uint64_t{0};
283+
const float mag = std::clamp(std::fabs(signedValue), magMin, magMax);
284+
const float logLo = std::log(magMin);
285+
const float logHi = std::log(magMax);
286+
const float step = (logHi - logLo) / static_cast<float>(HalfLevels - 1);
287+
auto idx = static_cast<int64_t>(std::round((std::log(mag) - logLo) / step));
288+
idx = std::clamp(idx, int64_t{0}, static_cast<int64_t>(HalfLevels - 1));
289+
return static_cast<T>((sign << (TotalBits - 1)) | static_cast<uint64_t>(idx));
276290
}
277291

278292
template <typename T>
279-
inline float unBinLogSigned(T binned, float magMin, float magMax)
293+
float unBinLogSigned(T binned, float magMin, float magMax)
280294
{
281-
constexpr uint32_t TotalBits = sizeof(T) * 8;
282-
constexpr uint32_t HalfLevels = 1u << (TotalBits - 1);
283-
constexpr T SignMask = static_cast<T>(1u << (TotalBits - 1));
295+
static_assert(std::is_unsigned_v<T>, "unBinLogSigned requires an unsigned storage type");
296+
constexpr uint64_t TotalBits = sizeof(T) * 8;
297+
constexpr uint64_t HalfLevels = uint64_t{1} << (TotalBits - 1);
298+
constexpr T SignMask = static_cast<T>(uint64_t{1} << (TotalBits - 1));
284299
constexpr T MagMask = static_cast<T>(SignMask - 1);
285-
float sign = (binned & SignMask) ? -1.f : 1.f;
286-
uint32_t idx = binned & MagMask;
287-
float logLo = std::log(magMin);
288-
float logHi = std::log(magMax);
289-
float step = (logHi - logLo) / static_cast<float>(HalfLevels - 1);
290-
float mag = std::exp(logLo + static_cast<float>(idx) * step);
291-
return sign * mag;
300+
const float sign = (binned & SignMask) ? -1.f : 1.f;
301+
const auto idx = static_cast<uint64_t>(binned & MagMask);
302+
const float logLo = std::log(magMin);
303+
const float logHi = std::log(magMax);
304+
const float step = (logHi - logLo) / static_cast<float>(HalfLevels - 1);
305+
return sign * std::exp(logLo + static_cast<float>(idx) * step);
292306
}
293307

294308
template <typename T>
295-
inline int unBinSign(T binned)
309+
int unBinSign(T binned)
296310
{
297311
static_assert(std::is_unsigned_v<T>, "unBinSign requires an unsigned storage type");
298312
constexpr uint64_t TotalBits = sizeof(T) * 8;
@@ -301,7 +315,7 @@ inline int unBinSign(T binned)
301315
}
302316

303317
template <typename T>
304-
inline T binLogUnsigned(float value, float magMin, float magMax)
318+
T binLogUnsigned(float value, float magMin, float magMax)
305319
{
306320
static_assert(std::is_unsigned_v<T>, "binLogUnsigned requires an unsigned storage type");
307321
constexpr uint64_t TotalBits = sizeof(T) * 8;
@@ -316,7 +330,7 @@ inline T binLogUnsigned(float value, float magMin, float magMax)
316330
}
317331

318332
template <typename T>
319-
inline float unBinLogUnsigned(T binned, float magMin, float magMax)
333+
float unBinLogUnsigned(T binned, float magMin, float magMax)
320334
{
321335
constexpr uint64_t TotalBits = sizeof(T) * 8;
322336
constexpr uint64_t Levels = uint64_t{1} << TotalBits;

0 commit comments

Comments
 (0)