Skip to content

Commit be58c8f

Browse files
authored
[PWGJE] Add FT0 event-activity support to track QA (#18477)
1 parent 7d05194 commit be58c8f

1 file changed

Lines changed: 111 additions & 11 deletions

File tree

‎PWGJE/Tasks/trackEfficiency.cxx‎

Lines changed: 111 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <algorithm>
4040
#include <cmath>
41+
#include <limits>
4142
#include <string>
4243
#include <vector>
4344

@@ -95,6 +96,32 @@ struct TrackEfficiency {
9596

9697
Configurable<bool> useTrueTrackWeight{"useTrueTrackWeight", true, "test configurable, should be set to 1 then config removed once well tested"};
9798

99+
// Normalization FT0 by means
100+
struct FT0A : ConfigurableGroup {
101+
std::string prefix = "ft0a";
102+
Configurable<float> mean{"mean", 3499., "Mean FT0A signal"};
103+
Configurable<float> meanMCDetLevel{"meanMCDetLevel", 2640., "Mean FT0A signal at MC detector level"};
104+
} ft0a;
105+
106+
struct FT0C : ConfigurableGroup {
107+
std::string prefix = "ft0c";
108+
Configurable<float> mean{"mean", 844.6, "Mean FT0C signal"};
109+
Configurable<float> meanMCDetLevel{"meanMCDetLevel", 802.9, "Mean FT0C signal at MC detector level"};
110+
} ft0c;
111+
112+
// FT0C event activity thresholds
113+
struct Hist : ConfigurableGroup {
114+
std::string prefix = "hist";
115+
116+
// Raw data
117+
ConfigurableAxis multFT0CThresh{"multFT0CThresh", {VARIABLE_WIDTH, 0.0, 0.109421, 0.215022, 0.343214, 0.50515, 0.712277, 0.978245, 1.3189, 1.75744, 2.36001, 3.59696, 25.}, "Percentiles of scaled FT0C: 100%, 90%, 80%, 70%, 60%, 50%, 40%, 30%, 20%, 10%, 1%"};
118+
ConfigurableAxis multFT0MThresh{"multFT0MThresh", {VARIABLE_WIDTH, 0.0, 0.130987, 0.237916, 0.36664, 0.528441, 0.734705, 0.996611, 1.32785, 1.74896, 2.31024, 3.37852, 25.}, "Percentiles of scaled FT0M: 100%, 90%, 80%, 70%, 60%, 50%, 40%, 30%, 20%, 10%, 1%"};
119+
120+
// MC detector-level data
121+
ConfigurableAxis multFT0CThreshMCDetLevel{"multFT0CThreshMCDetLevel", {VARIABLE_WIDTH, 0.0, 0.124992, 0.243769, 0.380291, 0.543998, 0.748078, 1.00424, 1.3237, 1.72648, 2.27373, 3.43144, 25.}, "Percentiles of scaled FT0C: 100%, 90%, 80%, 70%, 60%, 50%, 40%, 30%, 20%, 10%, 1%"};
122+
ConfigurableAxis multFT0MThreshMCDetLevel{"multFT0MThreshMCDetLevel", {VARIABLE_WIDTH, 0.0, 0.142622, 0.262095, 0.397069, 0.558622, 0.762008, 1.01685, 1.33219, 1.72377, 2.24008, 3.26309, 25.}, "Percentiles of scaled FT0M: 100%, 90%, 80%, 70%, 60%, 50%, 40%, 30%, 20%, 10%, 1%"};
123+
} hist;
124+
98125
// systematics variation - Run 2 guidelines: https://twiki.cern.ch/twiki/bin/view/ALICE/AliDPGtoolsTrackSystematicUncertainty
99126
TrackSelection customTrackSelection;
100127
Configurable<bool> useCustomTrackSelection{"useCustomTrackSelection", false, "whether to use the custom cuts (used for cut variation for tracking efficiency systematics)"};
@@ -117,6 +144,11 @@ struct TrackEfficiency {
117144
SplitOkCheckFirstAssocCollOnly // 2
118145
};
119146

147+
enum class TrackSample {
148+
Data,
149+
MCDetLevel
150+
};
151+
120152
template <typename TJetTrack>
121153
bool isAcceptedTrack(TJetTrack const& jetTrack)
122154
{
@@ -147,19 +179,20 @@ struct TrackEfficiency {
147179
return std::abs(charge) >= chargeUnit;
148180
}
149181

150-
template <typename TCollision, typename TJetTracks>
182+
template <TrackSample sample, typename TCollision, typename TJetTracks>
151183
void fillTrackHistograms(TCollision const& collision, TJetTracks const& jetTracks, float weight = 1.0)
152184
{
185+
const float meanFT0A = sample == TrackSample::Data ? ft0a.mean.value : ft0a.meanMCDetLevel.value;
186+
const float meanFT0C = sample == TrackSample::Data ? ft0c.mean.value : ft0c.meanMCDetLevel.value;
187+
const auto ft0Metrics = getFT0Metrics(collision, meanFT0A, meanFT0C);
188+
const auto scaledFT0C = ft0Metrics.scaledFT0C;
189+
const auto scaledFT0M = ft0Metrics.scaledFT0M;
190+
153191
for (auto const& track : jetTracks) {
154192
if (!isAcceptedTrack(track)) {
155193
continue;
156194
}
157195

158-
float pTHat = simPtRef / (std::pow(weight, 1.0 / pTHatExponent));
159-
if (track.pt() > pTHatMaxFractionMCD * pTHat) {
160-
continue;
161-
}
162-
163196
float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C();
164197

165198
registry.fill(HIST("h2_centrality_track_pt"), centrality, track.pt(), weight);
@@ -172,6 +205,14 @@ struct TrackEfficiency {
172205
registry.fill(HIST("h2_track_pt_high_track_sigmapt"), track.pt(), track.sigma1Pt() * track.pt(), weight);
173206
registry.fill(HIST("h3_intrate_centrality_track_pt"), collision.hadronicRate(), centrality, track.pt(), weight);
174207
registry.fill(HIST("h3_track_pt_track_eta_track_phi"), track.pt(), track.eta(), track.phi(), weight);
208+
209+
if constexpr (sample == TrackSample::Data) {
210+
registry.fill(HIST("hScaledFT0CTrackPt"), scaledFT0C, track.pt(), weight);
211+
registry.fill(HIST("hScaledFT0MTrackPt"), scaledFT0M, track.pt(), weight);
212+
} else {
213+
registry.fill(HIST("hScaledFT0CTrackPt_MCDetLevel"), scaledFT0C, track.pt(), weight);
214+
registry.fill(HIST("hScaledFT0MTrackPt_MCDetLevel"), scaledFT0M, track.pt(), weight);
215+
}
175216
}
176217
}
177218

@@ -205,6 +246,12 @@ struct TrackEfficiency {
205246
LOGP(fatal, "Configurable acceptSplitCollisions has wrong input value; stopping workflow");
206247
}
207248

249+
constexpr float minFT0Mean = std::numeric_limits<float>::epsilon();
250+
if (std::fabs(ft0a.mean.value) <= minFT0Mean || std::fabs(ft0c.mean.value) <= minFT0Mean ||
251+
std::fabs(ft0a.meanMCDetLevel.value) <= minFT0Mean || std::fabs(ft0c.meanMCDetLevel.value) <= minFT0Mean) {
252+
LOGP(fatal, "FT0A and FT0C means must have magnitude greater than {} to avoid near-zero denominators; stopping workflow", minFT0Mean);
253+
}
254+
208255
eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast<std::string>(eventSelections));
209256
trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast<std::string>(trackSelections));
210257

@@ -254,6 +301,10 @@ struct TrackEfficiency {
254301
AxisSpec etaAxisEff{etaEffBinning, "#eta"};
255302
AxisSpec phiAxisEff{phiEffBinning, "#phi"};
256303
AxisSpec centAxis = {centralityBinning, "centrality (%)"};
304+
AxisSpec scaledFT0C{hist.multFT0CThresh, "FT0C / #LT FT0C #GT"};
305+
AxisSpec scaledFT0M{hist.multFT0MThresh, "FT0M^{*}"};
306+
AxisSpec scaledFT0CMCDetLevel{hist.multFT0CThreshMCDetLevel, "FT0C / #LT FT0C #GT"};
307+
AxisSpec scaledFT0MMCDetLevel{hist.multFT0MThreshMCDetLevel, "FT0M^{*}"};
257308
AxisSpec intRateAxis = {intRateBinning, "int. rate (kHz)"};
258309
AxisSpec occupancyAxis = {140, -0.5, 13999.5, "occupancy"};
259310
AxisSpec nTracksAxis = {16001, -1., 16000, "n tracks"};
@@ -346,6 +397,12 @@ struct TrackEfficiency {
346397
registry.add("h2_track_pt_high_track_sigma1overpt", "#sigma(1/#it{p}_{T}); #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {{90, 10., 100.}, {10000, 0.0, 1.0}}});
347398
registry.add("h3_intrate_centrality_track_pt", "interaction rate vs centrality vs track pT; int. rate; centrality; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH3F, {intRateAxis, centAxis, {200, 0., 200.}}});
348399
registry.add("h3_track_pt_track_eta_track_phi", "track pT vs track #eta vs track #varphi; #it{p}_{T,track} (GeV/#it{c}); #eta_{track}; #varphi_{track}", {HistType::kTH3F, {{200, 0., 200.}, {100, -1.0, 1.0}, {160, -1.0, 7.}}});
400+
401+
// EA analysis
402+
registry.add("hScaledFT0CTrackPt", "scaled FT0C vs track pT; FT0C / #LT FT0C #GT; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {scaledFT0C, {200, 0., 200.}}});
403+
registry.add("hScaledFT0MTrackPt", "scaled FT0M vs track pT; FT0M^{*}; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {scaledFT0M, {200, 0., 200.}}});
404+
registry.add("hScaledFT0CTrackPt_MCDetLevel", "MC detector-level scaled FT0C vs track pT; FT0C / #LT FT0C #GT; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {scaledFT0CMCDetLevel, {200, 0., 200.}}});
405+
registry.add("hScaledFT0MTrackPt_MCDetLevel", "MC detector-level scaled FT0M vs track pT; FT0M^{*}; #it{p}_{T,track} (GeV/#it{c})", {HistType::kTH2F, {scaledFT0MMCDetLevel, {200, 0., 200.}}});
349406
}
350407

351408
if (doprocessParticles || doprocessParticlesWeighted) {
@@ -853,7 +910,7 @@ struct TrackEfficiency {
853910
return;
854911
}
855912

856-
fillTrackHistograms(collision, jetTracks);
913+
fillTrackHistograms<TrackSample::Data>(collision, jetTracks);
857914
}
858915
PROCESS_SWITCH(TrackEfficiency, processTracksFromData, "QA for charged tracks in data", false);
859916

@@ -881,22 +938,26 @@ struct TrackEfficiency {
881938
return;
882939
}
883940

884-
fillTrackHistograms(collision, jetTracks);
941+
fillTrackHistograms<TrackSample::MCDetLevel>(collision, jetTracks);
885942
}
886943
PROCESS_SWITCH(TrackEfficiency, processTracksFromMc, "QA for charged tracks in MC without weights", false);
887944

888-
void processTracksFromMcWeighted(soa::Filtered<soa::Join<aod::JetCollisions, aod::JMcCollisionLbs>>::iterator const& collision,
945+
void processTracksFromMcWeighted(soa::Filtered<soa::Join<aod::JetCollisions, aod::JMcCollisionLbs, aod::JCollisionOutliers>>::iterator const& collision,
889946
aod::JetMcCollisions const&,
890947
soa::Filtered<soa::Join<aod::JetTracksMCD, aod::JTrackExtras, aod::JTrackPIs>> const& jetTracks,
891948
soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA> const&)
892949
{
893950
if (!collision.has_mcCollision()) { // the collision is fake and has no associated mc coll; skip as .mccollision() cannot be called
894951
return;
895952
}
896-
float eventWeight = collision.mcCollision().weight();
897953
if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, skipMBGapEvents, applyRCTSelections, rctSelection)) {
898954
return;
899955
}
956+
957+
if (collision.isOutlier()) {
958+
return;
959+
}
960+
900961
float centrality = checkCentFT0M ? collision.centFT0M() : collision.centFT0C();
901962
if (cutCentrality && (centrality < centralityMin || centralityMax < centrality)) {
902963
return;
@@ -905,12 +966,13 @@ struct TrackEfficiency {
905966
return;
906967
}
907968

969+
float eventWeight = collision.mcCollision().weight();
908970
float pTHat = collision.mcCollision().ptHard() < pTHatSettingSentinelValue ? collision.mcCollision().ptHard() : simPtRef / (std::pow(eventWeight, 1.0 / pTHatExponent));
909971
if (pTHat < ptHatMin || pTHat > ptHatMax) { // only allows mcCollisions with weight in between min and max
910972
return;
911973
}
912974

913-
fillTrackHistograms(collision, jetTracks, eventWeight);
975+
fillTrackHistograms<TrackSample::MCDetLevel>(collision, jetTracks, eventWeight);
914976
}
915977
PROCESS_SWITCH(TrackEfficiency, processTracksFromMcWeighted, "QA for charged tracks in weighted MC", false);
916978

@@ -1711,6 +1773,44 @@ struct TrackEfficiency {
17111773
}
17121774
}
17131775
PROCESS_SWITCH(TrackEfficiency, processQcCheck, "Histograms for QC checks", false);
1776+
1777+
// FT0 event activity helpers
1778+
struct FT0Metrics {
1779+
float multFT0A = 0.f;
1780+
float multFT0C = 0.f;
1781+
float multFT0M = 0.f;
1782+
float scaledFT0A = 0.f;
1783+
float scaledFT0C = 0.f;
1784+
float scaledFT0M = 0.f;
1785+
};
1786+
1787+
float getScaledFT0(const float& multFT0, const float& meanFT0)
1788+
{
1789+
return multFT0 / meanFT0;
1790+
}
1791+
1792+
float getScaledFT0M(const float& scaledMultFT0A, const float& scaledMultFT0C)
1793+
{
1794+
return 0.5 * (scaledMultFT0A + scaledMultFT0C);
1795+
}
1796+
1797+
FT0Metrics makeFT0Metrics(float multFT0A, float multFT0C, float meanFT0A, float meanFT0C)
1798+
{
1799+
FT0Metrics values;
1800+
values.multFT0A = multFT0A;
1801+
values.multFT0C = multFT0C;
1802+
values.multFT0M = multFT0A + multFT0C;
1803+
values.scaledFT0A = getScaledFT0(values.multFT0A, meanFT0A);
1804+
values.scaledFT0C = getScaledFT0(values.multFT0C, meanFT0C);
1805+
values.scaledFT0M = getScaledFT0M(values.scaledFT0A, values.scaledFT0C);
1806+
return values;
1807+
}
1808+
1809+
template <typename Collision>
1810+
FT0Metrics getFT0Metrics(const Collision& collision, float meanFT0A, float meanFT0C)
1811+
{
1812+
return makeFT0Metrics(collision.multFT0A(), collision.multFT0C(), meanFT0A, meanFT0C);
1813+
}
17141814
};
17151815

17161816
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)