diff --git a/.clang-format b/.clang-format index 674e1494ecd..5fd38a073da 100644 --- a/.clang-format +++ b/.clang-format @@ -51,7 +51,7 @@ IncludeCategories: Priority: 3 CaseSensitive: true # O2 - - Regex: ^(<|")(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|Field|Framework|FT0|FV0|GlobalTracking|GPU|ITS|MathUtils|MFT|MCH|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*/.*\.h + - Regex: ^(<|")(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|FDD|Field|Framework|FT0|FV0|GlobalTracking|GPU|ITS|MathUtils|MCH|MFT|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*/.*\.h Priority: 4 CaseSensitive: true # ROOT diff --git a/.github/workflows/clean-test.yml b/.github/workflows/clean-test.yml index c6c9bc12067..7ec1b0355a6 100644 --- a/.github/workflows/clean-test.yml +++ b/.github/workflows/clean-test.yml @@ -34,6 +34,11 @@ name: Clean PR checks type: boolean default: true + 'check_build/O2Physics/staging': + description: build/O2Physics/staging + type: boolean + default: true + permissions: {} jobs: diff --git a/ALICE3/Core/Decayer.h b/ALICE3/Core/Decayer.h index 81f08f5412d..2280261dd21 100644 --- a/ALICE3/Core/Decayer.h +++ b/ALICE3/Core/Decayer.h @@ -30,7 +30,6 @@ #include #include -#include #include #include #include diff --git a/ALICE3/Core/TrackUtilities.h b/ALICE3/Core/TrackUtilities.h index bca0b82cf1a..1b042452899 100644 --- a/ALICE3/Core/TrackUtilities.h +++ b/ALICE3/Core/TrackUtilities.h @@ -22,6 +22,7 @@ #include +#include #include namespace o2::upgrade diff --git a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx index 614e0f6f84b..9c308ebe6ab 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx @@ -31,7 +31,6 @@ #include #include #include -#include #include #include diff --git a/ALICE3/Tasks/alice3TrackingPerformance.cxx b/ALICE3/Tasks/alice3TrackingPerformance.cxx index bb47ffde7da..e29a914d848 100644 --- a/ALICE3/Tasks/alice3TrackingPerformance.cxx +++ b/ALICE3/Tasks/alice3TrackingPerformance.cxx @@ -37,7 +37,6 @@ #include #include #include -#include #include using namespace o2; diff --git a/Common/Core/PID/ParamBase.h b/Common/Core/PID/ParamBase.h index fa9f0749d2a..0e730b717ff 100644 --- a/Common/Core/PID/ParamBase.h +++ b/Common/Core/PID/ParamBase.h @@ -36,7 +36,7 @@ namespace o2::pid { -/// Variable to use for the pid input/output i.e. float, double et cetera +/// Variable to use for the pid input/output i.e. float, double et cetera// using pidvar_t = float; /// \brief Class to handle the parameters of a given detector response diff --git a/Common/Core/RecoDecay.h b/Common/Core/RecoDecay.h index fcc50d23bf8..2b78740254f 100644 --- a/Common/Core/RecoDecay.h +++ b/Common/Core/RecoDecay.h @@ -19,12 +19,12 @@ #include -#include // for VMC Particle Production Process #include // for PDG codes #include // std::find #include // std::array #include // std::abs, std::sqrt +#include "TMCProcess.h" // for VMC Particle Production Process #include // std::size_t #include // intX_t #include // std::apply @@ -38,7 +38,7 @@ /// - useful arithmetic operations and basic vector algebra /// - calculation of kinematic quantities /// - calculation of topological properties of secondary vertices -/// - Monte Carlo matching of decays at track and particle level +/// - Monte Carlo matching of decays at track and particle level//// struct RecoDecay { // mapping of charm-hadron origin type diff --git a/Common/TableProducer/qVectorsTable.cxx b/Common/TableProducer/qVectorsTable.cxx index 574c370a16a..ce5152aace6 100644 --- a/Common/TableProducer/qVectorsTable.cxx +++ b/Common/TableProducer/qVectorsTable.cxx @@ -309,19 +309,21 @@ struct qVectorsTable { corrsQvecSp.push_back(modeCorrQvecSp); } - corrsQvecEse.clear(); - for (std::size_t i = 0; i < cfgnMods->size(); i++) { - int ind = cfgnMods->at(i); - fullPath = cfgQvecCalibPath; - fullPath += "/eseq"; - fullPath += std::to_string(ind); - auto modeCorrQvecEse = getForTsOrRun(fullPath, timestamp, runnumber); - if (!modeCorrQvecEse) { + if (cfgProduceRedQVecs) { + corrsQvecEse.clear(); + for (std::size_t i = 0; i < cfgnMods->size(); i++) { + int ind = cfgnMods->at(i); fullPath = cfgQvecCalibPath; - fullPath += "/eseq2"; - modeCorrQvecEse = getForTsOrRun(fullPath, timestamp, runnumber); + fullPath += "/eseq"; + fullPath += std::to_string(ind); + auto modeCorrQvecEse = getForTsOrRun(fullPath, timestamp, runnumber); + if (!modeCorrQvecEse) { + fullPath = cfgQvecCalibPath; + fullPath += "/eseq2"; + modeCorrQvecEse = getForTsOrRun(fullPath, timestamp, runnumber); + } + corrsQvecEse.push_back(modeCorrQvecEse); } - corrsQvecEse.push_back(modeCorrQvecEse); } if (cfgShiftCorr) { diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index ed3237ed0bc..57f8f414e16 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -699,7 +699,7 @@ struct FemtoUniversePairTaskTrackV0Extended { // track cleaning & checking for duplicate pairs if (!pairCleanerV0.isCleanPair(p1, p2, parts)) { - // mark for rejection the cascade that shares a daughter with another cascade and has an invariant mass further from default value + // mark for rejection the v0 that shares a daughter with another v0 and has an invariant mass further from default value. Set confV0DuplCosPA as TRUE to do the same check with cosPA instead. if (!ConfV0Selection.confV0DuplCosPA) { if (std::abs(p1.mLambda() - v0InvMass[ConfV0Selection.confV0Type1]) < std::abs(p2.mLambda() - v0InvMass[ConfV0Selection.confV0Type2])) { v0Duplicates.insert(p2.globalIndex()); diff --git a/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h b/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h deleted file mode 100644 index b3f7a654ccd..00000000000 --- a/PWGCF/FemtoWorld/Core/FemtoWorldUtils.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file CFFilter.cxx -/// \brief Utilities for the FemtoWorld framework -/// -/// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -/// \author Zuzanna Chochulska, WUT Warsaw, zchochul@cern.ch - -#ifndef PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ -#define PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ - -#include "PWGCF/FemtoWorld/DataModel/FemtoWorldDerived.h" - -#include - -#include -#include -#include - -namespace o2::analysis::femtoWorld -{ - -enum kPIDselection { - k3d5sigma = 0, - k3sigma = 1, - k2d5sigma = 2 -}; - -enum kDetector { - kTPC = 0, - kTPCTOF = 1, - kNdetectors = 2 -}; - -/// internal function that returns the kPIDselection element corresponding to a specifica n-sigma value -/// \param nSigma number of sigmas for PID -/// \param vNsigma vector with the number of sigmas of interest -/// \return kPIDselection corresponding to n-sigma -kPIDselection getPIDselection(const float nSigma, const std::vector& vNsigma) -{ - for (int i = 0; i < (int)vNsigma.size(); i++) { - if (abs(nSigma - vNsigma[i]) < 1e-3) { - return static_cast(i); - } - } - LOG(info) << "Invalid value of nSigma: " << nSigma << ". Standard 3 sigma returned." << std::endl; - return kPIDselection::k3sigma; -} - -/// function that checks whether the PID selection specified in the vectors is fulfilled -/// \param pidcut Bit-wise container for the PID -/// \param vSpecies vector with ID corresponding to the selected species (output from cutculator) -/// \param nSpecies number of available selected species (output from cutculator) -/// \param nSigma number of sigma selection fo PID -/// \param vNsigma vector with available n-sigma selections for PID -/// \param kDetector enum corresponding to the PID technique -/// \return Whether the PID selection specified in the vectors is fulfilled -bool isPIDSelected(aod::femtoworldparticle::cutContainerType const& pidcut, std::vector const& vSpecies, int nSpecies, float nSigma, const std::vector& vNsigma, const kDetector iDet = kDetector::kTPC) -{ - bool pidSelection = true; - kPIDselection iNsigma = getPIDselection(nSigma, vNsigma); - for (auto iSpecies : vSpecies) { - //\todo we also need the possibility to specify whether the bit is true/false ->std>>vector> - // if (!((pidcut >> it.first) & it.second)) { - int bit_to_check = nSpecies * kDetector::kNdetectors * iNsigma + iSpecies * kDetector::kNdetectors + iDet; - if (!(pidcut & (1UL << bit_to_check))) { - pidSelection = false; - } - } - return pidSelection; -}; - -/// function that checks whether the PID selection specified in the vectors is fulfilled, depending on the momentum TPC or TPC+TOF PID is conducted -/// \param pidcut Bit-wise container for the PID -/// \param momentum Momentum of the track -/// \param pidThresh Momentum threshold that separates between TPC and TPC+TOF PID -/// \param vSpecies Vector with the species of interest (number returned by the CutCulator) -/// \param nSpecies number of available selected species (output from cutculator) -/// \param nSigmaTPC Number of TPC sigmas for selection -/// \param nSigmaTPCTOF Number of TPC+TOF sigmas for selection (circular selection) -/// \return Whether the PID selection is fulfilled -bool isFullPIDSelected(aod::femtoworldparticle::cutContainerType const& pidCut, float const momentum, float const pidThresh, std::vector const& vSpecies, int nSpecies, const std::vector& vNsigma = {3.5, 3., 2.5}, const float nSigmaTPC = 3.5, const float nSigmaTPCTOF = 3.5) -{ - bool pidSelection = true; - if (momentum < pidThresh) { - /// TPC PID only - pidSelection = isPIDSelected(pidCut, vSpecies, nSpecies, nSigmaTPC, vNsigma, kDetector::kTPC); - } else { - /// TPC + TOF PID - pidSelection = isPIDSelected(pidCut, vSpecies, nSpecies, nSigmaTPCTOF, vNsigma, kDetector::kTPCTOF); - } - return pidSelection; -}; - -} // namespace o2::analysis::femtoWorld - -#endif // PWGCF_FEMTOWORLD_CORE_FEMTOWORLDUTILS_H_ diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index f1b672c76e6..37b48ee0f50 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -73,100 +73,109 @@ using namespace o2::aod::rctsel; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; struct FlowSP { - RCTFlagsChecker rctChecker; + // event selection configurable group struct : ConfigurableGroup { - O2_DEFINE_CONFIGURABLE(cfgEvtUseRCTFlagChecker, bool, false, "Evt sel: use RCT flag checker"); - O2_DEFINE_CONFIGURABLE(cfgEvtRCTFlagCheckerLabel, std::string, "CBT_hadronPID", "Evt sel: RCT flag checker label (CBT, CBT_hadronPID)"); // all Labels can be found in Common/CCDB/RCTSelectionFlags.h - O2_DEFINE_CONFIGURABLE(cfgEvtRCTFlagCheckerZDCCheck, bool, false, "Evt sel: RCT flag checker ZDC check"); - O2_DEFINE_CONFIGURABLE(cfgEvtRCTFlagCheckerLimitAcceptAsBad, bool, false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"); - } rctFlags; + O2_DEFINE_CONFIGURABLE(cEvtUseRCTFlagChecker, bool, false, "Evt sel: use RCT flag checker"); + O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerLabel, std::string, "CBT_hadronPID", "Evt sel: RCT flag checker label (CBT, CBT_hadronPID)"); // all Labels can be found in Common/CCDB/RCTSelectionFlags.h + O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerZDCCheck, bool, false, "Evt sel: RCT flag checker ZDC check"); + O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerLimitAcceptAsBad, bool, false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"); + O2_DEFINE_CONFIGURABLE(cEvSelsUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); + O2_DEFINE_CONFIGURABLE(cEvSelsMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); + O2_DEFINE_CONFIGURABLE(cEvSelsMinOccupancy, int, 0, "Minimum occupancy of selected events"); + O2_DEFINE_CONFIGURABLE(cEvSelsNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); + O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); + O2_DEFINE_CONFIGURABLE(cEvSelsNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); + O2_DEFINE_CONFIGURABLE(cEvSelsNoCollInTimeRangeNarrow, bool, true, "kNoCollInTimeRangeNarrow"); + O2_DEFINE_CONFIGURABLE(cEvSelsDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); + O2_DEFINE_CONFIGURABLE(cEvSelsIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); + O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); + O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodITSLayer0123, bool, true, "Cut time intervals with dead ITS staves"); + + // QA Plots + O2_DEFINE_CONFIGURABLE(cFillEventQA, bool, false, "Fill histograms for event QA"); + O2_DEFINE_CONFIGURABLE(cFillTrackQA, bool, false, "Fill histograms for track QA"); + O2_DEFINE_CONFIGURABLE(cFillPIDQA, bool, false, "Fill histograms for PID QA"); + O2_DEFINE_CONFIGURABLE(cFillEventPlaneQA, bool, false, "Fill histograms for Event Plane QA"); + O2_DEFINE_CONFIGURABLE(cFillQABefore, bool, false, "Fill QA histograms before cuts, only for processData"); + O2_DEFINE_CONFIGURABLE(cFillMeanPT, bool, false, "Fill histograms for mean PX/PT"); + O2_DEFINE_CONFIGURABLE(cFillMeanPTextra, bool, false, "Fill histograms for mean PX/PT extra"); + O2_DEFINE_CONFIGURABLE(cUseCentAveragePt, bool, false, "Use in 1% centrality intervals and not cent average"); + O2_DEFINE_CONFIGURABLE(cFillWithMCParticle, bool, false, "Fill histograms with MCParticle instead of Track"); + // Flags to make and fill histograms + O2_DEFINE_CONFIGURABLE(cFillGeneralV1Histos, bool, true, "Fill histograms for vn analysis"); + O2_DEFINE_CONFIGURABLE(cFillMixedHarmonics, bool, true, "Flag to make and fill histos for mixed harmonics"); + O2_DEFINE_CONFIGURABLE(cFillEventPlane, bool, false, "Flag to make and fill histos with Event Plane"); + O2_DEFINE_CONFIGURABLE(cFillXandYterms, bool, false, "Flag to make and fill histos for with separate x and y terms for SPM"); + O2_DEFINE_CONFIGURABLE(cFillChargeDependence, bool, true, "Flag to make and fill histos for charge dependent flow"); + O2_DEFINE_CONFIGURABLE(cFillChargeDependenceQA, bool, true, "Flag to make and fill QA histos for charge dependent flow"); + O2_DEFINE_CONFIGURABLE(cFillPID, bool, false, "Flag to make and fill histos for PID flow"); + // Centrality Estimators -> standard is FT0C + O2_DEFINE_CONFIGURABLE(cCentFT0Cvariant1, bool, false, "Set centrality estimator to CentFT0Cvariant1"); + O2_DEFINE_CONFIGURABLE(cCentFT0M, bool, false, "Set centrality estimator to CentFT0M"); + O2_DEFINE_CONFIGURABLE(cCentFV0A, bool, false, "Set centrality estimator to CentFV0A"); + O2_DEFINE_CONFIGURABLE(cCentNGlobal, bool, false, "Set centrality estimator to CentNGlobal"); + // Standard selections + O2_DEFINE_CONFIGURABLE(cTrackSelsDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); + O2_DEFINE_CONFIGURABLE(cTrackSelsNcls, float, 70, "Cut on number of TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cTrackSelsFshcls, float, 0.4, "Cut on fraction of shared TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cTrackSelsPtmin, float, 0.2, "minimum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cTrackSelsPtmax, float, 10, "maximum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cTrackSelsEta, float, 0.8, "eta cut"); + O2_DEFINE_CONFIGURABLE(cIsMCReco, bool, true, "Is MC Reco"); + O2_DEFINE_CONFIGURABLE(cEvSelsVtxZ, float, 10, "vertex cut (cm)"); + O2_DEFINE_CONFIGURABLE(cMagField, float, 99999, "Configurable magnetic field;default CCDB will be queried"); + O2_DEFINE_CONFIGURABLE(cCentMin, float, 0, "Minimum cenrality for selected events"); + O2_DEFINE_CONFIGURABLE(cCentMax, float, 90, "Maximum cenrality for selected events"); + O2_DEFINE_CONFIGURABLE(cFilterLeptons, bool, true, "Filter out leptons from MCGenerated by requiring |pdgCode| > 100"); + // NUA and NUE weights + O2_DEFINE_CONFIGURABLE(cFillWeights, bool, true, "Fill NUA weights"); + O2_DEFINE_CONFIGURABLE(cFillWeightsPOS, bool, true, "Fill NUA weights only for positive charges"); + O2_DEFINE_CONFIGURABLE(cFillWeightsNEG, bool, true, "Fill NUA weights only for negative charges"); + O2_DEFINE_CONFIGURABLE(cUseNUA1D, bool, true, "Use 1D NUA weights (only phi)"); + O2_DEFINE_CONFIGURABLE(cUseNUA2D, bool, false, "Use 2D NUA weights (phi and eta)"); + O2_DEFINE_CONFIGURABLE(cUseNUE2D, bool, false, "Use 2D NUE weights"); + O2_DEFINE_CONFIGURABLE(cUseNUE3D, bool, false, "Use 3D NUE weights (pt, eta, centrality)"); + O2_DEFINE_CONFIGURABLE(cUseNUE2Deta, bool, false, "Use 2D NUE weights TRUE: (pt and eta) FALSE: (pt and centrality)"); + // Additional track Selections + O2_DEFINE_CONFIGURABLE(cTrackSelsUseAdditionalTrackCut, bool, false, "Bool to enable Additional Track Cut"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDoDCApt, bool, false, "Apply Pt dependent DCAz cut"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDCApt1, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets a"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDCApt2, float, 0.035, "DcaZ < const + (a * b) / pt^1.1 -> this sets b"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDCAptConsMin, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets const"); + O2_DEFINE_CONFIGURABLE(cTrackSelsPIDNsigma, float, 2.0, "nSigma cut for PID"); + O2_DEFINE_CONFIGURABLE(cTrackSelDoTrackQAvsCent, bool, true, "Do track selection QA plots as function of centrality"); + // harmonics for v coefficients + O2_DEFINE_CONFIGURABLE(cHarm, int, 1, "Flow harmonic n for ux and uy: (Cos(n*phi), Sin(n*phi))"); + O2_DEFINE_CONFIGURABLE(cHarmMixed, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); + // settings for CCDB data + O2_DEFINE_CONFIGURABLE(cCCDBdir_QQ, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass5/meanQQ/Default", "ccdb dir for average QQ values in 1% centrality bins"); + O2_DEFINE_CONFIGURABLE(cCCDBdir_SP, std::string, "", "ccdb dir for average event plane resolution in 1% centrality bins"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUA, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/Default", "ccdb dir for NUA corrections"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUE, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/Default", "ccdb dir for NUE corrections (pt)"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUE2D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/2D", "ccdb dir for NUE 2D corrections (pt, eta)"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUE3D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/3D", "ccdb dir for NUE 3D corrections (pt, eta, centrality)"); + O2_DEFINE_CONFIGURABLE(cCCDBdir_centrality, std::string, "", "ccdb dir for Centrality corrections"); + O2_DEFINE_CONFIGURABLE(cCCDBdir_meanPt, std::string, "", "ccdb dir for Mean Pt corrections"); + + // Confogirable axis + // ConfigurableAxis axisCentrality{"axisCentrality", {20, 0, 100}, "Centrality bins for vn "}; + // ConfigurableAxis axisMomentum{"axisMomentum", {20, 0, 10}, "Momentum bins for vn"}; + // ConfigurableAxis axisEtaVn{"axisEtaVn", {8, -0.8, 0.8}, "Eta bins for vn"}; + + // Configurables containing vector + Configurable> cEvSelsMultPv{"cEvSelsMultPv", std::vector{2223.49, -75.1444, 0.963572, -0.00570399, 1.34877e-05, 3790.99, -137.064, 2.13044, -0.017122, 5.82834e-05}, "Multiplicity cuts (PV) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; + Configurable> cEvSelsMult{"cEvSelsMult", std::vector{1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; + Configurable> cPtBinning{"cPtBinning", std::vector{0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, "pT binning for vn"}; - // event selection configurable group - O2_DEFINE_CONFIGURABLE(cfgEvSelsUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsMinOccupancy, int, 0, "Minimum occupancy of selected events"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsNoCollInTimeRangeNarrow, bool, true, "kNoCollInTimeRangeNarrow"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsIsGoodITSLayer0123, bool, true, "Cut time intervals with dead ITS staves"); - - // QA Plots - O2_DEFINE_CONFIGURABLE(cfgFillEventQA, bool, false, "Fill histograms for event QA"); - O2_DEFINE_CONFIGURABLE(cfgFillTrackQA, bool, false, "Fill histograms for track QA"); - O2_DEFINE_CONFIGURABLE(cfgFillPIDQA, bool, false, "Fill histograms for PID QA"); - O2_DEFINE_CONFIGURABLE(cfgFillEventPlaneQA, bool, false, "Fill histograms for Event Plane QA"); - O2_DEFINE_CONFIGURABLE(cfgFillQABefore, bool, false, "Fill QA histograms before cuts, only for processData"); - O2_DEFINE_CONFIGURABLE(cfgFillMeanPT, bool, false, "Fill histograms for mean PX/PT"); - O2_DEFINE_CONFIGURABLE(cfgUseCentAveragePt, bool, false, "Use in 1% centrality intervals and not ecent average"); - // Flags to make and fill histograms - O2_DEFINE_CONFIGURABLE(cfgFillGeneralV1Histos, bool, true, "Fill histograms for vn analysis"); - O2_DEFINE_CONFIGURABLE(cfgFillMixedHarmonics, bool, true, "Flag to make and fill histos for mixed harmonics"); - O2_DEFINE_CONFIGURABLE(cfgFillEventPlane, bool, false, "Flag to make and fill histos with Event Plane"); - O2_DEFINE_CONFIGURABLE(cfgFillXandYterms, bool, false, "Flag to make and fill histos for with separate x and y terms for SPM"); - O2_DEFINE_CONFIGURABLE(cfgFillChargeDependence, bool, true, "Flag to make and fill histos for charge dependent flow"); - O2_DEFINE_CONFIGURABLE(cfgFillChargeDependenceQA, bool, true, "Flag to make and fill QA histos for charge dependent flow"); - O2_DEFINE_CONFIGURABLE(cfgFillPID, bool, false, "Flag to make and fill histos for PID flow"); - // Centrality Estimators -> standard is FT0C - O2_DEFINE_CONFIGURABLE(cfgCentFT0Cvariant1, bool, false, "Set centrality estimator to cfgCentFT0Cvariant1"); - O2_DEFINE_CONFIGURABLE(cfgCentFT0M, bool, false, "Set centrality estimator to cfgCentFT0M"); - O2_DEFINE_CONFIGURABLE(cfgCentFV0A, bool, false, "Set centrality estimator to cfgCentFV0A"); - O2_DEFINE_CONFIGURABLE(cfgCentNGlobal, bool, false, "Set centrality estimator to cfgCentNGlobal"); - // Standard selections - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsNcls, float, 70, "Cut on number of TPC clusters found"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsFshcls, float, 0.4, "Cut on fraction of shared TPC clusters found"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsPtmin, float, 0.2, "minimum pt (GeV/c)"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsPtmax, float, 10, "maximum pt (GeV/c)"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsEta, float, 0.8, "eta cut"); - O2_DEFINE_CONFIGURABLE(cfgEvSelsVtxZ, float, 10, "vertex cut (cm)"); - O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field;default CCDB will be queried"); - O2_DEFINE_CONFIGURABLE(cfgCentMin, float, 0, "Minimum cenrality for selected events"); - O2_DEFINE_CONFIGURABLE(cfgCentMax, float, 90, "Maximum cenrality for selected events"); - O2_DEFINE_CONFIGURABLE(cfgFilterLeptons, bool, true, "Filter out leptons from MCGenerated by requiring |pdgCode| > 100"); - // NUA and NUE weights - O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, true, "Fill NUA weights"); - O2_DEFINE_CONFIGURABLE(cfgFillWeightsPOS, bool, true, "Fill NUA weights only for positive charges"); - O2_DEFINE_CONFIGURABLE(cfgFillWeightsNEG, bool, true, "Fill NUA weights only for negative charges"); - O2_DEFINE_CONFIGURABLE(cfgUseNUA1D, bool, false, "Use 1D NUA weights (only phi)"); - O2_DEFINE_CONFIGURABLE(cfgUseNUA2D, bool, true, "Use 2D NUA weights (phi and eta)"); - O2_DEFINE_CONFIGURABLE(cfgUseNUE2D, bool, true, "Use 2D NUE weights"); - O2_DEFINE_CONFIGURABLE(cfgUseNUE2Deta, bool, true, "Use 2D NUE weights TRUE: (pt and eta) FALSE: (pt and centrality)"); - // Additional track Selections - O2_DEFINE_CONFIGURABLE(cfgTrackSelsUseAdditionalTrackCut, bool, false, "Bool to enable Additional Track Cut"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDoDCApt, bool, false, "Apply Pt dependent DCAz cut"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt1, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets a"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCApt2, float, 0.035, "DcaZ < const + (a * b) / pt^1.1 -> this sets b"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsDCAptConsMin, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets const"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelsPIDNsigma, float, 2.0, "nSigma cut for PID"); - O2_DEFINE_CONFIGURABLE(cfgTrackSelDoTrackQAvsCent, bool, true, "Do track selection QA plots as function of centrality"); - // harmonics for v coefficients - O2_DEFINE_CONFIGURABLE(cfgHarm, int, 1, "Flow harmonic n for ux and uy: (Cos(n*phi), Sin(n*phi))"); - O2_DEFINE_CONFIGURABLE(cfgHarmMixed, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); - // settings for CCDB data - O2_DEFINE_CONFIGURABLE(cfgCCDBdir_QQ, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass5/meanQQ/Default", "ccdb dir for average QQ values in 1% centrality bins"); - O2_DEFINE_CONFIGURABLE(cfgCCDBdir_SP, std::string, "", "ccdb dir for average event plane resolution in 1% centrality bins"); - O2_DEFINE_CONFIGURABLE(cfgCCDB_NUA, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/Default", "ccdb dir for NUA corrections"); - O2_DEFINE_CONFIGURABLE(cfgCCDB_NUE, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/Default", "ccdb dir for NUE corrections (pt)"); - O2_DEFINE_CONFIGURABLE(cfgCCDB_NUE2D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/2D", "ccdb dir for NUE 2D corrections (eta, pt)"); - O2_DEFINE_CONFIGURABLE(cfgCCDBdir_centrality, std::string, "", "ccdb dir for Centrality corrections"); - O2_DEFINE_CONFIGURABLE(cfgCCDBdir_meanPt, std::string, "", "ccdb dir for Mean Pt corrections"); - // Confogirable axis - ConfigurableAxis axisCentrality{"axisCentrality", {20, 0, 100}, "Centrality bins for vn "}; - ConfigurableAxis axisNch = {"axisNch", {400, 0, 4000}, "Global N_{ch}"}; - ConfigurableAxis axisMultpv = {"axisMultpv", {400, 0, 4000}, "N_{ch} (PV)"}; - // Configurables containing vector - Configurable> cfgEvSelsMultPv{"cfgEvSelsMultPv", std::vector{2223.49, -75.1444, 0.963572, -0.00570399, 1.34877e-05, 3790.99, -137.064, 2.13044, -0.017122, 5.82834e-05}, "Multiplicity cuts (PV) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; - Configurable> cfgEvSelsMult{"cfgEvSelsMult", std::vector{1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; - - Filter collisionFilter = nabs(aod::collision::posZ) < cfgEvSelsVtxZ; - Filter trackFilter = nabs(aod::track::eta) < cfgTrackSelsEta && aod::track::pt > cfgTrackSelsPtmin&& aod::track::pt < cfgTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && nabs(aod::track::dcaXY) < cfgTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfgTrackSelsDCAz; - Filter trackFilterMC = nabs(aod::mcparticle::eta) < cfgTrackSelsEta && aod::mcparticle::pt > cfgTrackSelsPtmin&& aod::mcparticle::pt < cfgTrackSelsPtmax; + } cfg; + + RCTFlagsChecker rctChecker; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfg.cEvSelsVtxZ; + Filter trackFilter = nabs(aod::track::eta) < cfg.cTrackSelsEta && aod::track::pt > cfg.cTrackSelsPtmin&& aod::track::pt < cfg.cTrackSelsPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true) || cfg.cIsMCReco) && nabs(aod::track::dcaXY) < cfg.cTrackSelsDCAxy&& nabs(aod::track::dcaZ) < cfg.cTrackSelsDCAz; + Filter trackFilterMC = nabs(aod::mcparticle::eta) < cfg.cTrackSelsEta && aod::mcparticle::pt > cfg.cTrackSelsPtmin&& aod::mcparticle::pt < cfg.cTrackSelsPtmax; using GeneralCollisions = soa::Join; using UnfilteredTracksPID = soa::Join; using UnfilteredTracks = soa::Join; @@ -196,6 +205,7 @@ struct FlowSP { struct Config { std::vector mEfficiency = {}; std::vector mEfficiency2D = {}; + std::vector mEfficiency3D = {}; std::vector mAcceptance = {}; std::vector mAcceptance2D = {}; bool correctionsLoaded = false; @@ -213,7 +223,7 @@ struct FlowSP { bool clCentrality = false; bool clMeanPt = false; - } cfg; + } conf; struct SPMvars { std::vector> wacc = {{{0, 1.0}, {1, 1.0}, {2, 1.0}, {3, 1.0}}, {{0, 1.0}, {1, 1.0}, {2, 1.0}, {3, 1.0}}, {{0, 1.0}, {1, 1.0}, {2, 1.0}, {3, 1.0}}}; // int for part species, float for weight vector for kIncl, kPos, kNeg @@ -345,6 +355,7 @@ struct FlowSP { AxisSpec axisPhi = {60, 0, constants::math::TwoPI, "#varphi"}; AxisSpec axisEta = {64, -1.6, 1.6, "#eta"}; AxisSpec axisEtaVn = {8, -.8, .8, "#eta"}; + AxisSpec axisCentrality = {20, 0, 100, "Centrality (%)"}; AxisSpec axisVx = {40, -0.01, 0.01, "v_{x}"}; AxisSpec axisVy = {40, -0.01, 0.01, "v_{y}"}; AxisSpec axisVz = {40, -10, 10, "v_{z}"}; @@ -360,13 +371,12 @@ struct FlowSP { AxisSpec axisBeta = {150, 0, 1.5, "Beta for PID"}; AxisSpec axisCharge = {3, 0, 3, "Charge: 0 = inclusive, 1 = positive, 2 = negative"}; AxisSpec axisPx = {100, -0.05, 0.05, "p_{x} (GeV/c)"}; + AxisSpec axisNch = {400, 0, 4000, "Global N_{ch}"}; + AxisSpec axisMultpv = {400, 0, 4000, "N_{ch} (PV)"}; + AxisSpec axisPt = {cfg.cPtBinning, "#it{p}_{T} GeV/#it{c}"}; + int ptbins = cfg.cPtBinning->size() - 1; - std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; - AxisSpec axisPt = {ptbinning, "#it{p}_{T} GeV/#it{c}"}; - - int ptbins = ptbinning.size() - 1; - - rctChecker.init(rctFlags.cfgEvtRCTFlagCheckerLabel, rctFlags.cfgEvtRCTFlagCheckerZDCCheck, rctFlags.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + rctChecker.init(cfg.cEvtRCTFlagCheckerLabel, cfg.cEvtRCTFlagCheckerZDCCheck, cfg.cEvtRCTFlagCheckerLimitAcceptAsBad); histos.add("hCentrality", "Centrality; Centrality (%); ", {HistType::kTH1D, {axisCent}}); @@ -398,23 +408,23 @@ struct FlowSP { histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ZeroCharge + 1, "Only charged"); histos.get(HIST("hTrackCount"))->GetXaxis()->SetBinLabel(trackSel_ParticleWeights + 1, "Apply weights"); - if (cfgFillWeights) { + if (cfg.cFillWeights) { registry.add("weights2D/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); registry.add("weights2D/hPhi_Eta_vz_positive", "", kTH3D, {axisPhi, axisEta, axisVz}); registry.add("weights2D/hPhi_Eta_vz_negative", "", kTH3D, {axisPhi, axisEta, axisVz}); // define output objects - fWeights->setPtBins(ptbins, &ptbinning[0]); + fWeights->setPtBins(ptbins, &cfg.cPtBinning.value[0]); fWeights->init(true, false); - fWeightsPOS->setPtBins(ptbins, &ptbinning[0]); + fWeightsPOS->setPtBins(ptbins, &cfg.cPtBinning.value[0]); fWeightsPOS->init(true, false); - fWeightsNEG->setPtBins(ptbins, &ptbinning[0]); + fWeightsNEG->setPtBins(ptbins, &cfg.cPtBinning.value[0]); fWeightsNEG->init(true, false); } - if (cfgFillEventQA) { + if (cfg.cFillEventQA) { histos.add("QA/after/hCentFT0C", " ; Cent FT0C (%); ", {HistType::kTH1D, {axisCent}}); histos.add("QA/after/hCentFT0M", "; Cent FT0M (%); ", {HistType::kTH1D, {axisCent}}); histos.add("QA/after/hCentFV0A", "; Cent FV0A (%); ", {HistType::kTH1D, {axisCent}}); @@ -431,7 +441,7 @@ struct FlowSP { histos.add("QA/after/CentFT0C_vs_CentFV0A", " ; Cent FT0C (%); Cent FV0A (%) ", {HistType::kTH2D, {axisCent, axisCent}}); histos.add("QA/after/CentFT0C_vs_CentNGlobal", " ; Cent FT0C (%); Cent NGlobal (%) ", {HistType::kTH2D, {axisCent, axisCent}}); - if (cfgFillEventPlaneQA && doprocessData) { + if (cfg.cFillEventPlaneQA && doprocessData) { histos.add("QA/after/PsiA_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); histos.add("QA/after/PsiC_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); histos.add("QA/after/PsiFull_vs_Cent", "", {HistType::kTH2D, {axisPhiPlane, axisCent}}); @@ -447,14 +457,14 @@ struct FlowSP { // histos.add("QA/after/DeltaPsivsPx", "", {HistType::kTH3D, {axisCent, axisPhiPlane, axisPx}}); } - if (cfgFillQABefore) { + if (cfg.cFillQABefore) { histos.addClone("QA/after/", "QA/before/"); } } if (doprocessData || doprocessMCReco || doprocessDataPID) { - if (cfgFillTrackQA) { + if (cfg.cFillTrackQA) { histos.add("incl/QA/after/pt_phi", "", {HistType::kTH2D, {axisPt, axisPhiMod}}); histos.add("incl/QA/after/hPhi_Eta_vz", "", kTH3D, {axisPhi, axisEta, axisVz}); histos.add("incl/QA/after/hPhi_Eta_vz_corrected", "", kTH3D, {axisPhi, axisEta, axisVz}); @@ -465,7 +475,7 @@ struct FlowSP { histos.add("incl/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); histos.add("incl/QA/after/hMeanPtEta", "", {HistType::kTProfile2D, {axisEta, axisCent}}); - if (cfgTrackSelDoTrackQAvsCent) { + if (cfg.cTrackSelDoTrackQAvsCent) { histos.add("incl/QA/after/hPt_Eta", "", kTH3D, {axisPt, axisEta, axisCent}); histos.add("incl/QA/after/hPt_Eta_uncorrected", "", kTH3D, {axisPt, axisEta, axisCent}); histos.add("incl/QA/after/hPhi_Eta", "", kTH3D, {axisPhi, axisEta, axisCent}); @@ -475,11 +485,11 @@ struct FlowSP { histos.add("incl/QA/after/hPhi_Eta_Pt_corrected", "", kTH3D, {axisPhi, axisEta, axisPt}); } - if (cfgFillQABefore) + if (cfg.cFillQABefore) histos.addClone("incl/QA/after/", "incl/QA/before/"); } - if (cfgFillPIDQA && doprocessDataPID) { + if (cfg.cFillPIDQA && doprocessDataPID) { histos.add("hPIDcounts", "", kTH2D, {{{4, 0, 4}, axisPt}}); histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(1, "UFO"); histos.get(HIST("hPIDcounts"))->GetXaxis()->SetBinLabel(2, "Pion"); @@ -494,7 +504,7 @@ struct FlowSP { histos.add("incl/pion/QA/after/hNsigmaTPC_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); histos.add("incl/pion/QA/after/hNsigmaTOF_pt", "", {HistType::kTH2D, {axisPt, axisNsigma}}); - if (cfgTrackSelDoTrackQAvsCent) { + if (cfg.cTrackSelDoTrackQAvsCent) { histos.add("incl/pion/QA/after/hPt_Eta", "", kTH3D, {axisPt, axisEta, axisCent}); histos.add("incl/pion/QA/after/hPt_Eta_uncorrected", "", kTH3D, {axisPt, axisEta, axisCent}); histos.add("incl/pion/QA/after/hPhi_Eta", "", kTH3D, {axisPhi, axisEta, axisCent}); @@ -511,7 +521,7 @@ struct FlowSP { histos.add("incl/pion/QA/after/hCrossedRows_pt", "", {HistType::kTH2D, {axisPt, axisCl}}); histos.add("incl/pion/QA/after/hCrossedRows_vs_SharedClusters", "", {HistType::kTH2D, {axisCl, axisShCl}}); - if (cfgFillQABefore) { + if (cfg.cFillQABefore) { histos.addClone("incl/pion/QA/after/", "incl/pion/QA/before/"); } @@ -519,16 +529,16 @@ struct FlowSP { histos.addClone("incl/pion/", "incl/proton/"); } - if (cfgFillEventQA) { + if (cfg.cFillEventQA) { histos.add("QA/hCentFull", " ; Centrality (%); ", {HistType::kTH1D, {axisCent}}); } if (doprocessMCReco) { - registry.add("trackMCReco/after/hIsPhysicalPrimary", "", {HistType::kTH2D, {{2, 0, 2}, axisCentrality}}); + registry.add("trackMCReco/after/incl/hIsPhysicalPrimary", "", {HistType::kTH3D, {{2, 0, 2}, axisCentrality, axisPt}}); + registry.get(HIST("trackMCReco/after/incl/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(1, "Secondary"); + registry.get(HIST("trackMCReco/after/incl/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(2, "Primary"); registry.add("trackMCReco/hTrackSize_unFiltered", "", {HistType::kTH2D, {{100, 0, 200000}, axisCentrality}}); registry.add("trackMCReco/hTrackSize_Filtered", "", {HistType::kTH2D, {{100, 0, 20000}, axisCentrality}}); - registry.get(HIST("trackMCReco/after/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(1, "Secondary"); - registry.get(HIST("trackMCReco/after/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(2, "Primary"); registry.add("trackMCReco/after/incl/hPt_hadron", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); registry.add("trackMCReco/after/incl/hPt_proton", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); registry.add("trackMCReco/after/incl/hPt_pion", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); @@ -547,7 +557,7 @@ struct FlowSP { registry.add("QQCorrelations/qAYqCX", "", kTProfile, {axisCent}); registry.add("QQCorrelations/qAXYqCXY", "", kTProfile, {axisCent}); - if (cfgFillGeneralV1Histos) { + if (cfg.cFillGeneralV1Histos) { // track properties per centrality and per eta, pt bin registry.add("incl/vnCodd", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnAodd", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); @@ -555,48 +565,52 @@ struct FlowSP { registry.add("incl/vnA", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnCSetPlane", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnASetPlane", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); + registry.add("incl/vnOdd", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); + registry.add("incl/vnEven", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillMeanPT) { - registry.add("incl/meanPT/meanRelPtA", "", kTProfile2D, {axisEtaVn, axisCentrality}); - registry.add("incl/meanPT/meanRelPtC", "", kTProfile2D, {axisEtaVn, axisCentrality}); - - registry.add("incl/meanPT/hMeanPtEtaCent", "", kTProfile2D, {axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1A", "", kTProfile2D, {axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1C", "", kTProfile2D, {axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1Aodd", "", kTProfile2D, {axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1Codd", "", kTProfile2D, {axisEtaVn, axisCent}); - registry.add("incl/meanPT/hMeanPtCent", "", kTProfile, {axisCent}); - + if (cfg.cFillMeanPT) { registry.add("incl/meanPT/ptV1A3D", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); registry.add("incl/meanPT/ptV1C3D", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1A3Dx", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1C3Dx", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + if (cfg.cFillMeanPTextra) { + registry.add("incl/meanPT/meanRelPtA", "", kTProfile2D, {axisEtaVn, axisCentrality}); + registry.add("incl/meanPT/meanRelPtC", "", kTProfile2D, {axisEtaVn, axisCentrality}); - registry.add("incl/meanPT/ptV1A3Dy", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); - registry.add("incl/meanPT/ptV1C3Dy", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + registry.add("incl/meanPT/hMeanPtEtaCent", "", kTProfile2D, {axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1A", "", kTProfile2D, {axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1C", "", kTProfile2D, {axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1Aodd", "", kTProfile2D, {axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1Codd", "", kTProfile2D, {axisEtaVn, axisCent}); + registry.add("incl/meanPT/hMeanPtCent", "", kTProfile, {axisCent}); - registry.add("incl/meanPT/meanPxA", "", kTH3D, {axisCent, axisPhiPlane, axisPx}); - registry.add("incl/meanPT/meanPxC", "", kTH3D, {axisCent, axisPhiPlane, axisPx}); + registry.add("incl/meanPT/ptV1A3Dx", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1C3Dx", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + + registry.add("incl/meanPT/ptV1A3Dy", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + registry.add("incl/meanPT/ptV1C3Dy", "", kTProfile3D, {axisPt, axisEtaVn, axisCent}); + + registry.add("incl/meanPT/meanPxA", "", kTH3D, {axisCent, axisPhiPlane, axisPx}); + registry.add("incl/meanPT/meanPxC", "", kTH3D, {axisCent, axisPhiPlane, axisPx}); + } } - if (cfgFillXandYterms) { + if (cfg.cFillXandYterms) { registry.add("incl/vnAx", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnAy", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnCx", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnCy", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillMixedHarmonics) { + if (cfg.cFillMixedHarmonics) { registry.add("incl/MH/vnAxCxUx_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/MH/vnAyCyUx_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/MH/vnAxCyUy_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/MH/vnAyCxUy_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillEventPlane) { + if (cfg.cFillEventPlane) { registry.add("incl/vnA_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnC_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/vnFull_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillEventPlaneQA) { + if (cfg.cFillEventPlaneQA) { histos.add("QA/hSPplaneA", "hSPplaneA", kTH1D, {axisPhiPlane}); histos.add("QA/hSPplaneC", "hSPplaneC", kTH1D, {axisPhiPlane}); histos.add("QA/hSPplaneFull", "hSPplaneFull", kTH1D, {axisPhiPlane}); @@ -609,7 +623,7 @@ struct FlowSP { } // end of doProcessData - if (cfgFillChargeDependence || cfgFillChargeDependenceQA) { + if (cfg.cFillChargeDependence || cfg.cFillChargeDependenceQA) { LOGF(info, "Cloning charge dependence histograms"); registry.addClone("incl/", "pos/"); registry.addClone("incl/", "neg/"); @@ -619,7 +633,7 @@ struct FlowSP { } if (doprocessDataPID) { - if (cfgFillGeneralV1Histos) { + if (cfg.cFillGeneralV1Histos) { registry.add("incl/pion/vnCodd", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnAodd", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnC", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); @@ -628,18 +642,18 @@ struct FlowSP { registry.add("incl/vnASetPlane", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillEventPlane) { + if (cfg.cFillEventPlane) { registry.add("incl/pion/vnA_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnC_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnFull_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillXandYterms) { + if (cfg.cFillXandYterms) { registry.add("incl/pion/vnAx", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnAy", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnCx", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/vnCy", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } - if (cfgFillMixedHarmonics) { + if (cfg.cFillMixedHarmonics) { registry.add("incl/pion/MH/vnAxCxUx_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/MH/vnAyCyUx_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); registry.add("incl/pion/MH/vnAxCyUy_MH", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); @@ -647,7 +661,7 @@ struct FlowSP { } registry.addClone("incl/pion/", "incl/proton/"); registry.addClone("incl/pion/", "incl/kaon/"); - if (cfgFillChargeDependence) { + if (cfg.cFillChargeDependence) { registry.addClone("incl/", "pos/"); registry.addClone("incl/", "neg/"); } @@ -665,22 +679,22 @@ struct FlowSP { registry.addClone("trackMCGen/after/", "trackMCGen/before/"); } - if (cfgEvSelsUseAdditionalEventCut) { + if (cfg.cEvSelsUseAdditionalEventCut) { fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); - std::vector paramsMultPVCut = cfgEvSelsMultPv; - std::vector paramsMultCut = cfgEvSelsMult; + std::vector paramsMultPVCut = cfg.cEvSelsMultPv; + std::vector paramsMultCut = cfg.cEvSelsMult; - // number of parameters required in cfgEvSelsMultPv and cfgEvSelsMult. (5 Low + 5 High) + // number of parameters required in cfg.cEvSelsMultPv and cfg.cEvSelsMult. (5 Low + 5 High) uint64_t nParams = 10; if (paramsMultPVCut.size() < nParams) { - LOGF(fatal, "cfgEvSelsMultPv not set properly.. size = %d (should be 10) --> Check your config files!", paramsMultPVCut.size()); + LOGF(fatal, "cfg.cEvSelsMultPv not set properly.. size = %d (should be 10) --> Check your config files!", paramsMultPVCut.size()); } else if (paramsMultCut.size() < nParams) { - LOGF(fatal, "cfgEvSelsMult not set properly.. size = %d (should be 10) --> Check your config files!", paramsMultCut.size()); + LOGF(fatal, "cfg.cEvSelsMult not set properly.. size = %d (should be 10) --> Check your config files!", paramsMultCut.size()); } else { fMultPVCutLow->SetParameters(paramsMultPVCut[0], paramsMultPVCut[1], paramsMultPVCut[2], paramsMultPVCut[3], paramsMultPVCut[4]); fMultPVCutHigh->SetParameters(paramsMultPVCut[5], paramsMultPVCut[6], paramsMultPVCut[7], paramsMultPVCut[8], paramsMultPVCut[9]); @@ -689,7 +703,7 @@ struct FlowSP { } } - if (cfgTrackSelsUseAdditionalTrackCut) { + if (cfg.cTrackSelsUseAdditionalTrackCut) { fPhiCutLow = new TF1("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); fPhiCutHigh = new TF1("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); } @@ -736,7 +750,7 @@ struct FlowSP { ParticleType valPID = kUnidentified; for (const auto& nsigma : usedNSigma) { - if (std::abs(nsigma.first) < cfgTrackSelsPIDNsigma) { + if (std::abs(nsigma.first) < cfg.cTrackSelsPIDNsigma) { valPID = nsigma.second; nIdentified++; } @@ -783,88 +797,107 @@ struct FlowSP { void loadCorrections(uint64_t timestamp) { // corrections saved on CCDB as TList {incl, pos, neg} of GFWWeights (acc) TH1D (eff) objects! - if (cfg.correctionsLoaded) + if (conf.correctionsLoaded) return; int nWeights = 3; - if (cfgUseNUA1D) { - if (cfgCCDB_NUA.value.empty() == false) { - TList* listCorrections = ccdb->getForTimeStamp(cfgCCDB_NUA, timestamp); - cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights"))); - cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_positive"))); - cfg.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_negative"))); - int sizeAcc = cfg.mAcceptance.size(); + if (cfg.cUseNUA1D) { + if (cfg.cCCDB_NUA.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfg.cCCDB_NUA, timestamp); + conf.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights"))); + conf.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_positive"))); + conf.mAcceptance.push_back(reinterpret_cast(listCorrections->FindObject("weights_negative"))); + int sizeAcc = conf.mAcceptance.size(); if (sizeAcc < nWeights) - LOGF(fatal, "Could not load acceptance weights from %s", cfgCCDB_NUA.value.c_str()); + LOGF(fatal, "Could not load acceptance weights from %s", cfg.cCCDB_NUA.value.c_str()); else - LOGF(info, "Loaded acceptance weights from %s", cfgCCDB_NUA.value.c_str()); + LOGF(info, "Loaded acceptance weights from %s", cfg.cCCDB_NUA.value.c_str()); } else { - LOGF(info, "cfgCCDB_NUA empty! No corrections loaded"); + LOGF(info, "cfg.cCCDB_NUA empty! No corrections loaded"); } - } else if (cfgUseNUA2D) { - if (cfgCCDB_NUA.value.empty() == false) { - TH3D* hNUA2D = ccdb->getForTimeStamp(cfgCCDB_NUA, timestamp); + } else if (cfg.cUseNUA2D) { + if (cfg.cCCDB_NUA.value.empty() == false) { + TH3D* hNUA2D = ccdb->getForTimeStamp(cfg.cCCDB_NUA, timestamp); if (!hNUA2D) { - LOGF(fatal, "Could not load acceptance weights from %s", cfgCCDB_NUA.value.c_str()); + LOGF(fatal, "Could not load acceptance weights from %s", cfg.cCCDB_NUA.value.c_str()); } else { - LOGF(info, "Loaded acceptance weights from %s", cfgCCDB_NUA.value.c_str()); - cfg.mAcceptance2D.push_back(hNUA2D); + LOGF(info, "Loaded acceptance weights from %s", cfg.cCCDB_NUA.value.c_str()); + conf.mAcceptance2D.push_back(hNUA2D); } } else { - LOGF(info, "cfgCCDB_NUA empty! No corrections loaded"); + LOGF(info, "cfg.cCCDB_NUA empty! No corrections loaded"); } } // Get Efficiency correction - if (cfgCCDB_NUE.value.empty() == false) { - TList* listCorrections = ccdb->getForTimeStamp(cfgCCDB_NUE, timestamp); - cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); - cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); - cfg.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); - int sizeEff = cfg.mEfficiency.size(); + if (cfg.cCCDB_NUE.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfg.cCCDB_NUE, timestamp); + conf.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); + conf.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); + conf.mEfficiency.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); + int sizeEff = conf.mEfficiency.size(); if (sizeEff < nWeights) - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCCDB_NUE.value.c_str()); + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfg.cCCDB_NUE.value.c_str()); else - LOGF(info, "Loaded efficiency histogram from %s", cfgCCDB_NUE.value.c_str()); + LOGF(info, "Loaded efficiency histogram from %s", cfg.cCCDB_NUE.value.c_str()); } else { - LOGF(info, "cfgCCDB_NUE empty! No corrections loaded"); + LOGF(info, "cfg.cCCDB_NUE empty! No corrections loaded"); } // Get Efficiency correction - if (cfgCCDB_NUE2D.value.empty() == false) { - TList* listCorrections = ccdb->getForTimeStamp(cfgCCDB_NUE2D, timestamp); - cfg.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); - cfg.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); - cfg.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); - int sizeEff = cfg.mEfficiency2D.size(); + if (cfg.cCCDB_NUE2D.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfg.cCCDB_NUE2D, timestamp); + conf.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); + conf.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); + conf.mEfficiency2D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); + int sizeEff = conf.mEfficiency2D.size(); + if (sizeEff < nWeights) + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfg.cCCDB_NUE.value.c_str()); + else + LOGF(info, "Loaded efficiency histogram from %s", cfg.cCCDB_NUE.value.c_str()); + } else { + LOGF(info, "cfg.cCCDB_NUE2 empty! No corrections loaded"); + } + + if (cfg.cCCDB_NUE3D.value.empty() == false) { + TList* listCorrections = ccdb->getForTimeStamp(cfg.cCCDB_NUE3D, timestamp); + conf.mEfficiency3D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency"))); + conf.mEfficiency3D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_pos"))); + conf.mEfficiency3D.push_back(reinterpret_cast(listCorrections->FindObject("Efficiency_neg"))); + int sizeEff = conf.mEfficiency3D.size(); if (sizeEff < nWeights) - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCCDB_NUE.value.c_str()); + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfg.cCCDB_NUE.value.c_str()); else - LOGF(info, "Loaded efficiency histogram from %s", cfgCCDB_NUE.value.c_str()); + LOGF(info, "Loaded efficiency histogram from %s", cfg.cCCDB_NUE.value.c_str()); } else { - LOGF(info, "cfgCCDB_NUE2 empty! No corrections loaded"); + LOGF(info, "cfg.cCCDB_NUE2 empty! No corrections loaded"); } - cfg.correctionsLoaded = true; + conf.correctionsLoaded = true; } // From Generic Framework bool setCurrentParticleWeights(int pID, int spec, const float& phi, const float& eta, const float& pt, const float& vtxz, const float& centrality) { float eff = 1.; - int sizeEff = cfg.mEfficiency.size(); + int sizeEff = conf.mEfficiency.size(); if (sizeEff > pID) { - if (cfgUseNUE2D) { + if (cfg.cUseNUE3D) { + int binx = conf.mEfficiency3D[pID]->GetXaxis()->FindBin(pt); + int biny = conf.mEfficiency3D[pID]->GetYaxis()->FindBin(eta); + int binz = conf.mEfficiency3D[pID]->GetZaxis()->FindBin(centrality); + eff = conf.mEfficiency3D[pID]->GetBinContent(binx, biny, binz); + } else if (cfg.cUseNUE2D) { int binx; int biny; - if (cfgUseNUE2Deta) { - biny = cfg.mEfficiency2D[pID]->GetYaxis()->FindBin(pt); - binx = cfg.mEfficiency2D[pID]->GetXaxis()->FindBin(eta); + if (cfg.cUseNUE2Deta) { + biny = conf.mEfficiency2D[pID]->GetYaxis()->FindBin(pt); + binx = conf.mEfficiency2D[pID]->GetXaxis()->FindBin(eta); } else { - binx = cfg.mEfficiency2D[pID]->GetXaxis()->FindBin(pt); - biny = cfg.mEfficiency2D[pID]->GetYaxis()->FindBin(centrality); + binx = conf.mEfficiency2D[pID]->GetXaxis()->FindBin(pt); + biny = conf.mEfficiency2D[pID]->GetYaxis()->FindBin(centrality); } - eff = cfg.mEfficiency2D[pID]->GetBinContent(binx, biny); + eff = conf.mEfficiency2D[pID]->GetBinContent(binx, biny); } else { - eff = cfg.mEfficiency[pID]->GetBinContent(cfg.mEfficiency[pID]->FindBin(pt)); + eff = conf.mEfficiency[pID]->GetBinContent(conf.mEfficiency[pID]->FindBin(pt)); } } else { eff = 1.0; @@ -874,16 +907,16 @@ struct FlowSP { spm.weff[pID][spec] = 1. / eff; - if (cfgUseNUA1D) { - int sizeAcc = cfg.mAcceptance.size(); + if (cfg.cUseNUA1D) { + int sizeAcc = conf.mAcceptance.size(); if (sizeAcc > pID) { - spm.wacc[pID][spec] = cfg.mAcceptance[pID]->getNUA(phi, eta, vtxz); + spm.wacc[pID][spec] = conf.mAcceptance[pID]->getNUA(phi, eta, vtxz); } else { spm.wacc[pID][spec] = 1; } - } else if (cfgUseNUA2D) { - if (cfg.mAcceptance2D.size() > 0) { - spm.wacc[pID][spec] = getNUA2D(cfg.mAcceptance2D[0], eta, phi, vtxz); + } else if (cfg.cUseNUA2D) { + if (conf.mAcceptance2D.size() > 0) { + spm.wacc[pID][spec] = getNUA2D(conf.mAcceptance2D[0], eta, phi, vtxz); } else { spm.wacc[pID][spec] = 1; } @@ -898,20 +931,20 @@ struct FlowSP { return 0; histos.fill(HIST("hEventCount"), evSel_sel8); - if (rctFlags.cfgEvtUseRCTFlagChecker && !rctChecker(collision)) + if (cfg.cEvtUseRCTFlagChecker && !rctChecker(collision)) return 0; histos.fill(HIST("hEventCount"), evSel_RCTFlagsZDC); // Occupancy - if (cfgEvSelsDoOccupancySel) { + if (cfg.cEvSelsDoOccupancySel) { auto occupancy = collision.trackOccupancyInTimeRange(); - if (occupancy > cfgEvSelsMaxOccupancy || occupancy < cfgEvSelsMinOccupancy) { + if (occupancy > cfg.cEvSelsMaxOccupancy || occupancy < cfg.cEvSelsMinOccupancy) { return 0; } histos.fill(HIST("hEventCount"), evSel_occupancy); } - if (cfgEvSelsNoSameBunchPileupCut) { + if (cfg.cEvSelsNoSameBunchPileupCut) { if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { // rejects collisions which are associated with the same "found-by-T0" bunch crossing // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof @@ -919,7 +952,7 @@ struct FlowSP { } histos.fill(HIST("hEventCount"), evSel_kNoSameBunchPileup); } - if (cfgEvSelsIsGoodZvtxFT0vsPV) { + if (cfg.cEvSelsIsGoodZvtxFT0vsPV) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference // use this cut at low multiplicities with caution @@ -927,21 +960,21 @@ struct FlowSP { } histos.fill(HIST("hEventCount"), evSel_kIsGoodZvtxFT0vsPV); } - if (cfgEvSelsNoCollInTimeRangeStandard) { + if (cfg.cEvSelsNoCollInTimeRangeStandard) { if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { // Rejection of the collisions which have other events nearby return 0; } histos.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeStandard); } - if (cfgEvSelsNoCollInTimeRangeNarrow) { + if (cfg.cEvSelsNoCollInTimeRangeNarrow) { if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { // Rejection of the collisions which have other events nearby return 0; } histos.fill(HIST("hEventCount"), evSel_kNoCollInTimeRangeNarrow); } - if (cfgEvSelsIsVertexITSTPC) { + if (cfg.cEvSelsIsVertexITSTPC) { if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { // selects collisions with at least one ITS-TPC track, and thus rejects vertices built from ITS-only tracks return 0; @@ -949,7 +982,7 @@ struct FlowSP { histos.fill(HIST("hEventCount"), evSel_kIsVertexITSTPC); } - if (cfgEvSelsIsGoodITSLayersAll) { + if (cfg.cEvSelsIsGoodITSLayersAll) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { // New event selection bits to cut time intervals with dead ITS staves // https://indico.cern.ch/event/1493023/ (09-01-2025) @@ -957,14 +990,14 @@ struct FlowSP { } histos.fill(HIST("hEventCount"), evSel_kIsGoodITSLayersAll); } - if (cfgEvSelsIsGoodITSLayer0123) { + if (cfg.cEvSelsIsGoodITSLayer0123) { if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { return 0; } histos.fill(HIST("hEventCount"), evSel_kIsGoodITSLayer0123); } - if (cfgEvSelsUseAdditionalEventCut) { + if (cfg.cEvSelsUseAdditionalEventCut) { float vtxz = -999; if (collision.numContrib() > 1) { vtxz = collision.posZ(); @@ -977,7 +1010,7 @@ struct FlowSP { auto multNTracksPV = collision.multNTracksPV(); - if (vtxz > cfgEvSelsVtxZ || vtxz < -cfgEvSelsVtxZ) + if (vtxz > cfg.cEvSelsVtxZ || vtxz < -cfg.cEvSelsVtxZ) return 0; if (multNTracksPV < fMultPVCutLow->Eval(collision.centFT0C())) return 0; @@ -997,33 +1030,33 @@ struct FlowSP { template bool trackSelected(TrackObject track, const int& field) { - if (std::fabs(track.eta()) > cfgTrackSelsEta) + if (std::fabs(track.eta()) > cfg.cTrackSelsEta) return false; histos.fill(HIST("hTrackCount"), trackSel_Eta); - if (track.pt() < cfgTrackSelsPtmin || track.pt() > cfgTrackSelsPtmax) + if (track.pt() < cfg.cTrackSelsPtmin || track.pt() > cfg.cTrackSelsPtmax) return false; histos.fill(HIST("hTrackCount"), trackSel_Pt); - if (track.dcaXY() > cfgTrackSelsDCAxy) + if (track.dcaXY() > cfg.cTrackSelsDCAxy) return false; histos.fill(HIST("hTrackCount"), trackSel_DCAxy); - if (track.dcaZ() > cfgTrackSelsDCAz) + if (track.dcaZ() > cfg.cTrackSelsDCAz) return false; - if (cfgTrackSelsDoDCApt && std::fabs(track.dcaZ()) > (cfgTrackSelsDCAptConsMin + (cfgTrackSelsDCApt1 * cfgTrackSelsDCApt2) / (std::pow(track.pt(), 1.1)))) + if (cfg.cTrackSelsDoDCApt && std::fabs(track.dcaZ()) > (cfg.cTrackSelsDCAptConsMin + (cfg.cTrackSelsDCApt1 * cfg.cTrackSelsDCApt2) / (std::pow(track.pt(), 1.1)))) return false; histos.fill(HIST("hTrackCount"), trackSel_DCAz); - if (track.tpcNClsCrossedRows() < cfgTrackSelsNcls) + if (track.tpcNClsCrossedRows() < cfg.cTrackSelsNcls) return false; histos.fill(HIST("hTrackCount"), trackSel_NCls); - if (track.tpcFractionSharedCls() > cfgTrackSelsFshcls) + if (track.tpcFractionSharedCls() > cfg.cTrackSelsFshcls) return false; histos.fill(HIST("hTrackCount"), trackSel_FshCls); @@ -1037,14 +1070,14 @@ struct FlowSP { phimodn += o2::constants::math::PI / 18.0; // to center gap in the middle phimodn = fmod(phimodn, o2::constants::math::PI / 9.0); - if (cfgFillTrackQA && cfgFillQABefore) + if (cfg.cFillTrackQA && cfg.cFillQABefore) histos.fill(HIST("incl/QA/before/pt_phi"), track.pt(), phimodn); - if (cfgTrackSelsUseAdditionalTrackCut) { + if (cfg.cTrackSelsUseAdditionalTrackCut) { if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) return false; // reject track } - if (cfgFillTrackQA) + if (cfg.cFillTrackQA) histos.fill(HIST("incl/QA/after/pt_phi"), track.pt(), phimodn); histos.fill(HIST("hTrackCount"), trackSel_TPCBoundary); return true; @@ -1053,7 +1086,7 @@ struct FlowSP { template inline void fillEventQA(CollisionObject collision, TracksObject tracks) { - if (!cfgFillEventQA) + if (!cfg.cFillEventQA) return; static constexpr std::string_view Time[] = {"before", "after"}; @@ -1074,7 +1107,7 @@ struct FlowSP { histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentFV0A"), collision.centFT0C(), collision.centFV0A(), spm.centWeight); histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/CentFT0C_vs_CentNGlobal"), collision.centFT0C(), collision.centNGlobal(), spm.centWeight); - if (cfgFillEventPlaneQA) { + if (cfg.cFillEventPlaneQA) { if constexpr (o2::framework::has_type_v) { double psiA = 1.0 * std::atan2(collision.qyA(), collision.qxA()); double psiC = 1.0 * std::atan2(collision.qyC(), collision.qxC()); @@ -1107,64 +1140,68 @@ struct FlowSP { if (track.eta() < 0) scale = -1.0; - if (cfgFillGeneralV1Histos) { + if (cfg.cFillGeneralV1Histos) { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAodd"), track.pt(), track.eta(), spm.centrality, scale * (spm.uy * spm.qyA + spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQ)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCodd"), track.pt(), track.eta(), spm.centrality, scale * (spm.uy * spm.qyC + spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnOdd"), track.pt(), track.eta(), spm.centrality, scale * 0.5 * ((spm.uy * spm.qyA + spm.ux * spm.qxA) - (spm.uy * spm.qyC + spm.ux * spm.qxC)) / std::sqrt(std::fabs(spm.corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnEven"), track.pt(), track.eta(), spm.centrality, 0.5 * ((spm.uy * spm.qyA + spm.ux * spm.qxA) + (spm.uy * spm.qyC + spm.ux * spm.qxC)) / std::sqrt(std::fabs(spm.corrQQ)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyA + spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQ)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyC + spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQ)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCSetPlane"), track.pt(), track.eta(), spm.centrality, (spm.uy + spm.ux) / std::sqrt(std::fabs(spm.corrQQ)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnASetPlane"), track.pt(), track.eta(), spm.centrality, (minusQ * spm.ux - spm.uy) / std::sqrt(std::fabs(spm.corrQQ)), weight); } - if (cfgFillMixedHarmonics) { + if (cfg.cFillMixedHarmonics) { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("MH/vnAxCxUx_MH"), track.pt(), track.eta(), spm.centrality, (spm.uxMH * spm.qxA * spm.qxC) / spm.corrQQx, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("MH/vnAyCyUx_MH"), track.pt(), track.eta(), spm.centrality, (spm.uxMH * spm.qyA * spm.qyC) / spm.corrQQy, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("MH/vnAxCyUy_MH"), track.pt(), track.eta(), spm.centrality, (spm.uyMH * spm.qxA * spm.qyC) / spm.corrQQx, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("MH/vnAyCxUy_MH"), track.pt(), track.eta(), spm.centrality, (spm.uyMH * spm.qyA * spm.qxC) / spm.corrQQy, weight); } - if (cfgFillXandYterms) { + if (cfg.cFillXandYterms) { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQx)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyA) / std::sqrt(std::fabs(spm.corrQQy)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQx)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyC) / std::sqrt(std::fabs(spm.corrQQy)), weight); } - if (cfgFillEventPlane) { // only fill for inclusive! + if (cfg.cFillEventPlane) { // only fill for inclusive! registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA_EP"), track.pt(), track.eta(), spm.centrality, spm.vnA, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC_EP"), track.pt(), track.eta(), spm.centrality, spm.vnC, weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnFull_EP"), track.pt(), track.eta(), spm.centrality, spm.vnFull, weight); } - if (cfgFillMeanPT) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtEtaCent"), track.eta(), spm.centrality, track.pt(), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtCent"), spm.centrality, track.pt(), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Aodd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Codd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - + if (cfg.cFillMeanPT) { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); + if (cfg.cFillMeanPTextra) { + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtEtaCent"), track.eta(), spm.centrality, track.pt(), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtCent"), spm.centrality, track.pt(), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Aodd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Codd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); + } } } template inline void fillTrackQA(TrackObject track) { - if (!cfgFillTrackQA) + if (!cfg.cFillTrackQA) return; static constexpr std::string_view Time[] = {"before/", "after/"}; - // NOTE: species[kUnidentified] = "" (when nocfgTrackSelDo) { - if (cfgTrackSelDoTrackQAvsCent) { + // NOTE: species[kUnidentified] = "" (when nocfg.cTrackSelDo) { + if (cfg.cTrackSelDoTrackQAvsCent) { histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta"), track.pt(), track.eta(), spm.centrality, spm.wacc[ct][par] * spm.weff[ct][par]); histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta_uncorrected"), track.pt(), track.eta(), spm.centrality); histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta"), track.phi(), track.eta(), spm.centrality, spm.wacc[ct][par] * spm.weff[ct][par]); @@ -1187,7 +1224,7 @@ struct FlowSP { template inline void fillPIDQA(TrackObject track) { - if (!cfgFillTrackQA) + if (!cfg.cFillTrackQA) return; if constexpr (framework::has_type_v) { histos.fill(HIST(Charge[ct]) + HIST("pion/") + HIST("QA/") + HIST(Time[ft]) + HIST("hNsigmaTOF_pt"), track.pt(), track.tofNSigmaPi()); @@ -1238,15 +1275,15 @@ struct FlowSP { } } - template + template inline void fillPrimaryHistos(McParticleObject mcparticle) { static constexpr std::string_view Time[] = {"/before", "/after"}; if (!mcparticle.isPhysicalPrimary()) { - registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/hIsPhysicalPrimary"), 0, spm.centrality); + registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/") + HIST(Charge[ct]) + HIST("hIsPhysicalPrimary"), 0, spm.centrality, mcparticle.pt()); } else { - registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/hIsPhysicalPrimary"), 1, spm.centrality); + registry.fill(HIST("trackMCReco") + HIST(Time[ft]) + HIST("/") + HIST(Charge[ct]) + HIST("hIsPhysicalPrimary"), 1, spm.centrality, mcparticle.pt()); } } @@ -1256,7 +1293,7 @@ struct FlowSP { fillTrackQA(track); fillPIDQA(track); - if (cfgFillChargeDependenceQA) { + if (cfg.cFillChargeDependenceQA) { switch (spm.charge) { case kPositive: { fillTrackQA(track); @@ -1278,30 +1315,30 @@ struct FlowSP { histos.fill(HIST("hEventCount"), evSel_FilteredEvent); auto bc = collision.bc_as(); int standardMagField = 99999; - auto field = (cfgMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfgMagField; - - if (bc.runNumber() != cfg.lastRunNumber) { - cfg.correctionsLoaded = false; - cfg.clCentrality = false; - cfg.lastRunNumber = bc.runNumber(); - cfg.mAcceptance.clear(); - LOGF(info, "Size of mAcceptance: %i (should be 0)", (int)cfg.mAcceptance.size()); + auto field = (cfg.cMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfg.cMagField; + + if (bc.runNumber() != conf.lastRunNumber) { + conf.correctionsLoaded = false; + conf.clCentrality = false; + conf.lastRunNumber = bc.runNumber(); + conf.mAcceptance.clear(); + LOGF(info, "Size of mAcceptance: %i (should be 0)", (int)conf.mAcceptance.size()); } - if (cfgFillQABefore) + if (cfg.cFillQABefore) fillEventQA(collision, tracks); loadCorrections(bc.timestamp()); spm.centrality = collision.centFT0C(); - if (cfgCentFT0Cvariant1) + if (cfg.cCentFT0Cvariant1) spm.centrality = collision.centFT0CVariant1(); - if (cfgCentFT0M) + if (cfg.cCentFT0M) spm.centrality = collision.centFT0M(); - if (cfgCentFV0A) + if (cfg.cCentFV0A) spm.centrality = collision.centFV0A(); - if (cfgCentNGlobal) + if (cfg.cCentNGlobal) spm.centrality = collision.centNGlobal(); if (!eventSelected(collision, tracks.size())) @@ -1336,10 +1373,10 @@ struct FlowSP { registry.fill(HIST("QQCorrelations/qAqCX"), spm.centrality, spm.qxA * spm.qxC); registry.fill(HIST("QQCorrelations/qAqCY"), spm.centrality, spm.qyA * spm.qyC); - if (cfgFillEventQA) { + if (cfg.cFillEventQA) { histos.fill(HIST("QA/hCentFull"), spm.centrality, 1); } - if (cfgFillEventPlaneQA) { + if (cfg.cFillEventPlaneQA) { histos.fill(HIST("QA/hSPplaneA"), spm.psiA, 1); histos.fill(HIST("QA/hSPplaneC"), spm.psiC, 1); histos.fill(HIST("QA/hSPplaneFull"), spm.psiFull, 1); @@ -1350,7 +1387,7 @@ struct FlowSP { histos.fill(HIST("QA/hFullEvPlaneRes"), spm.centrality, -1 * std::cos(spm.psiA - spm.psiC)); } - if (spm.centrality > cfgCentMax || spm.centrality < cfgCentMin) + if (spm.centrality > cfg.cCentMax || spm.centrality < cfg.cCentMin) return; histos.fill(HIST("hEventCount"), evSel_CentCuts); @@ -1359,38 +1396,38 @@ struct FlowSP { // Only load once! // If not loaded set to 1 - if (cfgCCDBdir_QQ.value.empty() == false) { - if (!cfg.clQQ) { - TList* hcorrList = ccdb->getForTimeStamp(cfgCCDBdir_QQ.value, bc.timestamp()); - cfg.hcorrQQ = reinterpret_cast(hcorrList->FindObject("qAqCXY")); - cfg.hcorrQQx = reinterpret_cast(hcorrList->FindObject("qAqCX")); - cfg.hcorrQQy = reinterpret_cast(hcorrList->FindObject("qAqCY")); - cfg.clQQ = true; + if (cfg.cCCDBdir_QQ.value.empty() == false) { + if (!conf.clQQ) { + TList* hcorrList = ccdb->getForTimeStamp(cfg.cCCDBdir_QQ.value, bc.timestamp()); + conf.hcorrQQ = reinterpret_cast(hcorrList->FindObject("qAqCXY")); + conf.hcorrQQx = reinterpret_cast(hcorrList->FindObject("qAqCX")); + conf.hcorrQQy = reinterpret_cast(hcorrList->FindObject("qAqCY")); + conf.clQQ = true; } - spm.corrQQ = cfg.hcorrQQ->GetBinContent(cfg.hcorrQQ->FindBin(spm.centrality)); - spm.corrQQx = cfg.hcorrQQx->GetBinContent(cfg.hcorrQQx->FindBin(spm.centrality)); - spm.corrQQy = cfg.hcorrQQy->GetBinContent(cfg.hcorrQQy->FindBin(spm.centrality)); + spm.corrQQ = conf.hcorrQQ->GetBinContent(conf.hcorrQQ->FindBin(spm.centrality)); + spm.corrQQx = conf.hcorrQQx->GetBinContent(conf.hcorrQQx->FindBin(spm.centrality)); + spm.corrQQy = conf.hcorrQQy->GetBinContent(conf.hcorrQQy->FindBin(spm.centrality)); } double evPlaneRes = 1.; - if (cfgCCDBdir_SP.value.empty() == false) { - if (!cfg.clEvPlaneRes) { - cfg.hEvPlaneRes = ccdb->getForTimeStamp(cfgCCDBdir_SP.value, bc.timestamp()); - cfg.clEvPlaneRes = true; + if (cfg.cCCDBdir_SP.value.empty() == false) { + if (!conf.clEvPlaneRes) { + conf.hEvPlaneRes = ccdb->getForTimeStamp(cfg.cCCDBdir_SP.value, bc.timestamp()); + conf.clEvPlaneRes = true; } - evPlaneRes = cfg.hEvPlaneRes->GetBinContent(cfg.hEvPlaneRes->FindBin(spm.centrality)); + evPlaneRes = conf.hEvPlaneRes->GetBinContent(conf.hEvPlaneRes->FindBin(spm.centrality)); if (evPlaneRes < 0) LOGF(fatal, " > 0 for centrality %.2f! Cannot determine resolution.. Change centrality ranges!!!", spm.centrality); evPlaneRes = std::sqrt(evPlaneRes); } spm.centWeight = 1.; - if (cfgCCDBdir_centrality.value.empty() == false) { - if (!cfg.clCentrality) { - cfg.hCentrality = ccdb->getForTimeStamp(cfgCCDBdir_centrality.value, bc.timestamp()); - cfg.clCentrality = true; + if (cfg.cCCDBdir_centrality.value.empty() == false) { + if (!conf.clCentrality) { + conf.hCentrality = ccdb->getForTimeStamp(cfg.cCCDBdir_centrality.value, bc.timestamp()); + conf.clCentrality = true; } - double centW = cfg.hCentrality->GetBinContent(cfg.hCentrality->FindBin(spm.centrality)); + double centW = conf.hCentrality->GetBinContent(conf.hCentrality->FindBin(spm.centrality)); if (centW < 0) { spm.centWeight = 0.; LOGF(fatal, "Centrality weight cannot be negative .. setting to 0. for (%.2f)", spm.centrality); @@ -1425,7 +1462,7 @@ struct FlowSP { spm.charge = ((track.sign() > 0)) ? kPositive : kNegative; - if (cfgFillQABefore) { + if (cfg.cFillQABefore) { fillAllQA(track); } @@ -1433,14 +1470,14 @@ struct FlowSP { continue; spm.meanPtWeight = 1.0; - if (cfgCCDBdir_meanPt.value.empty() == false) { - if (!cfg.clMeanPt) { - cfg.hMeanPt = ccdb->getForTimeStamp(cfgCCDBdir_meanPt.value, bc.timestamp()); - cfg.clMeanPt = true; + if (cfg.cCCDBdir_meanPt.value.empty() == false) { + if (!conf.clMeanPt) { + conf.hMeanPt = ccdb->getForTimeStamp(cfg.cCCDBdir_meanPt.value, bc.timestamp()); + conf.clMeanPt = true; } - int etaBin = cfg.hMeanPt->GetXaxis()->FindBin(track.eta()); - int centBin = cfg.hMeanPt->GetYaxis()->FindBin(spm.centrality); - double weight = cfg.hMeanPt->GetBinContent(etaBin, centBin); + int etaBin = conf.hMeanPt->GetXaxis()->FindBin(track.eta()); + int centBin = conf.hMeanPt->GetYaxis()->FindBin(spm.centrality); + double weight = conf.hMeanPt->GetBinContent(etaBin, centBin); if (weight > 0) { spm.meanPtWeight = 1.0 / weight; } else { @@ -1454,15 +1491,15 @@ struct FlowSP { // Fill NUA weights (last 0 is for Data see GFWWeights class (not a weight)) // ToDo: Add pi, ka, proton here! - if (cfgFillWeights) { + if (cfg.cFillWeights) { fWeights->fill(phi, track.eta(), spm.vz, track.pt(), spm.centrality, 0); registry.fill(HIST("weights2D/hPhi_Eta_vz"), phi, track.eta(), spm.vz, 1); } - if (cfgFillWeightsPOS && spm.charge == kPositive) { + if (cfg.cFillWeightsPOS && spm.charge == kPositive) { fWeightsPOS->fill(phi, track.eta(), spm.vz, track.pt(), spm.centrality, 0); registry.fill(HIST("weights2D/hPhi_Eta_vz_positive"), phi, track.eta(), spm.vz, 1); } - if (cfgFillWeightsNEG && spm.charge == kNegative) { + if (cfg.cFillWeightsNEG && spm.charge == kNegative) { fWeightsNEG->fill(phi, track.eta(), spm.vz, track.pt(), spm.centrality, 0); registry.fill(HIST("weights2D/hPhi_Eta_vz_negative"), phi, track.eta(), spm.vz, 1); } @@ -1478,16 +1515,16 @@ struct FlowSP { fillAllQA(track); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - spm.ux = std::cos(cfgHarm * phi); - spm.uy = std::sin(cfgHarm * phi); + spm.ux = std::cos(cfg.cHarm * phi); + spm.uy = std::sin(cfg.cHarm * phi); - spm.uxMH = std::cos(cfgHarmMixed * phi); - spm.uyMH = std::sin(cfgHarmMixed * phi); + spm.uxMH = std::cos(cfg.cHarmMixed * phi); + spm.uyMH = std::sin(cfg.cHarmMixed * phi); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - spm.vnA = std::cos(cfgHarm * (phi - spm.psiA)) / evPlaneRes; - spm.vnC = std::cos(cfgHarm * (phi - spm.psiC)) / evPlaneRes; - spm.vnFull = std::cos(cfgHarm * (phi - spm.psiFull)) / evPlaneRes; + spm.vnA = std::cos(cfg.cHarm * (phi - spm.psiA)) / evPlaneRes; + spm.vnC = std::cos(cfg.cHarm * (phi - spm.psiC)) / evPlaneRes; + spm.vnFull = std::cos(cfg.cHarm * (phi - spm.psiFull)) / evPlaneRes; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1496,7 +1533,7 @@ struct FlowSP { fillHistograms(track); - if (cfgFillChargeDependence) { + if (cfg.cFillChargeDependence) { switch (spm.charge) { case kPositive: fillHistograms(track); @@ -1539,14 +1576,14 @@ struct FlowSP { double meanPxAEvent = sumPxAEvent / meanPxEventCount; double meanPxCEvent = sumPxCEvent / meanPxEventCount; - if (cfgFillMeanPT) { + if (cfg.cFillMeanPTextra) { registry.fill(HIST("incl/meanPT/meanPxA"), spm.centrality, spm.psiA - spm.psiC, meanPxAEvent); registry.fill(HIST("incl/meanPT/meanPxC"), spm.centrality, spm.psiA - spm.psiC, meanPxCEvent); } // Now we want to fill the final relPt histogram // Loop over all eta and fill bins - if (cfgFillMeanPT) { + if (cfg.cFillMeanPTextra) { int nBinsEta = 8; for (int etabin = 1; etabin <= nBinsEta; etabin++) { // eta bin is 1 --> Find centbin!! @@ -1567,7 +1604,7 @@ struct FlowSP { registry.fill(HIST("incl/meanPT/meanRelPtA"), eta, spm.centrality, drelPxA / meanPt, spm.centWeight); registry.fill(HIST("incl/meanPT/meanRelPtC"), eta, spm.centrality, drelPxC / meanPt, spm.centWeight); - if (cfgFillChargeDependence) { + if (cfg.cFillChargeDependence) { registry.fill(HIST("neg/meanPT/meanRelPtA"), eta, spm.centrality, drelPxANeg / meanPtNeg, spm.centWeight); registry.fill(HIST("pos/meanPT/meanRelPtA"), eta, spm.centrality, drelPxAPos / meanPtPos, spm.centWeight); registry.fill(HIST("neg/meanPT/meanRelPtC"), eta, spm.centrality, drelPxCNeg / meanPtNeg, spm.centWeight); @@ -1596,30 +1633,30 @@ struct FlowSP { histos.fill(HIST("hEventCount"), evSel_FilteredEvent); auto bc = collision.bc_as(); int standardMagField = 99999; - auto field = (cfgMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfgMagField; - - if (bc.runNumber() != cfg.lastRunNumber) { - cfg.correctionsLoaded = false; - cfg.clCentrality = false; - cfg.lastRunNumber = bc.runNumber(); - cfg.mAcceptance.clear(); - LOGF(info, "Size of mAcceptance: %i (should be 0)", (int)cfg.mAcceptance.size()); + auto field = (cfg.cMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfg.cMagField; + + if (bc.runNumber() != conf.lastRunNumber) { + conf.correctionsLoaded = false; + conf.clCentrality = false; + conf.lastRunNumber = bc.runNumber(); + conf.mAcceptance.clear(); + LOGF(info, "Size of mAcceptance: %i (should be 0)", (int)conf.mAcceptance.size()); } - if (cfgFillQABefore) + if (cfg.cFillQABefore) fillEventQA(collision, tracks); loadCorrections(bc.timestamp()); spm.centrality = collision.centFT0C(); - if (cfgCentFT0Cvariant1) + if (cfg.cCentFT0Cvariant1) spm.centrality = collision.centFT0CVariant1(); - if (cfgCentFT0M) + if (cfg.cCentFT0M) spm.centrality = collision.centFT0M(); - if (cfgCentFV0A) + if (cfg.cCentFV0A) spm.centrality = collision.centFV0A(); - if (cfgCentNGlobal) + if (cfg.cCentNGlobal) spm.centrality = collision.centNGlobal(); if (!eventSelected(collision, tracks.size())) @@ -1645,45 +1682,45 @@ struct FlowSP { // https://twiki.cern.ch/twiki/pub/ALICE/DirectedFlowAnalysisNote/vn_ZDC_ALICE_INT_NOTE_version02.pdf spm.psiFull = 1.0 * std::atan2(spm.qyA + spm.qyC, spm.qxA + spm.qxC); - if (spm.centrality > cfgCentMax || spm.centrality < cfgCentMin) + if (spm.centrality > cfg.cCentMax || spm.centrality < cfg.cCentMin) return; // Load correlations and SP resolution needed for Scalar Product and event plane methods. // Only load once! // If not loaded set to 1 - if (cfgCCDBdir_QQ.value.empty() == false) { - if (!cfg.clQQ) { - TList* hcorrList = ccdb->getForTimeStamp(cfgCCDBdir_QQ.value, bc.timestamp()); - cfg.hcorrQQ = reinterpret_cast(hcorrList->FindObject("qAqCXY")); - cfg.hcorrQQx = reinterpret_cast(hcorrList->FindObject("qAqCX")); - cfg.hcorrQQy = reinterpret_cast(hcorrList->FindObject("qAqCY")); - cfg.clQQ = true; + if (cfg.cCCDBdir_QQ.value.empty() == false) { + if (!conf.clQQ) { + TList* hcorrList = ccdb->getForTimeStamp(cfg.cCCDBdir_QQ.value, bc.timestamp()); + conf.hcorrQQ = reinterpret_cast(hcorrList->FindObject("qAqCXY")); + conf.hcorrQQx = reinterpret_cast(hcorrList->FindObject("qAqCX")); + conf.hcorrQQy = reinterpret_cast(hcorrList->FindObject("qAqCY")); + conf.clQQ = true; } - spm.corrQQ = cfg.hcorrQQ->GetBinContent(cfg.hcorrQQ->FindBin(spm.centrality)); - spm.corrQQx = cfg.hcorrQQx->GetBinContent(cfg.hcorrQQx->FindBin(spm.centrality)); - spm.corrQQy = cfg.hcorrQQy->GetBinContent(cfg.hcorrQQy->FindBin(spm.centrality)); + spm.corrQQ = conf.hcorrQQ->GetBinContent(conf.hcorrQQ->FindBin(spm.centrality)); + spm.corrQQx = conf.hcorrQQx->GetBinContent(conf.hcorrQQx->FindBin(spm.centrality)); + spm.corrQQy = conf.hcorrQQy->GetBinContent(conf.hcorrQQy->FindBin(spm.centrality)); } double evPlaneRes = 1.; - if (cfgCCDBdir_SP.value.empty() == false) { - if (!cfg.clEvPlaneRes) { - cfg.hEvPlaneRes = ccdb->getForTimeStamp(cfgCCDBdir_SP.value, bc.timestamp()); - cfg.clEvPlaneRes = true; + if (cfg.cCCDBdir_SP.value.empty() == false) { + if (!conf.clEvPlaneRes) { + conf.hEvPlaneRes = ccdb->getForTimeStamp(cfg.cCCDBdir_SP.value, bc.timestamp()); + conf.clEvPlaneRes = true; } - evPlaneRes = cfg.hEvPlaneRes->GetBinContent(cfg.hEvPlaneRes->FindBin(spm.centrality)); + evPlaneRes = conf.hEvPlaneRes->GetBinContent(conf.hEvPlaneRes->FindBin(spm.centrality)); if (evPlaneRes < 0) LOGF(fatal, " > 0 for centrality %.2f! Cannot determine resolution.. Change centrality ranges!!!", spm.centrality); evPlaneRes = std::sqrt(evPlaneRes); } spm.centWeight = 1.; - if (cfgCCDBdir_centrality.value.empty() == false) { - if (!cfg.clCentrality) { - cfg.hCentrality = ccdb->getForTimeStamp(cfgCCDBdir_centrality.value, bc.timestamp()); - cfg.clCentrality = true; + if (cfg.cCCDBdir_centrality.value.empty() == false) { + if (!conf.clCentrality) { + conf.hCentrality = ccdb->getForTimeStamp(cfg.cCCDBdir_centrality.value, bc.timestamp()); + conf.clCentrality = true; } - double centW = cfg.hCentrality->GetBinContent(cfg.hCentrality->FindBin(spm.centrality)); + double centW = conf.hCentrality->GetBinContent(conf.hCentrality->FindBin(spm.centrality)); if (centW < 0) { spm.centWeight = 1. / centW; } else { @@ -1696,7 +1733,7 @@ struct FlowSP { for (const auto& track : tracks) { - ParticleType trackPID = (cfgFillPID || cfgFillPIDQA) ? getTrackPID(track) : kUnidentified; + ParticleType trackPID = (cfg.cFillPID || cfg.cFillPIDQA) ? getTrackPID(track) : kUnidentified; histos.fill(HIST("hPIDcounts"), trackPID, track.pt()); @@ -1707,7 +1744,7 @@ struct FlowSP { spm.charge = ((track.sign() > 0)) ? kPositive : kNegative; - if (cfgFillQABefore) { + if (cfg.cFillQABefore) { switch (trackPID) { case kPions: fillAllQA(track); @@ -1744,16 +1781,16 @@ struct FlowSP { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - spm.ux = std::cos(cfgHarm * phi); - spm.uy = std::sin(cfgHarm * phi); + spm.ux = std::cos(cfg.cHarm * phi); + spm.uy = std::sin(cfg.cHarm * phi); - spm.uxMH = std::cos(cfgHarmMixed * phi); - spm.uyMH = std::sin(cfgHarmMixed * phi); + spm.uxMH = std::cos(cfg.cHarmMixed * phi); + spm.uyMH = std::sin(cfg.cHarmMixed * phi); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - spm.vnA = std::cos(cfgHarm * (phi - spm.psiA)) / evPlaneRes; - spm.vnC = std::cos(cfgHarm * (phi - spm.psiC)) / evPlaneRes; - spm.vnFull = std::cos(cfgHarm * (phi - spm.psiFull)) / evPlaneRes; + spm.vnA = std::cos(cfg.cHarm * (phi - spm.psiA)) / evPlaneRes; + spm.vnC = std::cos(cfg.cHarm * (phi - spm.psiC)) / evPlaneRes; + spm.vnFull = std::cos(cfg.cHarm * (phi - spm.psiFull)) / evPlaneRes; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1773,7 +1810,7 @@ struct FlowSP { break; } - if (cfgFillChargeDependence) { + if (cfg.cFillChargeDependence) { switch (spm.charge) { case kPositive: { switch (trackPID) { @@ -1818,26 +1855,26 @@ struct FlowSP { { auto bc = collision.template bc_as(); int standardMagField = 99999; - auto field = (cfgMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfgMagField; + auto field = (cfg.cMagField == standardMagField) ? getMagneticField(bc.timestamp()) : cfg.cMagField; spm.vz = collision.posZ(); spm.centrality = collision.centFT0C(); - if (cfgCentFT0Cvariant1) + if (cfg.cCentFT0Cvariant1) spm.centrality = collision.centFT0CVariant1(); - if (cfgCentFT0M) + if (cfg.cCentFT0M) spm.centrality = collision.centFT0M(); - if (cfgCentFV0A) + if (cfg.cCentFV0A) spm.centrality = collision.centFV0A(); - if (cfgCentNGlobal) + if (cfg.cCentNGlobal) spm.centrality = collision.centNGlobal(); - if (cfgFillQABefore) + if (cfg.cFillQABefore) fillEventQA(collision, filteredTracks); if (!eventSelected(collision, filteredTracks.size())) return; - if (spm.centrality > cfgCentMax || spm.centrality < cfgCentMin) + if (spm.centrality > cfg.cCentMax || spm.centrality < cfg.cCentMin) return; histos.fill(HIST("hEventCount"), evSel_CentCuts); @@ -1853,28 +1890,33 @@ struct FlowSP { registry.fill(HIST("trackMCReco/hTrackSize_Filtered"), filteredTracks.size(), spm.centrality); for (const auto& track : filteredTracks) { + + if (!track.has_mcParticle()) + continue; + auto mcParticle = track.mcParticle(); + if (track.sign() == 0.0) continue; histos.fill(HIST("hTrackCount"), trackSel_ZeroCharge); - fillMCPtHistos(track, mcParticle.pdgCode()); - fillPrimaryHistos(mcParticle); - - if (!mcParticle.isPhysicalPrimary()) - continue; + if (cfg.cFillWithMCParticle) { + fillMCPtHistos(mcParticle, mcParticle.pdgCode()); + } else { + fillMCPtHistos(track, mcParticle.pdgCode()); + } spm.charge = (track.sign() > 0) ? kPositive : kNegative; int minVal = 100; - if (cfgFilterLeptons && std::abs(mcParticle.pdgCode()) < minVal) { + if (cfg.cFilterLeptons && std::abs(mcParticle.pdgCode()) < minVal) { continue; } // This neglects PID (for now) later use getPID like in data. - if (cfgFillQABefore) { + if (cfg.cFillQABefore) { fillAllQA(track); - if (cfgFillPIDQA) { + if (cfg.cFillPIDQA) { switch (std::abs(mcParticle.pdgCode())) { case kPiPlus: fillAllQA(track); @@ -1889,14 +1931,34 @@ struct FlowSP { } } + fillPrimaryHistos(mcParticle); + if (spm.charge == kPositive) { + fillPrimaryHistos(mcParticle); + } else { + fillPrimaryHistos(mcParticle); + } + if (!trackSelected(track, field)) continue; - fillMCPtHistos(track, mcParticle.pdgCode()); + fillPrimaryHistos(mcParticle); + if (spm.charge == kPositive) { + fillPrimaryHistos(mcParticle); + } else { + fillPrimaryHistos(mcParticle); + } + if (!mcParticle.isPhysicalPrimary()) + continue; + + if (cfg.cFillWithMCParticle) { + fillMCPtHistos(mcParticle, mcParticle.pdgCode()); + } else { + fillMCPtHistos(track, mcParticle.pdgCode()); + } fillAllQA(track); - if (cfgFillPIDQA) { + if (cfg.cFillPIDQA) { switch (std::abs(mcParticle.pdgCode())) { case kPions: fillAllQA(track); @@ -1910,8 +1972,6 @@ struct FlowSP { } } - fillPrimaryHistos(mcParticle); - } // end of track loop } PROCESS_SWITCH(FlowSP, processMCReco, "Process analysis for MC reconstructed events", false); @@ -1940,16 +2000,16 @@ struct FlowSP { auto filteredTrackSlice = filteredTracks.sliceBy(trackPerCollision, col.globalIndex()); spm.centrality = col.centFT0C(); - if (cfgCentFT0Cvariant1) + if (cfg.cCentFT0Cvariant1) spm.centrality = col.centFT0CVariant1(); - if (cfgCentFT0M) + if (cfg.cCentFT0M) spm.centrality = col.centFT0M(); - if (cfgCentFV0A) + if (cfg.cCentFV0A) spm.centrality = col.centFV0A(); - if (cfgCentNGlobal) + if (cfg.cCentNGlobal) spm.centrality = col.centNGlobal(); - if (cfgFillQABefore) + if (cfg.cFillQABefore) fillEventQA(col, filteredTrackSlice); if (trackSlice.size() < 1) { @@ -1961,7 +2021,7 @@ struct FlowSP { continue; } - if (spm.centrality > cfgCentMax || spm.centrality < cfgCentMin) { + if (spm.centrality > cfg.cCentMax || spm.centrality < cfg.cCentMin) { colSelected = false; continue; } @@ -1989,7 +2049,7 @@ struct FlowSP { spm.charge = (pdgInfo->Charge() > 0) ? kPositive : kNegative; int minVal = 100; - if (cfgFilterLeptons && std::abs(pdgCode) < minVal) { + if (cfg.cFilterLeptons && std::abs(pdgCode) < minVal) { continue; } @@ -2003,7 +2063,7 @@ struct FlowSP { registry.fill(HIST("trackMCGen/before/neg/phi_eta_vtxZ_gen"), particle.phi(), particle.eta(), vtxz); } - if (particle.eta() < -cfgTrackSelsEta || particle.eta() > cfgTrackSelsEta || particle.pt() < cfgTrackSelsPtmin || particle.pt() > cfgTrackSelsPtmax) + if (particle.eta() < -cfg.cTrackSelsEta || particle.eta() > cfg.cTrackSelsEta || particle.pt() < cfg.cTrackSelsPtmin || particle.pt() > cfg.cTrackSelsPtmax) continue; fillMCPtHistos(particle, pdgCode); diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index b71bc85dc75..b67a72bd13e 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -21,6 +21,7 @@ #include "PWGCF/GenericFramework/Core/GFWWeights.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/CCDB/ctpRateFetcher.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -75,10 +76,11 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::genericframework; +using namespace o2::aod::rctsel; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; static constexpr double LongArrayDouble[4][2] = {{-2.0, -2.0}, {-2.0, -2.0}, {-2.0, -2.0}, {-2.0, -2.0}}; -static constexpr float TrackCutArray[6][2] = {{2.5f, 2.5f}, {50.0f, 50.0f}, {70.0f, 70.0f}, {5.0f, 5.0f}, {2.0f, 2.0f}, {7.0f, 7.0f}}; +static constexpr float TrackCutArray[7][2] = {{2.5f, 2.5f}, {50.0f, 50.0f}, {70.0f, 70.0f}, {5.0f, 5.0f}, {2.0f, 2.0f}, {7.0f, 7.0f}, {0.f, 0.f}}; struct FlowTask { @@ -97,7 +99,7 @@ struct FlowTask { O2_DEFINE_CONFIGURABLE(cfgEtaVnPt, float, 0.4, "eta range for pt in vn-pt correlations") Configurable> cfgPtPtGaps{"cfgPtPtGaps", {LongArrayDouble[0], 4, 2, {"subevent 1", "subevent 2", "subevent 3", "subevent 4"}, {"etamin", "etamax"}}, "{etamin,etamax} for all ptpt-subevents"}; O2_DEFINE_CONFIGURABLE(cfgEtaGapPtPtEnabled, bool, false, "switch of subevent pt-pt correlations") - Configurable> cfgTrackCuts{"cfgTrackCuts", {TrackCutArray[0], 6, 2, {"chi2 per TPCcls", "TPC cluster", "TPC crossed rows", "ITS cluster", "DCAz", "DCAxy Nsigma"}, {"Nch", "Observable"}}, "separate Nch and observable track selections"}; + Configurable> cfgTrackCuts{"cfgTrackCuts", {TrackCutArray[0], 7, 2, {"chi2 per TPCcls", "TPC cluster", "TPC crossed rows", "ITS cluster", "DCAz", "DCAxy Nsigma", "DCAz Nsigma(override)"}, {"Nch", "Observable"}}, "separate Nch and observable track selections"}; enum TrackCut { // enum for labelledArray track selection kChi2prTPCcls = 0, // max chi2 per TPC clusters @@ -105,7 +107,8 @@ struct FlowTask { kTPCCrossedRows, // minimum TPC crossed rows kITSclu, // minimum ITS found clusters kDCAz, // max DCA to vertex z - kDCAxyNSigma // 0: disable; Cut on number of sigma deviations from expected DCA in the transverse direction, nsigma=7 is the same with global track + kDCAxyNSigma, // 0: disable; Cut on number of sigma deviations from expected DCA in the transverse direction, nsigma=7 is the same with global track + kDCAzNSigma // 0: disable; Cut on number of sigma deviations from expected DCA in the transverse direction }; enum TrackCutGroup { kTrCutNch = 0, @@ -129,6 +132,7 @@ struct FlowTask { O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelRCTflags, std::string, "", "keep empty to disable, usage: 'CentralBarrelTracking', 'CBT_hadronPID' ") O2_DEFINE_CONFIGURABLE(cfgGetInteractionRate, bool, false, "Get interaction rate from CCDB") O2_DEFINE_CONFIGURABLE(cfgUseInteractionRateCut, bool, false, "Use events with low interaction rate") O2_DEFINE_CONFIGURABLE(cfgCutMaxIR, float, 50.0f, "maximum interaction rate (kHz)") @@ -211,7 +215,10 @@ struct FlowTask { // Functional form of pt-dependent DCAxy cut TF1* fPtDepDCAxy = nullptr; TF1* fPtDepDCAxyForNch = nullptr; + TF1* fPtDepDCAz = nullptr; + TF1* fPtDepDCAzForNch = nullptr; O2_DEFINE_CONFIGURABLE(cfgDCAxyFunc, std::string, "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"); + O2_DEFINE_CONFIGURABLE(cfgDCAzFunc, std::string, "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAz cut"); } cfgFuncParas; struct : ConfigurableGroup { @@ -316,6 +323,7 @@ struct FlowTask { std::unordered_map gHadronicRate; ctpRateFetcher mRateFetcher; TH2* gCurrentHadronicRate; + RCTFlagsChecker rctChecker{"CentralBarrelTracking"}; // phi-EP correction std::vector funcEff; @@ -346,7 +354,7 @@ struct FlowTask { registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(3, "after supicious Runs removal"); registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(4, "after additional event cut"); registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(5, "after correction loads"); - registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}}); + registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kNoITSROFrameBorder"); @@ -360,6 +368,7 @@ struct FlowTask { registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "occupancy"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(11, "MultCorrelation"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(12, "cfgEvSelV0AT0ACut"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(13, "RCTflags"); registry.add("hVtxZ", "Vexter Z distribution", {HistType::kTH1D, {axisVertex}}); registry.add("hMult", "Multiplicity distribution", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); @@ -739,6 +748,19 @@ struct FlowTask { cfgFuncParas.fPtDepDCAxyForNch->SetParameter(0, cfgTrackCuts->getData()[kDCAxyNSigma][kTrCutNch]); LOGF(info, "DCAxy pt-dependence function for Nch: %s", Form("%0.1f * %s", cfgTrackCuts->getData()[kDCAxyNSigma][kTrCutNch], cfgFuncParas.cfgDCAxyFunc->c_str())); } + if (cfgTrackCuts->getData()[kDCAzNSigma][kTrCutObs]) { + cfgFuncParas.fPtDepDCAz = new TF1("ptDepDCAz", Form("[0]*%s", cfgFuncParas.cfgDCAzFunc->c_str()), 0.001, 1000); + cfgFuncParas.fPtDepDCAz->SetParameter(0, cfgTrackCuts->getData()[kDCAzNSigma][kTrCutObs]); + LOGF(info, "DCAz pt-dependence function: %s", Form("%0.1f * %s", cfgTrackCuts->getData()[kDCAzNSigma][kTrCutObs], cfgFuncParas.cfgDCAzFunc->c_str())); + } + if (cfgTrackCuts->getData()[kDCAzNSigma][kTrCutNch]) { + cfgFuncParas.fPtDepDCAzForNch = new TF1("ptDepDCAzForNch", Form("[0]*%s", cfgFuncParas.cfgDCAzFunc->c_str()), 0.001, 1000); + cfgFuncParas.fPtDepDCAzForNch->SetParameter(0, cfgTrackCuts->getData()[kDCAzNSigma][kTrCutNch]); + LOGF(info, "DCAz pt-dependence function for Nch: %s", Form("%0.1f * %s", cfgTrackCuts->getData()[kDCAzNSigma][kTrCutNch], cfgFuncParas.cfgDCAzFunc->c_str())); + } + if (!cfgEvSelRCTflags.value.empty()) { + rctChecker.init(cfgEvSelRCTflags.value.c_str(), true); // override initialzation + } } void createOutputObjectsForRun(int runNumber) @@ -1054,6 +1076,11 @@ struct FlowTask { if (cfgFuncParas.cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 11.5); + if (!cfgEvSelRCTflags.value.empty() && !rctChecker(*collision)) + return 0; + if (!cfgEvSelRCTflags.value.empty()) + registry.fill(HIST("hEventCountSpecific"), 12.5); + return 1; } @@ -1076,6 +1103,8 @@ struct FlowTask { { if (cfgTrackCuts->getData()[kDCAxyNSigma][kTrCutObs] && (std::fabs(track.dcaXY()) > cfgFuncParas.fPtDepDCAxy->Eval(track.pt()))) return false; + if (cfgTrackCuts->getData()[kDCAzNSigma][kTrCutObs] && (std::fabs(track.dcaZ()) > cfgFuncParas.fPtDepDCAz->Eval(track.pt()))) + return false; return ((track.tpcNClsFound() >= cfgTrackCuts->getData()[kTPCclu][kTrCutObs]) && (track.tpcNClsCrossedRows() >= cfgTrackCuts->getData()[kTPCCrossedRows][kTrCutObs]) && (track.itsNCls() >= cfgTrackCuts->getData()[kITSclu][kTrCutObs]) && (track.tpcChi2NCl() < cfgTrackCuts->getData()[kChi2prTPCcls][kTrCutObs]) && (std::fabs(track.dcaZ()) < cfgTrackCuts->getData()[kDCAz][kTrCutObs])); } @@ -1084,6 +1113,8 @@ struct FlowTask { { if (cfgTrackCuts->getData()[kDCAxyNSigma][kTrCutNch] && (std::fabs(track.dcaXY()) > cfgFuncParas.fPtDepDCAxyForNch->Eval(track.pt()))) return false; + if (cfgTrackCuts->getData()[kDCAzNSigma][kTrCutNch] && (std::fabs(track.dcaZ()) > cfgFuncParas.fPtDepDCAzForNch->Eval(track.pt()))) + return false; return ((track.tpcNClsFound() >= cfgTrackCuts->getData()[kTPCclu][kTrCutNch]) && (track.tpcNClsCrossedRows() >= cfgTrackCuts->getData()[kTPCCrossedRows][kTrCutNch]) && (track.itsNCls() >= cfgTrackCuts->getData()[kITSclu][kTrCutNch]) && (track.tpcChi2NCl() < cfgTrackCuts->getData()[kChi2prTPCcls][kTrCutNch]) && (std::fabs(track.dcaZ()) < cfgTrackCuts->getData()[kDCAz][kTrCutNch])); } diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 1e4cfa7bbec..6d8e581ab84 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -61,7 +61,6 @@ struct FlowZdcTask { Configurable eventSelection{"eventSelection", 1, "event selection"}; Configurable maxZem{"maxZem", 3099.5, "Max ZEM signal"}; // for ZDC info and analysis - Configurable nBinsAmp{"nBinsAmp", 1025, "nbinsAmp"}; Configurable nBinsADC{"nBinsADC", 1000, "nbinsADC"}; Configurable maxZn{"maxZn", 125.5, "Max ZN signal"}; Configurable maxZp{"maxZp", 125.5, "Max ZP signal"}; @@ -70,9 +69,10 @@ struct FlowZdcTask { Configurable nBinsAmpFT0{"nBinsAmpFT0", 100, "N bins FT0 amp"}; Configurable maxAmpFT0{"maxAmpFT0", 2500, "Max FT0 amp"}; Configurable maxAmpFT0M{"maxAmpFT0M", 2500, "Max FT0M amp"}; - Configurable nBinsAmpFV0{"nBinsAmpFV0", 100, "N bins FV0 amp"}; - Configurable maxAmpFV0{"maxAmpFV0", 2000, "Max FV0 amp"}; + Configurable nBinsAmpFT0M{"nBinsAmpFT0M", 100, "N bins FT0M amp"}; Configurable nBinsZDC{"nBinsZDC", 400, "nBinsZDC"}; + Configurable nBinsZP{"nBinsZP", 50, "nBinsZP"}; + Configurable nBinsZN{"nBinsZN", 50, "nBinsZN"}; Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; Configurable maxNch{"maxNch", 2500, "Max Nch (|eta|<0.8)"}; Configurable nBinsTDC{"nBinsTDC", 150, "nbinsTDC"}; @@ -224,8 +224,8 @@ struct FlowZdcTask { histos.add("ZNCVsFT0C", ";T0C (#times 1/100);ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNCVsFT0M", ";T0A+T0C (#times 1/100);ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNCVsCent", ";T0C cent;ZNC Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZPAZNAVsFT0M", ";T0A+T0C (#times 1/100);ZPA Amplitude;ZNA Amplitude;", kTH3F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZPCZNCVsFT0M", ";T0A+T0C (#times 1/100);ZPC Amplitude;ZNC Amplitude;", kTH3F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}, {nBinsZDC, -0.5, maxZn}}}); + histos.add("ZPAZNAVsFT0M", ";T0A+T0C (#times 1/100);ZPA Amplitude;ZNA Amplitude;", kTH3F, {{{nBinsAmpFT0M, 0., maxAmpFT0M}, {nBinsZP, -0.5, maxZp}, {nBinsZN, -0.5, maxZn}}}); + histos.add("ZPCZNCVsFT0M", ";T0A+T0C (#times 1/100);ZPC Amplitude;ZNC Amplitude;", kTH3F, {{{nBinsAmpFT0M, 0., maxAmpFT0M}, {nBinsZP, -0.5, maxZp}, {nBinsZN, -0.5, maxZn}}}); histos.add("ZPAVsFT0A", ";T0A (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPAVsFT0C", ";T0C (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPAVsFT0M", ";T0A+T0C (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); @@ -269,11 +269,9 @@ struct FlowZdcTask { histos.add("ampFT0C", ";T0C (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); histos.add("ampFT0A", ";T0A (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); histos.add("ampFT0M", ";T0A+T0C (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0M}}); - histos.add("ampFV0A", ";V0A (#times 1/100);", kTH1F, {{nBinsAmpFV0, 0., maxAmpFV0}}); histos.add("NchVsFT0C", ";T0C (#times 1/100, -3.3 < #eta < -2.1);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 950.}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsFT0M", ";T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsFT0A", ";T0A (#times 1/100, 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsNch, minNch, maxNch}}}); - histos.add("NchVsFV0A", ";V0A (#times 1/100, 2.2 < #eta < 5);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFV0, 0., maxAmpFV0}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsEt", ";#it{E}_{T} (|#eta|<0.8);#LTITS+TPC tracks#GT (|#eta|<0.8);", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsMeanPt", ";#it{N}_{ch} (|#eta|<0.8);#LT[#it{p}_{T}]#GT (|#eta|<0.8);", kTProfile, {{nBinsNch, minNch, maxNch}}); histos.add("NchVsNPV", ";#it{N}_{PV} (|#eta|<1);ITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); @@ -406,7 +404,7 @@ struct FlowZdcTask { return true; } - void processQA(ColEvSels::iterator const& collision, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, aod::FV0As const& /*fv0as*/, aod::FT0s const& /*ft0s*/, TheFilteredTracks const& tracks) + void processQA(ColEvSels::iterator const& collision, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, aod::FT0s const& /*ft0s*/, TheFilteredTracks const& tracks) { const auto& foundBC = collision.foundBC_as(); if (!isEventSelected(collision)) { @@ -419,7 +417,7 @@ struct FlowZdcTask { auto zdc = foundBC.zdc(); auto cent = collision.centFT0C(); - float aT0A = 0., aT0C = 0., aV0A = 0.; + float aT0A = 0., aT0C = 0.; if (foundBC.has_ft0()) { for (const auto& amplitude : foundBC.ft0().amplitudeA()) { aT0A += amplitude; @@ -429,11 +427,6 @@ struct FlowZdcTask { } } histos.fill(HIST("hEventCounter"), EvCutLabel::TZero); - if (foundBC.has_fv0a()) { - for (const auto& amplitude : foundBC.fv0a().amplitude()) { - aV0A += amplitude; - } - } const double normT0M{(aT0A + aT0C) / 100.}; float et = 0., meanpt = 0.; int itsTracks = 0, glbTracks = 0; @@ -507,9 +500,7 @@ struct FlowZdcTask { histos.fill(HIST("ampFT0C"), aT0C / 100.); histos.fill(HIST("ampFT0A"), aT0A / 100.); histos.fill(HIST("ampFT0M"), (aT0A + aT0C) / 100.); - histos.fill(HIST("ampFV0A"), aV0A / 100.); // charged particle correlations - histos.fill(HIST("NchVsFV0A"), aV0A / 100., glbTracks); histos.fill(HIST("NchVsFT0A"), aT0A / 100., glbTracks); histos.fill(HIST("NchVsFT0C"), aT0C / 100., glbTracks); histos.fill(HIST("NchVsFT0M"), (aT0A + aT0C) / 100., glbTracks); diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index e1eedcd7744..d86048f7b10 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -74,6 +74,7 @@ #include #include #include +#include #include #include @@ -178,16 +179,16 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgTPCSectorCut, bool, false, "Cut on pt-phi distribution"); } cfgTrackCuts; struct : ConfigurableGroup { - O2_DEFINE_CONFIGURABLE(cfgNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); - O2_DEFINE_CONFIGURABLE(cfgIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); - O2_DEFINE_CONFIGURABLE(cfgIsGoodITSLayersAll, bool, true, "kIsGoodITSLayersAll"); - O2_DEFINE_CONFIGURABLE(cfgNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); - O2_DEFINE_CONFIGURABLE(cfgNoCollInRofStandard, bool, true, "kNoCollInRofStandard"); - O2_DEFINE_CONFIGURABLE(cfgNoHighMultCollInPrevRof, bool, true, "kNoHighMultCollInPrevRof"); - O2_DEFINE_CONFIGURABLE(cfgNoITSROFrameBorder, bool, true, "kNoITSROFrameBorder"); - O2_DEFINE_CONFIGURABLE(cfgNoTimeFrameBorder, bool, true, "kNoTimeFrameBorder"); - O2_DEFINE_CONFIGURABLE(cfgTVXinTRD, bool, true, "kTVXinTRD - Use kTVXinTRD (reject TRD triggered events)"); - O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "kIsVertexITSTPC - Selects collisions with at least one ITS-TPC track"); + O2_DEFINE_CONFIGURABLE(cfgNoSameBunchPileupCut, bool, true, "NoSameBunchPileupCut"); + O2_DEFINE_CONFIGURABLE(cfgIsGoodZvtxFT0vsPV, bool, true, "IsGoodZvtxFT0vsPV"); + O2_DEFINE_CONFIGURABLE(cfgIsGoodITSLayersAll, bool, true, "IsGoodITSLayersAll"); + O2_DEFINE_CONFIGURABLE(cfgNoCollInTimeRangeStandard, bool, true, "NoCollInTimeRangeStandard"); + O2_DEFINE_CONFIGURABLE(cfgNoCollInRofStandard, bool, true, "NoCollInRofStandard"); + O2_DEFINE_CONFIGURABLE(cfgNoHighMultCollInPrevRof, bool, true, "NoHighMultCollInPrevRof"); + O2_DEFINE_CONFIGURABLE(cfgNoITSROFrameBorder, bool, true, "NoITSROFrameBorder"); + O2_DEFINE_CONFIGURABLE(cfgNoTimeFrameBorder, bool, true, "NoTimeFrameBorder"); + O2_DEFINE_CONFIGURABLE(cfgTVXinTRD, bool, true, "TVXinTRD - Use TVXinTRD (reject TRD triggered events)"); + O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "IsVertexITSTPC - Selects collisions with at least one ITS-TPC track"); } cfgEventCutFlags; O2_DEFINE_CONFIGURABLE(cfgOccupancySelection, int, 2000, "Max occupancy selection, -999 to disable"); O2_DEFINE_CONFIGURABLE(cfgDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); @@ -274,54 +275,54 @@ struct FlowGenericFramework { // QA outputs std::map>> th1sList; std::map>> th3sList; - std::vector> histosNpt; - std::vector> histosResoNpt; + std::vector> histosNpt; + std::vector> histosResoNpt; enum OutputTH1Names { - hPhi = 0, - hEta, - hVtxZ, - hMult, - hCent, - hEventSel, - kCount_TH1Names + Phi = 0, + Eta, + VtxZ, + Mult, + Cent, + EventSel, + TH1NameCount }; // NUA outputs enum OutputTH3Names { - hNUAref = 0, - hNUAch, - hNUApi, - hNUAka, - hNUApr, - hPtPhiMult, - kCount_TH3Names + NUAref = 0, + NUAch, + NUApi, + NUAka, + NUApr, + PtPhiMult, + TH3NameCount }; enum CentEstimators { - kCentFT0C = 0, - kCentFT0CVariant1, - kCentFT0M, - kCentFV0A, - kCentNTPV, - kCentNGlobal, - kCentMFT + CentFT0C = 0, + CentFT0CVariant1, + CentFT0M, + CentFV0A, + CentNTPV, + CentNGlobal, + CentMFT }; - std::map centNamesMap = {{kCentFT0C, "FT0C"}, {kCentFT0CVariant1, "FT0C variant1"}, {kCentFT0M, "FT0M"}, {kCentFV0A, "FV0A"}, {kCentNTPV, "NTPV"}, {kCentNGlobal, "NGlobal"}, {kCentMFT, "MFT"}}; + std::map centNamesMap = {{CentFT0C, "FT0C"}, {CentFT0CVariant1, "FT0C variant1"}, {CentFT0M, "FT0M"}, {CentFV0A, "FV0A"}, {CentNTPV, "NTPV"}, {CentNGlobal, "NGlobal"}, {CentMFT, "MFT"}}; enum EventSelFlags { - kFilteredEvent = 1, - kSel8, - kOccupancy, - kTVXinTRD, - kNoSameBunchPileup, - kIsGoodZvtxFT0vsPV, - kNoCollInTimeRangeStandard, - kNoCollInRofStandard, - kNoHighMultCollInPrevRof, - kNoTimeFrameBorder, - kNoITSROFrameBorder, - kIsVertexITSTPC, - kIsGoodITSLayersAll, - kMultCuts, - kTrackCent + FilteredEvent = 1, + Sel8, + Occupancy, + TVXinTRD, + NoSameBunchPileup, + IsGoodZvtxFT0vsPV, + NoCollInTimeRangeStandard, + NoCollInRofStandard, + NoHighMultCollInPrevRof, + NoTimeFrameBorder, + NoITSROFrameBorder, + IsVertexITSTPC, + IsGoodITSLayersAll, + MultCuts, + TrackCent }; struct EventCut { bool enabled; @@ -330,73 +331,73 @@ struct FlowGenericFramework { }; std::vector eventcutflags; enum Particles { - PIONS, - KAONS, - PROTONS + Pions, + Kaons, + Protons }; enum ParticleIDs { - CHARGEDID = 0, - PIONID, - KAONID, - PROTONID, - SPECIESCOUNT + ChargedID = 0, + PionID, + KaonID, + ProtonID, + SpeciesCount }; enum ResoIDs { - K0SIDEBAND1 = 0, - K0SIGNAL, - K0SIDEBAND2, - LAMBDASIDEBAND1, - LAMBDASIGNAL, - LAMBDASIDEBAND2, - RESOCOUNT + K0Sideband1 = 0, + K0Signal, + K0Sideband2, + LambdaSideband1, + LambdaSignal, + LambdaSideband2, + ResonanceCount }; enum OutputSpecies { K0 = 0, - LAMBDA = 1, - PHI = 2, - ANLAMBDA = 3, - REF = 4, - kCount_OutputSpecies + Lambda = 1, + PhiMeson = 2, + LambdaBar = 3, + RefParticle = 4, + OutputSpeciesCount }; enum ParticleCuts { - kCosPA = 0, - kMassMin, - kMassMax, - kPosTrackPt, - kNegTrackPt, - kDCAPosToPVMin, - kDCANegToPVMin, - kDCAxDaughters, - kLifeTime, - kRadiusMin, - kRadiusMax, - kRapidity, - kArmPodMin, - kMassRejection + CosPA = 0, + MassMin, + MassMax, + PosTrackPt, + NegTrackPt, + DCAPosToPVMin, + DCANegToPVMin, + DCAxDaughters, + LifeTime, + RadiusMin, + RadiusMax, + Rapidity, + ArmPodMin, + MassRejection }; enum ParticleSwitches { - kUseParticle = 0, - kUseCosPA, - kMassBins, - kUseDCAxDaughters, - kUseProperLifetime, - kUseV0Radius, - kUseArmPodCut, - kUseCompetingMassRejection + UseParticle = 0, + UseCosPA, + MassBins, + UseDCAxDaughters, + UseProperLifetime, + UseV0Radius, + UseArmPodCut, + UseCompetingMassRejection }; enum V0Selection { - kFillCandidate = 1, - kFillDaughterPt, - kFillMassCut, - kFillRapidityCut, - kFillDCAtoPV, - kFillDCAxDaughters, - kFillV0Radius, - kFillCosPA, - kFillProperLifetime, - kFillArmPodCut, - kFillCompetingMass, - kFillDaughterTrackSelection + FillCandidate = 1, + FillDaughterPt, + FillMassCut, + FillRapidityCut, + FillDCAtoPV, + FillDCAxDaughters, + FillV0Radius, + FillCosPA, + FillProperLifetime, + FillArmPodCut, + FillCompetingMass, + FillDaughterTrackSelection }; // Define global variables @@ -497,7 +498,8 @@ struct FlowGenericFramework { readMatrix(cfgPIDCuts.resonanceSwitches->getData(), resoSwitchVals); printResoCuts(); - for (int i = 0; i < 4; ++i) { // o2-linter: disable=magic-number (maximum of 4 subevents) + int nPtPtSubMax = 4; + for (int i = 0; i < nPtPtSubMax; ++i) { if (cfgPtPtGaps->getData()[i][0] < -1. || cfgPtPtGaps->getData()[i][1] < -1.) continue; o2::analysis::gfw::etagapsPtPt.push_back(std::make_pair(cfgPtPtGaps->getData()[i][0], cfgPtPtGaps->getData()[i][1])); @@ -508,15 +510,15 @@ struct FlowGenericFramework { } // Setup event cuts - eventcutflags.push_back({cfgEventCutFlags.cfgNoSameBunchPileupCut, kNoSameBunchPileup, o2::aod::evsel::kNoSameBunchPileup}); - eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodZvtxFT0vsPV, kIsGoodZvtxFT0vsPV, o2::aod::evsel::kIsGoodZvtxFT0vsPV}); - eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInTimeRangeStandard, kNoCollInTimeRangeStandard, o2::aod::evsel::kNoCollInTimeRangeStandard}); - eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInRofStandard, kNoCollInRofStandard, o2::aod::evsel::kNoCollInRofStandard}); - eventcutflags.push_back({cfgEventCutFlags.cfgNoHighMultCollInPrevRof, kNoHighMultCollInPrevRof, o2::aod::evsel::kNoHighMultCollInPrevRof}); - eventcutflags.push_back({cfgEventCutFlags.cfgNoTimeFrameBorder, kNoTimeFrameBorder, o2::aod::evsel::kNoTimeFrameBorder}); - eventcutflags.push_back({cfgEventCutFlags.cfgNoITSROFrameBorder, kNoITSROFrameBorder, o2::aod::evsel::kNoITSROFrameBorder}); - eventcutflags.push_back({cfgEventCutFlags.cfgIsVertexITSTPC, kIsVertexITSTPC, o2::aod::evsel::kIsVertexITSTPC}); - eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodITSLayersAll, kIsGoodITSLayersAll, o2::aod::evsel::kIsGoodITSLayersAll}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoSameBunchPileupCut, NoSameBunchPileup, o2::aod::evsel::kNoSameBunchPileup}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodZvtxFT0vsPV, IsGoodZvtxFT0vsPV, o2::aod::evsel::kIsGoodZvtxFT0vsPV}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInTimeRangeStandard, NoCollInTimeRangeStandard, o2::aod::evsel::kNoCollInTimeRangeStandard}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInRofStandard, NoCollInRofStandard, o2::aod::evsel::kNoCollInRofStandard}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoHighMultCollInPrevRof, NoHighMultCollInPrevRof, o2::aod::evsel::kNoHighMultCollInPrevRof}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoTimeFrameBorder, NoTimeFrameBorder, o2::aod::evsel::kNoTimeFrameBorder}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoITSROFrameBorder, NoITSROFrameBorder, o2::aod::evsel::kNoITSROFrameBorder}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsVertexITSTPC, IsVertexITSTPC, o2::aod::evsel::kIsVertexITSTPC}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodITSLayersAll, IsGoodITSLayersAll, o2::aod::evsel::kIsGoodITSLayersAll}); for (const auto& cut : eventcutflags) { LOGF(info, "Flag %d is %senabled", cut.histBin, (cut.enabled) ? "" : "not "); } @@ -559,6 +561,10 @@ struct FlowGenericFramework { registryQA.add("MCGen/before/pt_gen", "", {HistType::kTH1D, {ptAxis}}); registryQA.add("MCGen/before/phi_eta_vtxZ_gen", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); registryQA.addClone("MCGen/before/", "MCGen/after/"); + registry.add("MCGen/after/pt_centrality_K0_pion_gen", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("MCGen/after/pt_centrality_Lambda_pion_gen", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("MCGen/after/pt_centrality_pion_gen", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("MCGen/after/pt_centrality_proton_gen", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); if (doprocessOnTheFly) registryQA.add("MCGen/impactParameter", "", {HistType::kTH2D, {{bAxis, nchAxis}}}); } @@ -580,19 +586,12 @@ struct FlowGenericFramework { registryQA.add("trackQA/after/etaNch", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); registryQA.add("trackQA/after/etaPtPt", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); registryQA.add("trackQA/after/etaV0Daughters", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); - - histosNpt.resize(SPECIESCOUNT); - histosNpt[CHARGEDID] = registry.add("nptCh", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); - histosNpt[PIONID] = registry.add("nptPi", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); - histosNpt[KAONID] = registry.add("nptKa", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); - histosNpt[PROTONID] = registry.add("nptPr", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); - histosResoNpt.resize(RESOCOUNT); - histosResoNpt[K0SIDEBAND1] = registry.add("nptK0SB1", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); - histosResoNpt[K0SIGNAL] = registry.add("nptK0Sig", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); - histosResoNpt[K0SIDEBAND2] = registry.add("nptK0SB2", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); - histosResoNpt[LAMBDASIDEBAND1] = registry.add("nptLambdaSB1", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); - histosResoNpt[LAMBDASIGNAL] = registry.add("nptLambdaSig", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); - histosResoNpt[LAMBDASIDEBAND2] = registry.add("nptLambdaSB2", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + if (doprocessMCReco) { + registry.add("trackQA/after/pt_centrality_K0_pion", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("trackQA/after/pt_centrality_Lambda_pion", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("trackQA/after/pt_centrality_pion", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + registry.add("trackQA/after/pt_centrality_proton", "; #it{p}_{T}; Centrality (%)", {HistType::kTH2D, {ptAxis, centAxis}}); + } registryQA.add("eventQA/before/centrality", "; centrality (%); Counts", {HistType::kTH1D, {centAxis}}); registryQA.add("eventQA/before/multiplicity", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); @@ -606,32 +605,21 @@ struct FlowGenericFramework { registryQA.add("eventQA/before/occ_mult_cent", "; occupancy; N_{ch}; centrality (%)", {HistType::kTH3D, {occAxis, nchAxis, centAxis}}); registryQA.addClone("eventQA/before/", "eventQA/after/"); registryQA.add("eventQA/eventSel", "Number of Events;; Counts", {HistType::kTH1D, {{15, 0.5, 15.5}}}); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kFilteredEvent, "Filtered event"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kSel8, "sel8"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kOccupancy, "occupancy"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kTVXinTRD, "kTVXinTRD"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoSameBunchPileup, "kNoSameBunchPileup"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kIsGoodZvtxFT0vsPV, "kIsGoodZvtxFT0vsPV"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoCollInTimeRangeStandard, "kNoCollInTimeRangeStandard"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoCollInRofStandard, "kNoCollInRofStandard"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoHighMultCollInPrevRof, "kNoHighMultCollInPrevRof"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoTimeFrameBorder, "kNoTimeFrameBorder"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoITSROFrameBorder, "kNoITSROFrameBorder"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kIsVertexITSTPC, "kIsVertexITSTPC"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kIsGoodITSLayersAll, "kIsGoodITSLayersAll"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kMultCuts, "after Mult cuts"); - registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kTrackCent, "has track + within cent"); - - registry.add("npt_ch", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_pi", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_ka", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_pr", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_K0_sig", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_K0_sb1", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_K0_sb2", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_Lambda_sig", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_Lambda_sb1", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); - registry.add("npt_Lambda_sb2", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(FilteredEvent, "Filtered event"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(Sel8, "sel8"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(Occupancy, "occupancy"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(TVXinTRD, "TVXinTRD"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsGoodZvtxFT0vsPV, "IsGoodZvtxFT0vsPV"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoCollInTimeRangeStandard, "NoCollInTimeRangeStandard"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoCollInRofStandard, "NoCollInRofStandard"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoHighMultCollInPrevRof, "NoHighMultCollInPrevRof"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoTimeFrameBorder, "NoTimeFrameBorder"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoITSROFrameBorder, "NoITSROFrameBorder"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsVertexITSTPC, "IsVertexITSTPC"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsGoodITSLayersAll, "IsGoodITSLayersAll"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(MultCuts, "after Mult cuts"); + registryQA.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(TrackCent, "has track + within cent"); if (!cfgRunByRun) { if (cfgUsePID) { @@ -645,11 +633,11 @@ struct FlowGenericFramework { } } - AxisSpec axisK0Mass = {resoSwitchVals[kMassBins][K0], resoCutVals[kMassMin][K0], resoCutVals[kMassMax][K0]}; - AxisSpec axisLambdaMass = {resoSwitchVals[kMassBins][LAMBDA], resoCutVals[kMassMin][LAMBDA], resoCutVals[kMassMax][LAMBDA]}; + AxisSpec axisK0Mass = {resoSwitchVals[MassBins][K0], resoCutVals[MassMin][K0], resoCutVals[MassMax][K0]}; + AxisSpec axisLambdaMass = {resoSwitchVals[MassBins][Lambda], resoCutVals[MassMin][Lambda], resoCutVals[MassMax][Lambda]}; // QA histograms for V0s - if (resoSwitchVals[kUseParticle][K0]) { + if (resoSwitchVals[UseParticle][K0]) { registryQA.add("K0/PiPlusTPC_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("K0/PiMinusTPC_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("K0/PiPlusTOF_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); @@ -661,21 +649,21 @@ struct FlowGenericFramework { registryQA.add("K0/hK0s_corrected", "", {HistType::kTH1D, {singleCount}}); registryQA.add("K0/hK0Count", "Number of K0;; Count", {HistType::kTH1D, {{12, 0.5, 12.5}}}); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillCandidate, "K0 candidates"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillDaughterPt, "Daughter pt"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillMassCut, "Mass cut"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillRapidityCut, "Rapidity cut"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillDCAtoPV, "DCA to PV"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillDCAxDaughters, "DCA between daughters"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillV0Radius, "V0radius"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillCosPA, "CosPA"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillProperLifetime, "Proper lifetime"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillArmPodCut, "Armenteros-Podolanski cut"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillCompetingMass, "Competing mass rejection"); - registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(kFillDaughterTrackSelection, "Daughter track selection"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillCandidate, "K0 candidates"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillDaughterPt, "Daughter pt"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillMassCut, "Mass cut"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillRapidityCut, "Rapidity cut"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillDCAtoPV, "DCA to PV"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillDCAxDaughters, "DCA between daughters"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillV0Radius, "V0radius"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillCosPA, "CosPA"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillProperLifetime, "Proper lifetime"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillArmPodCut, "Armenteros-Podolanski cut"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillCompetingMass, "Competing mass rejection"); + registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillDaughterTrackSelection, "Daughter track selection"); } - if (resoSwitchVals[kUseParticle][LAMBDA]) { + if (resoSwitchVals[UseParticle][Lambda]) { registryQA.add("Lambda/PrPlusTPC_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("Lambda/PiMinusTPC_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("Lambda/PrPlusTOF_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); @@ -694,21 +682,45 @@ struct FlowGenericFramework { registryQA.add("Lambda/hLambdas_corrected", "", {HistType::kTH1D, {singleCount}}); registryQA.add("Lambda/hLambdaCount", "Number of Lambda;; Count", {HistType::kTH1D, {{12, 0.5, 12.5}}}); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillCandidate, "Lambda candidates"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillDaughterPt, "Daughter pt"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillMassCut, "Mass cut"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillRapidityCut, "Rapidity cut"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillDCAtoPV, "DCA to PV"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillDCAxDaughters, "DCA between daughters"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillV0Radius, "V0radius"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillCosPA, "CosPA"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillProperLifetime, "Proper lifetime"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillArmPodCut, "Armenteros-Podolanski cut"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillCompetingMass, "Competing mass rejection"); - registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(kFillDaughterTrackSelection, "Daughter track selection"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillCandidate, "Lambda candidates"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillDaughterPt, "Daughter pt"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillMassCut, "Mass cut"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillRapidityCut, "Rapidity cut"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillDCAtoPV, "DCA to PV"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillDCAxDaughters, "DCA between daughters"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillV0Radius, "V0radius"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillCosPA, "CosPA"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillProperLifetime, "Proper lifetime"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillArmPodCut, "Armenteros-Podolanski cut"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillCompetingMass, "Competing mass rejection"); + registryQA.get(HIST("Lambda/hLambdaCount"))->GetXaxis()->SetBinLabel(FillDaughterTrackSelection, "Daughter track selection"); } } + registry.add("npt_ch", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_pi", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_ka", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_pr", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_K0_sig", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_K0_sb1", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_K0_sb2", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_Lambda_sig", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_Lambda_sb1", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + registry.add("npt_Lambda_sb2", "; #it{p}_{T} (GeV/#it{c}; ; centrality (%); fraction)", {HistType::kTProfile2D, {ptAxis, centAxis}}); + + histosNpt.resize(SpeciesCount); + histosNpt[ChargedID] = std::make_unique("nptCh", "; #it{p}_{T} (GeV/#it{c}; Count)", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptCh", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); + histosNpt[PionID] = std::make_unique("nptPi", "; #it{p}_{T} (GeV/#it{c}; Count)", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptPi", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); + histosNpt[KaonID] = std::make_unique("nptKa", "; #it{p}_{T} (GeV/#it{c}; Count)", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptKa", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); + histosNpt[ProtonID] = std::make_unique("nptPr", "; #it{p}_{T} (GeV/#it{c}; Count)", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptPr", "; #it{p}_{T} (GeV/#it{c}; Count)", {HistType::kTH1D, {ptAxis}}); + histosResoNpt.resize(ResonanceCount); + histosResoNpt[K0Sideband1] = std::make_unique("nptK0SB1", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptK0SB1", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + histosResoNpt[K0Signal] = std::make_unique("nptK0Sig", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptK0Sig", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + histosResoNpt[K0Sideband2] = std::make_unique("nptK0SB2", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptK0SB2", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + histosResoNpt[LambdaSideband1] = std::make_unique("nptLambdaSB1", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptLambdaSB1", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + histosResoNpt[LambdaSignal] = std::make_unique("nptLambdaSig", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptLambdaSig", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + histosResoNpt[LambdaSideband2] = std::make_unique("nptLambdaSB2", "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); // registry.add("nptLambdaSB2", "; #it{p}_{T} (GeV/#it{c}; Count", {HistType::kTH1D, {ptAxis}}); + if (o2::analysis::gfw::regions.GetSize() < 0) LOGF(error, "Configuration contains vectors of different size - check the GFWRegions configurable"); for (auto i(0); i < o2::analysis::gfw::regions.GetSize(); ++i) { @@ -893,8 +905,8 @@ struct FlowGenericFramework { printTable(cfgPIDCuts.resonanceSwitches.value, resoSwitchValsF, "Resonance Switches"); } enum QAFillTime { - kBefore, - kAfter + Before, + After }; void addConfigObjectsToObjArray(TObjArray* oba, const std::vector& configs) @@ -947,6 +959,9 @@ struct FlowGenericFramework { cfg.mAcceptance.push_back(ccdb->getForTimeStamp(cfgAcceptance.value + runstr, timestamp)); } } + // Run-by-run efficiencies are not supported at the moment + if (cfg.correctionsLoaded) + return; if (!cfgEfficiency.value.empty()) { if (!cfgUsePIDEfficiencies) { cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); @@ -1062,11 +1077,11 @@ struct FlowGenericFramework { } if (isPion) { - pid = PIONS; + pid = Pions; } else if (isKaon) { - pid = KAONS; + pid = Kaons; } else if (isProton) { - pid = PROTONS; + pid = Protons; } else { return 0; // no particle satisfies the criteria } @@ -1079,14 +1094,14 @@ struct FlowGenericFramework { { // Cut on trigger alias if (cfgEventCutFlags.cfgTVXinTRD) { - if (collision.alias_bit(kTVXinTRD)) { + if (collision.alias_bit(TVXinTRD)) { // TRD triggered // "CMTVX-B-NOPF-TRD,minbias_TVX" return false; } - registryQA.fill(HIST("eventQA/eventSel"), kTVXinTRD); + registryQA.fill(HIST("eventQA/eventSel"), TVXinTRD); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(kTVXinTRD); + th1sList[run][EventSel]->Fill(TVXinTRD); } // Cut on event selection flags for (const auto& cut : eventcutflags) { @@ -1096,7 +1111,7 @@ struct FlowGenericFramework { return false; registryQA.fill(HIST("eventQA/eventSel"), cut.histBin); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(cut.histBin); + th1sList[run][EventSel]->Fill(cut.histBin); } // Cut on vertex if (!selectVertex(collision)) @@ -1150,9 +1165,9 @@ struct FlowGenericFramework { return false; if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) return false; - registryQA.fill(HIST("eventQA/eventSel"), kMultCuts); + registryQA.fill(HIST("eventQA/eventSel"), MultCuts); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(kMultCuts); + th1sList[run][EventSel]->Fill(MultCuts); return true; } @@ -1187,12 +1202,15 @@ struct FlowGenericFramework { { if (std::fabs(track.dcaXY()) > (0.0105f + 0.035f / std::pow(track.pt(), 1.1))) return false; - return ((track.tpcNClsCrossedRows() >= 70) && (track.tpcNClsFound() >= 50) && (track.itsNCls() >= 5)); // o2-linter: disable=magic-number (hard coded default cuts) + int tpcNClsCrossedRowsDefault = 70; + int tpcNClsFoundDefault = 50; + int itsNclsDefault = 5; + return ((track.tpcNClsCrossedRows() >= tpcNClsCrossedRowsDefault) && (track.tpcNClsFound() >= tpcNClsFoundDefault) && (track.itsNCls() >= itsNclsDefault)); } enum DataType { - kReco, - kGen + Reco, + Gen }; template @@ -1205,9 +1223,9 @@ struct FlowGenericFramework { bool withinPtRef = (o2::analysis::gfw::ptreflow < track.pt()) && (track.pt() < o2::analysis::gfw::ptrefup); // within RF pT range if (cfgRunByRun) { if (withinPtRef && !pid_index) - th3sList[run][hNUAref]->Fill(track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow + th3sList[run][NUAref]->Fill(track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow if (withinPtPOI) - th3sList[run][hNUAch + pid_index]->Fill(track.phi(), track.eta(), vtxz); // charged and id'ed particle weights + th3sList[run][NUAch + pid_index]->Fill(track.phi(), track.eta(), vtxz); // charged and id'ed particle weights } else { if (withinPtRef && !pid_index) registryQA.fill(HIST("phi_eta_vtxz_ref"), track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow @@ -1230,7 +1248,7 @@ struct FlowGenericFramework { } } else { if (cfgRunByRun) - th3sList[run][hNUAref]->Fill(track.phi(), track.eta(), vtxz); + th3sList[run][NUAref]->Fill(track.phi(), track.eta(), vtxz); else registryQA.fill(HIST("phi_eta_vtxz_ref"), track.phi(), track.eta(), vtxz); } @@ -1246,36 +1264,36 @@ struct FlowGenericFramework { AxisSpec nchAxis = {o2::analysis::gfw::nchbins, o2::analysis::gfw::nchlow, o2::analysis::gfw::nchup, "N_{ch}"}; AxisSpec centAxis = {o2::analysis::gfw::centbinning, "Centrality (%)"}; AxisSpec ptAxis = {o2::analysis::gfw::ptbinning, "#it{p}_{T} GeV/#it{c}"}; - std::vector> histos(kCount_TH1Names); - histos[hPhi] = registryQA.add(Form("%d/phi", run), "", {HistType::kTH1D, {phiAxis}}); - histos[hEta] = registryQA.add(Form("%d/eta", run), "", {HistType::kTH1D, {etaAxis}}); - histos[hVtxZ] = registryQA.add(Form("%d/vtxz", run), "", {HistType::kTH1D, {vtxAxis}}); - histos[hMult] = registryQA.add(Form("%d/mult", run), "", {HistType::kTH1D, {nchAxis}}); - histos[hCent] = registryQA.add(Form("%d/cent", run), "", {HistType::kTH1D, {centAxis}}); - histos[hEventSel] = registryQA.add(Form("%d/eventSel", run), "Number of Events;; Counts", {HistType::kTH1D, {{11, 0, 11}}}); - histos[hEventSel]->GetXaxis()->SetBinLabel(1, "Filtered event"); - histos[hEventSel]->GetXaxis()->SetBinLabel(2, "sel8"); - histos[hEventSel]->GetXaxis()->SetBinLabel(3, "occupancy"); - histos[hEventSel]->GetXaxis()->SetBinLabel(4, "kTVXinTRD"); - histos[hEventSel]->GetXaxis()->SetBinLabel(5, "kNoSameBunchPileup"); - histos[hEventSel]->GetXaxis()->SetBinLabel(6, "kIsGoodZvtxFT0vsPV"); - histos[hEventSel]->GetXaxis()->SetBinLabel(7, "kNoCollInTimeRangeStandard"); - histos[hEventSel]->GetXaxis()->SetBinLabel(8, "kIsVertexITSTPC"); - histos[hEventSel]->GetXaxis()->SetBinLabel(9, "kIsGoodITSLayersAll"); - histos[hEventSel]->GetXaxis()->SetBinLabel(10, "after Mult cuts"); - histos[hEventSel]->GetXaxis()->SetBinLabel(11, "has track + within cent"); + std::vector> histos(TH1NameCount); + histos[Phi] = registryQA.add(Form("%d/phi", run), "", {HistType::kTH1D, {phiAxis}}); + histos[Eta] = registryQA.add(Form("%d/eta", run), "", {HistType::kTH1D, {etaAxis}}); + histos[VtxZ] = registryQA.add(Form("%d/vtxz", run), "", {HistType::kTH1D, {vtxAxis}}); + histos[Mult] = registryQA.add(Form("%d/mult", run), "", {HistType::kTH1D, {nchAxis}}); + histos[Cent] = registryQA.add(Form("%d/cent", run), "", {HistType::kTH1D, {centAxis}}); + histos[EventSel] = registryQA.add(Form("%d/eventSel", run), "Number of Events;; Counts", {HistType::kTH1D, {{11, 0, 11}}}); + histos[EventSel]->GetXaxis()->SetBinLabel(1, "Filtered event"); + histos[EventSel]->GetXaxis()->SetBinLabel(2, "sel8"); + histos[EventSel]->GetXaxis()->SetBinLabel(3, "occupancy"); + histos[EventSel]->GetXaxis()->SetBinLabel(4, "TVXinTRD"); + histos[EventSel]->GetXaxis()->SetBinLabel(5, "NoSameBunchPileup"); + histos[EventSel]->GetXaxis()->SetBinLabel(6, "IsGoodZvtxFT0vsPV"); + histos[EventSel]->GetXaxis()->SetBinLabel(7, "NoCollInTimeRangeStandard"); + histos[EventSel]->GetXaxis()->SetBinLabel(8, "IsVertexITSTPC"); + histos[EventSel]->GetXaxis()->SetBinLabel(9, "IsGoodITSLayersAll"); + histos[EventSel]->GetXaxis()->SetBinLabel(10, "after Mult cuts"); + histos[EventSel]->GetXaxis()->SetBinLabel(11, "has track + within cent"); th1sList.insert(std::make_pair(run, histos)); - std::vector> histos3d(kCount_TH3Names); + std::vector> histos3d(TH3NameCount); if (cfgUsePID) { - histos3d[hNUAref] = registryQA.add(Form("%d/phi_eta_vtxz_ref", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - histos3d[hNUAch] = registryQA.add(Form("%d/phi_eta_vtxz_ch", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - histos3d[hNUApi] = registryQA.add(Form("%d/phi_eta_vtxz_pi", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - histos3d[hNUAka] = registryQA.add(Form("%d/phi_eta_vtxz_ka", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - histos3d[hNUApr] = registryQA.add(Form("%d/phi_eta_vtxz_pr", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUAref] = registryQA.add(Form("%d/phi_eta_vtxz_ref", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUAch] = registryQA.add(Form("%d/phi_eta_vtxz_ch", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUApi] = registryQA.add(Form("%d/phi_eta_vtxz_pi", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUAka] = registryQA.add(Form("%d/phi_eta_vtxz_ka", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUApr] = registryQA.add(Form("%d/phi_eta_vtxz_pr", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); } else { - histos3d[hNUAref] = registryQA.add(Form("%d/phi_eta_vtxz_ref", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + histos3d[NUAref] = registryQA.add(Form("%d/phi_eta_vtxz_ref", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); } - histos3d[hPtPhiMult] = registryQA.add(Form("%d/pt_phi_mult", run), "", {HistType::kTH3D, {ptAxis, phiModAxis, (cfgUseNch) ? nchAxis : centAxis}}); + histos3d[PtPhiMult] = registryQA.add(Form("%d/pt_phi_mult", run), "", {HistType::kTH3D, {ptAxis, phiModAxis, (cfgUseNch) ? nchAxis : centAxis}}); th3sList.insert(std::make_pair(run, histos3d)); return; } @@ -1304,7 +1322,7 @@ struct FlowGenericFramework { continue; auto val = fGFW->Calculate(corrconfigs.at(l_ind), 0, kFALSE).real() / dnx; if (std::abs(val) < 1) { - (dt == kGen) ? fFCgen->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + (dt == Gen) ? fFCgen->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); if (cfgUseGapMethod) { fFCpt->fillVnPtProfiles(centmult, val, dnx, rndm, o2::analysis::gfw::configs.GetpTCorrMasks()[l_ind]); } @@ -1317,51 +1335,51 @@ struct FlowGenericFramework { continue; auto val = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, kFALSE).real() / dnx; if (std::abs(val) < 1) - (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); } } - if (histosNpt[CHARGEDID]->Integral() <= 0) + if (histosNpt[ChargedID]->Integral() <= 0) return; - double dnPi = histosNpt[CHARGEDID]->Integral(); - double dnKa = histosNpt[CHARGEDID]->Integral(); - double dnPr = histosNpt[CHARGEDID]->Integral(); + double dnPi = histosNpt[ChargedID]->Integral(); + double dnKa = histosNpt[ChargedID]->Integral(); + double dnPr = histosNpt[ChargedID]->Integral(); if (cfgUsePIDTotal) { - dnPi = histosNpt[PIONID]->Integral(); - dnKa = histosNpt[KAONID]->Integral(); - dnPr = histosNpt[PROTONID]->Integral(); + dnPi = histosNpt[PionID]->Integral(); + dnKa = histosNpt[KaonID]->Integral(); + dnPr = histosNpt[ProtonID]->Integral(); } for (int i = 1; i <= fPtAxis->GetNbins(); ++i) { - registry.fill(HIST("npt_ch"), fPtAxis->GetBinCenter(i), centmult, histosNpt[CHARGEDID]->GetBinContent(i) / histosNpt[CHARGEDID]->Integral()); + registry.fill(HIST("npt_ch"), fPtAxis->GetBinCenter(i), centmult, histosNpt[ChargedID]->GetBinContent(i) / histosNpt[ChargedID]->Integral()); if (dnPi > 0) - registry.fill(HIST("npt_pi"), fPtAxis->GetBinCenter(i), centmult, histosNpt[PIONID]->GetBinContent(i) / dnPi); + registry.fill(HIST("npt_pi"), fPtAxis->GetBinCenter(i), centmult, histosNpt[PionID]->GetBinContent(i) / dnPi); if (dnKa > 0) - registry.fill(HIST("npt_ka"), fPtAxis->GetBinCenter(i), centmult, histosNpt[KAONID]->GetBinContent(i) / dnKa); + registry.fill(HIST("npt_ka"), fPtAxis->GetBinCenter(i), centmult, histosNpt[KaonID]->GetBinContent(i) / dnKa); if (dnPr > 0) - registry.fill(HIST("npt_pr"), fPtAxis->GetBinCenter(i), centmult, histosNpt[PROTONID]->GetBinContent(i) / dnPr); + registry.fill(HIST("npt_pr"), fPtAxis->GetBinCenter(i), centmult, histosNpt[ProtonID]->GetBinContent(i) / dnPr); } - if (corrconfigsV02.size() < SPECIESCOUNT) + if (corrconfigsV02.size() < SpeciesCount) return; // For alternative normalisation with integrated pid spectra - std::vector dns = {histosNpt[CHARGEDID]->Integral(), dnPi, dnKa, dnPr}; + std::vector dns = {histosNpt[ChargedID]->Integral(), dnPi, dnKa, dnPr}; - for (uint l_ind = 0; l_ind < SPECIESCOUNT; ++l_ind) { + for (uint l_ind = 0; l_ind < SpeciesCount; ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { auto dnx = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kTRUE).real(); if (dnx == 0) continue; auto val = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kFALSE).real() / dnx; if (std::abs(val) < 1 && dns[l_ind] > 0) - (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); } } - if (corrconfigsV0.size() < SPECIESCOUNT) + if (corrconfigsV0.size() < SpeciesCount) return; double mpt = 0; @@ -1372,16 +1390,17 @@ struct FlowGenericFramework { } else { if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) return; - double mpt_sub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; - double mpt_sub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; - mpt = 0.5 * (mpt_sub1 + mpt_sub2); + double mptSub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; + double mptSub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; + mpt = 0.5 * (mptSub1 + mptSub2); } if (std::isnan(mpt)) return; - for (uint l_ind = 0; l_ind < SPECIESCOUNT; ++l_ind) { + + for (uint l_ind = 0; l_ind < SpeciesCount; ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { if (dns[l_ind] > 0) - (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], 1., rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], 1., rndm); + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], 1., rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosNpt[l_ind]->GetBinContent(i) / dns[l_ind], 1., rndm); } } return; @@ -1392,18 +1411,18 @@ struct FlowGenericFramework { { if (tracks.size() < 1) return; - if (dt != kGen && (centrality < o2::analysis::gfw::centbinning.front() || centrality > o2::analysis::gfw::centbinning.back())) + if (dt != Gen && (centrality < o2::analysis::gfw::centbinning.front() || centrality > o2::analysis::gfw::centbinning.back())) return; - if (dt != kGen) { - registryQA.fill(HIST("eventQA/eventSel"), kTrackCent); + if (dt != Gen) { + registryQA.fill(HIST("eventQA/eventSel"), TrackCent); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(kTrackCent); + th1sList[run][EventSel]->Fill(TrackCent); } float vtxz = collision.posZ(); - if (dt != kGen && cfgRunByRun) { - th1sList[run][hVtxZ]->Fill(vtxz); - th1sList[run][hMult]->Fill(tracks.size()); - th1sList[run][hCent]->Fill(centrality); + if (dt != Gen && cfgRunByRun) { + th1sList[run][VtxZ]->Fill(vtxz); + th1sList[run][Mult]->Fill(tracks.size()); + th1sList[run][Cent]->Fill(centrality); } fGFW->Clear(); fFCpt->clearVector(); @@ -1451,8 +1470,10 @@ struct FlowGenericFramework { for (const auto& track : tracks) { processTrack(track, vtxz, field, run, densitycorrections, acceptedTracks); } - registryQA.fill(HIST("trackQA/after/Nch_corrected"), acceptedTracks.total); - registryQA.fill(HIST("trackQA/after/Nch_uncorrected"), acceptedTracks.totaluncorr); + if (dt != Gen) { + registryQA.fill(HIST("trackQA/after/Nch_corrected"), acceptedTracks.total); + registryQA.fill(HIST("trackQA/after/Nch_uncorrected"), acceptedTracks.totaluncorr); + } int multiplicity = 0; switch (cfgUseNchCorrection) { @@ -1479,64 +1500,95 @@ struct FlowGenericFramework { for (const auto& h : histosResoNpt) h->Reset("ICESM"); - // Process V0s - for (const auto& v0 : v0s) { - if (resoSwitchVals[kUseParticle][K0]) { - double weff = 1; - if (selectK0(collision, v0, centrality, weff)) { - if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand1Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand1Max) - histosResoNpt[K0SIDEBAND1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mK0Short() > cfgPIDCuts.cfgK0SignalMin && v0.mK0Short() < cfgPIDCuts.cfgK0SignalMax) - histosResoNpt[K0SIGNAL]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand2Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand2Max) - histosResoNpt[K0SIDEBAND2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + // Process V0s only for reconstructed-track workflows. + if constexpr (dt != Gen) { + for (const auto& v0 : v0s) { + if (resoSwitchVals[UseParticle][K0]) { + double weff = 1; + if (selectK0(collision, v0, tracks, centrality, weff)) { + if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand1Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand1Max) + histosResoNpt[K0Sideband1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (v0.mK0Short() > cfgPIDCuts.cfgK0SignalMin && v0.mK0Short() < cfgPIDCuts.cfgK0SignalMax) + histosResoNpt[K0Signal]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand2Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand2Max) + histosResoNpt[K0Sideband2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + } + } + if (resoSwitchVals[UseParticle][Lambda]) { + double weff = 1.; + if (selectLambda(collision, v0, tracks, centrality, weff)) { + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand1Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand1Max) + histosResoNpt[LambdaSideband1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSignalMin && v0.mLambda() < cfgPIDCuts.cfgLambdaSignalMax) + histosResoNpt[LambdaSignal]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand2Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand2Max) + histosResoNpt[LambdaSideband2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + } } } - if (resoSwitchVals[kUseParticle][LAMBDA]) { - double weff = 1.; - if (selectLambda(collision, v0, centrality, weff)) { - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand1Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand1Max) - histosResoNpt[LAMBDASIDEBAND1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSignalMin && v0.mLambda() < cfgPIDCuts.cfgLambdaSignalMax) - histosResoNpt[LAMBDASIGNAL]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand2Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand2Max) - histosResoNpt[LAMBDASIDEBAND2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + } else { + for (const auto& particle : tracks) { + if (!particle.has_daughters()) + continue; + + bool isK0 = (particle.pdgCode() == PDG_t::kK0Short); + bool isLambda = (particle.pdgCode() == PDG_t::kLambda0); + + if (!isK0 && !isLambda) + continue; + + if (isK0) + histosResoNpt[K0Signal]->Fill(particle.pt(), 1.0); + if (isLambda) + histosResoNpt[LambdaSignal]->Fill(particle.pt(), 1.0); + + // For efficiency + for (const auto& d : particle.template daughters_as()) { + if (std::abs(d.pdgCode()) == PDG_t::kPiPlus) { + if (isK0) + registry.fill(HIST("MCGen/after/pt_centrality_K0_pion_gen"), d.pt(), centrality); + if (isLambda) + registry.fill(HIST("MCGen/after/pt_centrality_Lambda_pion_gen"), d.pt(), centrality); + registry.fill(HIST("MCGen/after/pt_centrality_pion_gen"), d.pt(), centrality); + } + if (std::abs(d.pdgCode()) == PDG_t::kProton) + registry.fill(HIST("MCGen/after/pt_centrality_proton_gen"), d.pt(), centrality); } } } - if (histosNpt[CHARGEDID]->Integral() <= 0) + if (histosNpt[ChargedID]->Integral() <= 0) return; - double dnK0SB1 = histosNpt[CHARGEDID]->Integral(); - double dnK0Sig = histosNpt[CHARGEDID]->Integral(); - double dnK0SB2 = histosNpt[CHARGEDID]->Integral(); - double dnLambdaSB1 = histosNpt[CHARGEDID]->Integral(); - double dnLambdaSig = histosNpt[CHARGEDID]->Integral(); - double dnLambdaSB2 = histosNpt[CHARGEDID]->Integral(); + double dnK0SB1 = histosNpt[ChargedID]->Integral(); + double dnK0Sig = histosNpt[ChargedID]->Integral(); + double dnK0SB2 = histosNpt[ChargedID]->Integral(); + double dnLambdaSB1 = histosNpt[ChargedID]->Integral(); + double dnLambdaSig = histosNpt[ChargedID]->Integral(); + double dnLambdaSB2 = histosNpt[ChargedID]->Integral(); if (cfgUsePIDTotal) { - dnK0SB1 = histosResoNpt[K0SIDEBAND1]->Integral(); - dnK0Sig = histosResoNpt[K0SIGNAL]->Integral(); - dnK0SB2 = histosResoNpt[K0SIDEBAND2]->Integral(); - dnLambdaSB1 = histosResoNpt[LAMBDASIDEBAND1]->Integral(); - dnLambdaSig = histosResoNpt[LAMBDASIGNAL]->Integral(); - dnLambdaSB2 = histosResoNpt[LAMBDASIDEBAND2]->Integral(); + dnK0SB1 = histosResoNpt[K0Sideband1]->Integral(); + dnK0Sig = histosResoNpt[K0Signal]->Integral(); + dnK0SB2 = histosResoNpt[K0Sideband2]->Integral(); + dnLambdaSB1 = histosResoNpt[LambdaSideband1]->Integral(); + dnLambdaSig = histosResoNpt[LambdaSignal]->Integral(); + dnLambdaSB2 = histosResoNpt[LambdaSideband2]->Integral(); } for (int i = 1; i <= fPtAxis->GetNbins(); ++i) { if (dnK0SB1 > 0) - registry.fill(HIST("npt_K0_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0SIDEBAND1]->GetBinContent(i) / dnK0SB1); + registry.fill(HIST("npt_K0_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0Sideband1]->GetBinContent(i) / dnK0SB1); if (dnK0Sig > 0) - registry.fill(HIST("npt_K0_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0SIGNAL]->GetBinContent(i) / dnK0Sig); + registry.fill(HIST("npt_K0_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0Signal]->GetBinContent(i) / dnK0Sig); if (dnK0SB2 > 0) - registry.fill(HIST("npt_K0_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0SIDEBAND2]->GetBinContent(i) / dnK0SB2); + registry.fill(HIST("npt_K0_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[K0Sideband2]->GetBinContent(i) / dnK0SB2); if (dnLambdaSB1 > 0) - registry.fill(HIST("npt_Lambda_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LAMBDASIDEBAND1]->GetBinContent(i) / dnLambdaSB1); + registry.fill(HIST("npt_Lambda_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LambdaSideband1]->GetBinContent(i) / dnLambdaSB1); if (dnLambdaSig > 0) - registry.fill(HIST("npt_Lambda_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LAMBDASIGNAL]->GetBinContent(i) / dnLambdaSig); + registry.fill(HIST("npt_Lambda_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LambdaSignal]->GetBinContent(i) / dnLambdaSig); if (dnLambdaSB2 > 0) - registry.fill(HIST("npt_Lambda_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LAMBDASIDEBAND2]->GetBinContent(i) / dnLambdaSB2); + registry.fill(HIST("npt_Lambda_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[LambdaSideband2]->GetBinContent(i) / dnLambdaSB2); } std::vector dns = {dnK0SB1, dnK0Sig, dnK0SB2, dnLambdaSB1, dnLambdaSig, dnLambdaSB2}; @@ -1548,23 +1600,33 @@ struct FlowGenericFramework { continue; auto val = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kFALSE).real() / dnx; if (std::abs(val) < 1 && dns[l_ind - 4] > 0) - (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgUseMultiplicityFlowWeights ? dnx : 1.0, lRandom) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgUseMultiplicityFlowWeights ? dnx : 1.0, lRandom); + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgUseMultiplicityFlowWeights ? dnx : 1.0, lRandom) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgUseMultiplicityFlowWeights ? dnx : 1.0, lRandom); } } if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) return; - double mpt_sub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; - double mpt_sub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; - double mpt = 0.5 * (mpt_sub1 + mpt_sub2); + double mpt = 0; + if (cfgEtaPtPt->first * cfgEtaPtPt->second >= 0) { + if (fFCpt->corrDen[1] == 0.) + return; + mpt = fFCpt->corrNum[1] / fFCpt->corrDen[1]; + } else { + if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) + return; + double mptSub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; + double mptSub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; + mpt = 0.5 * (mptSub1 + mptSub2); + } + if (std::isnan(mpt)) return; for (uint l_ind = 4; l_ind < corrconfigsV0.size(); ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { if (dns[l_ind] > 0) - (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, lRandom) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, lRandom); + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, lRandom) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, lRandom); } } } @@ -1580,7 +1642,7 @@ struct FlowGenericFramework { if (!mcParticle.isPhysicalPrimary()) return; if (cfgFillQA) - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); if (mcParticle.eta() < o2::analysis::gfw::etalow || mcParticle.eta() > o2::analysis::gfw::etaup || mcParticle.pt() < o2::analysis::gfw::ptlow || mcParticle.pt() > o2::analysis::gfw::ptup) return; @@ -1600,40 +1662,38 @@ struct FlowGenericFramework { return; int pidIndex = 0; - if (cfgUsePID) { - if (std::abs(mcParticle.pdgCode()) == kPiPlus) - pidIndex = PIONID; - if (std::abs(mcParticle.pdgCode()) == kKPlus) - pidIndex = KAONID; - if (std::abs(mcParticle.pdgCode()) == kProton) - pidIndex = PROTONID; - } + if (std::abs(mcParticle.pdgCode()) == kPiPlus) + pidIndex = PionID; + if (std::abs(mcParticle.pdgCode()) == kKPlus) + pidIndex = KaonID; + if (std::abs(mcParticle.pdgCode()) == kProton) + pidIndex = ProtonID; if (track.eta() > cfgEtaNch->first && track.eta() < cfgEtaNch->second) { double weff = getEfficiency(track, pidIndex); if (weffCh > 0) - histosNpt[CHARGEDID]->Fill(track.pt(), (cfgUseNchCorrection) ? weffCh : 1.0); - if (pidIndex == PIONID && weff > 0) - histosNpt[PIONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (pidIndex == KAONID && weff > 0) - histosNpt[KAONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (pidIndex == PROTONID && weff > 0) - histosNpt[PROTONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + histosNpt[ChargedID]->Fill(track.pt(), (cfgUseNchCorrection) ? weffCh : 1.0); + if (pidIndex == PionID && weff > 0) + histosNpt[PionID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (pidIndex == KaonID && weff > 0) + histosNpt[KaonID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (pidIndex == ProtonID && weff > 0) + histosNpt[ProtonID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); } if (cfgFillWeights) { fillWeights(mcParticle, vtxz, 0, run); } else { - fillPtSums(track, vtxz); - fillGFW(mcParticle, vtxz, pidIndex, densitycorrections); + fillPtSums(track, vtxz); + fillGFW(mcParticle, vtxz, pidIndex, densitycorrections); } if (cfgFillQA) { - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); if (cfgRunByRun) { - th1sList[run][hPhi]->Fill(track.phi()); - th1sList[run][hEta]->Fill(track.eta()); + th1sList[run][Phi]->Fill(track.phi()); + th1sList[run][Eta]->Fill(track.eta()); } } @@ -1641,42 +1701,38 @@ struct FlowGenericFramework { if (!track.isPhysicalPrimary()) return; if (cfgFillQA) - fillTrackQA(track, vtxz); - + fillTrackQA(track, vtxz); if (track.eta() < o2::analysis::gfw::etalow || track.eta() > o2::analysis::gfw::etaup || track.pt() < o2::analysis::gfw::ptlow || track.pt() > o2::analysis::gfw::ptup) return; - int pidIndex = 0; - if (cfgUsePID) { - if (std::abs(track.pdgCode()) == kPiPlus) - pidIndex = 1; - if (std::abs(track.pdgCode()) == kKPlus) - pidIndex = 2; - if (std::abs(track.pdgCode()) == kProton) - pidIndex = 3; - } + if (std::abs(track.pdgCode()) == kPiPlus) + pidIndex = PionID; + if (std::abs(track.pdgCode()) == kKPlus) + pidIndex = KaonID; + if (std::abs(track.pdgCode()) == kProton) + pidIndex = ProtonID; if (track.eta() > cfgEtaNch->first && track.eta() < cfgEtaNch->second) { ++acceptedTracks.total; ++acceptedTracks.totaluncorr; - histosNpt[CHARGEDID]->Fill(track.pt()); - if (pidIndex == PIONID) - histosNpt[PIONID]->Fill(track.pt()); - if (pidIndex == KAONID) - histosNpt[KAONID]->Fill(track.pt()); - if (pidIndex == PROTONID) - histosNpt[PROTONID]->Fill(track.pt()); + histosNpt[ChargedID]->Fill(track.pt()); + if (pidIndex == PionID) + histosNpt[PionID]->Fill(track.pt()); + if (pidIndex == KaonID) + histosNpt[KaonID]->Fill(track.pt()); + if (pidIndex == ProtonID) + histosNpt[ProtonID]->Fill(track.pt()); } - fillPtSums(track, vtxz); - fillGFW(track, vtxz, pidIndex, densitycorrections); - + fillPtSums(track, vtxz); + fillGFW(track, vtxz, pidIndex, densitycorrections); if (cfgFillQA) - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); + } else { if (cfgFillQA) - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); // Select tracks with nominal cuts always if (!nchSelected(track)) return; @@ -1698,26 +1754,26 @@ struct FlowGenericFramework { double weff = getEfficiency(track, pidIndex); if (weffCh > 0) - histosNpt[CHARGEDID]->Fill(track.pt(), (cfgUseNchCorrection) ? weffCh : 1.0); - if (pidIndex == PIONID && weff > 0) - histosNpt[PIONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (pidIndex == KAONID && weff > 0) - histosNpt[KAONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (pidIndex == PROTONID && weff > 0) - histosNpt[PROTONID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + histosNpt[ChargedID]->Fill(track.pt(), (cfgUseNchCorrection) ? weffCh : 1.0); + if (pidIndex == PionID && weff > 0) + histosNpt[PionID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (pidIndex == KaonID && weff > 0) + histosNpt[KaonID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); + if (pidIndex == ProtonID && weff > 0) + histosNpt[ProtonID]->Fill(track.pt(), (cfgUseNchCorrection) ? weff : 1.0); } if (cfgFillWeights) { fillWeights(track, vtxz, pidIndex, run); } else { - fillPtSums(track, vtxz); - fillGFW(track, vtxz, pidIndex, densitycorrections); + fillPtSums(track, vtxz); + fillGFW(track, vtxz, pidIndex, densitycorrections); } if (cfgFillQA) { - fillTrackQA(track, vtxz); + fillTrackQA(track, vtxz); if (cfgRunByRun) { - th1sList[run][hPhi]->Fill(track.phi()); - th1sList[run][hEta]->Fill(track.eta()); + th1sList[run][Phi]->Fill(track.phi()); + th1sList[run][Eta]->Fill(track.eta()); } } } @@ -1736,11 +1792,11 @@ struct FlowGenericFramework { return 0; if (cfgPIDCuts.cfgUseOnlyTPC) { - if (pid == PIONS && std::abs(track.tpcNSigmaPi()) > cfgPIDCuts.cfgTPCNsigmaCut) + if (pid == Pions && std::abs(track.tpcNSigmaPi()) > cfgPIDCuts.cfgTPCNsigmaCut) return false; - if (pid == KAONS && std::abs(track.tpcNSigmaKa()) > cfgPIDCuts.cfgTPCNsigmaCut) + if (pid == Kaons && std::abs(track.tpcNSigmaKa()) > cfgPIDCuts.cfgTPCNsigmaCut) return false; - if (pid == PROTONS && std::abs(track.tpcNSigmaPr()) > cfgPIDCuts.cfgTPCNsigmaCut) + if (pid == Protons && std::abs(track.tpcNSigmaPr()) > cfgPIDCuts.cfgTPCNsigmaCut) return false; } else { int partIndex = cfgPIDCuts.cfgUseAsymmetricPID ? getNsigmaPIDAssymmetric(track) : getNsigmaPID(track); @@ -1756,59 +1812,60 @@ struct FlowGenericFramework { return true; } - template - bool selectK0(TCollision const& collision, TV0 const& v0, const double& centrality, double& weff) + template + bool selectK0(TCollision const& collision, TV0 const& v0, TTracks const&, const double& centrality, double& weff) { + using V0TrackTable = std::decay_t; double massK0s = v0.mK0Short(); - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); - registryQA.fill(HIST("K0/hK0Count"), kFillCandidate); - if (postrack.pt() < resoCutVals[kPosTrackPt][K0] || negtrack.pt() < resoCutVals[kNegTrackPt][K0]) + registryQA.fill(HIST("K0/hK0Count"), FillCandidate); + if (postrack.pt() < resoCutVals[PosTrackPt][K0] || negtrack.pt() < resoCutVals[NegTrackPt][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillDaughterPt); - if (massK0s < resoCutVals[kMassMin][K0] && massK0s > resoCutVals[kMassMax][K0]) + registryQA.fill(HIST("K0/hK0Count"), FillDaughterPt); + if (massK0s < resoCutVals[MassMin][K0] && massK0s > resoCutVals[MassMax][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillMassCut); + registryQA.fill(HIST("K0/hK0Count"), FillMassCut); // Rapidity correction - if (v0.yK0Short() > resoCutVals[kRapidity][K0]) + if (v0.yK0Short() > resoCutVals[Rapidity][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillRapidityCut); + registryQA.fill(HIST("K0/hK0Count"), FillRapidityCut); // DCA cuts for K0short - if (std::abs(v0.dcapostopv()) < resoCutVals[kDCAPosToPVMin][K0] || std::abs(v0.dcanegtopv()) < resoCutVals[kDCANegToPVMin][K0]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][K0] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillDCAtoPV); - if (resoSwitchVals[kUseDCAxDaughters][K0] && std::abs(v0.dcaV0daughters()) > resoCutVals[kDCAxDaughters][K0]) + registryQA.fill(HIST("K0/hK0Count"), FillDCAtoPV); + if (resoSwitchVals[UseDCAxDaughters][K0] && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillDCAxDaughters); + registryQA.fill(HIST("K0/hK0Count"), FillDCAxDaughters); // v0 radius cuts - if (resoSwitchVals[kUseV0Radius][K0] && (v0.v0radius() < resoCutVals[kRadiusMin][K0] || v0.v0radius() > resoCutVals[kRadiusMax][K0])) + if (resoSwitchVals[UseV0Radius][K0] && (v0.v0radius() < resoCutVals[RadiusMin][K0] || v0.v0radius() > resoCutVals[RadiusMax][K0])) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillV0Radius); + registryQA.fill(HIST("K0/hK0Count"), FillV0Radius); // cosine pointing angle cuts - if (v0.v0cosPA() < resoCutVals[kCosPA][K0]) + if (v0.v0cosPA() < resoCutVals[CosPA][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillCosPA); + registryQA.fill(HIST("K0/hK0Count"), FillCosPA); // Proper lifetime - if (resoSwitchVals[kUseProperLifetime][K0] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massK0Short > resoCutVals[kLifeTime][K0]) + if (resoSwitchVals[UseProperLifetime][K0] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massK0Short > resoCutVals[LifeTime][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillProperLifetime); + registryQA.fill(HIST("K0/hK0Count"), FillProperLifetime); // ArmenterosPodolanskiCut - if (resoSwitchVals[kUseArmPodCut][K0] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[kArmPodMin][K0]) + if (resoSwitchVals[UseArmPodCut][K0] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][K0]) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillArmPodCut); - if (resoSwitchVals[kUseCompetingMassRejection][K0]) { - if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < resoCutVals[kMassRejection][K0]) + registryQA.fill(HIST("K0/hK0Count"), FillArmPodCut); + if (resoSwitchVals[UseCompetingMassRejection][K0]) { + if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) return false; - if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < resoCutVals[kMassRejection][K0]) + if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) return false; } - registryQA.fill(HIST("K0/hK0Count"), kFillCompetingMass); - if (!selectionV0Daughter(postrack, PIONS) || !selectionV0Daughter(negtrack, PIONS)) + registryQA.fill(HIST("K0/hK0Count"), FillCompetingMass); + if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Pions)) return false; - registryQA.fill(HIST("K0/hK0Count"), kFillDaughterTrackSelection); + registryQA.fill(HIST("K0/hK0Count"), FillDaughterTrackSelection); registryQA.fill(HIST("K0/hK0Mass_sparse"), massK0s, v0.pt(), centrality); registryQA.fill(HIST("K0/hK0Phi"), v0.phi()); @@ -1827,12 +1884,20 @@ struct FlowGenericFramework { registryQA.fill(HIST("K0/hK0s_corrected"), 0.5, weff); } + if (doprocessMCReco) { + registry.fill(HIST("trackQA/after/pt_centrality_K0_pion"), postrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_pion"), postrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_K0_pion"), negtrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_pion"), negtrack.pt(), centrality); + } + return true; } - template - bool selectLambda(TCollision const& collision, TV0 const& v0, const double& centrality, double& weff) + template + bool selectLambda(TCollision const& collision, TV0 const& v0, TTracks const&, const double& centrality, double& weff) { + using V0TrackTable = std::decay_t; bool isL = false; // Is lambda candidate bool isAL = false; // Is anti-lambda candidate @@ -1840,71 +1905,71 @@ struct FlowGenericFramework { double mantilambda = v0.mAntiLambda(); // separate the positive and negative V0 daughters - auto postrack = v0.template posTrack_as(); - auto negtrack = v0.template negTrack_as(); + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillCandidate); - if (postrack.pt() < resoCutVals[kPosTrackPt][LAMBDA] || negtrack.pt() < resoCutVals[kNegTrackPt][LAMBDA]) + registryQA.fill(HIST("Lambda/hLambdaCount"), FillCandidate); + if (postrack.pt() < resoCutVals[PosTrackPt][Lambda] || negtrack.pt() < resoCutVals[NegTrackPt][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillDaughterPt); - if (mlambda > resoCutVals[kMassMin][LAMBDA] && mlambda < resoCutVals[kMassMax][LAMBDA]) + registryQA.fill(HIST("Lambda/hLambdaCount"), FillDaughterPt); + if (mlambda > resoCutVals[MassMin][Lambda] && mlambda < resoCutVals[MassMax][Lambda]) isL = true; - if (mantilambda > resoCutVals[kMassMin][LAMBDA] && mantilambda < resoCutVals[kMassMax][LAMBDA]) + if (mantilambda > resoCutVals[MassMin][Lambda] && mantilambda < resoCutVals[MassMax][Lambda]) isAL = true; if (!isL && !isAL) { return false; } - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillMassCut); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillMassCut); // Rapidity correction - if (v0.yLambda() > resoCutVals[kRapidity][LAMBDA]) + if (v0.yLambda() > resoCutVals[Rapidity][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillRapidityCut); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillRapidityCut); // DCA cuts for lambda and antilambda if (isL) { - if (std::abs(v0.dcapostopv()) < resoCutVals[kDCAPosToPVMin][LAMBDA] || std::abs(v0.dcanegtopv()) < resoCutVals[kDCANegToPVMin][LAMBDA]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][Lambda]) return false; } if (isAL) { - if (std::abs(v0.dcapostopv()) < resoCutVals[kDCANegToPVMin][LAMBDA] || std::abs(v0.dcanegtopv()) < resoCutVals[kDCAPosToPVMin][LAMBDA]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCANegToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCAPosToPVMin][Lambda]) return false; } - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillDCAtoPV); - if (resoSwitchVals[kUseDCAxDaughters][LAMBDA] && std::abs(v0.dcaV0daughters()) > resoCutVals[kDCAxDaughters][LAMBDA]) + registryQA.fill(HIST("Lambda/hLambdaCount"), FillDCAtoPV); + if (resoSwitchVals[UseDCAxDaughters][Lambda] && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillDCAxDaughters); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillDCAxDaughters); // v0 radius cuts - if (resoSwitchVals[kUseV0Radius][LAMBDA] && (v0.v0radius() < resoCutVals[kRadiusMin][LAMBDA] || v0.v0radius() > resoCutVals[kRadiusMax][LAMBDA])) + if (resoSwitchVals[UseV0Radius][Lambda] && (v0.v0radius() < resoCutVals[RadiusMin][Lambda] || v0.v0radius() > resoCutVals[RadiusMax][Lambda])) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillV0Radius); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillV0Radius); // cosine pointing angle cuts - if (v0.v0cosPA() < resoCutVals[kCosPA][LAMBDA]) + if (v0.v0cosPA() < resoCutVals[CosPA][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillCosPA); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillCosPA); // Proper lifetime - if (resoSwitchVals[kUseProperLifetime][LAMBDA] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda > resoCutVals[kLifeTime][LAMBDA]) + if (resoSwitchVals[UseProperLifetime][Lambda] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda > resoCutVals[LifeTime][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillProperLifetime); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillProperLifetime); // ArmenterosPodolanskiCut - if (resoSwitchVals[kUseArmPodCut][LAMBDA] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[kArmPodMin][LAMBDA]) + if (resoSwitchVals[UseArmPodCut][Lambda] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][Lambda]) return false; - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillArmPodCut); - if (resoSwitchVals[kUseCompetingMassRejection][LAMBDA]) { - if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < resoCutVals[kMassRejection][LAMBDA]) + registryQA.fill(HIST("Lambda/hLambdaCount"), FillArmPodCut); + if (resoSwitchVals[UseCompetingMassRejection][Lambda]) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < resoCutVals[MassRejection][Lambda]) return false; } - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillCompetingMass); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillCompetingMass); if (isL) { - if (!selectionV0Daughter(postrack, PROTONS) || !selectionV0Daughter(negtrack, PIONS)) + if (!selectionV0Daughter(postrack, Protons) || !selectionV0Daughter(negtrack, Pions)) return false; } if (isAL) { - if (!selectionV0Daughter(postrack, PIONS) || !selectionV0Daughter(negtrack, PROTONS)) + if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Protons)) return false; } - registryQA.fill(HIST("Lambda/hLambdaCount"), kFillDaughterTrackSelection); + registryQA.fill(HIST("Lambda/hLambdaCount"), FillDaughterTrackSelection); if (isL) { registryQA.fill(HIST("Lambda/hLambdaMass_sparse"), mlambda, v0.pt(), centrality); @@ -1923,6 +1988,11 @@ struct FlowGenericFramework { if (weff > 0) registryQA.fill(HIST("Lambda/hLambdas_corrected"), 0.5, weff); } + if (doprocessMCReco) { + registry.fill(HIST("trackQA/after/pt_centrality_Lambda_pion"), negtrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_pion"), negtrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_proton"), postrack.pt(), centrality); + } } if (isAL) { registryQA.fill(HIST("Lambda/hAntiLambdaMass_sparse"), mantilambda, v0.pt(), centrality); @@ -1941,15 +2011,21 @@ struct FlowGenericFramework { if (weff > 0) registryQA.fill(HIST("Lambda/hLambdas_corrected"), 0.5, weff); } + if (doprocessMCReco) { + registry.fill(HIST("trackQA/after/pt_centrality_Lambda_pion"), postrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_pion"), postrack.pt(), centrality); + registry.fill(HIST("trackQA/after/pt_centrality_proton"), negtrack.pt(), centrality); + } } + return true; } template inline void fillPtSums(TTrack track, const double& vtxz) { - double wacc = (dt == kGen) ? 1. : getAcceptance(track, vtxz, 0); - double weff = (dt == kGen) ? 1. : getEfficiency(track); + double wacc = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); + double weff = (dt == Gen) ? 1. : getEfficiency(track); if (weff < 0) return; @@ -1985,9 +2061,9 @@ struct FlowGenericFramework { if (!withinPtPOI && !withinPtRef) return; - double waccRef = (dt == kGen) ? 1. : getAcceptance(track, vtxz, 0); - double waccPOI = (dt == kGen) ? 1. : withinPtPOI ? getAcceptance(track, vtxz, pid_index + 1) - : getAcceptance(track, vtxz, 0); // + double waccRef = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); + double waccPOI = (dt == Gen) ? 1. : withinPtPOI ? getAcceptance(track, vtxz, pid_index + 1) + : getAcceptance(track, vtxz, 0); // if (withinPtRef && withinPtPOI && pid_index) waccRef = waccPOI; // if particle is both (then it's overlap), override ref with POI if (withinPtRef) @@ -2005,10 +2081,10 @@ struct FlowGenericFramework { bool withinPtPOI = (track.pt() > o2::analysis::gfw::ptpoilow && track.pt() < o2::analysis::gfw::ptpoiup); if (!withinPtPOI && !withinPtRef) return; - double weff = (dt == kGen) ? 1. : getEfficiency(track, 0); + double weff = (dt == Gen) ? 1. : getEfficiency(track, 0); if (weff < 0) return; - if (cfgUseDensityDependentCorrection && withinPtRef && dt != kGen) { + if (cfgUseDensityDependentCorrection && withinPtRef && dt != Gen) { double fphi = densitycorrections.v2 * std::cos(2 * (track.phi() - densitycorrections.psi2Est)) + densitycorrections.v3 * std::cos(3 * (track.phi() - densitycorrections.psi3Est)) + densitycorrections.v4 * std::cos(4 * (track.phi() - densitycorrections.psi4Est)); fphi = (1 + 2 * fphi); int pTBinForEff = hFindPtBin->FindBin(track.pt()); @@ -2020,7 +2096,7 @@ struct FlowGenericFramework { } } } - double wacc = (dt == kGen) ? 1. : getAcceptance(track, vtxz, 0); + double wacc = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); if (withinPtRef) fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); if (withinPtPOI) @@ -2034,12 +2110,12 @@ struct FlowGenericFramework { template inline void fillTrackQA(TTrack track, const float vtxz) { - if constexpr (dt == kGen) { + if constexpr (dt == Gen) { registryQA.fill(HIST("MCGen/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ_gen"), track.phi(), track.eta(), vtxz); registryQA.fill(HIST("MCGen/") + HIST(FillTimeName[ft]) + HIST("pt_gen"), track.pt()); } else { double wacc = getAcceptance(track, vtxz, 0); - registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ"), track.phi(), track.eta(), vtxz, (ft == kAfter) ? wacc : 1.0); + registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ"), track.phi(), track.eta(), vtxz, (ft == After) ? wacc : 1.0); registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prTPCcls"), track.tpcChi2NCl()); @@ -2048,7 +2124,7 @@ struct FlowGenericFramework { registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nITSClusters"), track.itsNCls()); registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCCrossedRows"), track.tpcNClsCrossedRows()); - if (ft == kAfter) { + if (ft == After) { registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_ref"), track.pt()); registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_poi"), track.pt()); @@ -2064,19 +2140,19 @@ struct FlowGenericFramework { float getCentrality(TCollision collision) { switch (cfgCentEstimator) { - case kCentFT0C: + case CentFT0C: return collision.centFT0C(); - case kCentFT0CVariant1: + case CentFT0CVariant1: return collision.centFT0CVariant1(); - case kCentFT0M: + case CentFT0M: return collision.centFT0M(); - case kCentFV0A: + case CentFV0A: return collision.centFV0A(); - case kCentNTPV: + case CentNTPV: return collision.centNTPV(); - case kCentNGlobal: + case CentNGlobal: return collision.centNGlobal(); - case kCentMFT: + case CentMFT: return collision.centMFT(); default: return collision.centFT0C(); @@ -2102,6 +2178,7 @@ struct FlowGenericFramework { using GFWCollisions = soa::Filtered>; // using GFWTracks = soa::Filtered>; using GFWTracks = soa::Filtered>; + using GFWMCTracks = soa::Filtered>; SliceCache cache; Partition posTracks = aod::track::signed1Pt > 0.0f; @@ -2134,12 +2211,12 @@ struct FlowGenericFramework { loadCorrections(bc); registryQA.fill(HIST("eventQA/eventSel"), 0.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(0.5); + th1sList[run][EventSel]->Fill(0.5); if (!collision.sel8()) return; registryQA.fill(HIST("eventQA/eventSel"), 1.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(1.5); + th1sList[run][EventSel]->Fill(1.5); float centrality = getCentrality(collision); if (cfgDoOccupancySel) { @@ -2151,25 +2228,26 @@ struct FlowGenericFramework { } registryQA.fill(HIST("eventQA/eventSel"), 2.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(2.5); + th1sList[run][EventSel]->Fill(2.5); if (cfgFillQA) - fillEventQA(collision, tracks); + fillEventQA(collision, tracks); registryQA.fill(HIST("eventQA/before/centrality"), centrality); registryQA.fill(HIST("eventQA/before/multiplicity"), tracks.size()); if (!eventSelected(collision, tracks.size(), centrality, run)) return; if (cfgFillQA) - fillEventQA(collision, tracks); + fillEventQA(collision, tracks); registryQA.fill(HIST("eventQA/after/centrality"), centrality); registryQA.fill(HIST("eventQA/after/multiplicity"), tracks.size()); // Get magnetic field polarity - auto field = (cfgMagField == 99999) ? getMagneticField(bc.timestamp()) : cfgMagField; // o2-linter: disable=magic-number (hard coded default cut) + int defaultMagCut = 99999; + auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; - processCollision(collision, tracks, v0s, centrality, field, run); + processCollision(collision, tracks, v0s, centrality, field, run); } PROCESS_SWITCH(FlowGenericFramework, processData, "Process analysis for non-derived data", true); - void processMCReco(GFWCollisions::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks, aod::McParticles const&, aod::V0Datas const& v0s) + void processMCReco(GFWCollisions::iterator const& collision, aod::BCsWithTimestamps const&, GFWMCTracks const& tracks, aod::McParticles const&, aod::V0Datas const& v0s) { auto bc = collision.bc_as(); int run = bc.runNumber(); @@ -2181,14 +2259,14 @@ struct FlowGenericFramework { registryQA.fill(HIST("eventQA/eventSel"), 0.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(0.5); + th1sList[run][EventSel]->Fill(0.5); if (!collision.sel8()) return; registryQA.fill(HIST("eventQA/eventSel"), 1.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(1.5); + th1sList[run][EventSel]->Fill(1.5); const auto centrality = getCentrality(collision); @@ -2201,20 +2279,20 @@ struct FlowGenericFramework { } registryQA.fill(HIST("eventQA/eventSel"), 2.5); if (cfgRunByRun) - th1sList[run][hEventSel]->Fill(2.5); + th1sList[run][EventSel]->Fill(2.5); if (cfgFillQA) - fillEventQA(collision, tracks); + fillEventQA(collision, tracks); if (!eventSelected(collision, tracks.size(), centrality, run)) return; if (cfgFillQA) - fillEventQA(collision, tracks); + fillEventQA(collision, tracks); if (!cfgFillWeights) loadCorrections(bc); - - auto field = (cfgMagField == 99999) ? getMagneticField(bc.timestamp()) : cfgMagField; // o2-linter: disable=magic-number (hard coded default cut) - processCollision(collision, tracks, v0s, centrality, field, run); + int defaultMagCut = 99999; + auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + processCollision(collision, tracks, v0s, centrality, field, run); } PROCESS_SWITCH(FlowGenericFramework, processMCReco, "Process analysis for MC reconstructed events", false); @@ -2228,7 +2306,7 @@ struct FlowGenericFramework { centrality = getCentrality(collision); } int run = 0; - processCollision(mcCollision, particles, v0s, centrality, -999, run); + processCollision(mcCollision, particles, v0s, centrality, -999, run); } PROCESS_SWITCH(FlowGenericFramework, processMCGen, "Process analysis for MC generated events", false); @@ -2236,7 +2314,7 @@ struct FlowGenericFramework { { int run = 0; registryQA.fill(HIST("MCGen/impactParameter"), mcCollision.impactParameter(), mcParticles.size()); - processCollision(mcCollision, mcParticles, v0s, mcCollision.impactParameter(), -999, run); + processCollision(mcCollision, mcParticles, v0s, mcCollision.impactParameter(), -999, run); } PROCESS_SWITCH(FlowGenericFramework, processOnTheFly, "Process analysis for MC on-the-fly generated events", false); @@ -2254,9 +2332,9 @@ struct FlowGenericFramework { const auto centrality = collision.centRun2V0M(); if (!cfgFillWeights) loadCorrections(bc); - - auto field = (cfgMagField == 99999) ? getMagneticField(bc.timestamp()) : cfgMagField; // o2-linter: disable=magic-number (hard coded default cut) - processCollision(collision, tracks, v0s, centrality, field, run); + int defaultMagCut = 99999; + auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + processCollision(collision, tracks, v0s, centrality, field, run); } PROCESS_SWITCH(FlowGenericFramework, processRun2, "Process analysis for Run 2 converted data", false); }; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx index 15265a76dab..b873791944b 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx @@ -16,6 +16,7 @@ #include "PWGCF/Core/CorrelationContainer.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -56,9 +57,9 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; using namespace constants::math; -// define the filtered collisions and tracks #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; struct CorrFit { @@ -69,6 +70,7 @@ struct CorrFit { O2_DEFINE_CONFIGURABLE(cfgZVtxCut, float, 10.0f, "Accepted z-vertex range") O2_DEFINE_CONFIGURABLE(cfgUseTransverseMomentum, bool, false, "Use transverse momentum for correlation container") O2_DEFINE_CONFIGURABLE(cfgQaCheck, bool, true, "Enable QA histograms for event selection") + O2_DEFINE_CONFIGURABLE(cfgStrictTrackCounter, bool, false, "Strict track counter for multiplicity correlation cut, counts only tracks that pass all cuts and are used in the correlation") struct : ConfigurableGroup{ O2_DEFINE_CONFIGURABLE(cfgPtCutMin, float, 0.2f, "minimum accepted track pT") O2_DEFINE_CONFIGURABLE(cfgPtCutMax, float, 10.0f, "maximum accepted track pT") @@ -216,26 +218,6 @@ struct CorrFit { // define global variables TRandom3* gRandom = new TRandom3(); - enum EventCutTypes { - kFilteredEvents = 0, - kAfterSel8, - kUseNoTimeFrameBorder, - kUseNoITSROFrameBorder, - kUseNoSameBunchPileup, - kUseGoodZvtxFT0vsPV, - kUseNoCollInTimeRangeStandard, - kUseGoodITSLayersAll, - kUseGoodITSLayer0123, - kUseNoCollInRofStandard, - kUseNoHighMultCollInPrevRof, - kUseOccupancy, - kUseMultCorrCut, - kUseT0AV0ACut, - kUseVertexITSTPC, - kUseTVXinTRD, - kNEventCuts - }; - enum EventType { SameEvent = 1, MixedEvent = 3 @@ -246,26 +228,11 @@ struct CorrFit { kFT0C = 1 }; - enum DetectorChannels { - kFT0AInnerRingMin = 0, - kFT0AInnerRingMax = 31, - kFT0AOuterRingMin = 32, - kFT0AOuterRingMax = 95, - kFT0CInnerRingMin = 96, - kFT0CInnerRingMax = 143, - kFT0COuterRingMin = 144, - kFT0COuterRingMax = 207 - }; - - std::array, 16> eventCuts; + RCTFlagsChecker rctChecker{"CBT"}; void init(InitContext&) { - const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; - const AxisSpec axisEta{40, -1., 1., "#eta"}; - const AxisSpec axisEtaFull{90, -4., 5., "#eta"}; - ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); @@ -274,6 +241,9 @@ struct CorrFit { LOGF(info, "Starting init"); if (doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameTPC) { + registry.add("hEventCountRct", "Number of Event;; Count", {HistType::kTH1D, {{2, 0, 2}}}); + registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(1, "rct fail"); + registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(2, "rct pass"); registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); @@ -291,7 +261,7 @@ struct CorrFit { } if ((doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameTPC) && cfgQaCheck) { - registry.add("hPassedEventSelection", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); + registry.add("hPassedEventSelection", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}}); registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(1, "all tracks"); registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(2, "after sel8"); registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); @@ -304,7 +274,6 @@ struct CorrFit { registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoCollInRofStandard"); registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoHighMultCollInPrevRof"); registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(12, "occupancy"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(13, "cfgEvSelV0AT0ACut"); } if (doprocessSameTPC || doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c) { @@ -405,9 +374,23 @@ struct CorrFit { LOGF(info, "End of init"); } + template + bool eventRct(TCollision const& collision, const bool fillCounter) + { + if (!rctChecker(collision)) { + if (fillCounter) + registry.fill(HIST("hEventCountRct"), 0.5); + + return 0; + } + if (fillCounter) + registry.fill(HIST("hEventCountRct"), 1.5); + + return 1; + } template - bool eventSelected(TCollision collision, const int multTrk, const bool fillCounter) + bool eventSelected(TCollision const& collision, const int multTrk, const bool fillCounter) { registry.fill(HIST("hEventCountSpecific"), 0.5); if (cfgEventSelection.cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { @@ -505,7 +488,7 @@ struct CorrFit { } template - void eventSelectedIndividually(TCollision collision) + void eventSelectedIndividually(TCollision const& collision) { registry.fill(HIST("hPassedEventSelection"), 0.5); @@ -549,6 +532,11 @@ struct CorrFit { if (collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { registry.fill(HIST("hPassedEventSelection"), 10.5); } + + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgEventSelection.cfgEvSelOccupancy && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { + registry.fill(HIST("hPassedEventSelection"), 11.5); + } } double getPhiFT0(uint64_t chno, int i) @@ -591,13 +579,13 @@ struct CorrFit { } template - bool trackSelected(TTrack track) + bool trackSelected(TTrack const& track) { return ((track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgTrackCuts.cfgCutITSclu)); } template - bool trackSelectedSystematics(TTrack track) + bool trackSelectedSystematics(TTrack const& track) { return ((track.tpcNClsFound() >= cfgSystematics.cfgSystematicsCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgSystematics.cfgSystematicsCutTPCCrossedRows) && (track.itsNCls() >= cfgSystematics.cfgSystematicsCutITSclu)); } @@ -752,25 +740,21 @@ struct CorrFit { } template - void fillCorrelationsTPCFT0(TTracks tracks1, TFT0s const& ft0, float posZ, int system, int corType, float multiplicity, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillCorrelationsTPCFT0(TTracks tracks1, TFT0s const& ft0, float posZ, int system, int multiplicity, int corType, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { - if (system == SameEvent) { - registry.fill(HIST("Nch"), multiplicity); - } - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); float triggerWeight = 1.0f; // loop over all tracks for (auto const& track1 : tracks1) { + if (!trackSelected(track1)) + continue; + if (cfgSystematics.cfgSystematicsVariation) { if (!trackSelectedSystematics(track1)) continue; - } else { - if (!trackSelected(track1)) - continue; } if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) @@ -806,12 +790,14 @@ struct CorrFit { if (system == SameEvent) { if (corType == kFT0A) { if (cfgQaCheck) { + registry.fill(HIST("Nch"), multiplicity); registry.fill(HIST("Assoc_amp_same_TPC_FT0A"), chanelid, ampl); registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0A"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); } sameTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), multiplicity, deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); } else if (corType == kFT0C) { if (cfgQaCheck) { + registry.fill(HIST("Nch"), multiplicity); registry.fill(HIST("Assoc_amp_same_TPC_FT0C"), chanelid, ampl); registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0C"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); } @@ -861,10 +847,13 @@ struct CorrFit { } template - void fillCorrelationsFT0AFT0C(TFT0s const& ft0Col1, TFT0s const& ft0Col2, float posZ, int system, float multiplicity, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillCorrelationsFT0AFT0C(TFT0s const& ft0Col1, TFT0s const& ft0Col2, float posZ, int system, int multiplicity, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + if (cfgQaCheck) { + registry.fill(HIST("Nch"), multiplicity); + } float triggerWeight = 1.0f; std::size_t channelASize = ft0Col1.channelA().size(); std::size_t channelCSize = ft0Col2.channelC().size(); @@ -907,7 +896,7 @@ struct CorrFit { } template - void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, float multiplicity, int system, int magneticField) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int multiplicity, int magneticField) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); @@ -917,12 +906,12 @@ struct CorrFit { // loop over all tracks for (auto const& track1 : tracks1) { + if (!trackSelected(track1)) + continue; + if (cfgSystematics.cfgSystematicsVariation) { if (!trackSelectedSystematics(track1)) continue; - } else { - if (!trackSelected(track1)) - continue; } if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) @@ -993,6 +982,9 @@ struct CorrFit { if (!collision.sel8()) return; + if (!eventRct(collision, true)) + return; + auto bc = collision.bc_as(); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) @@ -1012,8 +1004,14 @@ struct CorrFit { fillYield(collision, tracks); + int multiplicity = tracks.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + const auto& ft0 = collision.foundFT0(); - fillCorrelationsTPCFT0(tracks, ft0, collision.posZ(), SameEvent, kFT0A, tracks.size(), eventWeight); + fillCorrelationsTPCFT0(tracks, ft0, collision.posZ(), SameEvent, multiplicity, kFT0A, eventWeight); } PROCESS_SWITCH(CorrFit, processSameTpcFt0a, "Process same event for TPC-FT0 correlation", false); @@ -1038,6 +1036,9 @@ struct CorrFit { if (!collision1.sel8() || !collision2.sel8()) continue; + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) continue; if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) @@ -1053,8 +1054,14 @@ struct CorrFit { loadCorrection(bc.timestamp()); float eventWeight = 1.0f; + int multiplicity = tracks1.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks1, multiplicity); + } + const auto& ft0 = collision2.foundFT0(); - fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, kFT0A, tracks1.size(), eventWeight); + fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, multiplicity, kFT0A, eventWeight); } } PROCESS_SWITCH(CorrFit, processMixedTpcFt0a, "Process mixed events for TPC-FT0A correlation", false); @@ -1068,6 +1075,10 @@ struct CorrFit { if (!collision.sel8()) return; + + if (!eventRct(collision, true)) + return; + auto bc = collision.bc_as(); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) @@ -1084,10 +1095,13 @@ struct CorrFit { const auto& ft0 = collision.foundFT0(); - int multiplicity = 0; - trackCounter(tracks, multiplicity); + int multiplicity = tracks.size(); - fillCorrelationsTPCFT0(tracks, ft0, collision.posZ(), SameEvent, kFT0C, multiplicity, 1.0f); + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + fillCorrelationsTPCFT0(tracks, ft0, collision.posZ(), SameEvent, multiplicity, kFT0C, 1.0f); } PROCESS_SWITCH(CorrFit, processSameTpcFt0c, "Process same event for TPC-FT0C correlation", false); @@ -1111,6 +1125,9 @@ struct CorrFit { if (!collision1.sel8() || !collision2.sel8()) continue; + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) continue; @@ -1127,11 +1144,13 @@ struct CorrFit { float eventWeight = 1.0f; const auto& ft0 = collision2.foundFT0(); + int multiplicity = tracks1.size(); - int multiplicity = 0; - trackCounter(tracks1, multiplicity); + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } - fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, kFT0C, multiplicity, eventWeight); + fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, multiplicity, kFT0C, eventWeight); } } PROCESS_SWITCH(CorrFit, processMixedTpcFt0c, "Process mixed events for TPC-FT0C correlation", false); @@ -1145,6 +1164,10 @@ struct CorrFit { if (!collision.sel8()) return; + + if (!eventRct(collision, true)) + return; + auto bc = collision.bc_as(); if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) @@ -1159,11 +1182,17 @@ struct CorrFit { float eventWeight = 1.0f; const auto& ft0 = collision.foundFT0(); - int multiplicity = 0; - trackCounter(tracks, multiplicity); fillYield(collision, tracks); + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + int multiplicity = tracks.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + fillCorrelationsFT0AFT0C(ft0, ft0, collision.posZ(), SameEvent, multiplicity, eventWeight); } PROCESS_SWITCH(CorrFit, processSameFt0aFt0c, "Process same event for FT0A-FT0C correlation", true); @@ -1190,6 +1219,9 @@ struct CorrFit { if (!collision1.sel8() || !collision2.sel8()) continue; + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) continue; if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) @@ -1206,9 +1238,13 @@ struct CorrFit { const auto& ft0Col1 = collision1.foundFT0(); const auto& ft0Col2 = collision2.foundFT0(); - int multiplicity = 0; + int multiplicity = tracks1.size(); - trackCounter(tracks, multiplicity); + if (cfgStrictTrackCounter) { + trackCounter(tracks1, multiplicity); + } + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin fillCorrelationsFT0AFT0C(ft0Col1, ft0Col2, collision1.posZ(), MixedEvent, multiplicity, eventWeight); } @@ -1221,6 +1257,8 @@ struct CorrFit { if (cfgQaCheck) { eventSelectedIndividually(collision); } + if (!eventRct(collision, true)) + return; if (!collision.sel8()) return; @@ -1232,12 +1270,15 @@ struct CorrFit { registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - int multiplicity = 0; - trackCounter(tracks, multiplicity); - fillYield(collision, tracks); - fillCorrelations(tracks, tracks, collision.posZ(), multiplicity, SameEvent, getMagneticField(bc.timestamp())); + int multiplicity = tracks.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, multiplicity, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(CorrFit, processSameTPC, "Process same event for TPC-TPC correlation", false); @@ -1258,6 +1299,10 @@ struct CorrFit { Pair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; + + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + if (!collision1.sel8() || !collision2.sel8()) continue; @@ -1268,10 +1313,13 @@ struct CorrFit { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - int multiplicity = 0; - trackCounter(tracks1, multiplicity); + int multiplicity = tracks1.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks1, multiplicity); + } - fillCorrelations(tracks1, tracks2, collision1.posZ(), multiplicity, MixedEvent, getMagneticField(collision1.bc_as().timestamp())); + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, multiplicity, getMagneticField(collision1.bc_as().timestamp())); } } PROCESS_SWITCH(CorrFit, processMixedTPC, "Process mixed events for TPC-TPC correlation", false); diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index da755a538ef..70eb8415d27 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -138,6 +138,7 @@ struct DalitzSelection { void init(o2::framework::InitContext&) { fIsTagAndProbe = false; + VarManager::SetDefaultVarNames(); // Event cuts fEventCut = new AnalysisCompositeCut(true); @@ -158,7 +159,7 @@ struct DalitzSelection { if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); for (const auto& t : addTrackCuts) { - fTrackCuts.push_back(reinterpret_cast(t)); + fTrackCuts.push_back(*dynamic_cast(t)); } } @@ -176,7 +177,7 @@ struct DalitzSelection { if (addTrackCutsProbeStr != "" && (cutNamesProbeStr.CompareTo(cutNamesStr) != 0 || addTrackCutsProbeStr.CompareTo(addTrackCutsStr) != 0)) { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsProbeStr.Data()); for (const auto& t : addTrackCuts) { - fTrackCutsProbe.push_back(reinterpret_cast(t)); + fTrackCutsProbe.push_back(*dynamic_cast(t)); } fIsTagAndProbe = true; } @@ -194,7 +195,7 @@ struct DalitzSelection { if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); for (const auto& t : addPairCuts) { - fPairCuts.push_back(reinterpret_cast(t)); + fPairCuts.push_back(*dynamic_cast(t)); } } @@ -212,7 +213,7 @@ struct DalitzSelection { } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill - VarManager::SetDefaultVarNames(); + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); @@ -229,13 +230,13 @@ struct DalitzSelection { histClasses += Form("TrackBarrelProbe_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); histClasses += Form("Pair_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); if (fConfigOptions.fConfigEnableLikeSign) { - histClasses += Form("Pair_LS_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); + histClasses += Form("PairLS_%s_%s_%s;", (*trackCut).GetName(), fTrackCutsProbe.at(iCut).GetName(), (*pairCut).GetName()); } } else { histClasses += Form("TrackBarrel_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); histClasses += Form("Pair_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); if (fConfigOptions.fConfigEnableLikeSign) { - histClasses += Form("Pair_LS_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); + histClasses += Form("PairLS_%s_%s;", (*trackCut).GetName(), (*pairCut).GetName()); } } } @@ -334,7 +335,7 @@ struct DalitzSelection { if (!fIsTagAndProbe && track1.globalIndex() >= track2.globalIndex()) { continue; } - if (!fConfigOptions.fConfigEnableLikeSign && track1.sign() * track2.sign() > 0) { + if (!fConfigOptions.fConfigEnableLikeSign && (track1.sign() * track2.sign() > 0)) { continue; } @@ -461,7 +462,7 @@ struct DalitzSelection { } for (const auto& track : tracks) { // Fill dalitz bits - dalitzbits(fDalitzmap[track.globalIndex()]); + dalitzbits(fIsTagAndProbe ? fDalitzmapProbe[track.globalIndex()] : fDalitzmap[track.globalIndex()]); } } diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index c574cb3689a..9b47e2d4dd4 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #ifndef PWGEM_DILEPTON_DATAMODEL_DILEPTONTABLES_H_ diff --git a/PWGEM/Dilepton/DataModel/lmeeMLTables.h b/PWGEM/Dilepton/DataModel/lmeeMLTables.h index 4f6e03441e0..149333eb33a 100644 --- a/PWGEM/Dilepton/DataModel/lmeeMLTables.h +++ b/PWGEM/Dilepton/DataModel/lmeeMLTables.h @@ -241,7 +241,7 @@ DECLARE_SOA_COLUMN(Lz, lz, float); //! decay length of LH pair DECLARE_SOA_COLUMN(LzSigma, lzSigma, float); //! decay length resolution of LH pair DECLARE_SOA_COLUMN(PdgCodeH, pdgCodeH, int); //! pdg code of associated hadron -DECLARE_SOA_COLUMN(PdgCodeHFH, pdgCodeHFH, int); //! pdg code of HF hadron +DECLARE_SOA_COLUMN(PdgCodeIM, pdgCodeIM, int); //! pdg code of intermediate hadron from HF hadrons. e.g K*, D* DECLARE_SOA_COLUMN(FoundCommonMother, foundCommonMother, bool); //! decay length resolution of LH pair } // namespace emmllhpair @@ -251,11 +251,12 @@ DECLARE_SOA_TABLE(EMMLLHPairs, "AOD", "EMMLLHPAIR", //! track::DcaXY, track::DcaZ, o2::aod::track::CYY, o2::aod::track::CZY, o2::aod::track::CZZ, pidtpc::TPCNSigmaPi, pidtof::TOFNSigmaPi, pidtpc::TPCNSigmaKa, pidtof::TOFNSigmaKa, + pidtpc::TPCNSigmaPr, pidtof::TOFNSigmaPr, emmllhpair::Mass, emmllhpair::DcaLH, emmllhpair::CosPA, emmllhpair::CosPAXY, emmllhpair::Lxyz, emmllhpair::LxyzSigma, emmllhpair::Lxy, emmllhpair::LxySigma, emmllhpair::Lz, emmllhpair::LzSigma, - emmllhpair::PdgCodeH, emmllhpair::FoundCommonMother); + emmllhpair::PdgCodeH, emmllhpair::PdgCodeIM, emmllhpair::FoundCommonMother); // iterators using EMMLLHPair = EMMLLHPairs::iterator; diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx index e9fe1653412..c8af8922bb6 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx @@ -168,7 +168,7 @@ struct skimmerPrimaryElectron { Configurable> cutsMl{"cutsMl", std::vector{0.95, 0.95, 0.7, 0.7, 0.8, 0.8, 0.7, 0.7}, "ML cuts per bin"}; Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"tpcInnerParam", "tpcNClsFound", "tpcChi2NCl", "tpcNSigmaEl", "tofNSigmaEl", "meanClusterSizeITSobCos"}, "Names of ML model input features"}; Configurable nameBinningFeature{"nameBinningFeature", "tpcInnerParam", "Names of ML model binning feature"}; - Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + // Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; @@ -237,32 +237,6 @@ struct skimmerPrimaryElectron { fRegistry.add("Track/hProbElBDT", "probability to be e from BDT;p_{in} (GeV/c);BDT score;", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/hNe", "electron counts;N_{e} per collision", kTH1F, {{51, -0.5, 50.5}}, false); } - - if (usePIDML) { - static constexpr int nClassesMl = 2; - const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutSmaller}; - const std::vector labelsClasses = {"Background", "Signal"}; - const uint32_t nBinsMl = binsMl.value.size() - 1; - const std::vector labelsBins(nBinsMl, "bin"); - double cutsMlArr[nBinsMl][nClassesMl]; - for (uint32_t i = 0; i < nBinsMl; i++) { - cutsMlArr[i][0] = 0.0; - cutsMlArr[i][1] = cutsMl.value[i]; - } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(onnxFileNames.value, ccdbApi, onnxPathsCCDB.value, timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(onnxFileNames.value); - } - mlResponseSingleTrack.cacheInputFeaturesIndices(namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(nameBinningFeature); - mlResponseSingleTrack.init(enableOptimizations.value); - mlResponseSingleTrack.useReassociatedTOF(useTOFNSigmaDeltaBC.value); - } // end of PID ML } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -319,6 +293,33 @@ struct skimmerPrimaryElectron { d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; } + + if (usePIDML) { + static constexpr int nClassesMl = 2; + const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutSmaller}; + const std::vector labelsClasses = {"Background", "Signal"}; + const uint32_t nBinsMl = binsMl.value.size() - 1; + const std::vector labelsBins(nBinsMl, "bin"); + double cutsMlArr[nBinsMl][nClassesMl]; + for (uint32_t i = 0; i < nBinsMl; i++) { + cutsMlArr[i][0] = 0.0; + cutsMlArr[i][1] = cutsMl.value[i]; + } + o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + mlResponseSingleTrack.configure(binsMl.value, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdburl); + mlResponseSingleTrack.setModelPathsCCDB(onnxFileNames.value, ccdbApi, onnxPathsCCDB.value, bc.timestamp()); + } else { + mlResponseSingleTrack.setModelPathsLocal(onnxFileNames.value); + } + mlResponseSingleTrack.cacheInputFeaturesIndices(namesInputFeatures); + mlResponseSingleTrack.cacheBinningIndex(nameBinningFeature); + mlResponseSingleTrack.init(enableOptimizations.value); + mlResponseSingleTrack.useReassociatedTOF(useTOFNSigmaDeltaBC.value); + } // end of PID ML + mRunNumber = bc.runNumber(); } diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx index 3815e0bc335..d17a395027e 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx @@ -126,10 +126,18 @@ struct skimmerPrimaryElectronQC { Configurable maxchi2its{"maxchi2its", 5.0, "max. chi2/NclsITS"}; Configurable dca_xy_max{"dca_xy_max", 0.2, "max DCAxy in cm"}; Configurable dca_z_max{"dca_z_max", 0.2, "max DCAz in cm"}; - Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; // Don't change. - Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", +2.0, "max. TPC n sigma for electron inclusion"}; // Don't change. - Configurable minTOFNsigmaEl{"minTOFNsigmaEl", -2.0, "min. TOF n sigma for electron inclusion"}; // Don't change. - Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", +2.0, "max. TOF n sigma for electron inclusion"}; // Don't change. + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; + Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", +2.0, "max. TPC n sigma for electron inclusion"}; + Configurable minTOFNsigmaEl{"minTOFNsigmaEl", -2.0, "min. TOF n sigma for electron inclusion"}; + Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", +2.0, "max. TOF n sigma for electron inclusion"}; + + Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 2.5, "max. TPC n sigma for pion exclusion"}; + Configurable minTPCNsigmaPi{"minTPCNsigmaPi", -1e+10, "min. TPC n sigma for pion exclusion"}; + Configurable maxTPCNsigmaKa{"maxTPCNsigmaKa", 2.5, "max. TPC n sigma for kaon exclusion"}; + Configurable minTPCNsigmaKa{"minTPCNsigmaKa", -2.5, "min. TPC n sigma for kaon exclusion"}; + Configurable maxTPCNsigmaPr{"maxTPCNsigmaPr", 2.5, "max. TPC n sigma for proton exclusion"}; + Configurable minTPCNsigmaPr{"minTPCNsigmaPr", -2.5, "min. TPC n sigma for proton exclusion"}; + Configurable requireTOF{"requireTOF", true, "require TOF hit"}; } tighttrackcut; Configurable storeOnlyTrueElectronMC{"storeOnlyTrueElectronMC", false, "Flag to store only true electron in MC"}; @@ -146,7 +154,7 @@ struct skimmerPrimaryElectronQC { Configurable> cutsMl{"cutsMl", std::vector{0.95}, "ML cuts per bin"}; Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; - Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + // Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; @@ -212,31 +220,6 @@ struct skimmerPrimaryElectronQC { fRegistry.add("Track/hProbElBDT", "probability to be e from BDT;p_{in} (GeV/c);BDT score;", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Pair/hMvsPhiV", "m_{ee} vs. #varphi_{V} ULS;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0.f, M_PI}, {100, 0, 0.1}}); } - - if (usePIDML) { - static constexpr int nClassesMl = 2; - const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutSmaller}; - const std::vector labelsClasses = {"Background", "Signal"}; - const uint32_t nBinsMl = binsMl.value.size() - 1; - const std::vector labelsBins(nBinsMl, "bin"); - double cutsMlArr[nBinsMl][nClassesMl]; - for (uint32_t i = 0; i < nBinsMl; i++) { - cutsMlArr[i][0] = 0.0; - cutsMlArr[i][1] = cutsMl.value[i]; - } - o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - - mlResponseSingleTrack.configure(binsMl.value, cutsMl, cutDirMl, nClassesMl); - if (loadModelsFromCCDB) { - ccdbApi.init(ccdburl); - mlResponseSingleTrack.setModelPathsCCDB(onnxFileNames.value, ccdbApi, onnxPathsCCDB.value, timestampCCDB.value); - } else { - mlResponseSingleTrack.setModelPathsLocal(onnxFileNames.value); - } - mlResponseSingleTrack.cacheInputFeaturesIndices(namesInputFeatures); - mlResponseSingleTrack.cacheBinningIndex(nameBinningFeature); - mlResponseSingleTrack.init(enableOptimizations.value); - } // end of PID ML } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -293,6 +276,32 @@ struct skimmerPrimaryElectronQC { d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; } + + if (usePIDML) { + static constexpr int nClassesMl = 2; + const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutSmaller}; + const std::vector labelsClasses = {"Background", "Signal"}; + const uint32_t nBinsMl = binsMl.value.size() - 1; + const std::vector labelsBins(nBinsMl, "bin"); + double cutsMlArr[nBinsMl][nClassesMl]; + for (uint32_t i = 0; i < nBinsMl; i++) { + cutsMlArr[i][0] = 0.0; + cutsMlArr[i][1] = cutsMl.value[i]; + } + o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + mlResponseSingleTrack.configure(binsMl.value, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdburl); + mlResponseSingleTrack.setModelPathsCCDB(onnxFileNames.value, ccdbApi, onnxPathsCCDB.value, bc.timestamp()); + } else { + mlResponseSingleTrack.setModelPathsLocal(onnxFileNames.value); + } + mlResponseSingleTrack.cacheInputFeaturesIndices(namesInputFeatures); + mlResponseSingleTrack.cacheBinningIndex(nameBinningFeature); + mlResponseSingleTrack.init(enableOptimizations.value); + } // end of PID ML + mRunNumber = bc.runNumber(); } @@ -467,9 +476,19 @@ struct skimmerPrimaryElectronQC { template bool isElectronTight(TTrack const& track) { - bool is_El_TPC = tighttrackcut.minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tighttrackcut.maxTPCNsigmaEl; - bool is_El_TOF = tighttrackcut.minTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tighttrackcut.maxTOFNsigmaEl; - return is_El_TPC && is_El_TOF; + if (tighttrackcut.requireTOF) { + bool is_El_TPC = tighttrackcut.minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tighttrackcut.maxTPCNsigmaEl; + bool is_El_TOF = tighttrackcut.minTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tighttrackcut.maxTOFNsigmaEl; + return is_El_TPC && is_El_TOF; + } else { // TPC hadron band rejection OR TOFreq + bool is_el_included_TPC = tighttrackcut.minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tighttrackcut.maxTPCNsigmaEl; + bool is_el_included_TOF = track.hasTOF() ? tighttrackcut.minTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tighttrackcut.maxTOFNsigmaEl : true; + bool is_pi_excluded_TPC = !(tighttrackcut.minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < tighttrackcut.maxTPCNsigmaPi); + bool is_ka_excluded_TPC = !(tighttrackcut.minTPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < tighttrackcut.maxTPCNsigmaKa); + bool is_pr_excluded_TPC = !(tighttrackcut.minTPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < tighttrackcut.maxTPCNsigmaPr); + bool is_el_included_TOFreq = tighttrackcut.minTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tighttrackcut.maxTOFNsigmaEl; + return (is_el_included_TPC && is_el_included_TOF && is_pi_excluded_TPC && is_ka_excluded_TPC && is_pr_excluded_TPC) || (is_el_included_TPC && is_pi_excluded_TPC && is_el_included_TOFreq); + } } template diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorMuonML.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorMuonML.cxx index 05eaeaf9ee1..d9ff8eee3ba 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorMuonML.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorMuonML.cxx @@ -23,6 +23,7 @@ #include "Common/Core/RecoDecay.h" #include "Common/Core/fwdtrackUtilities.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include #include @@ -42,7 +43,6 @@ #include #include #include -#include #include #include @@ -50,6 +50,7 @@ #include #include +#include #include #include #include diff --git a/PWGEM/Dilepton/Tasks/matchingMFT.cxx b/PWGEM/Dilepton/Tasks/matchingMFT.cxx index 477fbfbd33d..eab695fe25b 100644 --- a/PWGEM/Dilepton/Tasks/matchingMFT.cxx +++ b/PWGEM/Dilepton/Tasks/matchingMFT.cxx @@ -26,6 +26,7 @@ #include "Tools/ML/MlResponse.h" #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +52,7 @@ #include #include +#include #include #include #include diff --git a/PWGEM/Dilepton/Tasks/taggingHFE.cxx b/PWGEM/Dilepton/Tasks/taggingHFE.cxx index 3a2ea08cab4..c722d997add 100644 --- a/PWGEM/Dilepton/Tasks/taggingHFE.cxx +++ b/PWGEM/Dilepton/Tasks/taggingHFE.cxx @@ -30,7 +30,6 @@ #include "Common/DataModel/PIDResponseTPC.h" #include -#include #include #include #include @@ -100,7 +99,7 @@ struct taggingHFE { Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; Configurable cfgPdgLepton{"cfgPdgLepton", 11, "pdg code of desired lepton: 11 or 13"}; - Configurable cfgDownSampling{"cfgDownSampling", 1.1, "down sampling for fake matches"}; + Configurable cfgDownSamplingHc{"cfgDownSamplingHc", 1.1, "down sampling for charm hadrons"}; // there are enough hc, but not jpsi or hb. Configurable useTOFNSigmaDeltaBC{"useTOFNSigmaDeltaBC", true, "Flag to shift delta BC for TOF n sigma (only with TTCA)"}; struct : ConfigurableGroup { @@ -167,8 +166,12 @@ struct taggingHFE { Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3, "max n sigma ka in TPC"}; Configurable cfg_min_TOFNsigmaKa{"cfg_min_TOFNsigmaKa", -3, "min n sigma ka in TOF"}; Configurable cfg_max_TOFNsigmaKa{"cfg_max_TOFNsigmaKa", +3, "max n sigma ka in TOF"}; - Configurable requirePiKa{"requirePiKa", false, "require hadron to be pion or kaon"}; // proton is not involved in semileptonic decay of HF hadrons often. - Configurable applyTOFif{"applyTOFif", false, "apply TOFif for pion or kaon"}; // proton is not involved in semileptonic decay of HF hadrons often. + Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3, "min n sigma pr in TPC"}; + Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3, "max n sigma pr in TPC"}; + Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -3, "min n sigma pr in TOF"}; + Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +3, "max n sigma pr in TOF"}; + Configurable requirePiKaPr{"requirePiKaPr", true, "require hadron to be pion or kaon or proton"}; + Configurable applyTOFif{"applyTOFif", false, "apply TOFif for hadron identification"}; } hadronCut; struct : ConfigurableGroup { @@ -458,19 +461,23 @@ struct taggingHFE { } template - bool isKaon_or_isPion(TCollision const& collision, TTrack const& track) + bool isPiKaPr(TCollision const& collision, TTrack const& track) { float tofNSigmaPi = mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]; float tofNSigmaKa = mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]; - bool is_ka_included_TPC = hadronCut.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < hadronCut.cfg_max_TPCNsigmaKa; - bool is_ka_included_TOF = track.hasTOF() ? (hadronCut.cfg_min_TOFNsigmaKa < tofNSigmaKa && tofNSigmaKa < hadronCut.cfg_max_TOFNsigmaKa) : true; + float tofNSigmaPr = mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]; bool is_pi_included_TPC = hadronCut.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < hadronCut.cfg_max_TPCNsigmaPi; bool is_pi_included_TOF = track.hasTOF() ? (hadronCut.cfg_min_TOFNsigmaPi < tofNSigmaPi && tofNSigmaPi < hadronCut.cfg_max_TOFNsigmaPi) : true; + bool is_ka_included_TPC = hadronCut.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < hadronCut.cfg_max_TPCNsigmaKa; + bool is_ka_included_TOF = track.hasTOF() ? (hadronCut.cfg_min_TOFNsigmaKa < tofNSigmaKa && tofNSigmaKa < hadronCut.cfg_max_TOFNsigmaKa) : true; + bool is_pr_included_TPC = hadronCut.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < hadronCut.cfg_max_TPCNsigmaPr; + bool is_pr_included_TOF = track.hasTOF() ? (hadronCut.cfg_min_TOFNsigmaPr < tofNSigmaPr && tofNSigmaPr < hadronCut.cfg_max_TOFNsigmaPr) : true; if (!hadronCut.applyTOFif) { - is_ka_included_TOF = true; is_pi_included_TOF = true; + is_ka_included_TOF = true; + is_pr_included_TOF = true; } - return (is_ka_included_TPC && is_ka_included_TOF) || (is_pi_included_TPC && is_pi_included_TOF); + return (is_pi_included_TPC && is_pi_included_TOF) || (is_ka_included_TPC && is_ka_included_TOF) || (is_pr_included_TPC && is_pr_included_TOF); } template @@ -625,7 +632,7 @@ struct taggingHFE { return false; } - if (hadronCut.requirePiKa && !isKaon_or_isPion(collision, track)) { + if (hadronCut.requirePiKaPr && !isPiKaPr(collision, track)) { return false; } @@ -866,6 +873,7 @@ struct taggingHFE { std::map, float> mapTOFNsigmaPiReassociated; // map pair(collisionId, trackId) -> tof n sigma pi std::map, float> mapTOFNsigmaKaReassociated; // map pair(collisionId, trackId) -> tof n sigma ka + std::map, float> mapTOFNsigmaPrReassociated; // map pair(collisionId, trackId) -> tof n sigma pr std::map, float> mapTOFBetaReassociated; // map pair(collisionId, trackId) -> tof beta std::unordered_map mapCollisionTime; std::unordered_map mapCollisionTimeError; @@ -891,13 +899,16 @@ struct taggingHFE { auto bcTrack = track.template collision_as().template bc_as(); float tofNSigmaPi = mTOFResponse->nSigma(track.tofSignalInAnotherBC(bcTrack.globalBC(), bcCollision.globalBC()), track.tofExpMom(), track.length(), track.p(), track.eta(), mapCollisionTime[collision.globalIndex()], mapCollisionTimeError[collision.globalIndex()]); float tofNSigmaKa = mTOFResponse->nSigma(track.tofSignalInAnotherBC(bcTrack.globalBC(), bcCollision.globalBC()), track.tofExpMom(), track.length(), track.p(), track.eta(), mapCollisionTime[collision.globalIndex()], mapCollisionTimeError[collision.globalIndex()]); + float tofNSigmaPr = mTOFResponse->nSigma(track.tofSignalInAnotherBC(bcTrack.globalBC(), bcCollision.globalBC()), track.tofExpMom(), track.length(), track.p(), track.eta(), mapCollisionTime[collision.globalIndex()], mapCollisionTimeError[collision.globalIndex()]); float beta = track.length() / (track.tofSignalInAnotherBC(bcTrack.globalBC(), bcCollision.globalBC()) - mapCollisionTime[collision.globalIndex()]) / (TMath::C() * 1e+2 * 1e-12); mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = tofNSigmaPi; mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = tofNSigmaKa; + mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = tofNSigmaPr; mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = beta; } else { mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPi(); mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaKa(); + mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPr(); mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.beta(); } } // end of track loop @@ -911,6 +922,7 @@ struct taggingHFE { } mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPi(); mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaKa(); + mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPr(); mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.beta(); } } // end of track loop @@ -926,6 +938,7 @@ struct taggingHFE { } mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPi(); mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaKa(); + mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPr(); mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.beta(); } // end of track loop } // end of collision loop @@ -938,6 +951,7 @@ struct taggingHFE { } mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPi(); mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaKa(); + mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.tofNSigmaPr(); mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())] = track.beta(); } } // end of track loop @@ -971,10 +985,6 @@ struct taggingHFE { continue; } - if (dist01(engine) > cfgDownSampling) { // random sampling, if necessary - continue; - } - fillEventHistograms(collision); fRegistry.fill(HIST("Event/hCollisionCounter"), 1); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); @@ -1017,6 +1027,13 @@ struct taggingHFE { fRegistry.fill(HIST("Electron/hs"), trackParCov.getPt(), trackParCov.getEta(), RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U)); fRegistry.fill(HIST("Electron/hTPCdEdx"), track.tpcInnerParam(), track.mcTunedTPCSignal()); fRegistry.fill(HIST("Electron/hTOFbeta"), track.p(), mapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]); + + auto mcMother = mcParticle.template mothers_as()[0]; + bool is_e_from_hc = (std::abs(mcMother.pdgCode()) == 411 || std::abs(mcMother.pdgCode()) == 421 || std::abs(mcMother.pdgCode()) == 431 || std::abs(mcMother.pdgCode()) == 4122 || std::abs(mcMother.pdgCode()) == 4132 || std::abs(mcMother.pdgCode()) == 4232 || std::abs(mcMother.pdgCode()) == 4332) && isSemiLeptonic(mcMother, mcParticles, -cfgPdgLepton, cfgPdgLepton + 1); + if (is_e_from_hc && dist01(engine) > cfgDownSamplingHc) { // random sampling hc, if necessary + continue; + } + if (track.sign() > 0) { // positron positronIds.emplace_back(trackId.trackId()); } else { // electron @@ -1177,15 +1194,84 @@ struct taggingHFE { continue; } + int pdgCodeIM = 0; + auto mckaon = kaon.template mcParticle_as(); + bool foundCommonMother = FindCommonMotherFrom2ProngsWithoutPDG(mcpos, mckaon) > 0; + if (mckaon.has_mothers() && !foundCommonMother) { + auto mcMother_of_kaon = mckaon.template mothers_first_as(); + if (mcMother_of_kaon.pdgCode() == -323 || mcMother_of_kaon.pdgCode() == -313 || mcMother_of_kaon.pdgCode() == 333 || mcMother_of_kaon.pdgCode() == -413) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e + int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcpos, mcMother_of_kaon); + if (commonMotherId > 0) { + foundCommonMother = true; + pdgCodeIM = mcMother_of_kaon.pdgCode(); + } + } + } + + if (!(((is_e_from_hc || is_e_from_hb) && foundCommonMother) || ((is_e_from_dy || is_e_from_jpsi) && !foundCommonMother) || ((is_e_from_dy || is_e_from_jpsi) && foundCommonMother && std::abs(mckaon.pdgCode()) == cfgPdgLepton))) { + // I want 3 types. + // 1. truely found HF->eh (SV should found by eh, and truely found.) For signal sample in ML. + // 2. mistakenly found DY->eh (SV should not be found by eh, but found.) For bkg sample in ML. + // 3. truely found DY->ee with misidentified ee. (SV may be found at the same position of PV.) For bkg sample in ML. + continue; + } + + // if (std::abs(mckaon.pdgCode()) == 11) { + // LOGF(info, "mcMother.pdgCode() = %d, mckaon.pdgCode() = %d, foundCommonMother = %d", mcMother.pdgCode(), mckaon.pdgCode(), foundCommonMother); + // for (int d = mcMother.daughtersIds()[0]; d <= mcMother.daughtersIds()[1]; ++d) { + // auto daughter = mcParticles.rawIteratorAt(d); + // LOGF(info, "daughter.pdgCode() = %d", daughter.pdgCode()); + // } + // } + + float tofNSigmaPi = mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaKa = mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaPr = mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + + emmllhpair(leptonTable.lastIndex(), + trackParCov.getQ2Pt(), trackParCov.getEta(), dcaXY_kaon, dcaZ_kaon, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), + kaon.tpcNSigmaPi(), tofNSigmaPi, + kaon.tpcNSigmaKa(), tofNSigmaKa, + kaon.tpcNSigmaPr(), tofNSigmaPr, + eKpair.mass, eKpair.dca2legs, eKpair.cospa, eKpair.cospaXY, + eKpair.lxyz, eKpair.lxyzErr, + eKpair.lxy, eKpair.lxyErr, + eKpair.lz, eKpair.lzErr, + mckaon.pdgCode(), pdgCodeIM, foundCommonMother); + + } // end of kaon loop + + for (const auto& kaonId : kaonPlusIds) { + auto kaon = tracks.rawIteratorAt(kaonId); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(kaon); + trackParCov.setPID(kaon.pidForTracking()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY_kaon = mDcaInfoCov.getY(); + float dcaZ_kaon = mDcaInfoCov.getZ(); + + if (positronId == kaonId) { + continue; + } + + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, pos, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + if (!eKpair.isOK) { + continue; + } + if (!(lKPairCut.cfg_min_mass < eKpair.mass && eKpair.mass < lKPairCut.cfg_max_mass) || eKpair.cospa < lKPairCut.cfg_min_cospa || lKPairCut.cfg_max_lxyz < eKpair.lxyz || lKPairCut.cfg_max_dca2legs < eKpair.dca2legs) { + continue; + } + + int pdgCodeIM = 0; auto mckaon = kaon.template mcParticle_as(); bool foundCommonMother = FindCommonMotherFrom2ProngsWithoutPDG(mcpos, mckaon) > 0; if (mckaon.has_mothers() && !foundCommonMother) { auto mcMother_of_kaon = mckaon.template mothers_first_as(); - if (mcMother_of_kaon.pdgCode() == -323 || mcMother_of_kaon.pdgCode() == -313 || mcMother_of_kaon.pdgCode() == 333) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e + if (mcMother_of_kaon.pdgCode() == -323 || mcMother_of_kaon.pdgCode() == -313 || mcMother_of_kaon.pdgCode() == 333 || mcMother_of_kaon.pdgCode() == -413) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcpos, mcMother_of_kaon); - if (commonMotherId > 0 && std::abs(mcParticles.rawIteratorAt(commonMotherId).pdgCode()) != 2212) { + if (commonMotherId > 0) { foundCommonMother = true; - // LOGF(info, "eK: e+ and K*(892) or phi is found. mother is %d", mcParticles.rawIteratorAt(commonMotherId).pdgCode()); + pdgCodeIM = mcMother_of_kaon.pdgCode(); } } } @@ -1208,16 +1294,18 @@ struct taggingHFE { float tofNSigmaPi = mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; float tofNSigmaKa = mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaPr = mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; emmllhpair(leptonTable.lastIndex(), trackParCov.getQ2Pt(), trackParCov.getEta(), dcaXY_kaon, dcaZ_kaon, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), kaon.tpcNSigmaPi(), tofNSigmaPi, kaon.tpcNSigmaKa(), tofNSigmaKa, + kaon.tpcNSigmaPr(), tofNSigmaPr, eKpair.mass, eKpair.dca2legs, eKpair.cospa, eKpair.cospaXY, eKpair.lxyz, eKpair.lxyzErr, eKpair.lxy, eKpair.lxyErr, eKpair.lz, eKpair.lzErr, - mckaon.pdgCode(), foundCommonMother); + mckaon.pdgCode(), pdgCodeIM, foundCommonMother); } // end of kaon loop @@ -1272,9 +1360,8 @@ struct taggingHFE { auto mcMother_of_k0s = mcK0S.template mothers_first_as(); if (mcMother_of_k0s.pdgCode() == -323 || mcMother_of_k0s.pdgCode() == -313 || mcMother_of_k0s.pdgCode() == 333) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcpos, mcMother_of_k0s); - if (commonMotherId > 0 && std::abs(mcParticles.rawIteratorAt(commonMotherId).pdgCode()) != 2212) { // proton decay is implemented. reject it. + if (commonMotherId > 0) { foundCommonMother = true; - // LOGF(info, "eK0S: e+ and K*(892) or phi is found. mother is %d", mcParticles.rawIteratorAt(commonMotherId).pdgCode()); } } } @@ -1515,6 +1602,75 @@ struct taggingHFE { leptonParCov.getQ2Pt(), leptonParCov.getEta(), dcaXY_lepton, dcaZ_lepton, leptonParCov.getSigmaY2(), leptonParCov.getSigmaZY(), leptonParCov.getSigmaZ2(), isMotherFromB, mcMother.pdgCode()); + for (const auto& kaonId : kaonMinusIds) { + auto kaon = tracks.rawIteratorAt(kaonId); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(kaon); + trackParCov.setPID(kaon.pidForTracking()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY_kaon = mDcaInfoCov.getY(); + float dcaZ_kaon = mDcaInfoCov.getZ(); + + if (electronId == kaonId) { + continue; + } + + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, ele, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + if (!eKpair.isOK) { + continue; + } + + if (!(lKPairCut.cfg_min_mass < eKpair.mass && eKpair.mass < lKPairCut.cfg_max_mass) || eKpair.cospa < lKPairCut.cfg_min_cospa || lKPairCut.cfg_max_lxyz < eKpair.lxyz || lKPairCut.cfg_max_dca2legs < eKpair.dca2legs) { + continue; + } + + int pdgCodeIM = 0; + auto mckaon = kaon.template mcParticle_as(); + bool foundCommonMother = FindCommonMotherFrom2ProngsWithoutPDG(mcele, mckaon) > 0; + if (mckaon.has_mothers() && !foundCommonMother) { + auto mcMother_of_kaon = mckaon.template mothers_first_as(); + if (mcMother_of_kaon.pdgCode() == 323 || mcMother_of_kaon.pdgCode() == 313 || mcMother_of_kaon.pdgCode() == 333 || mcMother_of_kaon.pdgCode() == 413) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e + int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcele, mcMother_of_kaon); + if (commonMotherId > 0) { + foundCommonMother = true; + pdgCodeIM = mcMother_of_kaon.pdgCode(); + } + } + } + + if (!(((is_e_from_hc || is_e_from_hb) && foundCommonMother) || ((is_e_from_dy || is_e_from_jpsi) && !foundCommonMother) || ((is_e_from_dy || is_e_from_jpsi) && foundCommonMother && std::abs(mckaon.pdgCode()) == cfgPdgLepton))) { + // I want 3 types. + // 1. truely found HF->eh (SV should found by eh, and truely found.) For signal sample in ML. + // 2. mistakenly found DY->eh (SV should not be found by eh, but found.) For bkg sample in ML. + // 3. truely found DY->ee with misidentified ee. (SV may be found at the same position of PV.) For bkg sample in ML. + continue; + } + + // if (std::abs(mckaon.pdgCode()) == 11) { + // LOGF(info, "mcMother.pdgCode() = %d, mckaon.pdgCode() = %d, foundCommonMother = %d", mcMother.pdgCode(), mckaon.pdgCode(), foundCommonMother); + // for (int d = mcMother.daughtersIds()[0]; d <= mcMother.daughtersIds()[1]; ++d) { + // auto daughter = mcParticles.rawIteratorAt(d); + // LOGF(info, "daughter.pdgCode() = %d", daughter.pdgCode()); + // } + // } + + float tofNSigmaPi = mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaKa = mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaPr = mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + + emmllhpair(leptonTable.lastIndex(), + trackParCov.getQ2Pt(), trackParCov.getEta(), dcaXY_kaon, dcaZ_kaon, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), + kaon.tpcNSigmaPi(), tofNSigmaPi, + kaon.tpcNSigmaKa(), tofNSigmaKa, + kaon.tpcNSigmaPr(), tofNSigmaPr, + eKpair.mass, eKpair.dca2legs, eKpair.cospa, eKpair.cospaXY, + eKpair.lxyz, eKpair.lxyzErr, + eKpair.lxy, eKpair.lxyErr, + eKpair.lz, eKpair.lzErr, + mckaon.pdgCode(), pdgCodeIM, foundCommonMother); + + } // end of kaon loop + // D0bar -> e- anti-nu_e K+, br = 0.03538, ctau = 123.01 um, m = 1864 MeV/c2 for (const auto& kaonId : kaonPlusIds) { auto kaon = tracks.rawIteratorAt(kaonId); @@ -1537,15 +1693,16 @@ struct taggingHFE { continue; } + int pdgCodeIM = 0; auto mckaon = kaon.template mcParticle_as(); bool foundCommonMother = FindCommonMotherFrom2ProngsWithoutPDG(mcele, mckaon) > 0; if (mckaon.has_mothers() && !foundCommonMother) { auto mcMother_of_kaon = mckaon.template mothers_first_as(); - if (mcMother_of_kaon.pdgCode() == 323 || mcMother_of_kaon.pdgCode() == 313 || mcMother_of_kaon.pdgCode() == 333) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e + if (mcMother_of_kaon.pdgCode() == 323 || mcMother_of_kaon.pdgCode() == 313 || mcMother_of_kaon.pdgCode() == 333 || mcMother_of_kaon.pdgCode() == 413) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcele, mcMother_of_kaon); - if (commonMotherId > 0 && std::abs(mcParticles.rawIteratorAt(commonMotherId).pdgCode()) != 2212) { + if (commonMotherId > 0) { foundCommonMother = true; - // LOGF(info, "eK: e- and K*(892) or phi is found. mother is %d", mcParticles.rawIteratorAt(commonMotherId).pdgCode()); + pdgCodeIM = mcMother_of_kaon.pdgCode(); } } } @@ -1568,16 +1725,18 @@ struct taggingHFE { float tofNSigmaPi = mapTOFNsigmaPiReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; float tofNSigmaKa = mapTOFNsigmaKaReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; + float tofNSigmaPr = mapTOFNsigmaPrReassociated[std::make_pair(collision.globalIndex(), kaon.globalIndex())]; emmllhpair(leptonTable.lastIndex(), trackParCov.getQ2Pt(), trackParCov.getEta(), dcaXY_kaon, dcaZ_kaon, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), kaon.tpcNSigmaPi(), tofNSigmaPi, kaon.tpcNSigmaKa(), tofNSigmaKa, + kaon.tpcNSigmaPr(), tofNSigmaPr, eKpair.mass, eKpair.dca2legs, eKpair.cospa, eKpair.cospaXY, eKpair.lxyz, eKpair.lxyzErr, eKpair.lxy, eKpair.lxyErr, eKpair.lz, eKpair.lzErr, - mckaon.pdgCode(), foundCommonMother); + mckaon.pdgCode(), pdgCodeIM, foundCommonMother); } // end of kaon loop @@ -1631,9 +1790,8 @@ struct taggingHFE { auto mcMother_of_k0s = mcK0S.template mothers_first_as(); if (mcMother_of_k0s.pdgCode() == 323 || mcMother_of_k0s.pdgCode() == 313 || mcMother_of_k0s.pdgCode() == 333) { // accept short-lived resonances such as phi->KK, K*(892)->Kpi for D+ -> anti-K*0(892) e+ nu_e -> (K- pi+) e+ nu_e and Ds+ -> phi e+ nu_e int commonMotherId = FindCommonMotherFrom2ProngsWithoutPDG(mcele, mcMother_of_k0s); - if (commonMotherId > 0 && std::abs(mcParticles.rawIteratorAt(commonMotherId).pdgCode()) != 2212) { // proton decay is implemented. reject it. + if (commonMotherId > 0) { foundCommonMother = true; - // LOGF(info, "eK0S: e- and K*(892) or phi is found. mother is %d", mcParticles.rawIteratorAt(commonMotherId).pdgCode()); } } } @@ -2043,6 +2201,7 @@ struct taggingHFE { mapCollisionTimeError.clear(); mapTOFNsigmaPiReassociated.clear(); mapTOFNsigmaKaReassociated.clear(); + mapTOFNsigmaPrReassociated.clear(); mapTOFBetaReassociated.clear(); } PROCESS_SWITCH(taggingHFE, processMC, "process with TTCA", true); diff --git a/PWGEM/PhotonMeson/Tasks/photonResoTask.cxx b/PWGEM/PhotonMeson/Tasks/photonResoTask.cxx index 87ca1f0fb3a..3ae919f990c 100644 --- a/PWGEM/PhotonMeson/Tasks/photonResoTask.cxx +++ b/PWGEM/PhotonMeson/Tasks/photonResoTask.cxx @@ -49,6 +49,7 @@ #include #include +#include #include #include #include diff --git a/PWGEM/PhotonMeson/Utils/MCUtilities.h b/PWGEM/PhotonMeson/Utils/MCUtilities.h index 90568398c63..ff0b7307727 100644 --- a/PWGEM/PhotonMeson/Utils/MCUtilities.h +++ b/PWGEM/PhotonMeson/Utils/MCUtilities.h @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 1ffbbf3cd33..96296bf2c6b 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -114,6 +114,11 @@ o2physics_add_dpl_workflow(task-lc PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::SGCutParHolder O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-upc-lc + SOURCES taskUpcLc.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::SGCutParHolder O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-lc-to-k0s-p SOURCES taskLcToK0sP.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 14d9c2c190f..5279d032a1b 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -105,6 +105,12 @@ enum DecayChannel { DplusToPiKPi = 0, Xic0ToXiPi }; +enum RunMode { + kSP = 0, + kEsE, + kSPEsE, +}; + struct HfTaskFlowCharmHadrons { Produces rowCandMassPtMl; Produces rowCandMassPtMlSpCent; @@ -119,6 +125,7 @@ struct HfTaskFlowCharmHadrons { Configurable centralityMax{"centralityMax", 100., "Maximum centrality accepted in SP/EP computation (not applied in resolution process)"}; Configurable storeEP{"storeEP", false, "Flag to store EP-related axis"}; Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; + Configurable storeSPQVec{"storeSPQVec", true, "Flag to store the Q-vectors for SP"}; Configurable storeRedQVec{"storeRedQVec", false, "Flag to store reduced Q-vectors for ESE"}; Configurable fillMassPtMlTree{"fillMassPtMlTree", false, "Flag to fill mass, pt and ML scores tree"}; Configurable fillMassPtMlSpCentTree{"fillMassPtMlSpCentTree", false, "Flag to fill mass, pt, ML scores, SP and centrality tree"}; @@ -153,7 +160,9 @@ struct HfTaskFlowCharmHadrons { using CandXic0DataWMl = soa::Filtered>; using CandD0DataWMl = soa::Filtered>; using CandD0Data = soa::Filtered>; - using CollsWithQvecs = soa::Join; + using CollsWithSPQvecs = soa::Join; + using CollsWithEsEQvecs = soa::Join; + using CollsWithSPEsEQvecs = soa::Join; using TracksWithExtra = soa::Join; Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -212,6 +221,12 @@ struct HfTaskFlowCharmHadrons { if (storeResoOccu && occEstimator == 0) { LOGP(fatal, "Occupancy estimation must be enabled to store resolution THnSparse! Please check your configuration!"); } + if (storeRedQVec && !doprocessD0EsEMl && !doprocessD0SPEsEMl && !doprocessResolutionSPEsE) { + LOGP(fatal, "EsE q-vectors require dedicated process functions. Please check your configuration!"); + } + if (storeSPQVec && doprocessD0EsEMl) { + LOGP(fatal, "Scalar product tables not available for this process function. Please check your configuration!"); + } const AxisSpec thnAxisInvMass{thnConfigAxisInvMass, "Inv. mass (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality"}; @@ -237,7 +252,10 @@ struct HfTaskFlowCharmHadrons { const AxisSpec thnAxisResoFT0cTPCtot{thnConfigAxisResoFT0cTPCtot, "Q_{FT0c} #bullet Q_{TPCtot}"}; const AxisSpec thnAxisResoFV0aTPCtot{thnConfigAxisResoFV0aTPCtot, "Q_{FV0a} #bullet Q_{TPCtot}"}; - std::vector axes = {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisScalarProd}; + std::vector axes = {thnAxisInvMass, thnAxisPt, thnAxisCent}; + if (storeSPQVec) { + axes.insert(axes.end(), {thnAxisScalarProd}); + } if (storeEP) { axes.insert(axes.end(), {thnAxisCosNPhi, thnAxisSinNPhi, thnAxisCosDeltaPhi}); } @@ -279,7 +297,7 @@ struct HfTaskFlowCharmHadrons { registry.add("ep/hSparseEp", "THn for Event Plane distirbution", {HistType::kTHnSparseF, {thnAxisCent, thnAxisPsi, thnAxisCosNPhi, thnAxisSinNPhi}}); } - if (doprocessResolution) { // enable resolution histograms only for resolution process + if (doprocessResolutionSP || doprocessResolutionSPEsE) { // enable resolution histograms only for resolution process registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); registry.add("spReso/hSpResoFT0cFV0a", "hSpResoFT0cFV0a; centrality; Q_{FT0c} #bullet Q_{FV0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); @@ -298,9 +316,12 @@ struct HfTaskFlowCharmHadrons { registry.add("spReso/hSpResoFV0aTPCtot", "hSpResoFV0aTPCtot; centrality; Q_{FV0a} #bullet Q_{TPCtot}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); registry.add("spReso/hSpResoTPCposTPCneg", "hSpResoTPCposTPCneg; centrality; Q_{TPCpos} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - if (storeRedQVec) { + if (doprocessResolutionSPEsE) { registry.add("redQVecs/hSparseRedQVecs", "hSpResoRedQVec; centrality; Q_{red} #bullet Q_{TPCtot}", {HistType::kTHnSparseF, {thnAxisCent, thnAxisRedQVec, thnAxisRedQVec, thnAxisRedQVec, thnAxisRedQVec}}); registry.add("redQVecs/hRedQVecFT0C", "hRedQVecFT0C; centrality; q_{FT0c}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); + registry.add("redQVecs/hRedQVecFT0A", "hRedQVecFT0A; centrality; q_{FT0a}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); + registry.add("redQVecs/hRedQVecFT0M", "hRedQVecFT0M; centrality; q_{FT0m}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); + registry.add("redQVecs/hRedQVecFV0A", "hRedQVecFV0A; centrality; q_{FV0a}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); registry.add("redQVecs/hRedQVecTpcPos", "hRedQVecTpcPos; centrality; q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); registry.add("redQVecs/hRedQVecTpcNeg", "hRedQVecTpcNeg; centrality; q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); registry.add("redQVecs/hRedQVecTpcAll", "hRedQVecTpcAll; centrality; q_{TPCall}", {HistType::kTH2F, {thnAxisCent, thnAxisRedQVec}}); @@ -472,7 +493,9 @@ struct HfTaskFlowCharmHadrons { values.push_back(mass); values.push_back(pt); values.push_back(cent); - values.push_back(sp); + if (storeSPQVec) { + values.push_back(sp); + } if (storeEP) { values.push_back(cosNPhi); @@ -518,8 +541,8 @@ struct HfTaskFlowCharmHadrons { /// \param bc is the bunch crossing with timestamp information /// \param centrality is the collision centrality /// \return true if the collision is selected, false otherwise - template - bool isCollSelected(CollsWithQvecs::iterator const& collision, + template + bool isCollSelected(TCollision const& collision, aod::BCsWithTimestamps const&, float& centrality) { @@ -539,8 +562,8 @@ struct HfTaskFlowCharmHadrons { /// Compute the scalar product /// \param collision is the collision with the Q vector information and event plane /// \param candidates are the selected candidates - template - void runFlowAnalysis(CollsWithQvecs::iterator const& collision, + template + void runFlowAnalysis(TCollision const& collision, T1 const& candidates, Trk const& /*tracks*/) { @@ -563,7 +586,10 @@ struct HfTaskFlowCharmHadrons { float const sigmaMDplus = 0.015; // used 15 MeV as the D+ average peak width in run3 float const nSigmaMass = 2.5; - std::array qVecs = getQvec(collision, qVecDetector.value); + std::array qVecs{-999.f, -999.f, -999.f}; + if constexpr (StoreInfo == RunMode::kSP || StoreInfo == RunMode::kSPEsE) { + qVecs = getQvec(collision, qVecDetector.value); + } float xQVec = qVecs[0]; float yQVec = qVecs[1]; float const amplQVec = qVecs[2]; @@ -571,7 +597,7 @@ struct HfTaskFlowCharmHadrons { float redQVec{-999.f}; std::array qVecRedComps{-999.f, -999.f, -999.f}; - if (storeRedQVec) { + if constexpr (StoreInfo == RunMode::kEsE || StoreInfo == RunMode::kSPEsE) { qVecRedComps = getEseQvec(collision, qVecRedDetector.value); } float xRedQVec = qVecRedComps[0]; @@ -798,142 +824,169 @@ struct HfTaskFlowCharmHadrons { } // Ds with ML - void processDsMl(CollsWithQvecs::iterator const& collision, + void processDsMl(CollsWithSPQvecs::iterator const& collision, CandDsDataWMl const&, TracksWithExtra const& tracks) { auto candsDsToKKPiWMl = selectedDsToKKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsDsToPiKKWMl = selectedDsToPiKKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsDsToKKPiWMl, tracks); - runFlowAnalysis(collision, candsDsToPiKKWMl, tracks); + runFlowAnalysis(collision, candsDsToKKPiWMl, tracks); + runFlowAnalysis(collision, candsDsToPiKKWMl, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDsMl, "Process Ds candidates with ML", false); // Ds with rectangular cuts - void processDs(CollsWithQvecs::iterator const& collision, + void processDs(CollsWithSPQvecs::iterator const& collision, CandDsData const& /*candidatesDs*/, TracksWithExtra const& tracks) { auto candsDsToKKPi = selectedDsToKKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsDsToPiKK = selectedDsToPiKK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsDsToKKPi, tracks); - runFlowAnalysis(collision, candsDsToPiKK, tracks); + runFlowAnalysis(collision, candsDsToKKPi, tracks); + runFlowAnalysis(collision, candsDsToPiKK, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDs, "Process Ds candidates", false); // Dplus with ML - void processDplusMl(CollsWithQvecs::iterator const& collision, + void processDplusMl(CollsWithSPQvecs::iterator const& collision, CandDplusDataWMl const& candidatesDplus, TracksWithExtra const& tracks) { - runFlowAnalysis(collision, candidatesDplus, tracks); + runFlowAnalysis(collision, candidatesDplus, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplusMl, "Process Dplus candidates with ML", false); // Dplus with rectangular cuts - void processDplus(CollsWithQvecs::iterator const& collision, + void processDplus(CollsWithSPQvecs::iterator const& collision, CandDplusData const& candidatesDplus, TracksWithExtra const& tracks) { - runFlowAnalysis(collision, candidatesDplus, tracks); + runFlowAnalysis(collision, candidatesDplus, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplus, "Process Dplus candidates", true); // D0 with ML - void processD0Ml(CollsWithQvecs::iterator const& collision, + void processD0Ml(CollsWithSPQvecs::iterator const& collision, CandD0DataWMl const& /*candidatesD0*/, TracksWithExtra const& tracks) { auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsD0ToPiKWMl, tracks); - runFlowAnalysis(collision, candsD0ToKPiWMl, tracks); + runFlowAnalysis(collision, candsD0ToPiKWMl, tracks); + runFlowAnalysis(collision, candsD0ToKPiWMl, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0Ml, "Process D0 candidates with ML", false); + // D0 with ML + void processD0EsEMl(CollsWithEsEQvecs::iterator const& collision, + CandD0DataWMl const& /*candidatesD0*/, + TracksWithExtra const& tracks) + { + auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsD0ToPiKWMl, tracks); + runFlowAnalysis(collision, candsD0ToKPiWMl, tracks); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0EsEMl, "Process D0 candidates with ML for EsE information", false); + + // D0 with ML + void processD0SPEsEMl(CollsWithSPEsEQvecs::iterator const& collision, + CandD0DataWMl const& /*candidatesD0*/, + TracksWithExtra const& tracks) + { + auto candsD0ToPiKWMl = selectedD0ToPiKWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + auto candsD0ToKPiWMl = selectedD0ToKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + runFlowAnalysis(collision, candsD0ToPiKWMl, tracks); + runFlowAnalysis(collision, candsD0ToKPiWMl, tracks); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0SPEsEMl, "Process D0 candidates with ML for SP and EsE information", false); + // D0 with rectangular cuts - void processD0(CollsWithQvecs::iterator const& collision, + void processD0(CollsWithSPQvecs::iterator const& collision, CandD0Data const& /*candidatesD0*/, TracksWithExtra const& tracks) { auto candsD0ToPiK = selectedD0ToPiK->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsD0ToKPi = selectedD0ToKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsD0ToPiK, tracks); - runFlowAnalysis(collision, candsD0ToKPi, tracks); + runFlowAnalysis(collision, candsD0ToPiK, tracks); + runFlowAnalysis(collision, candsD0ToKPi, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processD0, "Process D0 candidates", false); // Lc with ML - void processLcMl(CollsWithQvecs::iterator const& collision, + void processLcMl(CollsWithSPQvecs::iterator const& collision, CandLcDataWMl const& /*candidatesLc*/, TracksWithExtra const& tracks) { auto candsLcToPKPiWMl = selectedLcToPKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsLcToPiKPWMl = selectedLcToPiKPWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsLcToPKPiWMl, tracks); - runFlowAnalysis(collision, candsLcToPiKPWMl, tracks); + runFlowAnalysis(collision, candsLcToPKPiWMl, tracks); + runFlowAnalysis(collision, candsLcToPiKPWMl, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processLcMl, "Process Lc candidates with ML", false); // Lc with rectangular cuts - void processLc(CollsWithQvecs::iterator const& collision, + void processLc(CollsWithSPQvecs::iterator const& collision, CandLcData const& /*candidatesLc*/, TracksWithExtra const& tracks) { auto candsLcToPKPi = selectedLcToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsLcToPiKP = selectedLcToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsLcToPKPi, tracks); - runFlowAnalysis(collision, candsLcToPiKP, tracks); + runFlowAnalysis(collision, candsLcToPKPi, tracks); + runFlowAnalysis(collision, candsLcToPiKP, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processLc, "Process Lc candidates", false); // Xic with ML - void processXicMl(CollsWithQvecs::iterator const& collision, + void processXicMl(CollsWithSPQvecs::iterator const& collision, CandXicDataWMl const& /*candidatesXic*/, TracksWithExtra const& tracks) { auto candsXicToPKPiWMl = selectedXicToPKPiWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsXicToPiKPWMl = selectedXicToPiKPWMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsXicToPKPiWMl, tracks); - runFlowAnalysis(collision, candsXicToPiKPWMl, tracks); + runFlowAnalysis(collision, candsXicToPKPiWMl, tracks); + runFlowAnalysis(collision, candsXicToPiKPWMl, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXicMl, "Process Xic candidates with ML", false); // Xic with rectangular cuts - void processXic(CollsWithQvecs::iterator const& collision, + void processXic(CollsWithSPQvecs::iterator const& collision, CandXicData const& /*candidatesXic*/, TracksWithExtra const& tracks) { auto candsXicToPKPi = selectedXicToPKPi->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); auto candsXicToPiKP = selectedXicToPiKP->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsXicToPKPi, tracks); - runFlowAnalysis(collision, candsXicToPiKP, tracks); + runFlowAnalysis(collision, candsXicToPKPi, tracks); + runFlowAnalysis(collision, candsXicToPiKP, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic, "Process Xic candidates", false); // Xic0 with ML - void processXic0Ml(CollsWithQvecs::iterator const& collision, + void processXic0Ml(CollsWithSPQvecs::iterator const& collision, CandXic0DataWMl const& /*candidatesXic0*/, TracksWithExtra const& tracks) { auto candsXic0WMl = selectedXic0WMl->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsXic0WMl, tracks); + runFlowAnalysis(collision, candsXic0WMl, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0Ml, "Process Xic0 candidates with ML", false); // Xic0 - void processXic0(CollsWithQvecs::iterator const& collision, + void processXic0(CollsWithSPQvecs::iterator const& collision, CandXic0Data const& /*candidatesXic0*/, TracksWithExtra const& tracks) { auto candsXic0 = selectedXic0->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); - runFlowAnalysis(collision, candsXic0, tracks); + runFlowAnalysis(collision, candsXic0, tracks); } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processXic0, "Process Xic0 candidates", false); - // Resolution - void processResolution(CollsWithQvecs::iterator const& collision, - aod::BCsWithTimestamps const& bcs) + /// Compute resolution + /// \param collision is the collision with the Q vector information + /// \param bcs is used for the event selection based on centrality estimators with time information + template + void fillResolution(TCollision const& collision, + aod::BCsWithTimestamps const& bcs) { float centrality{-1.f}; float const xQVecFT0a = collision.qvecFT0ARe(); @@ -944,12 +997,12 @@ struct HfTaskFlowCharmHadrons { float const yQVecFT0m = collision.qvecFT0MIm(); float const xQVecFV0a = collision.qvecFV0ARe(); float const yQVecFV0a = collision.qvecFV0AIm(); - float const xQVecTPCPos = collision.qvecTPCposRe(); - float const yQVecTPCPos = collision.qvecTPCposIm(); - float const xQVecTPCNeg = collision.qvecTPCnegRe(); - float const yQVecTPCNeg = collision.qvecTPCnegIm(); - float const xQVecTPCAll = collision.qvecTPCallRe(); - float const yQVecTPCAll = collision.qvecTPCallIm(); + float const xQVecTPCPos = collision.qvecBPosRe(); + float const yQVecTPCPos = collision.qvecBPosIm(); + float const xQVecTPCNeg = collision.qvecBNegRe(); + float const yQVecTPCNeg = collision.qvecBNegIm(); + float const xQVecTPCAll = collision.qvecBTotRe(); + float const yQVecTPCAll = collision.qvecBTotIm(); centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); if (storeResoOccu) { @@ -970,7 +1023,7 @@ struct HfTaskFlowCharmHadrons { registry.fill(HIST("hSparseCentEstimators"), o2::hf_centrality::getCentralityColl(collision, centEstimatorsForSparse->at(0)), o2::hf_centrality::getCentralityColl(collision, centEstimatorsForSparse->at(1)), o2::hf_centrality::getCentralityColl(collision, centEstimatorsForSparse->at(2)), o2::hf_centrality::getCentralityColl(collision, centEstimatorsForSparse->at(3))); } - if (storeRedQVec) { + if constexpr (HasRedQVecs) { registry.fill(HIST("redQVecs/hSparseRedQVecs"), centrality, std::hypot(collision.eseQvecFT0CRe(), collision.eseQvecFT0CIm()), std::hypot(collision.eseQvecTPCposRe(), collision.eseQvecTPCposIm()), @@ -1001,11 +1054,15 @@ struct HfTaskFlowCharmHadrons { registry.fill(HIST("spReso/hSpResoFV0aTPCtot"), centrality, xQVecFV0a * xQVecTPCAll + yQVecFV0a * yQVecTPCAll); registry.fill(HIST("spReso/hSpResoTPCposTPCneg"), centrality, xQVecTPCPos * xQVecTPCNeg + yQVecTPCPos * yQVecTPCNeg); - registry.fill(HIST("redQVecs/hRedQVecFT0C"), centrality, std::hypot(collision.eseQvecFT0CRe(), collision.eseQvecFT0CIm())); - registry.fill(HIST("redQVecs/hRedQVecTpcPos"), centrality, std::hypot(collision.eseQvecTPCposRe(), collision.eseQvecTPCposIm())); - registry.fill(HIST("redQVecs/hRedQVecTpcNeg"), centrality, std::hypot(collision.eseQvecTPCnegRe(), collision.eseQvecTPCnegIm())); - registry.fill(HIST("redQVecs/hRedQVecTpcAll"), centrality, std::hypot(collision.eseQvecTPCallRe(), collision.eseQvecTPCallIm())); - + if constexpr (HasRedQVecs) { + registry.fill(HIST("redQVecs/hRedQVecFT0C"), centrality, std::hypot(collision.eseQvecFT0CRe(), collision.eseQvecFT0CIm())); + registry.fill(HIST("redQVecs/hRedQVecFT0M"), centrality, std::hypot(collision.eseQvecFT0MRe(), collision.eseQvecFT0MIm())); + registry.fill(HIST("redQVecs/hRedQVecFT0A"), centrality, std::hypot(collision.eseQvecFT0ARe(), collision.eseQvecFT0AIm())); + registry.fill(HIST("redQVecs/hRedQVecFV0A"), centrality, std::hypot(collision.eseQvecFV0ARe(), collision.eseQvecFV0AIm())); + registry.fill(HIST("redQVecs/hRedQVecTpcPos"), centrality, std::hypot(collision.eseQvecTPCposRe(), collision.eseQvecTPCposIm())); + registry.fill(HIST("redQVecs/hRedQVecTpcNeg"), centrality, std::hypot(collision.eseQvecTPCnegRe(), collision.eseQvecTPCnegIm())); + registry.fill(HIST("redQVecs/hRedQVecTpcAll"), centrality, std::hypot(collision.eseQvecTPCallRe(), collision.eseQvecTPCallIm())); + } if (saveEpResoHisto) { float const epFT0a = epHelper.GetEventPlane(xQVecFT0a, yQVecFT0a, harmonic); float const epFT0c = epHelper.GetEventPlane(xQVecFT0c, yQVecFT0c, harmonic); @@ -1041,7 +1098,20 @@ struct HfTaskFlowCharmHadrons { std::sin(harmonic * epHelper.GetEventPlane(xQVecFT0c, yQVecFT0c, harmonic))); } } - PROCESS_SWITCH(HfTaskFlowCharmHadrons, processResolution, "Process resolution", false); + + void processResolutionSP(CollsWithSPQvecs::iterator const& collision, + aod::BCsWithTimestamps const& bcs) + { + fillResolution(collision, bcs); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processResolutionSP, "Process SP resolution", false); + + void processResolutionSPEsE(CollsWithSPEsEQvecs::iterator const& collision, + aod::BCsWithTimestamps const& bcs) + { + fillResolution(collision, bcs); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processResolutionSPEsE, "Process SP and EsE resolution", false); }; // End struct HfTaskFlowCharmHadrons diff --git a/PWGHF/D2H/Tasks/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index e7144cf505d..805ae3f05ed 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -17,7 +17,6 @@ /// \author Vít Kučera , CERN /// \author Annalena Kalteyer , GSI Darmstadt /// \author Biao Zhang , Heidelberg University -/// \author Ran Tu , Fudan University /// \author Oleksii Lubynets , Heidelberg University, GSI Darmstadt #include "PWGHF/Core/CentralityEstimation.h" @@ -29,9 +28,6 @@ #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGHF/Utils/utilsEvSelHf.h" -#include "PWGHF/Utils/utilsUpcHf.h" -#include "PWGUD/Core/SGSelector.h" -#include "PWGUD/Core/UPCHelpers.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -69,7 +65,6 @@ using namespace o2::framework::expressions; using namespace o2::hf_centrality; using namespace o2::hf_occupancy; using namespace o2::hf_evsel; -using namespace o2::analysis::hf_upc; /// Λc± → p± K∓ π± analysis task struct HfTaskLc { @@ -79,7 +74,6 @@ struct HfTaskLc { Configurable> binsPt{"binsPt", std::vector{hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits"}; // ThnSparse for ML outputScores and Vars Configurable fillTHn{"fillTHn", false, "fill THn"}; - Configurable fillUPCTHnLite{"fillUPCTHnLite", false, "fill THn"}; Configurable storeOccupancy{"storeOccupancy", true, "Flag to store occupancy information"}; Configurable occEstimator{"occEstimator", 2, "Occupancy estimation (None: 0, ITS: 1, FT0C: 2)"}; Configurable storeProperLifetime{"storeProperLifetime", false, "Flag to store proper lifetime"}; @@ -88,8 +82,7 @@ struct HfTaskLc { 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 - HfUpcGapThresholds upcThresholds; // UPC gap determination thresholds + HfEventSelection hfEvSel; // event selection and monitoring SliceCache cache; Service ccdb{}; @@ -127,13 +120,7 @@ struct HfTaskLc { ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Number of PV contributors"}; ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {14, 0, 14000}, "axis for centrality"}; ConfigurableAxis thnConfigAxisProperLifetime{"thnConfigAxisProperLifetime", {200, 0, 2}, "Proper lifetime, ps"}; - ConfigurableAxis thnConfigAxisGapType{"thnConfigAxisGapType", {7, -1.5, 5.5}, "axis for UPC gap type (see TrueGap enum in o2::aod::sgselector)"}; - ConfigurableAxis thnConfigAxisFV0A{"thnConfigAxisFV0A", {1001, -1.5, 999.5}, "axis for FV0-A amplitude (a.u.)"}; - ConfigurableAxis thnConfigAxisFT0{"thnConfigAxisFT0", {1001, -1.5, 999.5}, "axis for FT0 amplitude (a.u.)"}; - ConfigurableAxis thnConfigAxisZN{"thnConfigAxisZN", {510, -1.5, 49.5}, "axis for ZN energy (a.u.)"}; - ConfigurableAxis thnConfigAxisZNTime{"thnConfigAxisZNTime", {200, -10, 10}, "axis for ZN energy (a.u.)"}; HistogramRegistry registry{"registry", {}}; - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; // Factors for conversion between units constexpr static float CtToProperLifetimePs = 1.f / o2::constants::physics::LightSpeedCm2PS; @@ -157,13 +144,12 @@ struct HfTaskLc { void init(InitContext&) { - const std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessDataWithMl, doprocessDataWithMlWithFT0C, doprocessDataWithMlWithFT0M, doprocessDataWithMlWithUpc, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M, doprocessMcWithMl, doprocessMcWithMlWithFT0C, doprocessMcWithMlWithFT0M, doprocessDataStdWithUpc}; + const std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessDataWithMl, doprocessDataWithMlWithFT0C, doprocessDataWithMlWithFT0M, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M, doprocessMcWithMl, doprocessMcWithMlWithFT0C, doprocessMcWithMlWithFT0M}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "no or more than one process function enabled! Please check your configuration!"); } - const bool isData = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M || doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M || doprocessDataWithMlWithUpc; - const bool isUpc = doprocessDataWithMlWithUpc || doprocessDataStdWithUpc; + const bool isData = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M || doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M; auto addHistogramsRec = [&](const std::string& histoName, const std::string& xAxisTitle, const std::string& yAxisTitle, const HistogramConfigSpec& configSpec) { if (isData) { @@ -266,14 +252,6 @@ struct HfTaskLc { /// decay length error addHistogramsRec("hDecLenErrVsPt", "decay length error (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 1.}, {vbins}}}); - if (isUpc) { - 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, {{500, 0., 500}, {500, 0., 500}}}); - qaRegistry.add("Data/zdc/energyZNA_vs_energyZNC", "ZNA vs ZNC common energy;E_{ZNA}^{common} (a.u.);E_{ZNC}^{common} (a.u.)", {HistType::kTH2F, {{100, 0., 10}, {100, 0., 10}}}); - qaRegistry.add("Data/zdc/timeZNA_vs_timeZNC", "ZNA vs ZNC time;ZNA Time;ZNC time", {HistType::kTH2F, {{200, -10., 10}, {200, -10., 10}}}); - qaRegistry.add("Data/hUpcGapAfterSelection", "UPC gap type after selection;Gap side;Counts", {HistType::kTH1F, {{7, -1.5, 5.5}}}); - qaRegistry.add("Data/hUpcMulti", "Multiplicity of UPC events;Multiplicity;Counts", {HistType::kTH1F, {{200, -0.5, 199.5}}}); - qaRegistry.add("Data/hUpcVtz", "Vertex Z position of UPC events;Vz (cm);Counts", {HistType::kTH1F, {{200, -10., 10.}}}); - } 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})"}; @@ -293,39 +271,26 @@ struct HfTaskLc { const AxisSpec thnAxisTracklets{thnConfigAxisNumPvContr, "Number of PV contributors"}; const AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"}; const AxisSpec thnAxisProperLifetime{thnConfigAxisProperLifetime, "T_{proper} (ps)"}; - const AxisSpec thnAxisFV0A{thnConfigAxisFV0A, "FV0-A amplitude"}; - const AxisSpec thnAxisFT0A{thnConfigAxisFT0, "FT0-A amplitude"}; - const AxisSpec thnAxisFT0C{thnConfigAxisFT0, "FT0-C amplitude"}; - const AxisSpec thnAxisZNA{thnConfigAxisZN, "ZNA energy"}; - const AxisSpec thnAxisZNC{thnConfigAxisZN, "ZNC energy"}; - const AxisSpec thnAxisZNATime{thnConfigAxisZNTime, "ZNA time"}; - const AxisSpec thnAxisZNCTime{thnConfigAxisZNTime, "ZNC time"}; - - bool const isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M || doprocessDataWithMlWithUpc; + + bool const isDataWithMl = doprocessDataWithMl || doprocessDataWithMlWithFT0C || doprocessDataWithMlWithFT0M; bool const isMcWithMl = doprocessMcWithMl || doprocessMcWithMlWithFT0C || doprocessMcWithMlWithFT0M; - bool const isDataStd = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M || doprocessDataStdWithUpc; + bool const isDataStd = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M; bool const isMcStd = doprocessMcStd || doprocessMcStdWithFT0C || doprocessMcStdWithFT0M; - std::vector axesStd, axesWithBdt, axesGen, axesUpc, axesUpcWithBdt; + std::vector axesStd, axesWithBdt, axesGen; - if (isDataStd && !isUpc) { + if (isDataStd) { axesStd = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets}; } - if (isDataStd && isUpc) { - axesUpc = {thnAxisMass, thnAxisPt, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets, thnAxisFV0A, thnAxisFT0A, thnAxisFT0C, thnAxisZNA, thnAxisZNC, thnAxisZNATime, thnAxisZNCTime}; - } if (isMcStd) { axesStd = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisTracklets, thnAxisPtB, thnAxisCanType}; } if (isMcStd || isMcWithMl) { axesGen = {thnAxisPt, thnAxisCentrality, thnAxisY, thnAxisTracklets, thnAxisPtB, thnAxisCanType}; } - if (isDataWithMl && !isUpc) { + if (isDataWithMl) { axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets}; } - if (isDataWithMl && isUpc) { - axesUpcWithBdt = {thnAxisMass, thnAxisPt, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisFV0A, thnAxisFT0A, thnAxisFT0C, thnAxisZNA, thnAxisZNC, thnAxisZNATime, thnAxisZNCTime}; - } if (isMcWithMl) { axesWithBdt = {thnAxisMass, thnAxisPt, thnAxisCentrality, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcPrompt, thnAxisBdtScoreLcNonPrompt, thnAxisTracklets, thnAxisPtB, thnAxisCanType}; } @@ -344,13 +309,7 @@ struct HfTaskLc { } } } - if (isUpc) { - if (isDataStd) { - registry.add("hnLcUpcVars", "THn for Lambdac candidates for Data in UPC", HistType::kTHnSparseF, axesUpc); - } else if (isDataWithMl) { - registry.add("hnLcUpcVarsWithBdt", "THn for Lambdac candidates with BDT scores for data in UPC", HistType::kTHnSparseF, axesUpcWithBdt); - } - } else if (isDataWithMl) { + if (isDataWithMl) { registry.add("hnLcVarsWithBdt", "THn for Lambdac candidates with BDT scores for data with ML", HistType::kTHnSparseF, axesWithBdt); } else if (isMcWithMl) { registry.add("hnLcVarsWithBdt", "THn for Lambdac candidates with BDT scores for mc with ML", HistType::kTHnSparseF, axesWithBdt); @@ -363,10 +322,6 @@ struct HfTaskLc { } } - if (isUpc) { - hfEvSel.addHistograms(qaRegistry); // collision monitoring - } - ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -732,127 +687,6 @@ 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) { - float centrality{-1.f}; - const auto rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, qaRegistry, bcs); - if (rejectionMask != 0) { - /// at least one event selection not satisfied --> reject the candidate - continue; - } - const auto thisCollId = collision.globalIndex(); - const auto& groupedLcCandidates = candidates.sliceBy(candLcPerCollision, thisCollId); - const auto numPvContributors = collision.numContrib(); - const auto& bc = collision.template bc_as(); - - // Determine gap type using SGSelector with BC range checking - const auto gapResult = hf_upc::determineGapType(collision, bcs, upcThresholds); - const int gap = gapResult.value; - - // Use the BC with FIT activity if available from SGSelector - auto bcForUPC = bc; - if (gapResult.bc) { - bcForUPC = *(gapResult.bc); - } - - // Get FIT information from the UPC BC - upchelpers::FITInfo fitInfo{}; - udhelpers::getFITinfo(fitInfo, bcForUPC, bcs, ft0s, fv0as, fdds); - - // Get ZDC energies if available (extract once and reuse) - const bool hasZdc = bcForUPC.has_zdc(); - float zdcEnergyZNA = -1.f; - float zdcEnergyZNC = -1.f; - float zdcTimeZNA = -1.f; - float zdcTimeZNC = -1.f; - - if (hasZdc) { - const auto zdc = bcForUPC.zdc(); - zdcEnergyZNA = zdc.energyCommonZNA(); - zdcEnergyZNC = zdc.energyCommonZNC(); - zdcTimeZNA = zdc.timeZNA(); - zdcTimeZNC = zdc.timeZNC(); - qaRegistry.fill(HIST("Data/fitInfo/ampFT0A_vs_ampFT0C"), fitInfo.ampFT0A, fitInfo.ampFT0C); - qaRegistry.fill(HIST("Data/zdc/energyZNA_vs_energyZNC"), zdcEnergyZNA, zdcEnergyZNC); - qaRegistry.fill(HIST("Data/zdc/timeZNA_vs_timeZNC"), zdcTimeZNA, zdcTimeZNC); - qaRegistry.fill(HIST("Data/hUpcGapAfterSelection"), static_cast(gap)); - } - for (const auto& candidate : groupedLcCandidates) { - if (!(candidate.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { - continue; - } - if (yCandRecoMax >= 0. && std::abs(HfHelper::yLc(candidate)) > yCandRecoMax) { - continue; - } - const auto pt = candidate.pt(); - const auto ptProng0 = candidate.ptProng0(); - const auto ptProng1 = candidate.ptProng1(); - const auto ptProng2 = candidate.ptProng2(); - const auto decayLength = candidate.decayLength(); - const auto chi2PCA = candidate.chi2PCA(); - const auto cpa = candidate.cpa(); - if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { - qaRegistry.fill(HIST("Data/hUpcMulti"), collision.multNTracksPV()); - qaRegistry.fill(HIST("Data/hUpcVtz"), collision.posZ()); - } - - if (fillTHn) { - double outputBkg(-1), outputPrompt(-1), outputFD(-1); - - auto fillTHnData = [&](bool isPKPi) { - const auto massLc = isPKPi ? HfHelper::invMassLcToPKPi(candidate) : HfHelper::invMassLcToPiKP(candidate); - - if constexpr (FillMl) { - const auto& mlProb = isPKPi ? candidate.mlProbLcToPKPi() : candidate.mlProbLcToPiKP(); - if (mlProb.size() == NumberOfMlClasses) { - outputBkg = mlProb[MlClassBackground]; /// bkg score - outputPrompt = mlProb[MlClassPrompt]; /// prompt score - outputFD = mlProb[MlClassNonPrompt]; /// non-prompt score - } - /// Fill the ML outputScores and variables of candidate - if (fillUPCTHnLite) { - if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { - std::vector valuesToFill{massLc, pt, outputBkg, outputPrompt, outputFD, static_cast(numPvContributors), static_cast(fitInfo.ampFV0A), static_cast(fitInfo.ampFT0A), static_cast(fitInfo.ampFT0C), static_cast(zdcEnergyZNA), static_cast(zdcEnergyZNC), static_cast(zdcTimeZNA), static_cast(zdcTimeZNC)}; - registry.get(HIST("hnLcUpcVarsWithBdt"))->Fill(valuesToFill.data()); - } - } else { - std::vector valuesToFill{massLc, pt, outputBkg, outputPrompt, outputFD, static_cast(numPvContributors), static_cast(fitInfo.ampFV0A), static_cast(fitInfo.ampFT0A), static_cast(fitInfo.ampFT0C), static_cast(zdcEnergyZNA), static_cast(zdcEnergyZNC), static_cast(zdcTimeZNA), static_cast(zdcTimeZNC)}; - registry.get(HIST("hnLcUpcVarsWithBdt"))->Fill(valuesToFill.data()); - } - - } else { - if (fillUPCTHnLite) { - if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { - std::vector valuesToFill{massLc, pt, ptProng0, ptProng1, ptProng2, chi2PCA, decayLength, cpa, static_cast(numPvContributors), static_cast(fitInfo.ampFV0A), static_cast(fitInfo.ampFT0A), static_cast(fitInfo.ampFT0C), static_cast(zdcEnergyZNA), static_cast(zdcEnergyZNC), static_cast(zdcTimeZNA), static_cast(zdcTimeZNC)}; - registry.get(HIST("hnLcUpcVars"))->Fill(valuesToFill.data()); - } - } else { - std::vector valuesToFill{massLc, pt, ptProng0, ptProng1, ptProng2, chi2PCA, decayLength, cpa, static_cast(numPvContributors), static_cast(fitInfo.ampFV0A), static_cast(fitInfo.ampFT0A), static_cast(fitInfo.ampFT0C), static_cast(zdcEnergyZNA), static_cast(zdcEnergyZNC), static_cast(zdcTimeZNA), static_cast(zdcTimeZNC)}; - registry.get(HIST("hnLcUpcVars"))->Fill(valuesToFill.data()); - } - } - }; - - if (candidate.isSelLcToPKPi() >= selectionFlagLc) { - fillTHnData(true); - } - if (candidate.isSelLcToPiKP() >= selectionFlagLc) { - fillTHnData(false); - } - } - } - } - } - /// Run the analysis on MC data /// \tparam FillMl switch to fill ML histograms template @@ -916,32 +750,6 @@ 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 processDataStdWithUpc(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, processDataStdWithUpc, "Process real data with the standard method with UPC", false); - void processMcStd(CollisionsMc const& collisions, LcCandidatesMc const& selectedLcCandidatesMc, McParticles3ProngMatched const& mcParticles, diff --git a/PWGHF/D2H/Tasks/taskUpcLc.cxx b/PWGHF/D2H/Tasks/taskUpcLc.cxx new file mode 100644 index 00000000000..fcf2200a1e3 --- /dev/null +++ b/PWGHF/D2H/Tasks/taskUpcLc.cxx @@ -0,0 +1,351 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskUpcLc.cxx +/// \brief Λc± → p± K∓ π± analysis task +/// \note Extended from taskLc +/// +/// \author Biao Zhang , Heidelberg University +/// \author Ran Tu , Fudan University + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/DataModel/AliasTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" +#include "PWGHF/Utils/utilsEvSelHf.h" +#include "PWGHF/Utils/utilsUpcHf.h" +#include "PWGUD/Core/SGSelector.h" +#include "PWGUD/Core/UPCHelpers.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include // std::vector + +using namespace o2; +using namespace o2::analysis; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::hf_centrality; +using namespace o2::hf_evsel; +using namespace o2::analysis::hf_upc; + +namespace o2::aod +{ +namespace full +{ +DECLARE_SOA_COLUMN(M, m, float); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(BkgScore, bkgScore, float); +DECLARE_SOA_COLUMN(PromptScore, promptScore, float); +DECLARE_SOA_COLUMN(FdScore, fdScore, float); +DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); +DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); +DECLARE_SOA_COLUMN(PtProng2, ptProng2, float); +DECLARE_SOA_COLUMN(Chi2PCA, chi2PCA, float); +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); +DECLARE_SOA_COLUMN(Cpa, cpa, float); +DECLARE_SOA_COLUMN(PvContributors, pvContributors, float); +DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float); +DECLARE_SOA_COLUMN(Vtz, vtz, float); +DECLARE_SOA_COLUMN(AmpFV0A, ampFV0A, float); +DECLARE_SOA_COLUMN(AmpFT0A, ampFT0A, float); +DECLARE_SOA_COLUMN(AmpFT0C, ampFT0C, float); +DECLARE_SOA_COLUMN(ZdcTimeZNA, zdcTimeZNA, float); +DECLARE_SOA_COLUMN(ZdcTimeZNC, zdcTimeZNC, float); +} // namespace full +DECLARE_SOA_TABLE(HfUpcQa, "AOD", "HFUPCQA", + full::PvContributors, + full::Multiplicity, + full::Vtz, + full::AmpFV0A, + full::AmpFT0A, + full::AmpFT0C, + full::ZdcTimeZNA, + full::ZdcTimeZNC); + +DECLARE_SOA_TABLE(HfUpcLcBdtInfos, "AOD", "HFUPCLCBDTINFOS", + full::M, + full::Pt, + full::BkgScore, + full::PromptScore, + full::FdScore, + full::AmpFV0A, + full::AmpFT0A, + full::AmpFT0C, + full::ZdcTimeZNA, + full::ZdcTimeZNC); + +DECLARE_SOA_TABLE(HfUpcLcInfos, "AOD", "HFUPCLCINFOS", + full::M, + full::Pt, + full::PtProng0, + full::PtProng1, + full::PtProng2, + full::Chi2PCA, + full::DecayLength, + full::Cpa, + full::AmpFV0A, + full::AmpFT0A, + full::AmpFT0C, + full::ZdcTimeZNA, + full::ZdcTimeZNC); +} // namespace o2::aod + +/// Λc± → p± K∓ π± analysis task +struct HfTaskUpcLc { + Produces rowCandUpcBdt; + Produces rowCandUpc; + Produces rowUpcQa; + + Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; + Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; + Configurable> binsPt{"binsPt", std::vector{hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits"}; + Configurable fillTreeOnlySingleGap{"fillTreeOnlySingleGap", false, "Only fill the tree for candidates that pass the single-gap UPC events"}; + Configurable fillTreeUpcQa{"fillTreeUpcQa", false, "Fill Tree for UPC QA"}; + Configurable verticesWithUpc{"verticesWithUpc", false, "Consider vertices with UPC settings"}; + // CCDB configuration + 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 + HfUpcGapThresholds upcThresholds; // UPC gap determination thresholds + SliceCache cache; + Service ccdb{}; + + using Collisions = soa::Join; + + using LcCandidates = soa::Filtered>; + using LcCandidatesMl = soa::Filtered>; + + Filter filterSelectCandidates = aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc; + Preslice candLcPerCollision = aod::hf_cand::collisionId; + PresliceUnsorted colPerMcCollision = aod::mcparticle::mcCollisionId; + + HistogramRegistry registry{"registry", {}}; + + enum MlClasses : int { + MlClassBackground = 0, + MlClassPrompt, + MlClassNonPrompt, + NumberOfMlClasses + }; + + void init(InitContext&) + { + const std::array doprocess{doprocessDataWithMlWithUpc, doprocessDataStdWithUpc}; + 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; + registry.add("Data/fitInfo/ampFT0A_vs_ampFT0C", "FT0-A vs FT0-C amplitude;FT0-A amplitude (a.u.);FT0-C amplitude (a.u.)", {HistType::kTH2F, {{500, 0., 500}, {500, 0., 500}}}); + registry.add("Data/zdc/energyZNA_vs_energyZNC", "ZNA vs ZNC common energy;E_{ZNA}^{common} (a.u.);E_{ZNC}^{common} (a.u.)", {HistType::kTH2F, {{100, 0., 10}, {100, 0., 10}}}); + registry.add("Data/zdc/timeZNA_vs_timeZNC", "ZNA vs ZNC time;ZNA Time;ZNC time", {HistType::kTH2F, {{200, -10., 10}, {200, -10., 10}}}); + registry.add("Data/hUpcGapAfterSelection", "UPC gap type after selection;Gap side;Counts", {HistType::kTH1F, {{7, -1.5, 5.5}}}); + registry.add("Data/hUpcMulti", "Multiplicity of UPC events;Multiplicity;Counts", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("Data/hUpcVtz", "Vertex Z position of UPC events;Vz (cm);Counts", {HistType::kTH1F, {{200, -10., 10.}}}); + + hfEvSel.addHistograms(registry); + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) + /// \param collision is collision + /// \return centrality/multiplicity percentile of the collision + template + float evaluateCentralityColl(const Coll& collision) + { + return o2::hf_centrality::getCentralityColl(collision); + } + + 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) { + float centrality{-1.f}; + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); + if (rejectionMask != 0) { + /// at least one event selection not satisfied --> reject the candidate + continue; + } + const auto thisCollId = collision.globalIndex(); + const auto& groupedLcCandidates = candidates.sliceBy(candLcPerCollision, thisCollId); + const auto numPvContributors = collision.numContrib(); + const auto& bc = collision.template bc_as(); + + // Determine gap type using SGSelector with BC range checking + const auto gapResult = hf_upc::determineGapType(collision, bcs, upcThresholds); + const int gap = gapResult.value; + const int upcFlag = (collision.flags() & dataformats::Vertex>::Flags::UPCMode) ? 1 : 0; + + // Use the BC with FIT activity if available from SGSelector + auto bcForUPC = bc; + if (gapResult.bc) { + bcForUPC = *(gapResult.bc); + } + + // Get FIT information from the UPC BC + upchelpers::FITInfo fitInfo{}; + udhelpers::getFITinfo(fitInfo, bcForUPC, bcs, ft0s, fv0as, fdds); + + // Get ZDC energies if available (extract once and reuse) + const bool hasZdc = bcForUPC.has_zdc(); + float zdcEnergyZNA = -1.f; + float zdcEnergyZNC = -1.f; + float zdcTimeZNA = -1.f; + float zdcTimeZNC = -1.f; + if (verticesWithUpc && !upcFlag) { + continue; + } + if (hasZdc) { + const auto zdc = bcForUPC.zdc(); + zdcEnergyZNA = zdc.energyCommonZNA(); + zdcEnergyZNC = zdc.energyCommonZNC(); + zdcTimeZNA = zdc.timeZNA(); + zdcTimeZNC = zdc.timeZNC(); + registry.fill(HIST("Data/fitInfo/ampFT0A_vs_ampFT0C"), fitInfo.ampFT0A, fitInfo.ampFT0C); + registry.fill(HIST("Data/zdc/energyZNA_vs_energyZNC"), zdcEnergyZNA, zdcEnergyZNC); + registry.fill(HIST("Data/zdc/timeZNA_vs_timeZNC"), zdcTimeZNA, zdcTimeZNC); + registry.fill(HIST("Data/hUpcGapAfterSelection"), static_cast(gap)); + } + if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { + registry.fill(HIST("Data/hUpcMulti"), collision.multNTracksPV()); + registry.fill(HIST("Data/hUpcVtz"), collision.posZ()); + } + if (fillTreeUpcQa) { + rowUpcQa(numPvContributors, collision.multNTracksPV(), collision.posZ(), fitInfo.ampFV0A, fitInfo.ampFT0A, fitInfo.ampFT0C, zdcTimeZNA, zdcTimeZNC); + } + + for (const auto& candidate : groupedLcCandidates) { + if (!(candidate.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { + continue; + } + if (yCandRecoMax >= 0. && std::abs(HfHelper::yLc(candidate)) > yCandRecoMax) { + continue; + } + const auto pt = candidate.pt(); + const auto ptProng0 = candidate.ptProng0(); + const auto ptProng1 = candidate.ptProng1(); + const auto ptProng2 = candidate.ptProng2(); + const auto decayLength = candidate.decayLength(); + const auto chi2PCA = candidate.chi2PCA(); + const auto cpa = candidate.cpa(); + + double outputBkg(-1), outputPrompt(-1), outputFD(-1); + + auto fillTHnData = [&](bool isPKPi) { + const auto massLc = isPKPi ? HfHelper::invMassLcToPKPi(candidate) : HfHelper::invMassLcToPiKP(candidate); + + if constexpr (FillMl) { + const auto& mlProb = isPKPi ? candidate.mlProbLcToPKPi() : candidate.mlProbLcToPiKP(); + if (mlProb.size() == NumberOfMlClasses) { + outputBkg = mlProb[MlClassBackground]; /// bkg score + outputPrompt = mlProb[MlClassPrompt]; /// prompt score + outputFD = mlProb[MlClassNonPrompt]; /// non-prompt score + } + /// Fill the ML outputScores and variables of candidate + if (fillTreeOnlySingleGap) { + if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { + rowCandUpcBdt(massLc, pt, outputBkg, outputPrompt, outputFD, fitInfo.ampFV0A, fitInfo.ampFT0A, fitInfo.ampFT0C, zdcTimeZNA, zdcTimeZNC); + } + } else { + rowCandUpcBdt(massLc, pt, outputBkg, outputPrompt, outputFD, fitInfo.ampFV0A, fitInfo.ampFT0A, fitInfo.ampFT0C, zdcTimeZNA, zdcTimeZNC); + } + + } else { + if (fillTreeOnlySingleGap) { + if (gap == o2::aod::sgselector::TrueGap::SingleGapA || gap == o2::aod::sgselector::TrueGap::SingleGapC) { + rowCandUpc(massLc, pt, ptProng0, ptProng1, ptProng2, chi2PCA, decayLength, cpa, fitInfo.ampFV0A, fitInfo.ampFT0A, fitInfo.ampFT0C, zdcTimeZNA, zdcTimeZNC); + } + } else { + rowCandUpc(massLc, pt, ptProng0, ptProng1, ptProng2, chi2PCA, decayLength, cpa, fitInfo.ampFV0A, fitInfo.ampFT0A, fitInfo.ampFT0C, zdcTimeZNA, zdcTimeZNC); + } + } + }; + + if (candidate.isSelLcToPKPi() >= selectionFlagLc) { + fillTHnData(true); + } + if (candidate.isSelLcToPiKP() >= selectionFlagLc) { + fillTHnData(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(HfTaskUpcLc, processDataWithMlWithUpc, "Process real data with the ML method with UPC", false); + + void processDataStdWithUpc(soa::Join const& collisions, + aod::BcFullInfos const& bcs, + LcCandidates const& selectedLcCandidates, + aod::Tracks const&, + aod::FT0s const& ft0s, + aod::FV0As const& fv0as, + aod::FDDs const& fdds, + aod::Zdcs const& /*zdcs*/) + { + runAnalysisPerCollisionDataWithUpc(collisions, selectedLcCandidates, bcs, ft0s, fv0as, fdds); + } + PROCESS_SWITCH(HfTaskUpcLc, processDataStdWithUpc, "Process real data with the standard method with UPC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/Utils/utilsFlow.h b/PWGHF/D2H/Utils/utilsFlow.h index 911fc60dd2c..02171203eba 100644 --- a/PWGHF/D2H/Utils/utilsFlow.h +++ b/PWGHF/D2H/Utils/utilsFlow.h @@ -202,6 +202,49 @@ std::array getQvec(TCollision const& collision, const int qvecEst) return std::array{-999.f, -999.f, -999.f}; } +/// Get the EsE Q vector +template +concept HasEsEQvecFT0A = requires(T collision) { + collision.eseQvecFT0ARe(); + collision.eseQvecFT0AIm(); +}; + +template +concept HasEsEQvecFT0C = requires(T collision) { + collision.eseQvecFT0CRe(); + collision.eseQvecFT0CIm(); +}; + +template +concept HasEsEQvecFT0M = requires(T collision) { + collision.eseQvecFT0MRe(); + collision.eseQvecFT0MIm(); +}; + +template +concept HasEsEQvecFV0A = requires(T collision) { + collision.eseQvecFV0ARe(); + collision.eseQvecFV0AIm(); +}; + +template +concept HasEsEQvecTPCpos = requires(T collision) { + collision.eseQvecTPCposRe(); + collision.eseQvecTPCposIm(); +}; + +template +concept HasEsEQvecTPCneg = requires(T collision) { + collision.eseQvecTPCnegRe(); + collision.eseQvecTPCnegIm(); +}; + +template +concept HasEsEQvecTPCtot = requires(T collision) { + collision.eseQvecTPCallRe(); + collision.eseQvecTPCallIm(); +}; + /// Get the Ese Q vector choosing your favourite estimator /// \param collision is the collision with the Q vector information /// \param qvecEst is the chosen Q-vector estimator @@ -210,37 +253,37 @@ std::array getEseQvec(TCollision const& collision, const int qvecEst) { switch (qvecEst) { case QvecEstimator::FV0A: - if constexpr (HasQvecFV0A) { + if constexpr (HasEsEQvecFV0A) { return std::array{collision.eseQvecFV0ARe(), collision.eseQvecFV0AIm(), collision.sumAmplFV0A()}; } break; case QvecEstimator::FT0A: - if constexpr (HasQvecFT0A) { + if constexpr (HasEsEQvecFT0A) { return std::array{collision.eseQvecFT0ARe(), collision.eseQvecFT0AIm(), collision.sumAmplFT0A()}; } break; case QvecEstimator::FT0C: - if constexpr (HasQvecFT0C) { + if constexpr (HasEsEQvecFT0C) { return std::array{collision.eseQvecFT0CRe(), collision.eseQvecFT0CIm(), collision.sumAmplFT0C()}; } break; case QvecEstimator::FT0M: - if constexpr (HasQvecFT0M) { + if constexpr (HasEsEQvecFT0M) { return std::array{collision.eseQvecFT0MRe(), collision.eseQvecFT0MIm(), collision.sumAmplFT0M()}; } break; case QvecEstimator::TPCPos: - if constexpr (HasQvecTPCpos) { + if constexpr (HasEsEQvecTPCpos) { return std::array{collision.eseQvecTPCposRe(), collision.eseQvecTPCposIm(), static_cast(collision.nTrkTPCpos())}; } break; case QvecEstimator::TPCNeg: - if constexpr (HasQvecTPCneg) { + if constexpr (HasEsEQvecTPCneg) { return std::array{collision.eseQvecTPCnegRe(), collision.eseQvecTPCnegIm(), static_cast(collision.nTrkTPCneg())}; } break; case QvecEstimator::TPCTot: - if constexpr (HasQvecTPCtot) { + if constexpr (HasEsEQvecTPCtot) { return std::array{collision.eseQvecTPCallRe(), collision.eseQvecTPCallIm(), static_cast(collision.nTrkTPCall())}; } break; diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index eb197529980..fcfd59ea839 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -391,7 +391,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { if (std::abs(nSigmaCombKa) >= kaonPidSel.nSigmaCombKaTightMax) { isTrackKaonPidMethod2 = false; } - if (std::abs(nSigmaCombPi) >= kaonPidSel.nSigmaCombPiMax) { + if (std::abs(nSigmaCombPi) <= kaonPidSel.nSigmaCombPiMax) { isTrackKaonPidMethod2 = false; } } diff --git a/PWGJE/DataModel/EMCALClusters.h b/PWGJE/DataModel/EMCALClusters.h index 5f85849bcc6..d711a5e08b9 100644 --- a/PWGJE/DataModel/EMCALClusters.h +++ b/PWGJE/DataModel/EMCALClusters.h @@ -50,6 +50,8 @@ const EMCALClusterDefinition kV3MostSplitSmallTimeDiff(ClusterAlgorithm_t::kV3, const EMCALClusterDefinition kV3MostSplitSmallerTimeDiff(ClusterAlgorithm_t::kV3, 44, 1, "kV3MostSplitSmallerTimeDiff", 0.5, 0.1, -10000, 10000, 100, true, 0., false); const EMCALClusterDefinition kV3MostSplitSmallestTimeDiff(ClusterAlgorithm_t::kV3, 45, 1, "kV3MostSplitSmallestTimeDiff", 0.5, 0.1, -10000, 10000, 50, true, 0., false); const EMCALClusterDefinition kV3MostSplitSmallestTimeDiffLowestSeed(ClusterAlgorithm_t::kV3, 50, 1, "kV3MostSplitSmallestTimeDiffLowestSeed", 0.1, 0.1, -10000, 10000, 50, true, 0., false); +const EMCALClusterDefinition kV3MostSplitSmallestTimeDiffLowSeed(ClusterAlgorithm_t::kV3, 51, 1, "kV3MostSplitSmallestTimeDiffLowSeed", 0.3, 0.1, -10000, 10000, 50, true, 0., false); +const EMCALClusterDefinition kV3MostSplitSmallestTimeDiffLowerSeed(ClusterAlgorithm_t::kV3, 52, 1, "kV3MostSplitSmallestTimeDiffLowerSeed", 0.2, 0.1, -10000, 10000, 50, true, 0., false); /// \brief function returns EMCALClusterDefinition for the given name /// \param name name of the cluster definition @@ -92,6 +94,10 @@ inline const EMCALClusterDefinition getClusterDefinitionFromString(const std::st return kV3MostSplitSmallestTimeDiff; } else if (clusterDefinitionName == "kV3MostSplitSmallestTimeDiffLowestSeed") { return kV3MostSplitSmallestTimeDiffLowestSeed; + } else if (clusterDefinitionName == "kV3MostSplitSmallestTimeDiffLowSeed") { + return kV3MostSplitSmallestTimeDiffLowSeed; + } else if (clusterDefinitionName == "kV3MostSplitSmallestTimeDiffLowerSeed") { + return kV3MostSplitSmallestTimeDiffLowerSeed; } else { throw std::invalid_argument("Cluster definition name not recognized"); } diff --git a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx index c1ee4dd3b73..d722cb4d743 100644 --- a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx +++ b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx @@ -283,7 +283,7 @@ struct SecondaryVertexReconstruction { zMomenta, energySV, massSV, chi2PCA, dispersion, errorDecayLength, errorDecayLengthXY); svIndices.push_back(sv2prongTableData.lastIndex()); - } else if ((doprocessDataNProngs || doprocessDataNProngsExternalMagneticField) && numProngs == TwoProngCount) { + } else if ((doprocessDataNProngs || doprocessDataNProngsExternalMagneticField)) { svnprongTableData(analysisJet.globalIndex(), primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), secondaryVertex[0], secondaryVertex[1], secondaryVertex[2], diff --git a/PWGJE/Tasks/bjetCentMult.cxx b/PWGJE/Tasks/bjetCentMult.cxx index fa0beb6081d..545fd434db0 100644 --- a/PWGJE/Tasks/bjetCentMult.cxx +++ b/PWGJE/Tasks/bjetCentMult.cxx @@ -144,7 +144,7 @@ struct BjetCentMultTask { registry.add("h2_centrality_percentile_multiplicity", "mcd collision centrality; centrality; counts", {HistType::kTH2F, {{axisRebinnedCentrality}, {axisPercentileMultiplicity}}}); } if (doprocessSVData) { - registry.add("h_event_rhoareasubtracted_centrality", "", {HistType::kTH1F, {{axisCentrality}}}); + registry.add("h_event_centrality", "", {HistType::kTH1F, {{axisCentrality}}}); registry.add("h2_jet_pt_centrality", "", {HistType::kTH2F, {{axisJetPt}, {axisCentrality}}}); registry.add("h2_jet_eta_centrality", "", {HistType::kTH2F, {{axisEta}, {axisCentrality}}}); registry.add("h2_jet_phi_centrality", "", {HistType::kTH2F, {{axisPhi}, {axisCentrality}}}); @@ -163,7 +163,7 @@ struct BjetCentMultTask { } } if (doprocessRhoAreaSubSVData) { - registry.add("h_event_centrality", "", {HistType::kTH1F, {{axisCentrality}}}); + registry.add("h_event_rhoareasubtracted_centrality", "", {HistType::kTH1F, {{axisCentrality}}}); registry.add("h2_jet_pt_rhoareasubtracted_centrality", "", {HistType::kTH2F, {{axisJetPt}, {axisCentrality}}}); registry.add("h2_jet_eta_rhoareasubtracted_centrality", "", {HistType::kTH2F, {{axisEta}, {axisCentrality}}}); registry.add("h2_jet_phi_rhoareasubtracted_centrality", "", {HistType::kTH2F, {{axisPhi}, {axisCentrality}}}); diff --git a/PWGJE/Tasks/jetSpectraEseTask.cxx b/PWGJE/Tasks/jetSpectraEseTask.cxx index c459561b70c..04ac8b3c1e7 100644 --- a/PWGJE/Tasks/jetSpectraEseTask.cxx +++ b/PWGJE/Tasks/jetSpectraEseTask.cxx @@ -412,8 +412,11 @@ struct JetSpectraEseTask { registry.add("hTrackPt", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTHnSparseF, {{centAxis}, {100, 0, 100}, {eseAxis}, {occAxis}}}); registry.add("hTrackEta", "track #eta;#eta_{track};entries", {HistType::kTH3F, {{centAxis}, {etaAxis}, {occAxis}}}); registry.add("hTrackPhi", "track #phi;#phi_{track};entries", {HistType::kTH3F, {{centAxis}, {phiAxis}, {occAxis}}}); - registry.add("hOccupancy", "Occupancy;Occupancy;entries", {HistType::kTH1F, {{occAxis}}}); + registry.add("hOccupancy", "Occupancy;Occupancy;entries", {HistType::kTH2F, {{centAxis}, {occAxis}}}); + registry.add("hOccupancyEv", "Occupancy;Occupancy;entries", {HistType::kTH1F, {{centAxis}, {occAxis}}}); registry.add("hPsiOccupancy", "Occupancy;#Psi_{2};entries", {HistType::kTH3F, {{centAxis}, {150, -2.5, 2.5}, {occAxis}}}); + registry.add("hSTrackPtPhiEtaOcc", ";cent;jpt;phi;eta;occ", {HistType::kTHnSparseF, {{centAxis}, {100, 0, 100}, {phiAxis}, {etaAxis}, {occAxis}}}); + registry.add("hSJetPtPhiEtaOcc", ";cent;jpt;phi;eta;occ", {HistType::kTHnSparseF, {{centAxis}, {jetPtAxis}, {phiAxis}, {etaAxis}, {occAxis}}}); } if (doprocessMCGenTrack) { LOGF(info, "JetSpectraEseTask::init() - MCGen track"); @@ -723,7 +726,7 @@ struct JetSpectraEseTask { PROCESS_SWITCH(JetSpectraEseTask, processESEBackground, "process random cones with event plane and ESE", false); void processESEOccupancy(soa::Join::iterator const& collision, - soa::Join const& tracks) + soa::Join const& tracks, soa::Filtered> const& jets) { float count{0.5}; registry.fill(HIST("hEventCounterOcc"), count++); @@ -732,22 +735,32 @@ struct JetSpectraEseTask { auto occupancy{collision.trackOccupancyInTimeRange()}; registry.fill(HIST("hPsiOccupancy"), collision.centFT0M(), psi.psi2, occupancy); - registry.fill(HIST("hOccupancy"), occupancy); + registry.fill(HIST("hOccupancy"), collision.centFT0M(), occupancy); if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) return; registry.fill(HIST("hEventCounterOcc"), count++); + registry.fill(HIST("hOccupancyEv"), collision.centFT0M(), occupancy); for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; registry.fill(HIST("hTrackPt"), collision.centFT0M(), track.pt(), qPerc[0], occupancy); + registry.fill(HIST("hSTrackPtPhiEtaOcc"), collision.centFT0M(), track.pt(), track.phi(), track.eta(), occupancy); if (track.pt() < cfgOccupancyPtCut->at(0) || track.pt() > cfgOccupancyPtCut->at(1)) continue; registry.fill(HIST("hTrackEta"), collision.centFT0M(), track.eta(), occupancy); registry.fill(HIST("hTrackPhi"), collision.centFT0M(), track.phi(), occupancy); } + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + continue; + if (!isAcceptedJet(jet)) { + continue; + } + registry.fill(HIST("hSJetPtPhiEtaOcc"), collision.centFT0M(), jet.pt(), jet.phi(), jet.eta(), occupancy); + } } PROCESS_SWITCH(JetSpectraEseTask, processESEOccupancy, "process occupancy", false); diff --git a/PWGLF/Tasks/QC/mcParticlePrediction.cxx b/PWGLF/Tasks/QC/mcParticlePrediction.cxx index 0da77c92ee9..2f506ba14e5 100644 --- a/PWGLF/Tasks/QC/mcParticlePrediction.cxx +++ b/PWGLF/Tasks/QC/mcParticlePrediction.cxx @@ -57,7 +57,7 @@ using namespace o2::pwglf; // Particles static const std::vector parameterNames{"Enable"}; static constexpr int nParameters = 1; -static const int defaultParticles[PIDExtended::NIDsTot][nParameters]{{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}; +static const int defaultParticles[PIDExtended::NIDsTot][nParameters]{{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {1}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}; bool enabledParticlesArray[PIDExtended::NIDsTot]; // Estimators diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index 55606515998..c5d120deb0e 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -2186,8 +2186,8 @@ struct HStrangeCorrelation { continue; float efficiency = 1.0f; float purity = 1.0f; - histos.fill(HIST("hDCAzAssocHadron"), assoc.dcaZ(), assoc.pt()); - histos.fill(HIST("hDCAxyAssocHadron"), assoc.dcaXY(), assoc.pt()); + histos.fill(HIST("hDCAzAssociatedHadron"), assoc.dcaZ(), assoc.pt()); + histos.fill(HIST("hDCAxyAssociatedHadron"), assoc.dcaXY(), assoc.pt()); if (efficiencyFlags.applyEfficiencyCorrection) { efficiency = hEfficiencyHadron->Interpolate(assoc.pt(), assoc.eta()); if (efficiencyFlags.applyPurityHadron) diff --git a/PWGLF/Utils/mcParticle.h b/PWGLF/Utils/mcParticle.h index 4f7690bc7e1..657e696ec9a 100644 --- a/PWGLF/Utils/mcParticle.h +++ b/PWGLF/Utils/mcParticle.h @@ -131,7 +131,10 @@ class PIDExtended static constexpr ID XiCPlus = PIDCounts + 37; static constexpr ID XiC0 = PIDCounts + 38; static constexpr ID Kstar = PIDCounts + 39; - static constexpr ID NIDsTot = PIDCounts + 40; + static constexpr ID KstarPM = PIDCounts + 40; + static constexpr ID Kshort = PIDCounts + 41; + static constexpr ID Xi1530 = PIDCounts + 42; + static constexpr ID NIDsTot = PIDCounts + 43; static constexpr const char* sNames[NIDsTot + 1] = { o2::track::pid_constants::sNames[Electron], // Electron @@ -193,6 +196,9 @@ class PIDExtended "XiCPlus", // XiCPlus "XiC0", // XiC0 "Kstar", // Kstar + "KstarPM", // KstarPM + "Kshort", // Kshort + "Xi1530", // Xi1530 nullptr}; static std::vector arrayNames() @@ -329,6 +335,12 @@ class PIDExtended return XiC0; case o2::constants::physics::Pdg::kK0Star892: return Kstar; + case 323: + return KstarPM; + case 310: + return Kshort; + case 3324: + return Xi1530; default: LOG(debug) << "Cannot identify particle with PDG code " << particle.pdgCode(); break; diff --git a/Scripts/format_includes.awk b/Scripts/format_includes.awk index ac22332acc5..d024e91e79c 100644 --- a/Scripts/format_includes.awk +++ b/Scripts/format_includes.awk @@ -7,7 +7,7 @@ if ($1 ~ /^#include/) { h = substr($2, 2, length($2) - 2) if ( h ~ /^(PWG[A-Z]{2}|Common|ALICE3|DPG|EventFiltering|Tools|Tutorials)\/.*\.h/ ) { $2 = "\""h"\"" } # O2Physics - else if ( h ~ /^(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|Field|Framework|FT0|FV0|GlobalTracking|GPU|ITS|MathUtils|MFT|MCH|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*\/.*\.h/ ) { $2 = "<"h">" } # O2 + else if ( h ~ /^(Algorithm|CCDB|Common[A-Z]|DataFormats|DCAFitter|Detectors|EMCAL|FDD|Field|Framework|FT0|FV0|GlobalTracking|GPU|ITS|MathUtils|MCH|MFT|MID|PHOS|PID|ReconstructionDataFormats|SimulationDataFormat|TOF|TPC|ZDC).*\/.*\.h/ ) { $2 = "<"h">" } # O2 else if ( h ~ /^(T[A-Z]|Math\/|Roo[A-Z])[[:alnum:]\/]+\.h/ ) { $2 = "<"h">" } # ROOT else if ( h ~ /^KF[A-Z][[:alnum:]]+\.h/ ) { $2 = "<"h">" } # KFParticle else if ( h ~ /^(fastjet\/|onnxruntime)/ ) { $2 = "<"h">" } # FastJet, ONNX