diff --git a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx index 2bcecf4fb12..51a2474a8a9 100644 --- a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx @@ -139,7 +139,7 @@ namespace fluctuation_calculator_base { inline constexpr std::int8_t MaxOrder{8}; inline constexpr std::int32_t NExponentKeys{MaxOrder * (MaxOrder + 1) / 2}; -inline constexpr std::array, NExponentKeys> ExponentKeys{[]() constexpr -> std::array, NExponentKeys> { +inline constexpr std::array, NExponentKeys> ExponentKeys{[]() consteval noexcept -> std::array, NExponentKeys> { std::array, NExponentKeys> result{}; std::int32_t index{}; for (std::int32_t const& iExponent : std::views::iota(1, MaxOrder + 1)) { @@ -149,7 +149,7 @@ inline constexpr std::array, NExponentKeys> } return result; }()}; -inline constexpr std::int32_t NOrderKeys{[]() constexpr -> std::int32_t { +inline constexpr std::int32_t NOrderKeys{[]() consteval noexcept -> std::int32_t { std::array counts{1}; for (std::pair const& exponentKey /* o2-linter: disable=const-ref-in-for-loop */ : ExponentKeys) { const std::int32_t weight{exponentKey.first}; @@ -159,11 +159,11 @@ inline constexpr std::int32_t NOrderKeys{[]() constexpr -> std::int32_t { } return std::accumulate(counts.begin(), counts.end(), 0); }()}; -inline constexpr std::array, NOrderKeys> OrderKeys{[]() constexpr -> std::array, NOrderKeys> { +inline constexpr std::array, NOrderKeys> OrderKeys{[]() consteval noexcept -> std::array, NOrderKeys> { std::array, NOrderKeys> result{}; std::array current{}; std::int32_t index{}; - const auto fillOrderKeys{[¤t, &index, &result](const auto& self, const std::int32_t position, const std::int32_t sum, const std::int32_t target) constexpr -> void { + const auto fillOrderKeys{[¤t, &index, &result](const auto& self, const std::int32_t position, const std::int32_t sum, const std::int32_t target) consteval noexcept -> void { if (position == NExponentKeys) { if (sum == target) { result[index++] = current; @@ -182,19 +182,42 @@ inline constexpr std::array, NOrderKeys> } return result; }()}; +inline constexpr std::array>, NOrderKeys> OrderKeyProductLinks{[]() consteval noexcept -> std::array>, NOrderKeys> { + std::array>, NOrderKeys> result{}; + for (std::int32_t const& iOrderKey : std::views::iota(1, NOrderKeys)) { + result[iOrderKey].first = iOrderKey; + std::array orderKeyParent{OrderKeys[iOrderKey]}; + for (std::int32_t const& iExponentKey : std::views::iota(0, NExponentKeys) | std::views::reverse) { + const std::int8_t power{orderKeyParent[iExponentKey]}; + if (power <= 0) { + continue; + } + + orderKeyParent[iExponentKey] = {}; + for (std::int32_t const& iOrderKeyParent : std::views::iota(0, iOrderKey)) { + if (OrderKeys[iOrderKeyParent] == orderKeyParent) { + result[iOrderKey] = {iOrderKeyParent, {iExponentKey, power}}; + break; + } + } + break; + } + } + return result; +}()}; } // namespace fluctuation_calculator_base class FluctuationCalculatorTrack { public: - FluctuationCalculatorTrack() = default; - FluctuationCalculatorTrack(const FluctuationCalculatorTrack&) = default; + FluctuationCalculatorTrack() noexcept = default; + FluctuationCalculatorTrack(const FluctuationCalculatorTrack&) noexcept = default; FluctuationCalculatorTrack(FluctuationCalculatorTrack&&) noexcept = default; - FluctuationCalculatorTrack& operator=(const FluctuationCalculatorTrack&) = default; + FluctuationCalculatorTrack& operator=(const FluctuationCalculatorTrack&) noexcept = default; FluctuationCalculatorTrack& operator=(FluctuationCalculatorTrack&&) noexcept = default; - virtual ~FluctuationCalculatorTrack() = default; + virtual ~FluctuationCalculatorTrack() noexcept = default; - [[nodiscard]] std::array getProducts(const double weight = 1.) const + [[nodiscard]] std::array getProducts(const double weight = 1.) const noexcept { std::array, fluctuation_calculator_base::NExponentKeys> powersQ{}; for (std::int32_t const& iExponentKey : std::views::iota(0, fluctuation_calculator_base::NExponentKeys)) { @@ -204,22 +227,20 @@ class FluctuationCalculatorTrack } } - std::array products{}; - products.fill(weight); - for (std::int32_t const& iOrderKey : std::views::iota(0, fluctuation_calculator_base::NOrderKeys)) { - for (std::int32_t const& iExponentKey : std::views::iota(0, fluctuation_calculator_base::NExponentKeys)) { - if (const std::int32_t power{fluctuation_calculator_base::OrderKeys[iOrderKey][iExponentKey]}; power > 0) { - products[iOrderKey] *= powersQ[iExponentKey][power]; - } - } + std::array products{weight}; + for (std::int32_t const& iOrderKey : std::views::iota(1, fluctuation_calculator_base::NOrderKeys)) { + const auto& [iOrderKeyParent, factor]{fluctuation_calculator_base::OrderKeyProductLinks[iOrderKey]}; + const auto& [iExponentKey, power]{factor}; + products[iOrderKey] = products[iOrderKeyParent] * powersQ[iExponentKey][power]; } return products; } - void clear() { mQs.fill({}); } - void fill(const double charge, const double efficiency, const double weight = 1.) + void addQ(const std::int32_t exponentKeyIndex, const double q) noexcept { mQs[exponentKeyIndex] += q; } + void clear() noexcept { mQs.fill({}); } + void fill(const double charge, const double efficiency, const double weight = 1.) noexcept { const double inverseEfficiency{1. / efficiency}; - std::array powersCharge{1.}; + std::array powersCharge{weight}; std::array powersInverseEfficiency{1.}; for (std::int32_t const& exponent : std::views::iota(1, fluctuation_calculator_base::MaxOrder + 1)) { powersCharge[exponent] = powersCharge[exponent - 1] * charge; @@ -227,7 +248,7 @@ class FluctuationCalculatorTrack } for (std::int32_t const& iExponentKey : std::views::iota(0, fluctuation_calculator_base::NExponentKeys)) { const auto& [exponentCharge, exponentEfficiency]{fluctuation_calculator_base::ExponentKeys[iExponentKey]}; - mQs[iExponentKey] += weight * powersCharge[exponentCharge] * powersInverseEfficiency[exponentEfficiency]; + addQ(iExponentKey, powersCharge[exponentCharge] * powersInverseEfficiency[exponentEfficiency]); } } @@ -516,10 +537,12 @@ struct PartNumFluc { struct HolderCcdb { [[maybe_unused]] static constexpr std::int32_t NDimensionsEfficiency{4}; + const TList* lCcdb{}; std::map> runNumbersIndicesGroupIndices; - std::vector, NEs>, NEs>, NEs>> fPtMeasureDca; - std::vector>, NEs>, NEs>> hCentralityPtEtaShiftNSigmaPid; - std::vector>, NEs>, NEs>> hVzCentralityPtEtaEfficiency; + std::int32_t runGroupIndexCurrent{}; + std::array, NEs>, NEs>, NEs> fPtMeasureDca{}; + std::array>, NEs>, NEs> hCentralityPtEtaShiftNSigmaPid{}; + std::array>, NEs>, NEs> hVzCentralityPtEtaEfficiency{}; } holderCcdb{}; struct HolderMcEvent { @@ -641,7 +664,7 @@ struct PartNumFluc { } } holderDerivedData{}; - std::array, NEs>, NEs> fluctuationCalculatorTrack{}; + std::array, NEs>, NEs> fluctuationCalculatorsTrack{}; struct : ConfigurableGroup { Configurable cfgCcdbUrl{"cfgCcdbUrl", "http://ccdb-test.cern.ch:8080", "Url of CCDB"}; @@ -778,41 +801,13 @@ struct PartNumFluc { if (groupCcdb.cfgCcdbTimestampLatest.value >= 0) { ccdb->setCreatedNotAfter(groupCcdb.cfgCcdbTimestampLatest.value); } - const TList* const ccdbObject{ccdb->get(groupCcdb.cfgCcdbPath.value)}; - if (!ccdbObject || ccdbObject->IsA() != TList::Class()) { - LOG(fatal) << "Invalid CCDB object!"; - } + readCcdb(); std::int32_t nRunsBad{}; - std::int32_t nRunGroups{}; - { - const TGraph* const gRunNumberGroupIndex{dynamic_cast(ccdbObject->FindObject("gRunNumberGroupIndex"))}; - if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { - LOG(fatal) << "Invalid gRunNumberGroupIndex!"; - } - for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { - const std::int32_t runGroupIndex{static_cast(std::llrint(gRunNumberGroupIndex->GetY()[iRun]))}; - if (runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && runGroupIndex < 0)) { - ++nRunsBad; - } - nRunGroups = std::max(nRunGroups, std::abs(runGroupIndex)); - holderCcdb.runNumbersIndicesGroupIndices[std::llrint(gRunNumberGroupIndex->GetX()[iRun])] = {iRun, runGroupIndex}; - } - } - if (groupEvent.cfgFlagRejectionRunBadMc.value) { - const TGraph* const gRunNumberGroupIndex{dynamic_cast(ccdbObject->FindObject("gRunNumberGroupIndex_mc"))}; - if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { - LOG(fatal) << "Invalid gRunNumberGroupIndex_mc!"; - } - for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { - if (std::llrint(gRunNumberGroupIndex->GetY()[iRun]) <= 0) { - if (const auto iter{holderCcdb.runNumbersIndicesGroupIndices.find(std::llrint(gRunNumberGroupIndex->GetX()[iRun]))}; iter != holderCcdb.runNumbersIndicesGroupIndices.end() && iter->second.second > 0) { - iter->second.second = -iter->second.second; - if (groupEvent.cfgFlagRejectionRunBad.value) { - ++nRunsBad; - } - } - } + for (const auto& runNumberIndexGroupIndex : holderCcdb.runNumbersIndicesGroupIndices) { + const std::int32_t runGroupIndex{runNumberIndexGroupIndex.second.second}; + if (runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && runGroupIndex < 0)) { + ++nRunsBad; } } @@ -871,68 +866,6 @@ struct PartNumFluc { break; } - static constexpr auto ReadListRunGroup{[](const TList* const ccdbObject, const std::int32_t runGroupIndex) -> const TList* { - const std::string name{std::format("lRunGroup_{}", runGroupIndex)}; - const TList* const lRunGroup{dynamic_cast(ccdbObject->FindObject(name.c_str()))}; - if (!lRunGroup) { - LOG(fatal) << "Invalid " << name << "!"; - } - return lRunGroup; - }}; - - if (groupTrack.cfgFlagRecalibrationDca.value) { - LOG(info) << "Enabling DCA recalibration."; - - holderCcdb.fPtMeasureDca.resize(nRunGroups); - for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup{ReadListRunGroup(ccdbObject, iRunGroup + 1)}; - for (std::int32_t const& iDcaMeasure : std::views::iota(0, NEs)) { - for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { - for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { - std::pair& calibration{holderCcdb.fPtMeasureDca[iRunGroup][iDcaMeasure][iDcaAxis][iChargeSpecies]}; - const std::string nameFormula{std::format("fPt{}Dca{}{}{}_runGroup{}", getName(iDcaMeasure), getName(iDcaAxis), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", iRunGroup + 1)}; - calibration.first = dynamic_cast(lRunGroup->FindObject(nameFormula.c_str())); - if (!calibration.first || calibration.first->GetNdim() != 1 || calibration.first->GetNpar() <= 0) { - LOG(fatal) << "Invalid " << nameFormula << "!"; - } - LOG(info) << "Reading from CCDB: " << nameFormula << " \"" << calibration.first->GetExpFormula() << "\""; - const std::int32_t nParameters{calibration.first->GetNpar()}; - - const std::string nameHistogram{std::format("hCentralityEtaParameterPt{}Dca{}{}{}_runGroup{}", getName(iDcaMeasure), getName(iDcaAxis), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", iRunGroup + 1)}; - calibration.second = dynamic_cast(lRunGroup->FindObject(nameHistogram.c_str())); - if (calibration.second == nullptr || calibration.second->GetNbinsZ() != nParameters || std::ranges::any_of(std::views::iota(0, nParameters), [zAxis = calibration.second->GetZaxis()](const std::int32_t binIndex) -> bool { return zAxis->GetBinCenter(binIndex + 1) != binIndex; })) { - LOG(fatal) << "Invalid " << nameHistogram << "!"; - } - LOG(info) << "Reading from CCDB: " << nameHistogram; - } - } - } - } - } - - for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!static_cast(groupTrack.cfgFlagsRecalibrationNSigmaPid.value.get(iParticleSpecies))) { - continue; - } - - LOG(info) << "Enabling nSigma" << getName(iParticleSpecies) << " recalibration."; - - holderCcdb.hCentralityPtEtaShiftNSigmaPid.resize(nRunGroups); - for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup{ReadListRunGroup(ccdbObject, iRunGroup + 1)}; - for (std::int32_t const& iDetector : std::views::iota(0, NEs)) { - for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { - const std::string name{std::format("hCentralityPtEtaShift{}NSigma{}{}{}_runGroup{}", getName(iDetector), getName(iParticleSpecies), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", iRunGroup + 1)}; - holderCcdb.hCentralityPtEtaShiftNSigmaPid[iRunGroup][iDetector][iParticleSpecies][iChargeSpecies] = dynamic_cast(lRunGroup->FindObject(name.c_str())); - if (!holderCcdb.hCentralityPtEtaShiftNSigmaPid[iRunGroup][iDetector][iParticleSpecies][iChargeSpecies]) { - LOG(fatal) << "Invalid " << name << "!"; - } - LOG(info) << "Reading from CCDB: " << name; - } - } - } - } - hrCounter.add("hNEvents", ";;No. of Events", {HistType::kTH1D, {{10 + aod::evsel::EventSelectionFlags::kNsel, -0.5, 9.5 + static_cast(aod::evsel::EventSelectionFlags::kNsel), "Selection"}}}); if (doProcessMc.value) { hrCounter.add("hNMcEvents", ";;No. of MC Events", {HistType::kTH1D, {{10, -0.5, 9.5, "Selection"}}}); @@ -1212,7 +1145,7 @@ struct PartNumFluc { const HistogramConfigSpec hcsFluctuationCalculator{HistType::kTH3D, {asCentrality, {groupEvent.cfgNSubgroups.value, -0.5, groupEvent.cfgNSubgroups.value - 0.5, "Subgroup Index"}, {fluctuation_calculator_base::NOrderKeys, -0.5, fluctuation_calculator_base::NOrderKeys - 0.5, "Order Key Index"}}}; for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { - fluctuationCalculatorTrack[iParticleNumber][iChargeNumber] = std::make_unique(); + fluctuationCalculatorsTrack[iParticleNumber][iChargeNumber] = std::make_unique(); } if (doProcessMc.value) { @@ -1227,20 +1160,111 @@ struct PartNumFluc { hrCalculationFluctuation.add(std::format("CalculationFluctuation/hFluctuationCalculator{}{}", getName(iParticleNumber), getName(iChargeNumber)).c_str(), "", hcsFluctuationCalculator); } } + } - for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Charge))) && (iParticleSpecies != toI(ParticleSpecies::Kaon) || !static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Kaon)))) && (iParticleSpecies != toI(ParticleSpecies::Proton) || !static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Proton))))) { - continue; + template + void readCcdb() + { + if constexpr (DoInit) { + holderCcdb.lCcdb = ccdb->get(groupCcdb.cfgCcdbPath.value); + if (!holderCcdb.lCcdb || holderCcdb.lCcdb->IsA() != TList::Class()) { + LOG(fatal) << "Invalid CCDB object!"; } - holderCcdb.hVzCentralityPtEtaEfficiency.resize(nRunGroups); - for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup{ReadListRunGroup(ccdbObject, iRunGroup + 1)}; + const TGraph* const gRunNumberGroupIndex{dynamic_cast(holderCcdb.lCcdb->FindObject("gRunNumberGroupIndex"))}; + if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { + LOG(fatal) << "Invalid gRunNumberGroupIndex!"; + } + for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { + holderCcdb.runNumbersIndicesGroupIndices[std::llrint(gRunNumberGroupIndex->GetX()[iRun])] = {iRun, static_cast(std::llrint(gRunNumberGroupIndex->GetY()[iRun]))}; + } + + if (groupEvent.cfgFlagRejectionRunBadMc.value) { + const TGraph* const gRunNumberGroupIndexMc{dynamic_cast(holderCcdb.lCcdb->FindObject("gRunNumberGroupIndex_mc"))}; + if (!gRunNumberGroupIndexMc || gRunNumberGroupIndexMc->IsA() != TGraph::Class()) { + LOG(fatal) << "Invalid gRunNumberGroupIndex_mc!"; + } + for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndexMc->GetN())) { + if (std::llrint(gRunNumberGroupIndexMc->GetY()[iRun]) <= 0) { + if (const auto iter{holderCcdb.runNumbersIndicesGroupIndices.find(std::llrint(gRunNumberGroupIndexMc->GetX()[iRun]))}; iter != holderCcdb.runNumbersIndicesGroupIndices.end() && iter->second.second > 0) { + iter->second.second = -iter->second.second; + } + } + } + } + } else { + const std::int32_t runGroupIndex{std::abs(holderEvent.runGroupIndex)}; + if (holderCcdb.runGroupIndexCurrent == runGroupIndex) { + return; + } + + holderCcdb.runGroupIndexCurrent = runGroupIndex; + holderCcdb.fPtMeasureDca = {}; + holderCcdb.hCentralityPtEtaShiftNSigmaPid = {}; + holderCcdb.hVzCentralityPtEtaEfficiency = {}; + if (!groupTrack.cfgFlagRecalibrationDca.value && !isEnabled(groupTrack.cfgFlagsRecalibrationNSigmaPid) && !doCalculationFluctuation) { + return; + } + + const std::string nameList{std::format("lRunGroup_{}", runGroupIndex)}; + const TList* const lRunGroup{dynamic_cast(holderCcdb.lCcdb->FindObject(nameList.c_str()))}; + if (!lRunGroup) { + LOG(fatal) << "Invalid " << nameList << "!"; + } + + if (groupTrack.cfgFlagRecalibrationDca.value) { + for (std::int32_t const& iDcaMeasure : std::views::iota(0, NEs)) { + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + std::pair& calibration{holderCcdb.fPtMeasureDca[iDcaMeasure][iDcaAxis][iChargeSpecies]}; + const std::string nameFormula{std::format("fPt{}Dca{}{}{}_runGroup{}", getName(iDcaMeasure), getName(iDcaAxis), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", runGroupIndex)}; + calibration.first = dynamic_cast(lRunGroup->FindObject(nameFormula.c_str())); + if (!calibration.first || calibration.first->GetNdim() != 1 || calibration.first->GetNpar() <= 0) { + LOG(fatal) << "Invalid " << nameFormula << "!"; + } + LOG(info) << "Reading from CCDB: " << nameFormula << " \"" << calibration.first->GetExpFormula() << "\""; + const std::int32_t nParameters{calibration.first->GetNpar()}; + + const std::string nameHistogram{std::format("hCentralityEtaParameterPt{}Dca{}{}{}_runGroup{}", getName(iDcaMeasure), getName(iDcaAxis), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", runGroupIndex)}; + calibration.second = dynamic_cast(lRunGroup->FindObject(nameHistogram.c_str())); + if (calibration.second == nullptr || calibration.second->GetNbinsZ() != nParameters || std::ranges::any_of(std::views::iota(0, nParameters), [zAxis = calibration.second->GetZaxis()](const std::int32_t binIndex) -> bool { return zAxis->GetBinCenter(binIndex + 1) != binIndex; })) { + LOG(fatal) << "Invalid " << nameHistogram << "!"; + } + LOG(info) << "Reading from CCDB: " << nameHistogram; + } + } + } + } + + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!static_cast(groupTrack.cfgFlagsRecalibrationNSigmaPid.value.get(iParticleSpecies))) { + continue; + } + + for (std::int32_t const& iDetector : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + const std::string name{std::format("hCentralityPtEtaShift{}NSigma{}{}{}_runGroup{}", getName(iDetector), getName(iParticleSpecies), getName(iChargeSpecies), doProcessMc.value ? "_mc" : "", runGroupIndex)}; + const TH3*& histogram{holderCcdb.hCentralityPtEtaShiftNSigmaPid[iDetector][iParticleSpecies][iChargeSpecies]}; + histogram = dynamic_cast(lRunGroup->FindObject(name.c_str())); + if (!histogram) { + LOG(fatal) << "Invalid " << name << "!"; + } + LOG(info) << "Reading from CCDB: " << name; + } + } + } + + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Charge))) && (iParticleSpecies != toI(ParticleSpecies::Kaon) || !static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Kaon)))) && (iParticleSpecies != toI(ParticleSpecies::Proton) || !static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::Proton))))) { + continue; + } + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { - const std::string name{std::format("hVzCentralityPtEtaEfficiency{}{}{}_runGroup{}", getName(iPidStrategy), getName(iParticleSpecies), getName(iChargeSpecies), iRunGroup + 1)}; - holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies] = dynamic_cast(lRunGroup->FindObject(name.c_str())); - if (!holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies] || holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies]->GetNdimensions() != HolderCcdb::NDimensionsEfficiency) { + const std::string name{std::format("hVzCentralityPtEtaEfficiency{}{}{}_runGroup{}", getName(iPidStrategy), getName(iParticleSpecies), getName(iChargeSpecies), runGroupIndex)}; + const THnBase*& histogram{holderCcdb.hVzCentralityPtEtaEfficiency[iPidStrategy][iParticleSpecies][iChargeSpecies]}; + histogram = dynamic_cast(lRunGroup->FindObject(name.c_str())); + if (!histogram || histogram->GetNdimensions() != HolderCcdb::NDimensionsEfficiency) { LOG(fatal) << "Invalid " << name << "!"; } LOG(info) << "Reading from CCDB: " << name; @@ -1254,34 +1278,34 @@ struct PartNumFluc { requires IsValid double getEfficiency(const bool doUseMcParticleMomentum) const { - const THnBase* const hVzCentralityPtEtaEfficiency{holderCcdb.hVzCentralityPtEtaEfficiency[std::abs(holderEvent.runGroupIndex) - 1][toI(PidStrategyValue)][toI(ParticleSpeciesValue)][toI(ChargeSpeciesValue)]}; + const THnBase* const hVzCentralityPtEtaEfficiency{holderCcdb.hVzCentralityPtEtaEfficiency[toI(PidStrategyValue)][toI(ParticleSpeciesValue)][toI(ChargeSpeciesValue)]}; return hVzCentralityPtEtaEfficiency ? hVzCentralityPtEtaEfficiency->GetBinContent(hVzCentralityPtEtaEfficiency->GetBin(std::array{doProcessMc.value && groupEvent.cfgFlagMcCollisionVz.value ? holderMcEvent.vz : holderEvent.vz, holderEvent.centrality, doUseMcParticleMomentum ? holderMcParticle.pt : holderTrack.pt, doUseMcParticleMomentum ? holderMcParticle.eta : holderTrack.eta}.data())) : 0.; } - template + template requires IsValid double getShiftNSigmaPid() const { - if constexpr (DoRecalibration) { + if constexpr (DoRecalibrate) { if (groupTrack.cfgFlagsRecalibrationNSigmaPid.value.get(toI(ParticleSpeciesValue))) { - return interpolate(holderCcdb.hCentralityPtEtaShiftNSigmaPid[std::abs(holderEvent.runGroupIndex) - 1][toI(DetectorValue)][toI(ParticleSpeciesValue)][holderTrack.sign > 0 ? toI(ChargeSpecies::Plus) : toI(ChargeSpecies::Minus)], holderEvent.centralityCalibration, holderTrack.pt, holderTrack.eta); + return interpolate(holderCcdb.hCentralityPtEtaShiftNSigmaPid[toI(DetectorValue)][toI(ParticleSpeciesValue)][holderTrack.sign > 0 ? toI(ChargeSpecies::Plus) : toI(ChargeSpecies::Minus)], holderEvent.centralityCalibration, holderTrack.pt, holderTrack.eta); } } return 0.; } - template + template void setNSigmaPid(const T& track) { if (holderTrack.hasPid[toI(Detector::Tpc)]) { - holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Pion)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPi(), getShiftNSigmaPid()); - holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Kaon)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaKa(), getShiftNSigmaPid()); - holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Proton)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPr(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Pion)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPi(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Kaon)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaKa(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tpc)][toI(ParticleSpecies::Proton)] = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPr(), getShiftNSigmaPid()); } if (holderTrack.hasPid[toI(Detector::Tof)]) { - holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Pion)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaPi(), getShiftNSigmaPid()); - holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Kaon)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaKa(), getShiftNSigmaPid()); - holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Proton)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaPr(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Pion)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaPi(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Kaon)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaKa(), getShiftNSigmaPid()); + holderTrack.nSigmaPid[toI(Detector::Tof)][toI(ParticleSpecies::Proton)] = HolderTrack::truncateNSigmaPid(track.tofNSigmaPr(), getShiftNSigmaPid()); } } @@ -1388,10 +1412,10 @@ struct PartNumFluc { } } else { const std::int32_t chargeSpeciesIndex{holderTrack.sign > 0 ? toI(ChargeSpecies::Plus) : toI(ChargeSpecies::Minus)}; - const std::array, NEs>, NEs>, NEs>& fPtMeasureDcaGroup{holderCcdb.fPtMeasureDca[std::abs(holderEvent.runGroupIndex) - 1]}; + const std::array, NEs>, NEs>, NEs>& fPtMeasureDca{holderCcdb.fPtMeasureDca}; for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { - const double mean{getMeasureDca(fPtMeasureDcaGroup[toI(DcaMeasure::Mean)][iDcaAxis][chargeSpeciesIndex])}; - const double sigma{getMeasureDca(fPtMeasureDcaGroup[toI(DcaMeasure::Sigma)][iDcaAxis][chargeSpeciesIndex])}; + const double mean{getMeasureDca(fPtMeasureDca[toI(DcaMeasure::Mean)][iDcaAxis][chargeSpeciesIndex])}; + const double sigma{getMeasureDca(fPtMeasureDca[toI(DcaMeasure::Sigma)][iDcaAxis][chargeSpeciesIndex])}; if (!(std::abs(holderTrack.dca[iDcaAxis] - mean) < groupTrack.cfgCutsMaxAbsNSigmaDca.value.get(iDcaAxis) * sigma)) { return false; } @@ -1786,7 +1810,7 @@ struct PartNumFluc { for (std::int32_t const& iParticleNumber : std::views::iota(0, NEs)) { if (static_cast(groupAnalysis.cfgFlagsCalculationFluctuation.value.get(iParticleNumber))) { for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { - fluctuationCalculatorTrack[iParticleNumber][iChargeNumber]->clear(); + fluctuationCalculatorsTrack[iParticleNumber][iChargeNumber]->clear(); } } } @@ -1865,13 +1889,13 @@ struct PartNumFluc { const auto fill{ [this, efficiency]() -> void { if constexpr (ChargeSpeciesValue == ChargeSpecies::Plus) { - fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Plus)]->fill(1., efficiency); - fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Net)]->fill(1., efficiency); + fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Plus)]->fill(1., efficiency); + fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Net)]->fill(1., efficiency); } else { - fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Minus)]->fill(1., efficiency); - fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Net)]->fill(-1., efficiency); + fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Minus)]->fill(1., efficiency); + fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Net)]->fill(-1., efficiency); } - fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Total)]->fill(1., efficiency); + fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumber::Total)]->fill(1., efficiency); }}; if constexpr (DataModeValue == DataMode::McMcParticle) { ++holderMcEvent.numbers[toI(ParticleNumberValue)][toI(ChargeSpeciesValue)]; @@ -1924,7 +1948,7 @@ struct PartNumFluc { [this] requires IsValid () -> void { - const std::array products{fluctuationCalculatorTrack[toI(ParticleNumberValue)][toI(ChargeNumberValue)]->getProducts()}; + const std::array products{fluctuationCalculatorsTrack[toI(ParticleNumberValue)][toI(ChargeNumberValue)]->getProducts()}; for (std::int32_t const& iOrderKey : std::views::iota(0, fluctuation_calculator_base::NOrderKeys)) { if constexpr (DataModeValue == DataMode::McMcParticle) { hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hFluctuationCalculator") + C_SV(getName(ParticleNumberValue)) + C_SV(getName(ChargeNumberValue)) + C_CS("_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderKey, products[iOrderKey]); @@ -2178,6 +2202,7 @@ struct PartNumFluc { } fillEventSelection(1.); + readCcdb(); if (groupAnalysis.cfgFlagQaEvent.value) { if (holderEvent.getNGlobalTracks() > 0) {