Skip to content

Commit 894434d

Browse files
committed
Multiplicity correlations
1 parent 267bfc5 commit 894434d

File tree

1 file changed

+73
-9
lines changed

1 file changed

+73
-9
lines changed

PWGCF/Tasks/correlations.cxx

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include <TDirectory.h>
3838
#include <TFile.h>
39+
#include <TFormula.h>
3940
#include <TH1F.h>
4041
#include <THn.h>
4142
#include <TVector2.h>
@@ -87,6 +88,8 @@ struct CorrelationTask {
8788
O2_DEFINE_CONFIGURABLE(cfgCentBinsForMC, int, 0, "0 = OFF and 1 = ON for data like multiplicity/centrality bins for MC steps");
8889
O2_DEFINE_CONFIGURABLE(cfgTrackBitMask, uint16_t, 0, "BitMask for track selection systematics; refer to the enum TrackSelectionCuts in filtering task");
8990
O2_DEFINE_CONFIGURABLE(cfgMultCorrelationsMask, uint16_t, 0, "Selection bitmask for the multiplicity correlations. This should match the filter selection cfgEstimatorBitMask.")
91+
O2_DEFINE_CONFIGURABLE(cfgMultCutFormula, std::string, "", "Multiplicity correlations cut formula. A result greater than zero results in accepted event. Parameters: [cFT0C] FT0C centrality, [mFV0A] V0A multiplicity, [mGlob] global track multiplicity, [mPV] PV track multiplicity")
92+
9093
// Suggested values: Photon: 0.004; K0 and Lambda: 0.005
9194
Configurable<LabeledArray<float>> cfgPairCut{"cfgPairCut", {kCfgPairCutDefaults[0], 5, {"Photon", "K0", "Lambda", "Phi", "Rho"}}, "Pair cuts on various particles"};
9295

@@ -124,7 +127,7 @@ struct CorrelationTask {
124127
Filter collisionVertexTypeFilter = (aod::collision::flags & static_cast<uint16_t>(aod::collision::CollisionFlagsRun2::Run2VertexerTracks)) == static_cast<uint16_t>(aod::collision::CollisionFlagsRun2::Run2VertexerTracks);
125128

126129
// Track filters
127-
Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true));
130+
Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true));
128131
Filter cfTrackFilter = (nabs(aod::cftrack::eta) < cfgCutEta) && (aod::cftrack::pt > cfgCutPt) && ((aod::track::trackType & (uint8_t)cfgTrackBitMask) == (uint8_t)cfgTrackBitMask);
129132

130133
// MC filters
@@ -142,6 +145,9 @@ struct CorrelationTask {
142145
std::vector<float> efficiencyAssociatedCache;
143146
std::vector<int> p2indexCache;
144147

148+
std::unique_ptr<TFormula> multCutFormula;
149+
std::array<uint, 4> multCutFormulaParamIndex;
150+
145151
struct Config {
146152
bool mPairCuts = false;
147153
THn* mEfficiencyTrigger = nullptr;
@@ -218,6 +224,24 @@ struct CorrelationTask {
218224

219225
// --- OBJECT INIT ---
220226

227+
if (!cfgMultCutFormula.value.empty()) {
228+
multCutFormula = std::make_unique<TFormula>("multCutFormula", cfgMultCutFormula.value.c_str());
229+
std::fill_n(multCutFormulaParamIndex.begin(), std::size(multCutFormulaParamIndex), ~0u);
230+
std::array<std::string, 4> pars = {"cFT0C", "mFV0A", "mGlob", "mPV"};
231+
for (uint i = 0; i < multCutFormula->GetNpar(); ++i) {
232+
auto m = std::find(pars.begin(), pars.end(), multCutFormula->GetParName(i));
233+
if (m == pars.end()) {
234+
235+
LOGF(warning, "Unknown parameter cfgMultCutFormula: %s", multCutFormula->GetParName(i));
236+
continue;
237+
}
238+
if (cfgMultCorrelationsMask.value & (1u << i) == 0)
239+
LOGF(warning, "The centrality/multiplicity estimator %s is not available to be used in cfgMultCutFormula. Ensure cfgMultCorrelationsMask is correct and matches the CFMultSets in derived data.");
240+
else
241+
multCutFormulaParamIndex[std::distance(pars.begin(), m)] = i;
242+
}
243+
}
244+
221245
std::vector<AxisSpec> corrAxis = {{axisDeltaEta, "#Delta#eta"},
222246
{axisPtAssoc, "p_{T} (GeV/c)"},
223247
{axisPtTrigger, "p_{T} (GeV/c)"},
@@ -426,6 +450,24 @@ struct CorrelationTask {
426450
template <class T>
427451
using HasPartDaugh1Id = decltype(std::declval<T&>().cfParticleDaugh1Id());
428452

453+
/*
454+
OO outlier cut:
455+
(567.785+172.715*[mGlob]+0.77888*[mGlob]*[mGlob]+-0.00693466*[mGlob]*[mGlob]*[mGlob]+1.40564e-05*[mGlob]*[mGlob]*[mGlob]*[mGlob] + 3.5*(679.853+66.8068*[mGlob]+-0.444332*[mGlob]*[mGlob]+0.00115002*[mGlob]*[mGlob]*[mGlob]+-4.92064e-07*[mGlob]*[mGlob]*[mGlob]*[mGlob])) < [mFV0A] &&(567.785+172.715*[mGlob]+0.77888*[mGlob]*[mGlob]+-0.00693466*[mGlob]*[mGlob]*[mGlob]+1.40564e-05*[mGlob]*[mGlob]*[mGlob]*[mGlob] - 3.0*(679.853+66.8068*[mGlob]+-0.444332*[mGlob]*[mGlob]+0.00115002*[mGlob]*[mGlob]*[mGlob]+-4.92064e-07*[mGlob]*[mGlob]*[mGlob]*[mGlob])) > [mFV0A] &&(172.406 + -4.50219*[cFT0C] + 0.0543038*[cFT0C]*[cFT0C] + -0.000373213*[cFT0C]*[cFT0C]*[cFT0C] + 1.15322e-06*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] + 4.0*(49.7503 + -1.29008*[cFT0C] + 0.0160059*[cFT0C]*[cFT0C] + -7.86846e-05*[cFT0C]*[cFT0C]*[cFT0C])) < [mPV] &&(172.406 + -4.50219*[cFT0C] + 0.0543038*[cFT0C]*[cFT0C] + -0.000373213*[cFT0C]*[cFT0C]*[cFT0C] + 1.15322e-06*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] - 2.5*(49.7503 + -1.29008*[cFT0C] + 0.0160059*[cFT0C]*[cFT0C] + -7.86846e-05*[cFT0C]*[cFT0C]*[cFT0C])) > [mPV] &&(125.02 + -3.30255*[cFT0C] + 0.0398663*[cFT0C]*[cFT0C] + -0.000271942*[cFT0C]*[cFT0C]*[cFT0C] + 8.34098e-07*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] + 4.0*(37.0244 + -0.949883*[cFT0C] + 0.0116622*[cFT0C]*[cFT0C] + -5.71117e-05*[cFT0C]*[cFT0C]*[cFT0C])) < [mGlob] &&(125.02 + -3.30255*[cFT0C] + 0.0398663*[cFT0C]*[cFT0C] + -0.000271942*[cFT0C]*[cFT0C]*[cFT0C] + 8.34098e-07*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] - 2.5*(37.0244 + -0.949883*[cFT0C] + 0.0116622*[cFT0C]*[cFT0C] + -5.71117e-05*[cFT0C]*[cFT0C]*[cFT0C])) > [mGlob] &&(-0.223013 + 0.715849*[mPV] + 3*(0.664242 + 0.0829653*[mPV] + -0.000503733*[mPV]*[mPV] + 1.21185e-06*[mPV]*[mPV]*[mPV])) < [mGlob]
456+
*/
457+
template <class CollType>
458+
bool passOutlier(CollType const& collision)
459+
{
460+
if (cfgMultCutFormula.value.empty())
461+
return true;
462+
for (uint i = 0; i < 4; ++i) {
463+
if ((cfgMultCorrelationsMask.value & (1u << i)) == 0)
464+
continue;
465+
auto estIndex = std::popcount(cfgMultCorrelationsMask.value & ((1u << i) - 1));
466+
multCutFormula->SetParameter(multCutFormulaParamIndex[i], collision.multiplicities()[estIndex]);
467+
}
468+
return multCutFormula->Eval() > 0.0f;
469+
}
470+
429471
template <typename T>
430472
std::tuple<bool, float> getV0Rapidity(const T& track)
431473
{
@@ -767,6 +809,8 @@ struct CorrelationTask {
767809
}
768810
PROCESS_SWITCH(CorrelationTask, processSameAOD, "Process same event on AOD", true);
769811

812+
using BinningTypeDerived = ColumnBinningPolicy<aod::collision::PosZ, aod::cfcollision::Multiplicity>;
813+
770814
template <class CollType, class TTracks1, class TTracks2>
771815
void processSameDerivedT(CollType const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2)
772816
{
@@ -807,6 +851,8 @@ struct CorrelationTask {
807851

808852
void processSameDerivedMultSet(soa::Filtered<soa::Join<aod::CFCollisions, aod::CFMultSets>>::iterator const& collision, soa::Filtered<aod::CFTracks> const& tracks)
809853
{
854+
if (!passOutlier(collision))
855+
return;
810856
processSameDerivedT(collision, tracks, tracks);
811857
}
812858
PROCESS_SWITCH(CorrelationTask, processSameDerivedMultSet, "Process same event on derived data with multiplicity sets", false);
@@ -878,21 +924,32 @@ struct CorrelationTask {
878924
}
879925
PROCESS_SWITCH(CorrelationTask, processMixedAOD, "Process mixed events on AOD", false);
880926

881-
using BinningTypeDerived = ColumnBinningPolicy<aod::collision::PosZ, aod::cfcollision::Multiplicity>;
882-
883-
template <typename... TrackTypes>
884-
void processMixedDerivedT(DerivedCollisions const& collisions, TrackTypes&&... tracks)
927+
template <class CollType, typename... TrackTypes>
928+
void processMixedDerivedT(CollType const& collisions, TrackTypes&&... tracks)
885929
{
886-
BinningTypeDerived configurableBinningDerived{{axisVertex, axisMultiplicity}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1.
887-
// Strictly upper categorised collisions, for cfgNoMixedEvents combinations per bin, skipping those in entry -1
930+
auto getMultiplicity =
931+
[&collisions, this](auto& col) {
932+
if constexpr (std::experimental::is_detected<HasMultSet, CollType>::value) {
933+
if (!passOutlier(col))
934+
return -1.0f;
935+
}
936+
return col.multiplicity();
937+
};
938+
939+
using BinningTypeDerived = FlexibleBinningPolicy<std::tuple<decltype(getMultiplicity)>, aod::collision::PosZ, decltype(getMultiplicity)>;
940+
BinningTypeDerived configurableBinningDerived{{getMultiplicity}, {axisVertex, axisMultiplicity}, true};
941+
// BinningTypeDerived configurableBinningDerived{{axisVertex, axisMultiplicity}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1.
942+
// Strictly upper categorised collisions, for cfgNoMixedEvents combinations per bin, skipping those in entry -1
888943
auto tracksTuple = std::make_tuple(std::forward<TrackTypes>(tracks)...);
889944
using TA = std::tuple_element<0, decltype(tracksTuple)>::type;
890945
using TB = std::tuple_element<std::tuple_size_v<decltype(tracksTuple)> - 1, decltype(tracksTuple)>::type;
891-
Pair<DerivedCollisions, TA, TB, BinningTypeDerived> pairs{configurableBinningDerived, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip
946+
Pair<CollType, TA, TB, BinningTypeDerived> pairs{configurableBinningDerived, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip
892947

893948
for (auto it = pairs.begin(); it != pairs.end(); it++) {
894949
auto& [collision1, tracks1, collision2, tracks2] = *it;
895-
int bin = configurableBinningDerived.getBin({collision1.posZ(), collision1.multiplicity()});
950+
// int bin = configurableBinningDerived.getBin({collision1.posZ(), collision1.multiplicity()});
951+
float multiplicity = getMultiplicity(collision1);
952+
int bin = configurableBinningDerived.getBin(std::tuple(collision1.posZ(), multiplicity));
896953
float eventWeight = 1.0f / it.currentWindowNeighbours();
897954
int field = 0;
898955
if (cfgTwoTrackCut > 0) {
@@ -930,6 +987,13 @@ struct CorrelationTask {
930987
}
931988
PROCESS_SWITCH(CorrelationTask, processMixedDerived, "Process mixed events on derived data", false);
932989

990+
void processMixedDerivedMultSet(soa::Filtered<soa::Join<aod::CFCollisions, aod::CFMultSets>> const& collisions, DerivedTracks const& tracks)
991+
{
992+
// TODO: use FlexibleBinningPolicy to reject (by returning -1 from lambda) outliers
993+
processMixedDerivedT(collisions, tracks);
994+
}
995+
PROCESS_SWITCH(CorrelationTask, processMixedDerivedMultSet, "Process mixed events on derived data with multiplicity sets", false);
996+
933997
void processMixed2ProngDerived(DerivedCollisions const& collisions, DerivedTracks const& tracks, soa::Filtered<aod::CF2ProngTracks> const& p2tracks)
934998
{
935999
processMixedDerivedT(collisions, p2tracks, tracks);

0 commit comments

Comments
 (0)