Skip to content

Commit 2f3ee94

Browse files
authored
[PWGHF] add more UPC infos in taskLc.cxx (#14007)
1 parent 3e96d82 commit 2f3ee94

File tree

1 file changed

+105
-39
lines changed

1 file changed

+105
-39
lines changed

PWGHF/D2H/Tasks/taskLc.cxx

Lines changed: 105 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "PWGHF/DataModel/CandidateSelectionTables.h"
3030
#include "PWGHF/DataModel/TrackIndexSkimmingTables.h"
3131
#include "PWGHF/Utils/utilsEvSelHf.h"
32+
#include "PWGHF/Utils/utilsUpcHf.h"
3233
#include "PWGUD/Core/UPCHelpers.h"
3334

3435
#include "Common/Core/RecoDecay.h"
@@ -67,6 +68,7 @@ using namespace o2::framework::expressions;
6768
using namespace o2::hf_centrality;
6869
using namespace o2::hf_occupancy;
6970
using namespace o2::hf_evsel;
71+
using namespace o2::analysis::hf_upc;
7072

7173
/// Λc± → p± K∓ π± analysis task
7274
struct HfTaskLc {
@@ -84,7 +86,8 @@ struct HfTaskLc {
8486
Configurable<std::string> ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"};
8587
Configurable<std::string> ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"};
8688

87-
HfEventSelection hfEvSel; // event selection and monitoring
89+
HfEventSelection hfEvSel; // event selection and monitoring
90+
HfUpcGapThresholds upcThresholds; // UPC gap determination thresholds
8891
SliceCache cache;
8992
Service<o2::ccdb::BasicCCDBManager> ccdb;
9093

@@ -121,7 +124,11 @@ struct HfTaskLc {
121124
ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Number of PV contributors"};
122125
ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {14, 0, 14000}, "axis for centrality"};
123126
ConfigurableAxis thnConfigAxisProperLifetime{"thnConfigAxisProperLifetime", {200, 0, 2}, "Proper lifetime, ps"};
124-
127+
ConfigurableAxis thnConfigAxisGapType{"thnConfigAxisGapType", {7, -1.5, 5.5}, "axis for UPC gap type (see TrueGap enum in o2::aod::sgselector)"};
128+
ConfigurableAxis thnConfigAxisFT0{"thnConfigAxisFT0", {1001, -1.5, 999.5}, "axis for FT0 amplitude (a.u.)"};
129+
ConfigurableAxis thnConfigAxisFV0A{"thnConfigAxisFV0A", {2001, -1.5, 1999.5}, "axis for FV0-A amplitude (a.u.)"};
130+
ConfigurableAxis thnConfigAxisFDD{"thnConfigAxisFDD", {200, 0., 4000.}, "axis for FDD amplitude (a.u.)"};
131+
ConfigurableAxis thnConfigAxisZN{"thnConfigAxisZN", {510, -1.5, 49.5}, "axis for ZN energy (a.u.)"};
125132
HistogramRegistry registry{"registry", {}};
126133
HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject};
127134

@@ -145,12 +152,6 @@ struct HfTaskLc {
145152
NonPrompt
146153
};
147154

148-
enum class GapType {
149-
GapA = 0,
150-
GapC = 1,
151-
DoubleGap = 2,
152-
};
153-
154155
void init(InitContext&)
155156
{
156157
const std::array<bool, 14> doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessDataWithMl, doprocessDataWithMlWithFT0C, doprocessDataWithMlWithFT0M, doprocessDataWithMlWithUpc, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M, doprocessMcWithMl, doprocessMcWithMlWithFT0C, doprocessMcWithMlWithFT0M, doprocessDataStdWithUpc};
@@ -265,10 +266,7 @@ struct HfTaskLc {
265266
if (isUpc) {
266267
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, {{1500, 0., 1500}, {1500, 0., 1500}}});
267268
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}}});
268-
qaRegistry.add("Data/hUpcGapAfterSelection", "UPC gap type after selection;Gap side;Counts", {HistType::kTH1F, {{3, -0.5, 2.5}}});
269-
qaRegistry.get<TH1>(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast<int>(GapType::GapA) + 1, "A");
270-
qaRegistry.get<TH1>(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast<int>(GapType::GapC) + 1, "C");
271-
qaRegistry.get<TH1>(HIST("Data/hUpcGapAfterSelection"))->GetXaxis()->SetBinLabel(static_cast<int>(GapType::DoubleGap) + 1, "Double");
269+
qaRegistry.add("Data/hUpcGapAfterSelection", "UPC gap type after selection;Gap side;Counts", {HistType::kTH1F, {{7, -1.5, 5.5}}});
272270
}
273271
if (fillTHn) {
274272
const AxisSpec thnAxisMass{thnConfigAxisMass, "inv. mass (p K #pi) (GeV/#it{c}^{2})"};
@@ -289,26 +287,40 @@ struct HfTaskLc {
289287
const AxisSpec thnAxisTracklets{thnConfigAxisNumPvContr, "Number of PV contributors"};
290288
const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"};
291289
const AxisSpec thnAxisProperLifetime{thnConfigAxisProperLifetime, "T_{proper} (ps)"};
290+
const AxisSpec thnAxisGapType{thnConfigAxisGapType, "Gap type"};
291+
const AxisSpec thnAxisFT0A{thnConfigAxisFT0, "FT0-A amplitude"};
292+
const AxisSpec thnAxisFT0C{thnConfigAxisFT0, "FT0-C amplitude"};
293+
const AxisSpec thnAxisFV0A{thnConfigAxisFV0A, "FV0-A amplitude"};
294+
const AxisSpec thnAxisFDDA{thnConfigAxisFDD, "FDD-A amplitude"};
295+
const AxisSpec thnAxisFDDC{thnConfigAxisFDD, "FDD-C amplitude"};
296+
const AxisSpec thnAxisZNA{thnConfigAxisZN, "ZNA energy"};
297+
const AxisSpec thnAxisZNC{thnConfigAxisZN, "ZNC energy"};
292298

293299
bool const isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M || doprocessDataWithMlWithUpc;
294300
bool const isMcWithMl = doprocessMcWithMl || doprocessMcWithMlWithFT0C || doprocessMcWithMlWithFT0M;
295301
bool const isDataStd = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M || doprocessDataStdWithUpc;
296302
bool const isMcStd = doprocessMcStd || doprocessMcStdWithFT0C || doprocessMcStdWithFT0M;
297303

298-
std::vector<AxisSpec> axesStd, axesWithBdt, axesGen;
304+
std::vector<AxisSpec> axesStd, axesWithBdt, axesGen, axesUpc, axesUpcWithBdt;
299305

300-
if (isDataStd) {
306+
if (isDataStd && !isUpc) {
301307
axesStd = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets};
302308
}
309+
if (isDataStd && isUpc) {
310+
axesUpc = {thnAxisMass, thnAxisPt, thnAxisRapidity, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets, thnAxisGapType, thnAxisFT0A, thnAxisFT0C, thnAxisFV0A, thnAxisFDDA, thnAxisFDDC, thnAxisZNA, thnAxisZNC};
311+
}
303312
if (isMcStd) {
304313
axesStd = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
305314
}
306315
if (isMcStd || isMcWithMl) {
307316
axesGen = {thnAxisPt, thnAxisCentrality, thnAxisY, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
308317
}
309-
if (isDataWithMl) {
318+
if (isDataWithMl && !isUpc) {
310319
axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets};
311320
}
321+
if (isDataWithMl && isUpc) {
322+
axesUpcWithBdt = {thnAxisMass, thnAxisPt, thnAxisRapidity, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisGapType, thnAxisFT0A, thnAxisFT0C, thnAxisFV0A, thnAxisFDDA, thnAxisFDDC, thnAxisZNA, thnAxisZNC};
323+
}
312324
if (isMcWithMl) {
313325
axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisPtB, thnAxisCanType};
314326
}
@@ -327,8 +339,13 @@ struct HfTaskLc {
327339
}
328340
}
329341
}
330-
331-
if (isDataWithMl) {
342+
if (isUpc) {
343+
if (isDataStd) {
344+
registry.add("hnLcUpcVars", "THn for Lambdac candidates for Data in UPC", HistType::kTHnSparseF, axesUpc);
345+
} else if (isDataWithMl) {
346+
registry.add("hnLcUpcVarsWithBdt", "THn for Lambdac candidates with BDT scores for data in UPC", HistType::kTHnSparseF, axesUpcWithBdt);
347+
}
348+
} else if (isDataWithMl) {
332349
registry.add("hnLcVarsWithBdt", "THn for Lambdac candidates with BDT scores for data with ML", HistType::kTHnSparseF, axesWithBdt);
333350
} else if (isMcWithMl) {
334351
registry.add("hnLcVarsWithBdt", "THn for Lambdac candidates with BDT scores for mc with ML", HistType::kTHnSparseF, axesWithBdt);
@@ -727,36 +744,85 @@ struct HfTaskLc {
727744
/// at least one event selection not satisfied --> reject the candidate
728745
continue;
729746
}
747+
const auto thisCollId = collision.globalIndex();
748+
const auto& groupedLcCandidates = candidates.sliceBy(candLcPerCollision, thisCollId);
749+
const auto numPvContributors = collision.numContrib();
730750
const auto& bc = collision.template bc_as<BCsType>();
751+
752+
// Determine gap type using SGSelector with BC range checking
753+
const auto gapResult = hf_upc::determineGapType(collision, bcs, upcThresholds);
754+
const int gap = gapResult.value;
755+
756+
// Use the BC with FIT activity if available from SGSelector
757+
auto bcForUPC = bc;
758+
if (gapResult.bc) {
759+
bcForUPC = *(gapResult.bc);
760+
}
761+
762+
// Get FIT information from the UPC BC
731763
upchelpers::FITInfo fitInfo{};
732-
udhelpers::getFITinfo(fitInfo, bc, bcs, ft0s, fv0as, fdds);
764+
udhelpers::getFITinfo(fitInfo, bcForUPC, bcs, ft0s, fv0as, fdds);
765+
766+
// Get ZDC energies if available (extract once and reuse)
767+
const bool hasZdc = bcForUPC.has_zdc();
768+
float zdcEnergyZNA = -1.f;
769+
float zdcEnergyZNC = -1.f;
733770

734-
GapType gap = GapType::DoubleGap;
735-
if (bc.has_zdc()) {
736-
const auto zdc = bc.zdc();
771+
if (hasZdc) {
772+
const auto zdc = bcForUPC.zdc();
773+
zdcEnergyZNA = zdc.energyCommonZNA();
774+
zdcEnergyZNC = zdc.energyCommonZNC();
737775
qaRegistry.fill(HIST("Data/fitInfo/ampFT0A_vs_ampFT0C"), fitInfo.ampFT0A, fitInfo.ampFT0C);
738-
qaRegistry.fill(HIST("Data/zdc/energyZNA_vs_energyZNC"), zdc.energyCommonZNA(), zdc.energyCommonZNC());
739-
gap = determineGapType(fitInfo.ampFT0A, fitInfo.ampFT0C, zdc.energyCommonZNA(), zdc.energyCommonZNC());
776+
qaRegistry.fill(HIST("Data/zdc/energyZNA_vs_energyZNC"), zdcEnergyZNA, zdcEnergyZNC);
740777
qaRegistry.fill(HIST("Data/hUpcGapAfterSelection"), static_cast<int>(gap));
741778
}
742-
if (gap == GapType::GapA || gap == GapType::GapC) {
743-
fillHistosData<FillMl>(collision, candidates);
744-
}
745-
}
746-
}
779+
for (const auto& candidate : groupedLcCandidates) {
780+
if (!(candidate.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) {
781+
continue;
782+
}
783+
if (yCandRecoMax >= 0. && std::abs(HfHelper::yLc(candidate)) > yCandRecoMax) {
784+
continue;
785+
}
786+
const auto pt = candidate.pt();
787+
const auto ptProng0 = candidate.ptProng0();
788+
const auto ptProng1 = candidate.ptProng1();
789+
const auto ptProng2 = candidate.ptProng2();
790+
const auto decayLength = candidate.decayLength();
791+
const auto chi2PCA = candidate.chi2PCA();
792+
const auto cpa = candidate.cpa();
793+
const auto rapidity = std::abs(HfHelper::yLc(candidate));
747794

748-
GapType determineGapType(float FT0A, float FT0C, float ZNA, float ZNC)
749-
{
750-
constexpr float FT0AThreshold = 100.0;
751-
constexpr float FT0CThreshold = 50.0;
752-
constexpr float ZDCThreshold = 1.0;
753-
if (FT0A < FT0AThreshold && FT0C > FT0CThreshold && ZNA < ZDCThreshold && ZNC > ZDCThreshold) {
754-
return GapType::GapA;
755-
}
756-
if (FT0A > FT0AThreshold && FT0C < FT0CThreshold && ZNA > ZDCThreshold && ZNC < ZDCThreshold) {
757-
return GapType::GapC;
795+
if (fillTHn) {
796+
double outputBkg(-1), outputPrompt(-1), outputFD(-1);
797+
798+
auto fillTHnData = [&](bool isPKPi) {
799+
const auto massLc = isPKPi ? HfHelper::invMassLcToPKPi(candidate) : HfHelper::invMassLcToPiKP(candidate);
800+
801+
if constexpr (FillMl) {
802+
const auto& mlProb = isPKPi ? candidate.mlProbLcToPKPi() : candidate.mlProbLcToPiKP();
803+
if (mlProb.size() == NumberOfMlClasses) {
804+
outputBkg = mlProb[MlClassBackground]; /// bkg score
805+
outputPrompt = mlProb[MlClassPrompt]; /// prompt score
806+
outputFD = mlProb[MlClassNonPrompt]; /// non-prompt score
807+
}
808+
/// Fill the ML outputScores and variables of candidate
809+
std::vector<double> valuesToFill{massLc, pt, rapidity, outputBkg, outputPrompt, outputFD, static_cast<double>(numPvContributors), static_cast<double>(gap), static_cast<double>(fitInfo.ampFT0A), static_cast<double>(fitInfo.ampFT0C), static_cast<double>(fitInfo.ampFV0A), static_cast<double>(fitInfo.ampFDDA), static_cast<double>(fitInfo.ampFDDC), static_cast<double>(zdcEnergyZNA), static_cast<double>(zdcEnergyZNC)};
810+
registry.get<THnSparse>(HIST("hnLcUpcVarsWithBdt"))->Fill(valuesToFill.data());
811+
} else {
812+
std::vector<double> valuesToFill{massLc, pt, rapidity, ptProng0, ptProng1, ptProng2, chi2PCA, decayLength, cpa, static_cast<double>(numPvContributors), static_cast<double>(gap), static_cast<double>(fitInfo.ampFT0A), static_cast<double>(fitInfo.ampFT0C), static_cast<double>(fitInfo.ampFV0A), static_cast<double>(fitInfo.ampFDDA), static_cast<double>(fitInfo.ampFDDC), static_cast<double>(zdcEnergyZNA), static_cast<double>(zdcEnergyZNC)};
813+
registry.get<THnSparse>(HIST("hnLcUpcVars"))->Fill(valuesToFill.data());
814+
}
815+
};
816+
817+
if (candidate.isSelLcToPKPi() >= selectionFlagLc) {
818+
fillTHnData(true);
819+
}
820+
if (candidate.isSelLcToPiKP() >= selectionFlagLc) {
821+
fillTHnData(false);
822+
}
823+
}
824+
}
758825
}
759-
return GapType::DoubleGap;
760826
}
761827

762828
/// Run the analysis on MC data

0 commit comments

Comments
 (0)