@@ -77,19 +77,35 @@ struct JetDsSpecSubs {
7777 using DsMCDJets = soa::Join<aod::DsChargedMCDetectorLevelJets, aod::DsChargedMCDetectorLevelJetConstituents, aod::DsChargedMCDetectorLevelJetsMatchedToDsChargedMCParticleLevelJets>;
7878 using DsMCPJets = soa::Join<aod::DsChargedMCParticleLevelJets, aod::DsChargedMCParticleLevelJetConstituents, aod::DsChargedMCParticleLevelJetsMatchedToDsChargedMCDetectorLevelJets>;
7979
80+ using DsDataJetsEWS = soa::Join<
81+ aod::DsChargedEventWiseSubtractedJets,
82+ aod::DsChargedEventWiseSubtractedJetConstituents>;
83+
84+ // Inclusive charged jets
85+ using ChargedJets = soa::Join<aod::ChargedJets, aod::ChargedJetConstituents>;
86+ using ChargedJetsEWS = soa::Join<aod::ChargedEventWiseSubtractedJets, aod::ChargedEventWiseSubtractedJetConstituents>;
87+
8088 // Slices for access to proper HF MCD jet collision that is associated to MCCollision
8189 PresliceUnsorted<aod::JetCollisionsMCD> collisionsPerMCCollisionPreslice = aod::jmccollisionlb::mcCollisionId;
90+
8291 Preslice<DsMCDJets> dsMCDJetsPerEXPCollisionPreslice = aod::jet::collisionId;
92+ // Preslice<DsMCDJetsEWS> dsMCDJetsEWSPerEXPCollisionPreslice = aod::jet::collisionId;
93+
8394 Preslice<DsMCPJets> dsMCPJetsPerMCCollisionPreslice = aod::jet::mcCollisionId;
95+ // Preslice<DsMCPJetsEWS> dsMCPJetsEWSPerMCCollisionPreslice = aod::jet::mcCollisionId;
8496
85- // Configurables
97+ // Event configurables
8698 Configurable<float > vertexZCut{" vertexZCut" , 10 .0f , " Accepted z-vertex range" };
8799 Configurable<float > jetPtMin{" jetPtMin" , 5.0 , " minimum jet pT cut" };
88100 Configurable<float > jetR{" jetR" , 0.4 , " jet resolution parameter" };
89101
90102 Configurable<std::string> eventSelections{" eventSelections" , " sel8" , " choose event selection" };
91103 Configurable<std::string> trackSelections{" trackSelections" , " globalTracks" , " set track selections" };
92104
105+ // Event-wise constituent subtraction jet tables
106+ Configurable<float > centralityMin{" centralityMin" , -999 .f , " Minimum FT0M centrality" };
107+ Configurable<float > centralityMax{" centralityMax" , 999 .f , " Maximum FT0M centrality" };
108+
93109 // internals
94110 std::vector<int > eventSelectionBits;
95111 int trackSelection = -1 ;
@@ -103,6 +119,19 @@ struct JetDsSpecSubs {
103119 using FilteredDsMCDJets = soa::Filtered<DsMCDJets>;
104120 using FilteredDsMCPJets = soa::Filtered<DsMCPJets>;
105121
122+ using FilteredDsDataJetsEWS = soa::Filtered<DsDataJetsEWS>;
123+ // using FilteredDsMCDJetsEWS = soa::Filtered<DsMCDJetsEWS>;
124+ // using FilteredDsMCPJetsEWS = soa::Filtered<DsMCPJetsEWS>;
125+
126+ // Filtered inclusive charged jets
127+ using FilteredChargedJets = soa::Filtered<ChargedJets>;
128+ using FilteredChargedJetsEWS = soa::Filtered<ChargedJetsEWS>;
129+
130+ Filter collisionFilter =
131+ nabs (aod::jcollision::posZ) < vertexZCut &&
132+ aod::jcollision::centFT0M >= centralityMin &&
133+ aod::jcollision::centFT0M < centralityMax;
134+
106135 // =============
107136 // Histograms
108137 // =============
@@ -112,10 +141,19 @@ struct JetDsSpecSubs {
112141 {
113142 {" h_collisions" , " event status;event status;entries" , {HistType::kTH1F , {{10 , 0.0 , 10.0 }}}},
114143 {" h_event_counter_data" , " ;Selection step;Events" , {HistType::kTH1F , {{3 , 0.5 , 3.5 }}}},
115-
144+ // Track QA
116145 {" h_track_pt" , " ;#it{p}_{T,track};entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
117146 {" h_track_eta" , " ;#eta_{track};entries" , {HistType::kTH1F , {{100 , -1 ., 1 .}}}},
118147 {" h_track_phi" , " ;#varphi_{track};entries" , {HistType::kTH1F , {{80 , -1 ., 7 .}}}},
148+ // Inclusive jet QA
149+ {" h_njets_inclusive" , " ;Number of charged jets per event;Events" , {HistType::kTH1F , {{100 , 0 ., 100 .}}}},
150+ {" h_jet_pt_inclusive" , " ;#it{p}_{T,jet} (GeV/#it{c});Entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
151+ {" h_jet_eta_inclusive" , " ;#eta_{jet};Entries" , {HistType::kTH1F , {{100 , -1 ., 1 .}}}},
152+ {" h_jet_phi_inclusive" , " ;#varphi_{jet} (rad);Entries" , {HistType::kTH1F , {{80 , -1 ., 7 .}}}},
153+ {" h_jet_mass_inclusive" , " ;#it{m}_{jet} (GeV/#it{c}^{2});Entries" , {HistType::kTH1F , {{120 , 0 ., 60 .}}}},
154+ {" h_jet_nconst_inclusive" , " ;Jet constituents;Entries" , {HistType::kTH1F , {{100 , 0 ., 100 .}}}},
155+ {" h_lambda11_inclusive" , " ;#lambda_{1}^{1};Entries" , {HistType::kTH1F , {{100 , 0 ., 1 .}}}},
156+ {" h_lambda21_inclusive" , " ;#lambda_{2}^{1};Entries" , {HistType::kTH1F , {{100 , 0 ., 1 .}}}},
119157
120158 // Data histograms
121159 {" h_jet_pt_data" , " jet pT;#it{p}_{T,jet} (GeV/#it{c});entries" , {HistType::kTH1F , {{200 , 0 ., 200 .}}}},
@@ -131,7 +169,7 @@ struct JetDsSpecSubs {
131169 {" h_ds_jet_distance_data" , " ;#DeltaR_{D_{S},jet};entries" , {HistType::kTH1F , {{200 , 0 ., 1 .}}}},
132170 {" h_ds_jet_mass_data" , " ;m_{jet}^{ch} (GeV/#it{c}^{2});entries" , {HistType::kTH1F , {{300 , 0 ., 25 .}}}},
133171 {" h_ds_jet_lambda11_data" , " ;#lambda_{1}^{1};entries" , {HistType::kTH1F , {{100 , 0 ., 1.0 }}}},
134- {" h_ds_jet_lambda12_data " , " ;#lambda_{2}^{1};entries" , {HistType::kTH1F , {{100 , 0 ., 1.0 }}}},
172+ {" h_ds_jet_lambda21_data " , " ;#lambda_{2}^{1};entries" , {HistType::kTH1F , {{100 , 0 ., 1.0 }}}},
135173
136174 {" hSparse_ds_data" , " ;m_{D_{S}};#it{p}_{T,D_{S}};#it{p}_{T,jet};z^{D_{S},jet}_{||};#DeltaR_{D_{S},jet}" , {HistType::kTHnSparseF , {{60 , 1.6 , 2.3 }, {60 , 0 ., 80 .}, {60 , 0 ., 100 .}, {20 , 0 ., 1.2 }, {20 , 0 ., 1.0 }}}},
137175
@@ -167,7 +205,7 @@ struct JetDsSpecSubs {
167205 {" h_ds_phi_mcp" , " ;#phi_{D_{S} jet}^{part};entries" , {HistType::kTH1F , {{80 , -1 ., 7 .}}}},
168206
169207 // MCP - Sparse: p_{T,Ds}, p_{T,jet}, z|| and DeltaR
170- {" hSparse_ds_mcp" , " ;#it{p}_{T,D_{S}}^{part};#it{p}_{T,jet}^{part};z^{D_{S},jet}_{||, part};#DeltaR_{D_{S},jet}^{part}" , {HistType::kTHnSparseF , {{60 , 0 ., 80 .}, {60 , 0 ., 100 .}, {20 , 0 ., 1.2 }, {20 , 0 ., 1.0 }}}},
208+ {" hSparse_ds_mcp" , " ;#it{p}_{T,D_{S}}^{part};#it{p}_{T,jet}^{part};z^{D_{S},jet}_{||, part};#DeltaR_{D_{S},jet}^{part};Origin(D_{S};Matching status) " , {HistType::kTHnSparseF , {{60 , 0 ., 80 .}, {60 , 0 ., 100 .}, {20 , 0 ., 1.2 }, {20 , 0 ., 1.0 }, { 2 , - 0.5 , 1.5 }, { 2 , - 0.5 , 1.5 }}}},
171209 }};
172210 // ========
173211 // INIT
@@ -193,13 +231,22 @@ struct JetDsSpecSubs {
193231 auto jetCounter = registry.get <TH1 >(HIST (" McEffJet" ));
194232 jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::ParticleLevelJetInMCCollision, " particle level" );
195233 jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::DetectorLevelJetInMCCollision, " detector level" );
196- jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::DetectorLevelJetWithMatchedCandidate, " particle matched jets" );
197- jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::ParticleLevelJetWithMatchedCandidate, " detector matched jets" );
234+ jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::DetectorLevelJetWithMatchedCandidate, " detector matched jets" );
235+ jetCounter->GetXaxis ()->SetBinLabel (BinMCJetCntr::ParticleLevelJetWithMatchedCandidate, " particle matched jets" );
198236
199237 auto hSparse_ds_mcd1 = registry.get <THnSparse>(HIST (" hSparse_ds_mcd1" ));
200238 auto * axisOrigin = hSparse_ds_mcd1->GetAxis (4 );
201239 axisOrigin->SetBinLabel (1 , " Prompt" );
202240 axisOrigin->SetBinLabel (2 , " Non-prompt" );
241+
242+ auto hSparse_ds_mcp = registry.get <THnSparse>(HIST (" hSparse_ds_mcp" ));
243+ auto * axisOriginMCP = hSparse_ds_mcp->GetAxis (4 );
244+ axisOriginMCP->SetBinLabel (1 , " Prompt" );
245+ axisOriginMCP->SetBinLabel (2 , " Non-prompt" );
246+
247+ auto * axisMatching = hSparse_ds_mcp->GetAxis (5 );
248+ axisMatching->SetBinLabel (1 , " Unmatched" );
249+ axisMatching->SetBinLabel (2 , " Matched" );
203250 }
204251 // ===============
205252 // Lambda compute
@@ -259,35 +306,76 @@ struct JetDsSpecSubs {
259306 // Collision QA
260307 // ==============
261308
262- void processCollisions (aod::JetCollision const & collision, aod::JetTracks const & tracks)
309+ // This function is shared by the pp and Pb–Pb (event-wise subtraction)
310+ template <typename JetTable>
311+ void fillInclusiveJetQA (aod::JetCollision const & collision,
312+ aod::JetTracks const & tracks,
313+ JetTable const & jets)
263314 {
264- registry.fill (HIST (" h_collisions" ), 0.5 );
315+ // Collision counter
316+ registry.fill (HIST (" h_collisions" ), getValFromBin (AllCollisions));
265317
266318 if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits)) {
267319 return ;
268320 }
321+ registry.fill (HIST (" h_collisions" ), getValFromBin (Sel8ZCut));
269322
270- registry.fill (HIST (" h_collisions" ), 1.5 );
271-
323+ // Track QA
272324 for (auto const & track : tracks) {
273-
274325 if (!jetderiveddatautilities::selectTrack (track, trackSelection)) {
275- return ;
326+ continue ;
276327 }
277328
278329 registry.fill (HIST (" h_track_pt" ), track.pt ());
279330 registry.fill (HIST (" h_track_eta" ), track.eta ());
280331 registry.fill (HIST (" h_track_phi" ), track.phi ());
281332 }
333+
334+ // Inclusive charged-jet QA
335+ registry.fill (HIST (" h_njets_inclusive" ), jets.size ());
336+
337+ for (auto const & jet : jets) {
338+
339+ registry.fill (HIST (" h_jet_pt_inclusive" ), jet.pt ());
340+ registry.fill (HIST (" h_jet_eta_inclusive" ), jet.eta ());
341+ registry.fill (HIST (" h_jet_phi_inclusive" ), jet.phi ());
342+
343+ auto constituents = jet.template tracks_as <aod::JetTracks>();
344+
345+ registry.fill (HIST (" h_jet_nconst_inclusive" ), constituents.size ());
346+
347+ registry.fill (HIST (" h_jet_mass_inclusive" ), computeJetMass (constituents));
348+ registry.fill (HIST (" h_lambda11_inclusive" ), computeLambda (jet, constituents, 1 .f , 1 .f ));
349+ registry.fill (HIST (" h_lambda21_inclusive" ), computeLambda (jet, constituents, 2 .f , 1 .f ));
350+ }
351+ }
352+ // Inclusive charged-jet QA for pp collisions
353+ void processCollisions (aod::JetCollision const & collision,
354+ aod::JetTracks const & tracks,
355+ FilteredChargedJets const & jets)
356+ {
357+ fillInclusiveJetQA (collision, tracks, jets);
282358 }
283359 PROCESS_SWITCH (JetDsSpecSubs, processCollisions, " collision QA" , false );
360+ // Inclusive charged-jet QA for Pb–Pb collisions using
361+ // event-wise constituent-subtracted jets
362+ void processCollisionsEWS (aod::JetCollision const & collision,
363+ aod::JetTracks const & tracks,
364+ FilteredChargedJetsEWS const & jets)
365+ {
366+ fillInclusiveJetQA (collision, tracks, jets);
367+ }
368+ PROCESS_SWITCH (JetDsSpecSubs, processCollisionsEWS, " collision QA EWS" , false );
284369
285- // ==============
286- // DATA process
287- // ==============
370+ // =====================================================================================
371+ // DATA function
372+ // =====================================================================================
288373
289- void processDataChargedSubstructure (aod::JetCollision const & collision, FilteredDsDataJets const & jets,
290- aod::CandidatesDsData const &, aod::JetTracks const &)
374+ // Common implementation of the Ds-in-jet analysis for data
375+ // Shared by the pp and Pb–Pb (event-wise subtraction) workflows
376+ template <typename JetTable>
377+ void analyseDataDsJet (aod::JetCollision const & collision,
378+ JetTable const & jets)
291379 {
292380 registry.fill (HIST (" h_event_counter_data" ), 1 );
293381
@@ -307,17 +395,17 @@ struct JetDsSpecSubs {
307395 registry.fill (HIST (" h_jet_eta_data" ), jet.eta ());
308396 registry.fill (HIST (" h_jet_phi_data" ), jet.phi ());
309397
310- auto jetTracks = jet.tracks_as <aod::JetTracks>();
398+ auto jetTracks = jet.template tracks_as <aod::JetTracks>();
311399
312400 const float lambda11 = computeLambda (jet, jetTracks, 1 .f , 1 .f );
313- const float lambda12 = computeLambda (jet, jetTracks, 2 .f , 1 .f );
401+ const float lambda21 = computeLambda (jet, jetTracks, 2 .f , 1 .f );
314402
315403 const float mjet = computeJetMass (jetTracks);
316404
317405 TVector3 jetVector (jet.px (), jet.py (), jet.pz ());
318406
319- // Loop over Ds candidates (particle level)
320- for (const auto & dsCandidate : jet.candidates_as <aod::CandidatesDsData>()) {
407+ // Loop over Ds candidates
408+ for (const auto & dsCandidate : jet.template candidates_as <aod::CandidatesDsData>()) {
321409
322410 TVector3 dsVector (dsCandidate.px (), dsCandidate.py (), dsCandidate.pz ());
323411
@@ -333,7 +421,6 @@ struct JetDsSpecSubs {
333421 registry.fill (HIST (" h_ds_phi_data" ), dsCandidate.phi ());
334422
335423 registry.fill (HIST (" h_ds_jet_projection_data" ), zParallel);
336-
337424 registry.fill (HIST (" h_ds_jet_distance_data" ), deltaR);
338425
339426 // Main THnSparse: invariant mass, pT, z, and DeltaR
@@ -345,39 +432,62 @@ struct JetDsSpecSubs {
345432 deltaR);
346433 }
347434
348- if (!jet.candidates_as <aod::CandidatesDsData>().empty ()) {
349- // Jet mass
435+ if (!jet.template candidates_as <aod::CandidatesDsData>().empty ()) {
436+ // Jet Mass
350437 registry.fill (HIST (" h_ds_jet_mass_data" ), mjet);
351438
352439 // Jet angularity
353440 if (lambda11 >= 0 .f ) {
354441 registry.fill (HIST (" h_ds_jet_lambda11_data" ), lambda11);
355442 }
356- if (lambda12 >= 0 .f ) {
357- registry.fill (HIST (" h_ds_jet_lambda12_data " ), lambda12 );
443+ if (lambda21 >= 0 .f ) {
444+ registry.fill (HIST (" h_ds_jet_lambda21_data " ), lambda21 );
358445 }
359446 }
360447 }
361448 }
449+
450+ // =====================================================================================
451+ // DATA process
452+ // =====================================================================================
453+
454+ // Data analysis using standard charged jets (pp)
455+ void processDataChargedSubstructure (aod::JetCollision const & collision,
456+ FilteredDsDataJets const & jets,
457+ aod::CandidatesDsData const &,
458+ aod::JetTracks const &)
459+ {
460+ analyseDataDsJet (collision, jets);
461+ }
362462 PROCESS_SWITCH (JetDsSpecSubs, processDataChargedSubstructure, " Data charged jets" , false );
363463
364- // ==============
464+ // Data analysis using event-wise constituent-subtracted charged jets (Pb–Pb)
465+ void processDataChargedSubstructureEWS (aod::JetCollision const & collision,
466+ FilteredDsDataJetsEWS const & jets,
467+ aod::CandidatesDsData const &,
468+ aod::JetTracks const &)
469+ {
470+ analyseDataDsJet (collision, jets);
471+ }
472+ PROCESS_SWITCH (JetDsSpecSubs, processDataChargedSubstructureEWS, " Data charged jets EWS" , false );
473+
474+ // =====================================================================================
365475 // MC function
366- // ==============
367- template <typename MCDJetsPerMCCollissionPreslice ,
368- typename MCPJetsPerMCCollissionPreslice ,
369- typename DsMCDJets ,
370- typename DsMCPJets ,
476+ // =====================================================================================
477+ template <typename MCDJetsPerCollisionPreslice ,
478+ typename MCPJetsPerCollisionPreslice ,
479+ typename MCDJetTable ,
480+ typename MCPJetTable ,
371481 typename DsCandidatesMCD,
372482 typename DsCandidatesMCP>
373- void analyseMonteCarloEfficiency (MCDJetsPerMCCollissionPreslice const & jetmcdpreslice,
374- MCPJetsPerMCCollissionPreslice const & jetmcppreslice,
483+ void analyseMonteCarloEfficiency (MCDJetsPerCollisionPreslice const & jetmcdpreslice,
484+ MCPJetsPerCollisionPreslice const & jetmcppreslice,
375485 aod::JetMcCollisions const & mccollisions,
376486 aod::JetCollisionsMCD const & collisions,
377- FilteredDsMCDJets const & mcdjets,
378- FilteredDsMCPJets const & mcpjets,
379- DsCandidatesMCD const & /* mcdCandidates */ ,
380- DsCandidatesMCP const & /* mcpCandidates */ )
487+ MCDJetTable const & mcdjets,
488+ MCPJetTable const & mcpjets,
489+ DsCandidatesMCD const &,
490+ DsCandidatesMCP const &)
381491 {
382492 for (const auto & mccollision : mccollisions) {
383493 // Count all generated MC collisions
@@ -469,6 +579,12 @@ struct JetDsSpecSubs {
469579 // obtain leading HF particle in jet
470580 auto mcpDscand = mcpjet.template candidates_first_as <DsCandidatesMCP>();
471581
582+ // Check if it's prompt 0 prompt, 1 non-prompt
583+ int originMCP = (mcpDscand.originMcGen () != RecoDecay::OriginType::Prompt) ? 1 : 0 ;
584+
585+ // Matching status: 1 if the particle-level jet has a detector-level partner, 0 otherwise
586+ int isMatched = mcpjet.has_matchedJetCand () ? 1 : 0 ;
587+
472588 if (mcpjet.has_matchedJetCand ()) {
473589 registry.fill (HIST (" McEffJet" ), getValFromBin (BinMCJetCntr::ParticleLevelJetWithMatchedCandidate));
474590 }
@@ -490,19 +606,22 @@ struct JetDsSpecSubs {
490606 registry.fill (HIST (" h_ds_eta_mcp" ), mcpDscand.eta ());
491607 registry.fill (HIST (" h_ds_phi_mcp" ), mcpDscand.phi ());
492608
493- // Main THnSparse: invariant mass, pT, z, and DeltaR
609+ // Main THnSparse: invariant mass, pT, z, DeltaR , and origin (prompt/non-prompt)
494610 registry.fill (HIST (" hSparse_ds_mcp" ),
495611 mcpDscand.pt (),
496612 mcpjet.pt (),
497613 mcp_zParallel,
498- mcp_deltaR);
614+ mcp_deltaR,
615+ originMCP,
616+ isMatched);
499617 }
500618 }
501619 }
502- // ==============
620+ // =====================================================================================
503621 // MC process
504- // ==============
622+ // =====================================================================================
505623
624+ // MC efficiency analysis using standard Ds-tagged jets (pp)
506625 void processMonteCarloEfficiencyDs (aod::JetMcCollisions const & mccollisions,
507626 aod::JetCollisionsMCD const & collisions,
508627 FilteredDsMCDJets const & mcdjets,
0 commit comments