1919
2020#include " PWGJE/Core/JetDerivedDataUtilities.h"
2121#include " PWGJE/Core/JetUtilities.h"
22+ #include " PWGJE/Core/JetHFUtilities.h"
2223#include " PWGJE/DataModel/Jet.h"
2324#include " PWGJE/DataModel/JetReducedData.h"
2425//
@@ -179,13 +180,17 @@ struct HfFragmentationFunction {
179180 Produces<aod::MatchJetDistanceTable> matchJetTable;
180181
181182 // Tables for MC jet matching
182- using JetMCDTable = soa::Join<aod::D0ChargedMCDetectorLevelJets, aod::D0ChargedMCDetectorLevelJetConstituents, aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets>;
183- using JetMCPTable = soa::Join<aod::D0ChargedMCParticleLevelJets, aod::D0ChargedMCParticleLevelJetConstituents, aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets>;
183+ using JetD0MCDTable = soa::Join<aod::D0ChargedMCDetectorLevelJets, aod::D0ChargedMCDetectorLevelJetConstituents, aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets>;
184+ using JetD0MCPTable = soa::Join<aod::D0ChargedMCParticleLevelJets, aod::D0ChargedMCParticleLevelJetConstituents, aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets>;
185+ using JetLcMCDTable = soa::Join<aod::LcChargedMCDetectorLevelJets, aod::LcChargedMCDetectorLevelJetConstituents, aod::LcChargedMCDetectorLevelJetsMatchedToLcChargedMCParticleLevelJets>;
186+ using JetLcMCPTable = soa::Join<aod::LcChargedMCParticleLevelJets, aod::LcChargedMCParticleLevelJetConstituents, aod::LcChargedMCParticleLevelJetsMatchedToLcChargedMCDetectorLevelJets>;
184187
185188 // slices for accessing proper HF mcdjets collision associated to mccollisions
186189 PresliceUnsorted<aod::JetCollisionsMCD> collisionsPerMCCollisionPreslice = aod::jmccollisionlb::mcCollisionId;
187- Preslice<JetMCDTable> d0MCDJetsPerCollisionPreslice = aod::jet::collisionId;
188- Preslice<JetMCPTable> d0MCPJetsPerMCCollisionPreslice = aod::jet::mcCollisionId;
190+ Preslice<JetD0MCDTable> d0MCDJetsPerCollisionPreslice = aod::jet::collisionId;
191+ Preslice<JetD0MCPTable> d0MCPJetsPerMCCollisionPreslice = aod::jet::mcCollisionId;
192+ Preslice<JetLcMCDTable> lcMCDJetsPerCollisionPreslice = aod::jet::collisionId;
193+ Preslice<JetLcMCPTable> lcMCPJetsPerMCCollisionPreslice = aod::jet::mcCollisionId;
189194
190195 // Histogram registry: an object to hold your histograms
191196 HistogramRegistry registry{" histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
@@ -282,7 +287,8 @@ struct HfFragmentationFunction {
282287
283288 } // end of jets loop
284289
285- } // end of process function
290+ } // end of analyzeData function
291+
286292 void processD0DataCharged (aod::JetCollision const & collision,
287293 soa::Join<aod::D0ChargedJets, aod::D0ChargedJetConstituents> const & jets,
288294 aod::CandidatesD0Data const & candidates,
@@ -301,8 +307,8 @@ struct HfFragmentationFunction {
301307
302308 void processMcEfficiency (aod::JetMcCollisions const & mccollisions,
303309 aod::JetCollisionsMCD const & collisions,
304- JetMCDTable const & mcdjets,
305- JetMCPTable const & mcpjets,
310+ JetD0MCDTable const & mcdjets,
311+ JetD0MCPTable const & mcpjets,
306312 aod::CandidatesD0MCD const &,
307313 aod::CandidatesD0MCP const &,
308314 aod::JetTracks const &,
@@ -389,87 +395,119 @@ struct HfFragmentationFunction {
389395 }
390396 PROCESS_SWITCH (HfFragmentationFunction, processMcEfficiency, " non-matched and matched MC HF and jets" , false );
391397
392- void processMcChargedMatched (aod::JetMcCollisions const & mccollisions,
393- aod::JetCollisionsMCD const & collisions,
394- JetMCDTable const & mcdjets,
395- JetMCPTable const &,
396- aod::CandidatesD0MCD const &,
397- aod::CandidatesD0MCP const &,
398- aod::JetTracks const &,
399- aod::JetParticles const &)
400- {
398+ template <typename TMCPJetsPerMCCollisionPreslice, typename TJetsMCD, typename TJetsMCP, typename TCandidatesMCD, typename TCandidatesMCP>
399+ void analyzeMC (TMCPJetsPerMCCollisionPreslice const & MCPJetsPerMCCollisionPreslice,
400+ aod::JetMcCollisions const & mccollisions,
401+ aod::JetCollisionsMCD const & collisions,
402+ TJetsMCD const &,
403+ TJetsMCP const & mcpjets,
404+ TCandidatesMCD const &,
405+ TCandidatesMCP const &,
406+ aod::JetTracks const &,
407+ aod::JetParticles const &) {
401408 for (const auto & mccollision : mccollisions) {
402-
403409 registry.fill (HIST (" h_collision_counter" ), 0.0 );
404-
405410 // skip collisions outside of |z| < vertexZCut
406411 if (std::abs (mccollision.posZ ()) > vertexZCut) {
407412 continue ;
408413 }
409414 registry.fill (HIST (" h_collision_counter" ), 1.0 );
410415
411- // reconstructed collisions associated to same mccollision
412- const auto collisionsPerMCCollision = collisions.sliceBy (collisionsPerMCCollisionPreslice, mccollision.globalIndex ());
413- for (const auto & collision : collisionsPerMCCollision) {
414-
415- registry.fill (HIST (" h_collision_counter" ), 2.0 );
416- if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits) || !(std::abs (collision.posZ ()) < vertexZCut)) {
417- continue ;
418- }
419- registry.fill (HIST (" h_collision_counter" ), 3.0 );
420- // d0 detector level jets associated to the current same collision
421- const auto d0mcdJetsPerCollision = mcdjets.sliceBy (d0MCDJetsPerCollisionPreslice, collision.globalIndex ());
422- for (const auto & mcdjet : d0mcdJetsPerCollision) {
423-
424- registry.fill (HIST (" h_jet_counter" ), 0.5 );
425-
426- // comparison with fill on bin on 2.5 for sanity check
427- if (mcdjet.has_matchedJetCand ()) {
428- registry.fill (HIST (" h_jet_counter" ), 1.5 );
429- }
430-
431- // obtain leading HF candidate in jet
432- auto mcdd0cand = mcdjet.candidates_first_as <aod::CandidatesD0MCD>();
433-
434- // reflection information for storage: D0 = +1, D0bar = -1, neither = 0
435- int matchedFrom = 0 ;
436- int decayChannel = o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK;
437- int selectedAs = 0 ;
416+ // hf particle level jets associated to same mccollision
417+ const auto mcpJetsPerMCCollision = mcpjets.sliceBy (MCPJetsPerMCCollisionPreslice, mccollision.globalIndex ());
418+ for (const auto & mcpjet : mcpJetsPerMCCollision) {
438419
439- if (mcdd0cand.flagMcMatchRec () == decayChannel) { // matched to D0 on truth level
440- matchedFrom = 1 ;
441- } else if (mcdd0cand.flagMcMatchRec () == -decayChannel) { // matched to D0bar on truth level
442- matchedFrom = -1 ;
443- }
444- // bitwise AND operation: Checks whether BIT(i) is set, regardless of other bits
445- if (mcdd0cand.candidateSelFlag () & BIT (0 )) { // CandidateSelFlag == BIT(0) -> selected as D0
446- selectedAs = 1 ;
447- } else if (mcdd0cand.candidateSelFlag () & BIT (1 )) { // CandidateSelFlag == BIT(1) -> selected as D0bar
448- selectedAs = -1 ;
449- }
420+ registry.fill (HIST (" h_jet_counter" ), 0.0 );
450421
451- // loop through detector level matched to current particle level
452- for ( const auto & mcpjet : mcdjet. matchedJetCand_as <JetMCPTable >()) {
422+ // obtain leading HF particle in jet
423+ auto mcpcand = mcpjet. template candidates_first_as <TCandidatesMCP >();
453424
454- registry.fill (HIST (" h_jet_counter" ), 2.5 );
425+ if (mcpjet.has_matchedJetCand ()) {
426+ registry.fill (HIST (" h_jet_counter" ), 1.0 );
427+
428+ // loop over detector level matched to current particle level
429+ for (const auto & mcdjet : mcpjet.template matchedJetCand_as <TJetsMCD>()) {
430+ registry.fill (HIST (" h_jet_counter" ), 2.0 );
431+
432+ // apply collision sel8 selection on detector level jet's collision
433+ // const auto& collision = mcdjet.get<aod::JetCollisionsMCD>();
434+ const auto & collision = collisions.iteratorAt (mcdjet.collisionId ());
435+ registry.fill (HIST (" h_collision_counter" ), 2.0 );
436+ if (!jetderiveddatautilities::selectCollision (collision, eventSelectionBits) || !(std::abs (collision.posZ ()) < vertexZCut)) {
437+ continue ;
438+ }
439+ registry.fill (HIST (" h_collision_counter" ), 3.0 );
455440
456441 // obtain leading HF candidate in jet
457- auto mcpd0cand = mcpjet.candidates_first_as <aod::CandidatesD0MCP>();
458-
442+ auto mcdcand = mcdjet.template candidates_first_as <TCandidatesMCD>();
443+
444+ // reflection information for storage: HF = +1, HFbar = -1, neither = 0
445+ int matchedFrom = 0 ;
446+ int decayChannel = 0 ;
447+ if (jethfutilities::isD0Table<TCandidatesMCD>()) {
448+ decayChannel = o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK;
449+ } else if (jethfutilities::isLcTable<TCandidatesMCD>()) {
450+ decayChannel = o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi;
451+ }
452+ int selectedAs = 0 ;
453+
454+ if (mcdcand.flagMcMatchRec () == decayChannel) { // matched to HF on truth level
455+ matchedFrom = 1 ;
456+ } else if (mcdcand.flagMcMatchRec () == -decayChannel) { // matched to HFbar on truth level
457+ matchedFrom = -1 ;
458+ }
459+ // bitwise AND operation: Checks whether BIT(i) is set, regardless of other bits
460+ if (mcdcand.candidateSelFlag () & BIT (0 )) { // CandidateSelFlag == BIT(0) -> selected as HF
461+ selectedAs = 1 ;
462+ } else if (mcdcand.candidateSelFlag () & BIT (1 )) { // CandidateSelFlag == BIT(1) -> selected as HFbar
463+ selectedAs = -1 ;
464+ }
465+
459466 // store matched particle and detector level data in one single table (calculate angular distance in eta-phi plane on the fly)
460- matchJetTable (jetutilities::deltaR (mcpjet, mcpd0cand ), mcpjet.pt (), mcpjet.eta (), mcpjet.phi (), mcpjet.tracks_as <aod::JetParticles>().size (), // particle level jet
461- mcpd0cand .pt (), mcpd0cand .eta (), mcpd0cand .phi (), mcpd0cand .y (), (mcpd0cand .originMcGen () == RecoDecay::OriginType::Prompt), // particle level D0
462- jetutilities::deltaR (mcdjet, mcdd0cand ), mcdjet.pt (), mcdjet.eta (), mcdjet.phi (), mcdjet.tracks_as <aod::JetTracks>().size (), // detector level jet
463- mcdd0cand .pt (), mcdd0cand .eta (), mcdd0cand .phi (), mcdd0cand .m (), mcdd0cand .y (), (mcdd0cand .originMcRec () == RecoDecay::OriginType::Prompt), // detector level D0
464- mcdd0cand .mlScores ()[0 ], mcdd0cand .mlScores ()[1 ], mcdd0cand .mlScores ()[2 ], // Machine Learning PID scores: background, prompt, non-prompt
465- matchedFrom, selectedAs); // D0 = +1, D0bar = -1, neither = 0
467+ matchJetTable (jetutilities::deltaR (mcpjet, mcpcand ), mcpjet.pt (), mcpjet.eta (), mcpjet.phi (), mcpjet.template tracks_as <aod::JetParticles>().size (), // particle level jet
468+ mcpcand .pt (), mcpcand .eta (), mcpcand .phi (), mcpcand .y (), (mcpcand .originMcGen () == RecoDecay::OriginType::Prompt), // particle level HF
469+ jetutilities::deltaR (mcdjet, mcdcand ), mcdjet.pt (), mcdjet.eta (), mcdjet.phi (), mcdjet.template tracks_as <aod::JetTracks>().size (), // detector level jet
470+ mcdcand .pt (), mcdcand .eta (), mcdcand .phi (), mcdcand .m (), mcdcand .y (), (mcdcand .originMcRec () == RecoDecay::OriginType::Prompt), // detector level HF
471+ mcdcand .mlScores ()[0 ], mcdcand .mlScores ()[1 ], mcdcand .mlScores ()[2 ], // Machine Learning PID scores: background, prompt, non-prompt
472+ matchedFrom, selectedAs); // HF = +1, HFbar = -1, neither = 0
466473 }
474+ } else {
475+ // store matched particle and detector level data in one single table (calculate angular distance in eta-phi plane on the fly)
476+ matchJetTable (jetutilities::deltaR (mcpjet, mcpcand), mcpjet.pt (), mcpjet.eta (), mcpjet.phi (), mcpjet.template tracks_as <aod::JetParticles>().size (), // particle level jet
477+ mcpcand.pt (), mcpcand.eta (), mcpcand.phi (), mcpcand.y (), (mcpcand.originMcGen () == RecoDecay::OriginType::Prompt), // particle level HF
478+ -2 , -2 , -2 , -2 , -2 , // detector level jet
479+ -2 , -2 , -2 , -2 , -2 , -2 , // detector level HF
480+ -2 , -2 , -2 , // Machine Learning PID scores: background, prompt, non-prompt
481+ -2 , -2 ); // HF = +1, HFbar = -1, neither = 0
467482 }
468- }
469- }
483+ } // end of mcpjets loop
484+ } // end of mccollisions loop
485+ } // end of analyzeMC function
486+
487+ void processD0MC (aod::JetMcCollisions const & mccollisions,
488+ aod::JetCollisionsMCD const & collisions,
489+ JetD0MCDTable const & mcdjets,
490+ JetD0MCPTable const & mcpjets,
491+ aod::CandidatesD0MCD const & mcdcands,
492+ aod::CandidatesD0MCP const & mcpcands,
493+ aod::JetTracks const & jettracks,
494+ aod::JetParticles const & jetparticles) {
495+ analyzeMC<Preslice<JetD0MCPTable>, JetD0MCDTable, JetD0MCPTable, aod::CandidatesD0MCD, aod::CandidatesD0MCP>(d0MCPJetsPerMCCollisionPreslice, mccollisions, collisions, mcdjets, mcpjets, mcdcands, mcpcands, jettracks, jetparticles);
470496 }
471- PROCESS_SWITCH (HfFragmentationFunction, processMcChargedMatched, " matched MC HF and jets" , false );
472-
497+ PROCESS_SWITCH (HfFragmentationFunction, processD0MC, " Store all simulated D0 jets information with matched candidate (if any found)" , false );
498+
499+ void processLcMC (aod::JetMcCollisions const & mccollisions,
500+ aod::JetCollisionsMCD const & collisions,
501+ JetLcMCDTable const & mcdjets,
502+ JetLcMCPTable const & mcpjets,
503+ aod::CandidatesLcMCD const & mcdcands,
504+ aod::CandidatesLcMCP const & mcpcands,
505+ aod::JetTracks const & jettracks,
506+ aod::JetParticles const & jetparticles) {
507+ analyzeMC<Preslice<JetLcMCPTable>, JetLcMCDTable, JetLcMCPTable, aod::CandidatesLcMCD, aod::CandidatesLcMCP>(lcMCPJetsPerMCCollisionPreslice, mccollisions, collisions, mcdjets, mcpjets, mcdcands, mcpcands, jettracks, jetparticles);
508+ }
509+ PROCESS_SWITCH (HfFragmentationFunction, processLcMC, " Store all simulated Lc jets information with matched candidate (if any found)" , false );
510+
473511};
474512
475513WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments