diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 24707fb011b..26e7b49ba8b 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -106,7 +106,7 @@ o2physics_add_dpl_workflow(task-lb-reduced o2physics_add_dpl_workflow(task-lc SOURCES taskLc.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::SGCutParHolder O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(task-lc-to-k0s-p diff --git a/PWGHF/D2H/Tasks/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index 8c391447428..5d587dcc090 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -17,6 +17,7 @@ /// \author Vít Kučera , CERN /// \author Annalena Kalteyer , GSI Darmstadt /// \author Biao Zhang , Heidelberg University +/// \author Ran Tu , Fudan University #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" @@ -30,6 +31,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include #include #include #include @@ -47,6 +49,7 @@ #include #include #include +#include #include // std::vector using namespace o2; @@ -55,6 +58,13 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_occupancy; +using namespace o2::hf_evsel; + +enum class GapType { + GapA = 0, + GapC = 1, + DoubleGap = 2, +}; /// Λc± → p± K∓ π± analysis task struct HfTaskLc { @@ -77,9 +87,15 @@ struct HfTaskLc { MlClassNonPrompt, NumberOfMlClasses }; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + + HfEventSelection hfEvSel; // event selection and monitoring HfHelper hfHelper; SliceCache cache; + Service ccdb; using Collisions = soa::Join; using CollisionsMc = soa::Join; @@ -205,13 +221,14 @@ struct HfTaskLc { {"MC/generated/prompt/hPhiGenPrompt", "MC particles (matched, prompt);#it{#Phi};entries", {HistType::kTH1F, {{100, 0., 6.3}}}}, {"MC/generated/nonprompt/hPhiGenNonPrompt", "MC particles (matched, non-prompt);#it{#Phi};entries", {HistType::kTH1F, {{100, 0., 6.3}}}}}}; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; + void init(InitContext&) { - std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessDataWithMl, doprocessDataWithMlWithFT0C, doprocessDataWithMlWithFT0M, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M, doprocessMcWithMl, doprocessMcWithMlWithFT0C, doprocessMcWithMlWithFT0M}; + std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessDataWithMl, doprocessDataWithMlWithFT0C, doprocessDataWithMlWithFT0M, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M, doprocessMcWithMl, doprocessMcWithMlWithFT0C, doprocessMcWithMlWithFT0M, doprocessDataWithMlWithUpc}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "no or more than one process function enabled! Please check your configuration!"); } - auto vbins = (std::vector)binsPt; /// mass candidate registry.add("Data/hMassVsPtVsNPvContributors", "3-prong candidates;inv. mass (p K #pi) (GeV/#it{c}^{2}); p_{T}; Number of PV contributors", {HistType::kTH3F, {{600, 1.98, 2.58}, {vbins, "#it{p}_{T} (GeV/#it{c})"}, {5000, 0., 10000.}}}); @@ -312,6 +329,12 @@ struct HfTaskLc { registry.add("MC/reconstructed/prompt/hDecLenErrSigPrompt", "3-prong candidates (matched, prompt);decay length error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("MC/reconstructed/nonprompt/hDecLenErrSigNonPrompt", "3-prong candidates (matched, non-prompt);decay length error (cm);entries", {HistType::kTH2F, {{100, 0., 1.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + qaRegistry.add("Data/fitInfo/ampFT0A_vs_ampFT0C", "FT0-A vs FT0-C amplitude;FT0-A amplitude (a.u.);FT0-C amplitude (a.u.)", {HistType::kTH2F, {{2500, 0., 250}, {2500, 0., 250}}}); + qaRegistry.add("Data/zdc/energyZNA_vs_energyZNC", "ZNA vs ZNC common energy;E_{ZNA}^{common} (a.u.);E_{ZNC}^{common} (a.u.)", {HistType::kTH2F, {{200, 0., 20}, {200, 0., 20}}}); + qaRegistry.add("Data/hUpcGapAfterSelection", "UPC gap type after selection;Gap side;Counts", {HistType::kTH1F, {{3, -0.5, 2.5}}}); + qaRegistry.get(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast(GapType::GapA) + 1, "A"); + qaRegistry.get(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast(GapType::GapC) + 1, "C"); + qaRegistry.get(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast(GapType::DoubleGap) + 1, "Double"); if (fillTHn) { const AxisSpec thnAxisMass{thnConfigAxisMass, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T}(#Lambda_{c}^{+}) (GeV/#it{c})"}; @@ -332,7 +355,7 @@ struct HfTaskLc { const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"}; const AxisSpec thnAxisProperLifetime{thnConfigAxisProperLifetime, "T_{proper} (ps)"}; - bool const isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M; + bool const isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M || doprocessDataWithMlWithUpc; bool const isMcWithMl = doprocessMcWithMl || doprocessMcWithMlWithFT0C || doprocessMcWithMlWithFT0M; bool const isDataStd = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M; bool const isMcStd = doprocessMcStd || doprocessMcStdWithFT0C || doprocessMcStdWithFT0M; @@ -382,6 +405,12 @@ struct HfTaskLc { registry.add("hnLcVarsGen", "THn for Generated Lambdac", HistType::kTHnSparseF, axesGen); } } + + hfEvSel.addHistograms(qaRegistry); // collision monitoring + + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); } /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) @@ -859,6 +888,60 @@ struct HfTaskLc { } } + template + void runAnalysisPerCollisionDataWithUpc(CollType const& collisions, + CandType const& candidates, + BCsType const& bcs, + aod::FT0s const& ft0s, + aod::FV0As const& fv0as, + aod::FDDs const& fdds + + ) + { + + for (const auto& collision : collisions) { + + uint32_t rejectionMask{0}; // 32 bits, in case new ev. selections will be added + float centrality{-1.f}; + rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, qaRegistry, bcs); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } + auto bc = collision.template bc_as(); + upchelpers::FITInfo fitInfo{}; + udhelpers::getFITinfo(fitInfo, bc, bcs, ft0s, fv0as, fdds); + + GapType gap = GapType::DoubleGap; + if (bc.has_zdc()) { + auto zdc = bc.zdc(); + qaRegistry.fill(HIST("Data/fitInfo/ampFT0A_vs_ampFT0C"), fitInfo.ampFT0A, fitInfo.ampFT0C); + qaRegistry.fill(HIST("Data/zdc/energyZNA_vs_energyZNC"), zdc.energyCommonZNA(), zdc.energyCommonZNC()); + gap = determineGapType(fitInfo.ampFT0A, fitInfo.ampFT0C, zdc.energyCommonZNA(), zdc.energyCommonZNC()); + qaRegistry.fill(HIST("Data/hUpcGapAfterSelection"), static_cast(gap)); + } + if (gap == GapType::GapA || gap == GapType::GapC) { + fillHistosData(collision, candidates); + } else { + continue; + } + } + } + + GapType determineGapType(float FT0A, float FT0C, float ZNA, float ZNC) + { + constexpr float FT0AThreshold = 100.0; + constexpr float FT0CThreshold = 50.0; + constexpr float ZDCThreshold = 1.0; + if (FT0A < FT0AThreshold && FT0C > FT0CThreshold && ZNA < ZDCThreshold && ZNC > ZDCThreshold) { + return GapType::GapA; + } + if (FT0A > FT0AThreshold && FT0C < FT0CThreshold && ZNA > ZDCThreshold && ZNC < ZDCThreshold) { + return GapType::GapC; + } + return GapType::DoubleGap; + } + /// Run the analysis on MC data /// \tparam fillMl switch to fill ML histograms template @@ -922,6 +1005,19 @@ struct HfTaskLc { } PROCESS_SWITCH(HfTaskLc, processDataWithMlWithFT0M, "Process real data with the ML method and with FT0M centrality", false); + void processDataWithMlWithUpc(soa::Join const& collisions, + aod::BcFullInfos const& bcs, + LcCandidatesMl const& selectedLcCandidatesMl, + aod::Tracks const&, + aod::FT0s const& ft0s, + aod::FV0As const& fv0as, + aod::FDDs const& fdds, + aod::Zdcs const& /*zdcs*/) + { + runAnalysisPerCollisionDataWithUpc(collisions, selectedLcCandidatesMl, bcs, ft0s, fv0as, fdds); + } + PROCESS_SWITCH(HfTaskLc, processDataWithMlWithUpc, "Process real data with the ML method with UPC", false); + void processMcStd(CollisionsMc const& collisions, LcCandidatesMc const& selectedLcCandidatesMc, McParticles3ProngMatched const& mcParticles,