Skip to content

Commit c0e2b5b

Browse files
authored
[PWGJE] Code update for hadron-jet analysis (#10926)
1 parent 708523b commit c0e2b5b

File tree

1 file changed

+135
-68
lines changed

1 file changed

+135
-68
lines changed

PWGJE/Tasks/recoilJets.cxx

Lines changed: 135 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct RecoilJets {
6868
Configurable<std::string> trkSel{"trkSel", "globalTracks", "Set track selection"};
6969
Configurable<float> vertexZCut{"vertexZCut", 10., "Accepted z-vertex range"};
7070
Configurable<float> fracSig{"fracSig", 0.9, "Fraction of events to use for signal TT"};
71+
Configurable<bool> bGetMissJets{"bGetMissJets", false, "Flag to get miss histo for particle level jets"};
7172

7273
Configurable<float> trkPtMin{"trkPtMin", 0.15, "Minimum pT of acceptanced tracks"};
7374
Configurable<float> trkPtMax{"trkPtMax", 100., "Maximum pT of acceptanced tracks"};
@@ -76,10 +77,12 @@ struct RecoilJets {
7677
Configurable<float> jetR{"jetR", 0.4, "Jet cone radius"};
7778

7879
Configurable<std::string> triggerMasks{"triggerMasks", "", "Relevant trigger masks: fTrackLowPt,fTrackHighPt"};
80+
Configurable<bool> skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"};
7981

8082
// List of configurable parameters for MC
8183
Configurable<float> pTHatExponent{"pTHatExponent", 4.0, "Exponent of the event weight for the calculation of pTHat"};
8284
Configurable<float> pTHatMax{"pTHatMax", 999.0, "Maximum fraction of hard scattering for jet acceptance in MC"};
85+
Configurable<float> pTHatMaxTrack{"pTHatMaxTrack", 999.0, "Maximum fraction of hard scattering for track acceptance in MC"};
8386

8487
// Parameters for recoil jet selection
8588
Configurable<float> ptTTrefMin{"ptTTrefMin", 5., "Minimum pT of reference TT"};
@@ -134,8 +137,14 @@ struct RecoilJets {
134137
// List of raw and MC det. distributions
135138
if (doprocessData || doprocessMCDetLevel || doprocessMCDetLevelWeighted) {
136139
spectra.add("vertexZ", "Z vertex of collisions", kTH1F, {{60, -12., 12.}});
140+
spectra.add("hHasAssocMcCollision", "Has det. level coll. associat. MC coll.", kTH1F, {{2, 0.0, 2.}});
141+
spectra.get<TH1>(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(1, "Yes");
142+
spectra.get<TH1>(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(2, "No");
137143

138144
spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, {pT, pseudorap, phiAngle});
145+
146+
spectra.add("hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, {{40, 10., 50.}}); // needed to distinguish merged data from diff. wagons
147+
139148
spectra.add("hNtrig", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}});
140149
spectra.get<TH1>(HIST("hNtrig"))->GetXaxis()->SetBinLabel(1, "TT_{ref}");
141150
spectra.get<TH1>(HIST("hNtrig"))->GetXaxis()->SetBinLabel(2, "TT_{sig}");
@@ -161,6 +170,9 @@ struct RecoilJets {
161170

162171
// List of MC particle level distributions
163172
if (doprocessMCPartLevel || doprocessMCPartLevelWeighted) {
173+
spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, {{60, -12., 12.}});
174+
spectra.add("ptHat", "Distribution of pT hat", kTH1F, {{500, 0.0, 100.}});
175+
164176
spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, {pT, pseudorap, phiAngle});
165177
spectra.add("hNtrig_Part", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}});
166178
spectra.get<TH1>(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(1, "TT_{ref}");
@@ -187,26 +199,30 @@ struct RecoilJets {
187199

188200
// Jet matching: part. vs. det.
189201
if (doprocessJetsMatched || doprocessJetsMatchedWeighted) {
190-
spectra.add("hJetPt_PartLevel_vs_DetLevel", "Correlation jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}});
202+
spectra.add("hJetPt_DetLevel_vs_PartLevel", "Correlation jet pT at det. vs. part. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}});
191203
// spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel", "Correlation jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr});
192-
spectra.add("hJetPt_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}});
204+
spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}});
193205
// spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr});
194206

195-
spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
196-
// spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr});
197-
// spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
198-
// spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr});
199-
200-
spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
201-
// spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr});
202-
spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
203-
// spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr});
207+
if (bGetMissJets) {
208+
spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
209+
// spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr});
210+
spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
211+
// spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr});
212+
} else {
213+
spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
214+
// spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr});
215+
spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}});
216+
// spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr});
217+
}
204218

205219
spectra.add("hJetPt_resolution", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT});
206220
spectra.add("hJetPt_resolution_RecoilJets", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT});
207221

208222
spectra.add("hJetPhi_resolution", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT});
209223
spectra.add("hJetPhi_resolution_RecoilJets", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT});
224+
225+
spectra.add("hNumberMatchedJetsPerOneBaseJet", "# of taged jets per 1 base jet vs. jet pT", kTH2F, {{10, 0.5, 10.5}, {100, 0.0, 100.}});
210226
}
211227
}
212228

@@ -231,11 +247,15 @@ struct RecoilJets {
231247
if (skipTrack(track))
232248
continue;
233249

250+
if (bIsMC && (track.pt() > pTHatMaxTrack * pTHat))
251+
continue;
252+
234253
spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), weight);
235254

236255
// Search for TT candidate
237256
if (bSigEv && (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax)) {
238257
vPhiOfTT.push_back(track.phi());
258+
spectra.fill(HIST("hTTSig_pT"), track.pt(), weight);
239259
++nTT;
240260
}
241261

@@ -301,6 +321,7 @@ struct RecoilJets {
301321
double phiTT = 0.;
302322
int nTT = 0;
303323
float pTHat = getPtHat(weight);
324+
spectra.fill(HIST("ptHat"), pTHat, weight);
304325

305326
auto dice = rand->Rndm();
306327
if (dice < fracSig)
@@ -316,6 +337,9 @@ struct RecoilJets {
316337
if (bParticleNeutral || !particle.isPhysicalPrimary())
317338
continue;
318339

340+
if (particle.pt() > pTHatMaxTrack * pTHat)
341+
continue;
342+
319343
spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), particle.phi(), weight);
320344

321345
if (bSigEv && (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) {
@@ -379,70 +403,36 @@ struct RecoilJets {
379403
}
380404
}
381405

382-
/// TODO: Add functionality to get rho for particle and detector level
383-
template <typename Tracks, typename DetLevelJets, typename PartLevelJets>
384-
void fillMatchedHistograms(Tracks const& tracks, DetLevelJets const& jets_det_level, PartLevelJets const& jets_part_level, float weight = 1.)
406+
template <typename TracksTable, typename JetsBase, typename JetsTag>
407+
void fillMatchedHistograms(TracksTable const& tracks, JetsBase const& jetsBase, JetsTag const& jetsTag, float weight = 1.)
385408
{
386409
std::vector<double> vPhiOfTT;
387-
double phiTT = 0.;
410+
double phiTTSig = 0.;
388411
float pTHat = getPtHat(weight);
389412

390413
for (const auto& track : tracks) {
391414
if (skipTrack(track))
392415
continue;
393416

417+
if (track.pt() > pTHatMaxTrack * pTHat)
418+
continue;
419+
394420
if (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax) {
395421
vPhiOfTT.push_back(track.phi());
396422
}
397423
}
398424

399-
bool bTT = vPhiOfTT.size() > 0;
400-
if (bTT)
401-
phiTT = getPhiTT(vPhiOfTT);
402-
403-
for (const auto& jet_det_level : jets_det_level) {
404-
if (jet_det_level.pt() > pTHatMax * pTHat)
405-
continue;
425+
bool bIsThereTTSig = vPhiOfTT.size() > 0;
406426

407-
bool bRecoilJet = get<1>(isRecoilJet(jet_det_level, phiTT)) && bTT;
427+
if (bIsThereTTSig)
428+
phiTTSig = getPhiTT(vPhiOfTT);
408429

409-
if (jet_det_level.has_matchedJetGeo()) {
410-
411-
const auto jetsMatchedPartLevel = jet_det_level.template matchedJetGeo_as<std::decay_t<PartLevelJets>>(); // we can add "matchedJetPt_as" later
412-
413-
for (const auto& jet_matched_part_level : jetsMatchedPartLevel) {
414-
415-
/*
416-
Which histos we want:
417-
1) det pT vs. part. pT for inclusive jets (corrected for rho*A and not)
418-
2) det pT vs. part. pT for recoil jets
419-
3) same as (1) and (2) but 4D with dphi parts
420-
4) distribution of fake and miss jets
421-
5) pT and phi resolutions
422-
*/
423-
424-
spectra.fill(HIST("hJetPt_PartLevel_vs_DetLevel"), jet_det_level.pt(), jet_matched_part_level.pt(), weight);
425-
spectra.fill(HIST("hJetPt_resolution"), (jet_matched_part_level.pt() - jet_det_level.pt()) / jet_matched_part_level.pt(), jet_matched_part_level.pt(), weight);
426-
spectra.fill(HIST("hJetPhi_resolution"), jet_matched_part_level.phi() - jet_det_level.phi(), jet_matched_part_level.pt(), weight);
427-
428-
if (bRecoilJet) {
429-
spectra.fill(HIST("hJetPt_PartLevel_vs_DetLevel_RecoilJets"), jet_det_level.pt(), jet_matched_part_level.pt(), weight);
430-
spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jet_matched_part_level.pt() - jet_det_level.pt()) / jet_matched_part_level.pt(), jet_matched_part_level.pt(), weight);
431-
spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jet_matched_part_level.phi() - jet_det_level.phi(), jet_matched_part_level.pt(), weight);
432-
}
433-
}
434-
} else {
435-
spectra.fill(HIST("hFakeJets_pT"), jet_det_level.pt(), weight);
436-
if (bRecoilJet)
437-
spectra.fill(HIST("hFakeJets_pT_RecoilJets"), jet_det_level.pt(), weight);
438-
}
439-
}
430+
for (const auto& jetBase : jetsBase) {
431+
if (jetBase.pt() > pTHatMax * pTHat)
432+
continue;
440433

441-
// Missed jets
442-
for (const auto& jet_part_level : jets_part_level) {
443-
if (!jet_part_level.has_matchedJetGeo()) {
444-
spectra.fill(HIST("hMissedJets_pT"), jet_part_level.pt(), weight);
445-
}
434+
bool bIsBaseJetRecoil = get<1>(isRecoilJet(jetBase, phiTTSig)) && bIsThereTTSig;
435+
dataForUnfolding(jetBase, jetsTag, bIsBaseJetRecoil, weight);
446436
}
447437
}
448438

@@ -462,7 +452,7 @@ struct RecoilJets {
462452
FilteredTracks const& tracks,
463453
FilteredJetsDetLevel const& jets)
464454
{
465-
if (skipEvent(collision))
455+
if (skipEvent(collision) || skipMBGapEvent(collision))
466456
return;
467457

468458
spectra.fill(HIST("vertexZ"), collision.posZ());
@@ -475,12 +465,18 @@ struct RecoilJets {
475465
FilteredTracks const& tracks,
476466
FilteredJetsDetLevel const& jets)
477467
{
478-
if (skipEvent(collision))
468+
if (skipEvent(collision) || skipMBGapEvent(collision))
479469
return;
480470

481-
/// \TODO: should we implement function to check whether Collision was reconstructed (has_mcCollision() function)? Example: https://github.com/AliceO2Group/O2Physics/blob/1cba330514ab47c15c0095d8cee9633723d8e2a7/PWGJE/Tasks/v0qa.cxx#L166?
482471
auto weight = collision.mcCollision().weight();
483472
spectra.fill(HIST("vertexZ"), collision.posZ(), weight);
473+
474+
if (collision.has_mcCollision()) {
475+
spectra.fill(HIST("hHasAssocMcCollision"), 0.5, weight);
476+
} else {
477+
spectra.fill(HIST("hHasAssocMcCollision"), 1.5, weight);
478+
}
479+
484480
fillHistograms(collision, jets, tracks, true, weight);
485481
}
486482
PROCESS_SWITCH(RecoilJets, processMCDetLevelWeighted, "process MC detector level with event weight", false);
@@ -489,7 +485,10 @@ struct RecoilJets {
489485
aod::JetParticles const& particles,
490486
FilteredJetsPartLevel const& jets)
491487
{
492-
spectra.fill(HIST("vertexZ"), collision.posZ());
488+
if (skipMBGapEvent(collision))
489+
return;
490+
491+
spectra.fill(HIST("vertexZMC"), collision.posZ());
493492
fillMCPHistograms(collision, jets, particles);
494493
}
495494
PROCESS_SWITCH(RecoilJets, processMCPartLevel, "process MC particle level", false);
@@ -498,8 +497,11 @@ struct RecoilJets {
498497
aod::JetParticles const& particles,
499498
FilteredJetsPartLevel const& jets)
500499
{
500+
if (skipMBGapEvent(collision))
501+
return;
502+
501503
auto weight = collision.weight();
502-
spectra.fill(HIST("vertexZ"), collision.posZ(), weight);
504+
spectra.fill(HIST("vertexZMC"), collision.posZ(), weight);
503505
fillMCPHistograms(collision, jets, particles, weight);
504506
}
505507
PROCESS_SWITCH(RecoilJets, processMCPartLevelWeighted, "process MC particle level with event weight", false);
@@ -510,10 +512,16 @@ struct RecoilJets {
510512
FilteredMatchedJetsDetLevel const& mcdjets,
511513
FilteredMatchedJetsPartLevel const& mcpjets)
512514
{
513-
if (skipEvent(collision))
515+
if (skipEvent(collision) || skipMBGapEvent(collision))
514516
return;
517+
515518
auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId());
516-
fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision);
519+
520+
if (bGetMissJets) {
521+
fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets);
522+
} else {
523+
fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision);
524+
}
517525
}
518526
PROCESS_SWITCH(RecoilJets, processJetsMatched, "process matching of MC jets (no weight)", false);
519527

@@ -523,13 +531,17 @@ struct RecoilJets {
523531
FilteredMatchedJetsDetLevel const& mcdjets,
524532
FilteredMatchedJetsPartLevel const& mcpjets)
525533
{
526-
if (skipEvent(collision))
534+
if (skipEvent(collision) || skipMBGapEvent(collision))
527535
return;
528536

529537
auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId());
530538
auto weight = collision.mcCollision().weight();
531539

532-
fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision, weight);
540+
if (bGetMissJets) {
541+
fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets, weight);
542+
} else {
543+
fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision, weight);
544+
}
533545
}
534546
PROCESS_SWITCH(RecoilJets, processJetsMatchedWeighted, "process matching of MC jets (weighted)", false);
535547

@@ -542,6 +554,12 @@ struct RecoilJets {
542554
return !jetderiveddatautilities::selectCollision(coll, eventSelectionBits) || !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits);
543555
}
544556

557+
template <typename Collision>
558+
bool skipMBGapEvent(const Collision& coll)
559+
{
560+
return (skipMBGapEvents && coll.subGeneratorId()) == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap;
561+
}
562+
545563
template <typename Track>
546564
bool skipTrack(const Track& track)
547565
{
@@ -566,6 +584,55 @@ struct RecoilJets {
566584
{
567585
return 10. / (std::pow(weight, 1.0 / pTHatExponent));
568586
}
587+
588+
template <typename JetBase, typename JetsTag>
589+
void dataForUnfolding(JetBase const& jetBase, JetsTag const&, bool bIsBaseJetRecoil, float weight = 1.0)
590+
{
591+
592+
bool bIsThereMatchedJet = jetBase.has_matchedJetGeo();
593+
if (bIsThereMatchedJet) {
594+
const auto& jetsMatched = jetBase.template matchedJetGeo_as<std::decay_t<JetsTag>>();
595+
596+
for (const auto& jetMatched : jetsMatched) {
597+
spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), jetsMatched.size(), jetMatched.pt(), weight);
598+
599+
if (bGetMissJets) {
600+
// Mean that base jet is particle level jet
601+
spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetMatched.pt(), jetBase.pt(), weight);
602+
spectra.fill(HIST("hJetPt_resolution"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight);
603+
spectra.fill(HIST("hJetPhi_resolution"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight);
604+
605+
if (bIsBaseJetRecoil) {
606+
spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetMatched.pt(), jetBase.pt(), weight);
607+
spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight);
608+
spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight);
609+
}
610+
} else {
611+
// Mean that base jet is detector level jet
612+
spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetBase.pt(), jetMatched.pt(), weight);
613+
spectra.fill(HIST("hJetPt_resolution"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight);
614+
spectra.fill(HIST("hJetPhi_resolution"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight);
615+
616+
if (bIsBaseJetRecoil) {
617+
spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetBase.pt(), jetMatched.pt(), weight);
618+
spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight);
619+
spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight);
620+
}
621+
}
622+
}
623+
} else {
624+
// No closest jet
625+
if (bGetMissJets) {
626+
spectra.fill(HIST("hMissedJets_pT"), jetBase.pt(), weight);
627+
if (bIsBaseJetRecoil)
628+
spectra.fill(HIST("hMissedJets_pT_RecoilJets"), jetBase.pt(), weight);
629+
} else {
630+
spectra.fill(HIST("hFakeJets_pT"), jetBase.pt(), weight);
631+
if (bIsBaseJetRecoil)
632+
spectra.fill(HIST("hFakeJets_pT_RecoilJets"), jetBase.pt(), weight);
633+
}
634+
}
635+
}
569636
};
570637

571638
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask<RecoilJets>(cfgc)}; }

0 commit comments

Comments
 (0)