Skip to content

Commit d9a1bb1

Browse files
authored
[PWGCF/FemtoUniverse] Add EfficiencyCorrection class & fix pT binning in FemtoUniverseParticleHisto (#10528)
1 parent 61b78c2 commit d9a1bb1

File tree

4 files changed

+189
-30
lines changed

4 files changed

+189
-30
lines changed

PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020
#include <map>
2121
#include <string>
22+
#include <algorithm>
2223

2324
#include "Framework/Configurable.h"
2425
#include "CCDB/BasicCCDBManager.h"
@@ -29,7 +30,7 @@ namespace o2::analysis::femto_universe::efficiency
2930
{
3031
enum ParticleNo : size_t {
3132
ONE = 1,
32-
TWO
33+
TWO,
3334
};
3435

3536
template <size_t T>
@@ -50,8 +51,8 @@ consteval auto getHistDim() -> int
5051

5152
struct EfficiencyConfigurableGroup : ConfigurableGroup {
5253
Configurable<bool> confEfficiencyApplyCorrections{"confEfficiencyApplyCorrections", false, "Should apply corrections from efficiency"};
53-
Configurable<int> confEfficiencyCCDBTrainNumber{"confEfficiencyCCDBTrainNumber", -1, "Train number for which to query CCDB objects (set to -1 to ignore)"};
54-
Configurable<std::vector<std::string>> confEfficiencyCCDBTimestamps{"confEfficiencyCCDBTimestamps", {}, "Timestamps of efficiency histograms in CCDB, to query for specific objects (default: ['-1', '-1'], gets the latest valid objects for both)"};
54+
Configurable<int> confEfficiencyCCDBTrainNumber{"confEfficiencyCCDBTrainNumber", 0, "Train number for which to query CCDB objects (set 0 to ignore)"};
55+
Configurable<std::vector<std::string>> confEfficiencyCCDBTimestamps{"confEfficiencyCCDBTimestamps", {}, "Timestamps of efficiency histograms in CCDB, to query for specific objects (default: [], set 0 to ignore, useful when running subwagons)"};
5556

5657
// NOTE: in the future we might move the below configurables to a separate struct, eg. CCDBConfigurableGroup
5758
Configurable<std::string> confCCDBUrl{"confCCDBUrl", "http://alice-ccdb.cern.ch", "CCDB URL to be used"};
@@ -73,17 +74,23 @@ class EfficiencyCalculator
7374
ccdb.setLocalObjectValidityChecking();
7475
ccdb.setFatalWhenNull(false);
7576

76-
int64_t now = duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
77+
auto now = duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
7778
ccdb.setCreatedNotAfter(now);
7879

7980
shouldApplyCorrections = config->confEfficiencyApplyCorrections;
8081

8182
if (config->confEfficiencyApplyCorrections && !config->confEfficiencyCCDBTimestamps.value.empty()) {
82-
for (const auto& timestamp : config->confEfficiencyCCDBTimestamps.value) {
83-
hLoaded.push_back(loadEfficiencyFromCCDB(std::stol(timestamp)));
83+
for (auto idx = 0UL; idx < config->confEfficiencyCCDBTimestamps.value.size(); idx++) {
84+
auto timestamp = 0L;
85+
try {
86+
timestamp = std::max(0L, std::stol(config->confEfficiencyCCDBTimestamps.value[idx]));
87+
} catch (const std::exception&) {
88+
LOGF(error, notify("Could not parse CCDB timestamp \"%s\""), config->confEfficiencyCCDBTimestamps.value[idx]);
89+
continue;
90+
}
91+
92+
hLoaded[idx] = timestamp > 0 ? loadEfficiencyFromCCDB(timestamp) : nullptr;
8493
}
85-
86-
LOGF(info, notify("Successfully loaded %d efficiency histogram(s)"), hLoaded.size());
8794
}
8895
}
8996

@@ -92,15 +99,12 @@ class EfficiencyCalculator
9299
auto getWeight(ParticleNo partNo, const BinVars&... binVars) const -> float
93100
{
94101
auto weight = 1.0f;
102+
auto hEff = hLoaded[partNo - 1];
95103

96-
if (partNo - 1 < config->confEfficiencyCCDBTimestamps.value.size()) {
97-
auto hEff = hLoaded[partNo - 1];
98-
99-
if (shouldApplyCorrections && hEff) {
100-
auto bin = hEff->FindBin(binVars...);
101-
auto eff = hEff->GetBinContent(bin);
102-
weight /= eff > 0 ? eff : 1.0f;
103-
}
104+
if (shouldApplyCorrections && hEff) {
105+
auto bin = hEff->FindBin(binVars...);
106+
auto eff = hEff->GetBinContent(bin);
107+
weight /= eff > 0 ? eff : 1.0f;
104108
}
105109

106110
return weight;
@@ -143,6 +147,7 @@ class EfficiencyCalculator
143147
LOGF(warn, notify("Histogram \"%s/%ld\" has been loaded, but it is empty"), config->confCCDBPath.value, timestamp);
144148
}
145149

150+
LOGF(info, notify("Successfully loaded %ld"), timestamp);
146151
return hEff;
147152
}
148153

@@ -151,7 +156,7 @@ class EfficiencyCalculator
151156
bool shouldApplyCorrections = false;
152157

153158
o2::ccdb::BasicCCDBManager& ccdb{o2::ccdb::BasicCCDBManager::instance()};
154-
std::vector<HistType*> hLoaded{};
159+
std::array<HistType*, 2> hLoaded{};
155160
};
156161

157162
} // namespace o2::analysis::femto_universe::efficiency
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright 2019-2022 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file FemtoUniverseEfficiencyCorrection.h
13+
/// \brief Abstraction for applying efficiency corrections based on weights from CCDB
14+
/// \author Dawid Karpiński, WUT Warsaw, dawid.karpinski@cern.ch
15+
16+
#ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCORRECTION_H_
17+
#define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCORRECTION_H_
18+
19+
#include <vector>
20+
#include <string>
21+
#include <algorithm>
22+
23+
#include "Framework/Configurable.h"
24+
#include "CCDB/BasicCCDBManager.h"
25+
#include "TH1.h"
26+
#include "TH2.h"
27+
#include "TH3.h"
28+
29+
namespace o2::analysis::femto_universe::efficiency_correction
30+
{
31+
enum ParticleNo : size_t {
32+
ONE = 1,
33+
TWO,
34+
};
35+
36+
template <size_t T>
37+
concept isOneOrTwo = T == ParticleNo::ONE || T == ParticleNo::TWO;
38+
39+
template <typename T>
40+
consteval auto getHistDim() -> int
41+
{
42+
if (std::is_same_v<T, TH1>)
43+
return 1;
44+
else if (std::is_same_v<T, TH2>)
45+
return 2;
46+
else if (std::is_same_v<T, TH3>)
47+
return 3;
48+
else
49+
return -1;
50+
}
51+
52+
struct EffCorConfigurableGroup : framework::ConfigurableGroup {
53+
framework::Configurable<bool> confEffCorApply{"confEffCorApply", false, "[Efficiency Correction] Should apply efficiency corrections"};
54+
framework::Configurable<std::string> confEffCorCCDBUrl{"confEffCorCCDBUrl", "http://alice-ccdb.cern.ch", "[Efficiency Correction] CCDB URL to use"};
55+
framework::Configurable<std::string> confEffCorCCDBPath{"confEffCorCCDBPath", "", "[Efficiency Correction] CCDB path to histograms"};
56+
framework::Configurable<std::vector<std::string>> confEffCorCCDBTimestamps{"confEffCorCCDBTimestamps", {}, "[Efficiency Correction] Timestamps of histograms in CCDB (0 can be used as a placeholder, e.g. when running subwagons)"};
57+
};
58+
59+
template <typename HistType>
60+
requires std::is_base_of_v<TH1, HistType>
61+
class EfficiencyCorrection
62+
{
63+
public:
64+
explicit EfficiencyCorrection(EffCorConfigurableGroup* config) : config(config) // o2-linter: disable=name/function-variable
65+
{
66+
}
67+
68+
auto init() -> void
69+
{
70+
ccdb.setURL(config->confEffCorCCDBUrl);
71+
ccdb.setLocalObjectValidityChecking();
72+
ccdb.setFatalWhenNull(false);
73+
74+
auto now = duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
75+
ccdb.setCreatedNotAfter(now);
76+
77+
shouldApplyCorrection = config->confEffCorApply;
78+
79+
if (shouldApplyCorrection && !config->confEffCorCCDBTimestamps.value.empty()) {
80+
for (auto idx = 0UL; idx < config->confEffCorCCDBTimestamps.value.size(); idx++) {
81+
auto timestamp = 0L;
82+
try {
83+
timestamp = std::max(0L, std::stol(config->confEffCorCCDBTimestamps.value[idx]));
84+
} catch (const std::exception&) {
85+
LOGF(error, notify("Could not parse CCDB timestamp \"%s\""), config->confEffCorCCDBTimestamps.value[idx]);
86+
continue;
87+
}
88+
89+
hLoaded[idx] = timestamp > 0 ? loadHistFromCCDB(timestamp) : nullptr;
90+
}
91+
}
92+
}
93+
94+
template <typename... BinVars>
95+
requires(sizeof...(BinVars) == getHistDim<HistType>())
96+
auto getWeight(ParticleNo partNo, const BinVars&... binVars) const -> float
97+
{
98+
auto weight = 1.0f;
99+
auto hWeights = hLoaded[partNo - 1];
100+
101+
if (shouldApplyCorrection && hWeights) {
102+
auto bin = hWeights->FindBin(binVars...);
103+
weight = hWeights->GetBinContent(bin);
104+
}
105+
106+
return weight;
107+
}
108+
109+
private:
110+
static inline auto notify(const std::string& msg) -> const std::string
111+
{
112+
return fmt::format("[EFFICIENCY CORRECTION] {}", msg);
113+
}
114+
115+
static auto isHistEmpty(HistType* hist) -> bool
116+
{
117+
if (!hist) {
118+
return true;
119+
}
120+
for (auto idx = 0; idx <= hist->GetNbinsX() + 1; idx++) {
121+
if (hist->GetBinContent(idx) > 0) {
122+
return false;
123+
}
124+
}
125+
return true;
126+
}
127+
128+
auto loadHistFromCCDB(const int64_t timestamp) const -> HistType*
129+
{
130+
auto hWeights = ccdb.getForTimeStamp<HistType>(config->confEffCorCCDBPath, timestamp);
131+
if (!hWeights || hWeights->IsZombie()) {
132+
LOGF(error, notify("Could not load histogram \"%s/%ld\""), config->confEffCorCCDBPath.value, timestamp);
133+
return nullptr;
134+
}
135+
136+
if (isHistEmpty(hWeights)) {
137+
LOGF(warn, notify("Histogram \"%s/%ld\" has been loaded, but it is empty"), config->confEffCorCCDBUrl.value, timestamp);
138+
}
139+
140+
LOGF(info, notify("Successfully loaded %ld"), timestamp);
141+
return hWeights;
142+
}
143+
144+
EffCorConfigurableGroup* config{};
145+
146+
bool shouldApplyCorrection = false;
147+
148+
o2::ccdb::BasicCCDBManager& ccdb{o2::ccdb::BasicCCDBManager::instance()};
149+
std::array<HistType*, 2> hLoaded{};
150+
};
151+
152+
} // namespace o2::analysis::femto_universe::efficiency_correction
153+
154+
#endif // PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCORRECTION_H_

PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class FemtoUniverseParticleHisto
5555
{
5656
std::string folderSuffix = static_cast<std::string>(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]).c_str();
5757
/// Histograms of the kinematic properties
58-
mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}});
58+
mHistogramRegistry->add((folderName + folderSuffix + "/hPt").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {tempFitVarpTAxis});
5959
mHistogramRegistry->add((folderName + folderSuffix + "/hEta").c_str(), "; #eta; Entries", kTH1F, {{200, -1.5, 1.5}});
6060
mHistogramRegistry->add((folderName + folderSuffix + "/hPhi").c_str(), "; #phi; Entries", kTH1F, {{200, 0, o2::constants::math::TwoPI}});
6161
mHistogramRegistry->add((folderName + folderSuffix + "/hPhiEta").c_str(), "; #phi; #eta", kTH2F, {{200, 0, o2::constants::math::TwoPI}, {200, -1.5, 1.5}});
@@ -135,7 +135,7 @@ class FemtoUniverseParticleHisto
135135
/// Particle-type specific histograms
136136
std::string folderSuffix = static_cast<std::string>(o2::aod::femtouniverse_mc_particle::MCTypeName[o2::aod::femtouniverse_mc_particle::MCType::kTruth]).c_str();
137137

138-
mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {{240, 0, 6}});
138+
mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", kTH1F, {tempFitVarpTAxis});
139139

140140
if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kTrack || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascadeBachelor || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kMCTruthTrack) {
141141
/// Track histograms

PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackExtended.cxx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h"
3434
#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h"
3535
#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h"
36-
#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h"
36+
#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCorrection.h"
3737

3838
using namespace o2;
3939
using namespace o2::analysis::femto_universe;
40-
using namespace o2::analysis::femto_universe::efficiency;
40+
using namespace o2::analysis::femto_universe::efficiency_correction;
4141
using namespace o2::framework;
4242
using namespace o2::framework::expressions;
4343
using namespace o2::soa;
@@ -177,8 +177,8 @@ struct FemtoUniversePairTaskTrackTrackExtended {
177177
HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject};
178178
HistogramRegistry mixQaRegistry{"mixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject};
179179

180-
EfficiencyConfigurableGroup effConfGroup;
181-
EfficiencyCalculator<TH1> efficiencyCalculator{&effConfGroup};
180+
EffCorConfigurableGroup effCorConfGroup;
181+
EfficiencyCorrection<TH1> effCorrection{&effCorConfGroup};
182182

183183
/// @brief Counter for particle swapping
184184
int fNeventsProcessed = 0;
@@ -328,7 +328,7 @@ struct FemtoUniversePairTaskTrackTrackExtended {
328328
hMCTruth2.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, false, tracktwofilter.confPDGCodePartTwo, false);
329329
}
330330
}
331-
efficiencyCalculator.init();
331+
effCorrection.init();
332332

333333
eventHisto.init(&qaRegistry);
334334
trackHistoPartOne.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarBins, twotracksconfigs.confIsMC, trackonefilter.confPDGCodePartOne, true); // last true = isDebug
@@ -505,9 +505,9 @@ struct FemtoUniversePairTaskTrackTrackExtended {
505505
continue;
506506
}
507507

508-
float weight = efficiencyCalculator.getWeight(ParticleNo::ONE, p1.pt());
508+
float weight = effCorrection.getWeight(ParticleNo::ONE, p1.pt());
509509
if (!confIsSame) {
510-
weight *= efficiencyCalculator.getWeight(ParticleNo::TWO, p2.pt());
510+
weight *= effCorrection.getWeight(ParticleNo::TWO, p2.pt());
511511
}
512512

513513
if (swpart)
@@ -566,9 +566,9 @@ struct FemtoUniversePairTaskTrackTrackExtended {
566566
continue;
567567
}
568568

569-
float weight = efficiencyCalculator.getWeight(ParticleNo::ONE, p1.pt());
569+
float weight = effCorrection.getWeight(ParticleNo::ONE, p1.pt());
570570
if (!confIsSame) {
571-
weight *= efficiencyCalculator.getWeight(ParticleNo::TWO, p2.pt());
571+
weight *= effCorrection.getWeight(ParticleNo::TWO, p2.pt());
572572
}
573573

574574
sameEventCont.setPair<isMC>(p1, p2, multCol, twotracksconfigs.confUse3D, weight);
@@ -674,9 +674,9 @@ struct FemtoUniversePairTaskTrackTrackExtended {
674674
}
675675
}
676676

677-
float weight = efficiencyCalculator.getWeight(ParticleNo::ONE, p1.pt());
677+
float weight = effCorrection.getWeight(ParticleNo::ONE, p1.pt());
678678
if (!confIsSame) {
679-
weight *= efficiencyCalculator.getWeight(ParticleNo::TWO, p2.pt());
679+
weight *= effCorrection.getWeight(ParticleNo::TWO, p2.pt());
680680
}
681681

682682
if (swpart)

0 commit comments

Comments
 (0)